Skip to content

Commit e6e5981

Browse files
committed
Allow pgxpool to more easily use LoadTypes
While LoadTypes is powerful on its own, retriving all salient type information in a single query, it is particularly powerful and useful when users of pgxpool can use this. To streamline its use, provide a helper function in pgxpool suitable for plugging directly into the AfterConnect configuration settings. It will load the types and register them, also reusing them if appropriate.
1 parent 161ce73 commit e6e5981

File tree

1 file changed

+56
-5
lines changed

1 file changed

+56
-5
lines changed

pgxpool/pool.go

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import (
1212

1313
"github.com/jackc/pgx/v5"
1414
"github.com/jackc/pgx/v5/pgconn"
15+
"github.com/jackc/pgx/v5/pgtype"
1516
"github.com/jackc/puddle/v2"
1617
)
1718

18-
var defaultMaxConns = int32(4)
19-
var defaultMinConns = int32(0)
20-
var defaultMaxConnLifetime = time.Hour
21-
var defaultMaxConnIdleTime = time.Minute * 30
22-
var defaultHealthCheckPeriod = time.Minute
19+
var (
20+
defaultMaxConns = int32(4)
21+
defaultMinConns = int32(0)
22+
defaultMaxConnLifetime = time.Hour
23+
defaultMaxConnIdleTime = time.Minute * 30
24+
defaultHealthCheckPeriod = time.Minute
25+
)
2326

2427
type connResource struct {
2528
conn *pgx.Conn
@@ -102,6 +105,54 @@ type Pool struct {
102105
closeChan chan struct{}
103106
}
104107

108+
// LoadTypesAfterConnect is suitable for assigning to the AfterConnect configuration setting.
109+
// It will automatically load the named types for each connection in an efficient manner,
110+
// performing a single query to the database backend. The underlying call to pgx.LoadTypes
111+
// is smart enough to also retrieve any related types required to support the definition of the
112+
// named types.
113+
// If reuseTypeMap is enabled, it is assumed that the OID mapping is stable across all database
114+
// backends in this pool, resulting in only needing to query when creating the initial connection;
115+
// subsequent connections will reuse the same OID type mapping.
116+
// Because it is not always possible for a client to know the database topology in the final usage
117+
// context, PGXPOOL_REUSE_TYPEMAP, when given a value of y or n, will take precedence over this argument.
118+
func LoadTypesAfterConnect(typeNames []string, reuseTypeMap bool) func(context.Context, *pgx.Conn) error {
119+
if reuseTypeMap {
120+
mutex := new(sync.Mutex)
121+
var types []*pgtype.Type
122+
return func(ctx context.Context, conn *pgx.Conn) error {
123+
if types != nil {
124+
// avoid acquiring the mutex if the types are already available
125+
conn.TypeMap().RegisterTypes(types)
126+
return nil
127+
}
128+
mutex.Lock()
129+
defer mutex.Unlock()
130+
var err error
131+
132+
// types may have become available while waiting for the mutex
133+
if types != nil {
134+
conn.TypeMap().RegisterTypes(types)
135+
return nil
136+
}
137+
types, err = conn.LoadTypes(ctx, typeNames)
138+
if err != nil {
139+
types = nil
140+
return err
141+
}
142+
conn.TypeMap().RegisterTypes(types)
143+
return nil
144+
}
145+
}
146+
return func(ctx context.Context, conn *pgx.Conn) error {
147+
types, err := conn.LoadTypes(ctx, typeNames)
148+
if err != nil {
149+
return err
150+
}
151+
conn.TypeMap().RegisterTypes(types)
152+
return nil
153+
}
154+
}
155+
105156
// Config is the configuration struct for creating a pool. It must be created by [ParseConfig] and then it can be
106157
// modified.
107158
type Config struct {

0 commit comments

Comments
 (0)