4
4
"context"
5
5
"fmt"
6
6
"math/rand"
7
+ "os"
7
8
"runtime"
8
9
"strconv"
9
10
"sync"
@@ -12,14 +13,17 @@ import (
12
13
13
14
"github.com/jackc/pgx/v5"
14
15
"github.com/jackc/pgx/v5/pgconn"
16
+ "github.com/jackc/pgx/v5/pgtype"
15
17
"github.com/jackc/puddle/v2"
16
18
)
17
19
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
20
+ var (
21
+ defaultMaxConns = int32 (4 )
22
+ defaultMinConns = int32 (0 )
23
+ defaultMaxConnLifetime = time .Hour
24
+ defaultMaxConnIdleTime = time .Minute * 30
25
+ defaultHealthCheckPeriod = time .Minute
26
+ )
23
27
24
28
type connResource struct {
25
29
conn * pgx.Conn
@@ -102,6 +106,60 @@ type Pool struct {
102
106
closeChan chan struct {}
103
107
}
104
108
109
+ // AutoloadAfterConnect is suitable for assigning to the AfterConnect configuration setting.
110
+ // It will automatically load the named types for each connection in an efficient manner,
111
+ // performing a single query to the database backend. The underlying call to pgx.LoadTypes
112
+ // is smart enough to also retrieve any related types required to support the definition of the
113
+ // named types.
114
+ // If reuseTypeMap is enabled, it is assumed that the OID mapping is stable across all database
115
+ // backends in this pool, resulting in only needing to query when creating the initial connection;
116
+ // subsequent connections will reuse the same OID type mapping.
117
+ // Because it is not always possible for a client to know the database topology in the final usage
118
+ // context, PGXPOOL_REUSE_TYPEMAP, when given a value of y or n, will take precedence over this argument.
119
+ func AutoloadAfterConnect (typeNames []string , reuseTypeMap bool ) func (context.Context , * pgx.Conn ) error {
120
+ switch os .Getenv ("PGXPOOL_REUSE_TYPEMAP" ) {
121
+ case "y" :
122
+ reuseTypeMap = true
123
+ case "n" :
124
+ reuseTypeMap = false
125
+ }
126
+ if reuseTypeMap {
127
+ mutex := new (sync.Mutex )
128
+ var types []* pgtype.Type
129
+ return func (ctx context.Context , conn * pgx.Conn ) error {
130
+ if types != nil {
131
+ // avoid acquiring the mutex if the types are already available
132
+ conn .TypeMap ().RegisterTypes (types )
133
+ return nil
134
+ }
135
+ mutex .Lock ()
136
+ defer mutex .Unlock ()
137
+ var err error
138
+
139
+ // types may have become available while waiting for the mutex
140
+ if types != nil {
141
+ conn .TypeMap ().RegisterTypes (types )
142
+ return nil
143
+ }
144
+ types , err = conn .LoadTypes (ctx , typeNames )
145
+ if err != nil {
146
+ types = nil
147
+ return err
148
+ }
149
+ conn .TypeMap ().RegisterTypes (types )
150
+ return nil
151
+ }
152
+ }
153
+ return func (ctx context.Context , conn * pgx.Conn ) error {
154
+ types , err := conn .LoadTypes (ctx , typeNames )
155
+ if err != nil {
156
+ return err
157
+ }
158
+ conn .TypeMap ().RegisterTypes (types )
159
+ return nil
160
+ }
161
+ }
162
+
105
163
// Config is the configuration struct for creating a pool. It must be created by [ParseConfig] and then it can be
106
164
// modified.
107
165
type Config struct {
0 commit comments