@@ -15,11 +15,13 @@ import (
1515 "github.com/jackc/puddle/v2"
1616)
1717
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
18+ var (
19+ defaultMaxConns = int32 (4 )
20+ defaultMinConns = int32 (0 )
21+ defaultMaxConnLifetime = time .Hour
22+ defaultMaxConnIdleTime = time .Minute * 30
23+ defaultHealthCheckPeriod = time .Minute
24+ )
2325
2426type connResource struct {
2527 conn * pgx.Conn
@@ -100,6 +102,11 @@ type Pool struct {
100102
101103 closeOnce sync.Once
102104 closeChan chan struct {}
105+
106+ autoLoadTypes []string
107+ reuseTypeMap bool
108+ autoLoadMutex * sync.Mutex
109+ autoLoadTypeInfos []* pgx.TypeInfo
103110}
104111
105112// Config is the configuration struct for creating a pool. It must be created by [ParseConfig] and then it can be
@@ -147,6 +154,15 @@ type Config struct {
147154 // HealthCheckPeriod is the duration between checks of the health of idle connections.
148155 HealthCheckPeriod time.Duration
149156
157+ // AutoLoadTypes is a list of user-defined types which should automatically be loaded
158+ // as each new connection is created. This will also load any related types, directly
159+ // or indirectly required to handle these types.
160+ AutoLoadTypes []string
161+
162+ // ReuseTypeMaps, if enabled, will reuse the typemap information being used by AutoLoadTypes.
163+ // This removes the need to query the database each time a new connection is created.
164+ ReuseTypeMaps bool
165+
150166 createdByParseConfig bool // Used to enforce created by ParseConfig rule.
151167}
152168
@@ -185,6 +201,8 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
185201 config : config ,
186202 beforeConnect : config .BeforeConnect ,
187203 afterConnect : config .AfterConnect ,
204+ autoLoadTypes : config .AutoLoadTypes ,
205+ reuseTypeMap : config .ReuseTypeMaps ,
188206 beforeAcquire : config .BeforeAcquire ,
189207 afterRelease : config .AfterRelease ,
190208 beforeClose : config .BeforeClose ,
@@ -196,6 +214,7 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
196214 healthCheckPeriod : config .HealthCheckPeriod ,
197215 healthCheckChan : make (chan struct {}, 1 ),
198216 closeChan : make (chan struct {}),
217+ autoLoadMutex : new (sync.Mutex ),
199218 }
200219
201220 if t , ok := config .ConnConfig .Tracer .(AcquireTracer ); ok {
@@ -237,6 +256,19 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
237256 }
238257 }
239258
259+ if len (p .autoLoadTypes ) > 0 {
260+ types , err := p .LoadTypes (ctx , conn , p .autoLoadTypes )
261+ if err != nil {
262+ conn .Close (ctx )
263+ panic (err )
264+ }
265+ if err = conn .RegisterTypes (types , conn .TypeMap ()); err != nil {
266+ conn .Close (ctx )
267+
268+ panic (err )
269+ }
270+ }
271+
240272 jitterSecs := rand .Float64 () * config .MaxConnLifetimeJitter .Seconds ()
241273 maxAgeTime := time .Now ().Add (config .MaxConnLifetime ).Add (time .Duration (jitterSecs ) * time .Second )
242274
@@ -388,6 +420,22 @@ func (p *Pool) Close() {
388420 })
389421}
390422
423+ func (p * Pool ) LoadTypes (ctx context.Context , conn * pgx.Conn , typeNames []string ) ([]* pgx.TypeInfo , error ) {
424+ p .autoLoadMutex .Lock ()
425+ defer p .autoLoadMutex .Unlock ()
426+ if p .autoLoadTypeInfos != nil {
427+ return p .autoLoadTypeInfos , nil
428+ }
429+ types , err := conn .LoadTypes (ctx , typeNames )
430+ if err != nil {
431+ return nil , err
432+ }
433+ if p .reuseTypeMap {
434+ p .autoLoadTypeInfos = types
435+ }
436+ return types , err
437+ }
438+
391439func (p * Pool ) isExpired (res * puddle.Resource [* connResource ]) bool {
392440 return time .Now ().After (res .Value ().maxAgeTime )
393441}
@@ -482,7 +530,6 @@ func (p *Pool) checkMinConns() error {
482530func (p * Pool ) createIdleResources (parentCtx context.Context , targetResources int ) error {
483531 ctx , cancel := context .WithCancel (parentCtx )
484532 defer cancel ()
485-
486533 errs := make (chan error , targetResources )
487534
488535 for i := 0 ; i < targetResources ; i ++ {
@@ -495,7 +542,6 @@ func (p *Pool) createIdleResources(parentCtx context.Context, targetResources in
495542 errs <- err
496543 }()
497544 }
498-
499545 var firstError error
500546 for i := 0 ; i < targetResources ; i ++ {
501547 err := <- errs
0 commit comments