func()

in dbconn/dbconn.go [190:249]


func (dbconn *DBConn) Connect(numConns int, utilityMode ...bool) error {
	if numConns < 1 {
		return errors.Errorf("Must specify a connection pool size that is a positive integer")
	}
	if dbconn.ConnPool != nil {
		return errors.Errorf("The database connection must be closed before reusing the connection")
	}
	// This string takes in the literal user/database names. They do not need
	// to be escaped or quoted.
	// By default pgx/v4 turns on automatic prepared statement caching. This
	// causes an issue in GPDB4 where creating an object, deleting it, creating
	// the same object again, then querying for the object in the same
	// connection will generate a cache lookup failure. To disable pgx's
	// automatic prepared statement cache we set statement_cache_capacity to 0.
	connStr := fmt.Sprintf("postgres://%s@%s:%d/%s?sslmode=disable&statement_cache_capacity=0", dbconn.User, dbconn.Host, dbconn.Port, dbconn.DBName)

	dbconn.ConnPool = make([]*sqlx.DB, numConns)
	if len(utilityMode) > 1 {
		return errors.Errorf("The utility mode parameter accepts exactly one boolean value")
	} else if len(utilityMode) == 1 && utilityMode[0] {
		// The utility mode GUC differs between GPDB 7 and later (gp_role)
		// and GPDB 6 and earlier (gp_session_role), and we don't get the
		// database version until after the connection is established, so
		// we need to just try one first and see whether it works.
		roleConnStr := connStr + "&gp_role=utility"
		sessionRoleConnStr := connStr + "&gp_session_role=utility"
		utilConn, err := dbconn.Driver.Connect("pgx", sessionRoleConnStr)
		if utilConn != nil {
			utilConn.Close()
		}
		if err != nil {
			if strings.Contains(err.Error(), `unrecognized configuration parameter "gp_session_role"`) {
				connStr = roleConnStr
			} else {
				return dbconn.handleConnectionError(err)
			}
		} else {
			connStr = sessionRoleConnStr
		}
	}

	for i := 0; i < numConns; i++ {
		conn, err := dbconn.Driver.Connect("pgx", connStr)
		err = dbconn.handleConnectionError(err)
		if err != nil {
			return err
		}
		conn.SetMaxOpenConns(1)
		conn.SetMaxIdleConns(1)
		dbconn.ConnPool[i] = conn
	}
	dbconn.Tx = make([]*sqlx.Tx, numConns)
	dbconn.NumConns = numConns
	version, err := InitializeVersion(dbconn)
	if err != nil {
		return errors.Wrap(err, "Failed to determine database version")
	}
	dbconn.Version = version
	return nil
}