pg 8.16.3 → 8.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +85 -38
- package/lib/connection-parameters.js +5 -1
- package/lib/defaults.js +8 -1
- package/lib/index.js +33 -24
- package/package.json +6 -6
package/lib/client.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const EventEmitter = require('events').EventEmitter
|
|
4
4
|
const utils = require('./utils')
|
|
5
|
+
const nodeUtils = require('util')
|
|
5
6
|
const sasl = require('./crypto/sasl')
|
|
6
7
|
const TypeOverrides = require('./type-overrides')
|
|
7
8
|
|
|
@@ -11,6 +12,27 @@ const defaults = require('./defaults')
|
|
|
11
12
|
const Connection = require('./connection')
|
|
12
13
|
const crypto = require('./crypto/utils')
|
|
13
14
|
|
|
15
|
+
const activeQueryDeprecationNotice = nodeUtils.deprecate(
|
|
16
|
+
() => {},
|
|
17
|
+
'Client.activeQuery is deprecated and will be removed in a future version.'
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const queryQueueDeprecationNotice = nodeUtils.deprecate(
|
|
21
|
+
() => {},
|
|
22
|
+
'Client.queryQueue is deprecated and will be removed in a future version.'
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const pgPassDeprecationNotice = nodeUtils.deprecate(
|
|
26
|
+
() => {},
|
|
27
|
+
'pgpass support is deprecated and will be removed in a future version. ' +
|
|
28
|
+
'You can provide an async function as the password property to the Client/Pool constructor that returns a password instead. Within this funciton you can call the pgpass module in your own code.'
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const byoPromiseDeprecationNotice = nodeUtils.deprecate(
|
|
32
|
+
() => {},
|
|
33
|
+
'Passing a custom Promise implementation to the Client/Pool constructor is deprecated and will be removed in a future version.'
|
|
34
|
+
)
|
|
35
|
+
|
|
14
36
|
class Client extends EventEmitter {
|
|
15
37
|
constructor(config) {
|
|
16
38
|
super()
|
|
@@ -34,6 +56,9 @@ class Client extends EventEmitter {
|
|
|
34
56
|
|
|
35
57
|
const c = config || {}
|
|
36
58
|
|
|
59
|
+
if (c.Promise) {
|
|
60
|
+
byoPromiseDeprecationNotice()
|
|
61
|
+
}
|
|
37
62
|
this._Promise = c.Promise || global.Promise
|
|
38
63
|
this._types = new TypeOverrides(c.types)
|
|
39
64
|
this._ending = false
|
|
@@ -42,6 +67,7 @@ class Client extends EventEmitter {
|
|
|
42
67
|
this._connected = false
|
|
43
68
|
this._connectionError = false
|
|
44
69
|
this._queryable = true
|
|
70
|
+
this._activeQuery = null
|
|
45
71
|
|
|
46
72
|
this.enableChannelBinding = Boolean(c.enableChannelBinding) // set true to use SCRAM-SHA-256-PLUS when offered
|
|
47
73
|
this.connection =
|
|
@@ -53,7 +79,7 @@ class Client extends EventEmitter {
|
|
|
53
79
|
keepAliveInitialDelayMillis: c.keepAliveInitialDelayMillis || 0,
|
|
54
80
|
encoding: this.connectionParameters.client_encoding || 'utf8',
|
|
55
81
|
})
|
|
56
|
-
this.
|
|
82
|
+
this._queryQueue = []
|
|
57
83
|
this.binary = c.binary || defaults.binary
|
|
58
84
|
this.processID = null
|
|
59
85
|
this.secretKey = null
|
|
@@ -70,6 +96,20 @@ class Client extends EventEmitter {
|
|
|
70
96
|
this._connectionTimeoutMillis = c.connectionTimeoutMillis || 0
|
|
71
97
|
}
|
|
72
98
|
|
|
99
|
+
get activeQuery() {
|
|
100
|
+
activeQueryDeprecationNotice()
|
|
101
|
+
return this._activeQuery
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
set activeQuery(val) {
|
|
105
|
+
activeQueryDeprecationNotice()
|
|
106
|
+
this._activeQuery = val
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
_getActiveQuery() {
|
|
110
|
+
return this._activeQuery
|
|
111
|
+
}
|
|
112
|
+
|
|
73
113
|
_errorAllQueries(err) {
|
|
74
114
|
const enqueueError = (query) => {
|
|
75
115
|
process.nextTick(() => {
|
|
@@ -77,13 +117,14 @@ class Client extends EventEmitter {
|
|
|
77
117
|
})
|
|
78
118
|
}
|
|
79
119
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
120
|
+
const activeQuery = this._getActiveQuery()
|
|
121
|
+
if (activeQuery) {
|
|
122
|
+
enqueueError(activeQuery)
|
|
123
|
+
this._activeQuery = null
|
|
83
124
|
}
|
|
84
125
|
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
126
|
+
this._queryQueue.forEach(enqueueError)
|
|
127
|
+
this._queryQueue.length = 0
|
|
87
128
|
}
|
|
88
129
|
|
|
89
130
|
_connect(callback) {
|
|
@@ -203,9 +244,7 @@ class Client extends EventEmitter {
|
|
|
203
244
|
con.on('notification', this._handleNotification.bind(this))
|
|
204
245
|
}
|
|
205
246
|
|
|
206
|
-
|
|
207
|
-
// it can be supplied by the user if required - this is a breaking change!
|
|
208
|
-
_checkPgPass(cb) {
|
|
247
|
+
_getPassword(cb) {
|
|
209
248
|
const con = this.connection
|
|
210
249
|
if (typeof this.password === 'function') {
|
|
211
250
|
this._Promise
|
|
@@ -233,6 +272,7 @@ class Client extends EventEmitter {
|
|
|
233
272
|
const pgPass = require('pgpass')
|
|
234
273
|
pgPass(this.connectionParameters, (pass) => {
|
|
235
274
|
if (undefined !== pass) {
|
|
275
|
+
pgPassDeprecationNotice()
|
|
236
276
|
this.connectionParameters.password = this.password = pass
|
|
237
277
|
}
|
|
238
278
|
cb()
|
|
@@ -244,13 +284,13 @@ class Client extends EventEmitter {
|
|
|
244
284
|
}
|
|
245
285
|
|
|
246
286
|
_handleAuthCleartextPassword(msg) {
|
|
247
|
-
this.
|
|
287
|
+
this._getPassword(() => {
|
|
248
288
|
this.connection.password(this.password)
|
|
249
289
|
})
|
|
250
290
|
}
|
|
251
291
|
|
|
252
292
|
_handleAuthMD5Password(msg) {
|
|
253
|
-
this.
|
|
293
|
+
this._getPassword(async () => {
|
|
254
294
|
try {
|
|
255
295
|
const hashedPassword = await crypto.postgresMd5PasswordHash(this.user, this.password, msg.salt)
|
|
256
296
|
this.connection.password(hashedPassword)
|
|
@@ -261,7 +301,7 @@ class Client extends EventEmitter {
|
|
|
261
301
|
}
|
|
262
302
|
|
|
263
303
|
_handleAuthSASL(msg) {
|
|
264
|
-
this.
|
|
304
|
+
this._getPassword(() => {
|
|
265
305
|
try {
|
|
266
306
|
this.saslSession = sasl.startSession(msg.mechanisms, this.enableChannelBinding && this.connection.stream)
|
|
267
307
|
this.connection.sendSASLInitialResponseMessage(this.saslSession.mechanism, this.saslSession.response)
|
|
@@ -314,8 +354,8 @@ class Client extends EventEmitter {
|
|
|
314
354
|
}
|
|
315
355
|
this.emit('connect')
|
|
316
356
|
}
|
|
317
|
-
const
|
|
318
|
-
this.
|
|
357
|
+
const activeQuery = this._getActiveQuery()
|
|
358
|
+
this._activeQuery = null
|
|
319
359
|
this.readyForQuery = true
|
|
320
360
|
if (activeQuery) {
|
|
321
361
|
activeQuery.handleReadyForQuery(this.connection)
|
|
@@ -355,49 +395,51 @@ class Client extends EventEmitter {
|
|
|
355
395
|
if (this._connecting) {
|
|
356
396
|
return this._handleErrorWhileConnecting(msg)
|
|
357
397
|
}
|
|
358
|
-
const activeQuery = this.
|
|
398
|
+
const activeQuery = this._getActiveQuery()
|
|
359
399
|
|
|
360
400
|
if (!activeQuery) {
|
|
361
401
|
this._handleErrorEvent(msg)
|
|
362
402
|
return
|
|
363
403
|
}
|
|
364
404
|
|
|
365
|
-
this.
|
|
405
|
+
this._activeQuery = null
|
|
366
406
|
activeQuery.handleError(msg, this.connection)
|
|
367
407
|
}
|
|
368
408
|
|
|
369
409
|
_handleRowDescription(msg) {
|
|
370
410
|
// delegate rowDescription to active query
|
|
371
|
-
this.
|
|
411
|
+
this._getActiveQuery().handleRowDescription(msg)
|
|
372
412
|
}
|
|
373
413
|
|
|
374
414
|
_handleDataRow(msg) {
|
|
375
415
|
// delegate dataRow to active query
|
|
376
|
-
this.
|
|
416
|
+
this._getActiveQuery().handleDataRow(msg)
|
|
377
417
|
}
|
|
378
418
|
|
|
379
419
|
_handlePortalSuspended(msg) {
|
|
380
420
|
// delegate portalSuspended to active query
|
|
381
|
-
this.
|
|
421
|
+
this._getActiveQuery().handlePortalSuspended(this.connection)
|
|
382
422
|
}
|
|
383
423
|
|
|
384
424
|
_handleEmptyQuery(msg) {
|
|
385
425
|
// delegate emptyQuery to active query
|
|
386
|
-
this.
|
|
426
|
+
this._getActiveQuery().handleEmptyQuery(this.connection)
|
|
387
427
|
}
|
|
388
428
|
|
|
389
429
|
_handleCommandComplete(msg) {
|
|
390
|
-
|
|
430
|
+
const activeQuery = this._getActiveQuery()
|
|
431
|
+
if (activeQuery == null) {
|
|
391
432
|
const error = new Error('Received unexpected commandComplete message from backend.')
|
|
392
433
|
this._handleErrorEvent(error)
|
|
393
434
|
return
|
|
394
435
|
}
|
|
395
436
|
// delegate commandComplete to active query
|
|
396
|
-
|
|
437
|
+
activeQuery.handleCommandComplete(msg, this.connection)
|
|
397
438
|
}
|
|
398
439
|
|
|
399
440
|
_handleParseComplete() {
|
|
400
|
-
|
|
441
|
+
const activeQuery = this._getActiveQuery()
|
|
442
|
+
if (activeQuery == null) {
|
|
401
443
|
const error = new Error('Received unexpected parseComplete message from backend.')
|
|
402
444
|
this._handleErrorEvent(error)
|
|
403
445
|
return
|
|
@@ -405,17 +447,17 @@ class Client extends EventEmitter {
|
|
|
405
447
|
// if a prepared statement has a name and properly parses
|
|
406
448
|
// we track that its already been executed so we don't parse
|
|
407
449
|
// it again on the same client
|
|
408
|
-
if (
|
|
409
|
-
this.connection.parsedStatements[
|
|
450
|
+
if (activeQuery.name) {
|
|
451
|
+
this.connection.parsedStatements[activeQuery.name] = activeQuery.text
|
|
410
452
|
}
|
|
411
453
|
}
|
|
412
454
|
|
|
413
455
|
_handleCopyInResponse(msg) {
|
|
414
|
-
this.
|
|
456
|
+
this._getActiveQuery().handleCopyInResponse(this.connection)
|
|
415
457
|
}
|
|
416
458
|
|
|
417
459
|
_handleCopyData(msg) {
|
|
418
|
-
this.
|
|
460
|
+
this._getActiveQuery().handleCopyData(msg, this.connection)
|
|
419
461
|
}
|
|
420
462
|
|
|
421
463
|
_handleNotification(msg) {
|
|
@@ -471,8 +513,8 @@ class Client extends EventEmitter {
|
|
|
471
513
|
con.on('connect', function () {
|
|
472
514
|
con.cancel(client.processID, client.secretKey)
|
|
473
515
|
})
|
|
474
|
-
} else if (client.
|
|
475
|
-
client.
|
|
516
|
+
} else if (client._queryQueue.indexOf(query) !== -1) {
|
|
517
|
+
client._queryQueue.splice(client._queryQueue.indexOf(query), 1)
|
|
476
518
|
}
|
|
477
519
|
}
|
|
478
520
|
|
|
@@ -497,21 +539,22 @@ class Client extends EventEmitter {
|
|
|
497
539
|
|
|
498
540
|
_pulseQueryQueue() {
|
|
499
541
|
if (this.readyForQuery === true) {
|
|
500
|
-
this.
|
|
501
|
-
|
|
542
|
+
this._activeQuery = this._queryQueue.shift()
|
|
543
|
+
const activeQuery = this._getActiveQuery()
|
|
544
|
+
if (activeQuery) {
|
|
502
545
|
this.readyForQuery = false
|
|
503
546
|
this.hasExecuted = true
|
|
504
547
|
|
|
505
|
-
const queryError =
|
|
548
|
+
const queryError = activeQuery.submit(this.connection)
|
|
506
549
|
if (queryError) {
|
|
507
550
|
process.nextTick(() => {
|
|
508
|
-
|
|
551
|
+
activeQuery.handleError(queryError, this.connection)
|
|
509
552
|
this.readyForQuery = true
|
|
510
553
|
this._pulseQueryQueue()
|
|
511
554
|
})
|
|
512
555
|
}
|
|
513
556
|
} else if (this.hasExecuted) {
|
|
514
|
-
this.
|
|
557
|
+
this._activeQuery = null
|
|
515
558
|
this.emit('drain')
|
|
516
559
|
}
|
|
517
560
|
}
|
|
@@ -565,9 +608,9 @@ class Client extends EventEmitter {
|
|
|
565
608
|
query.callback = () => {}
|
|
566
609
|
|
|
567
610
|
// Remove from queue
|
|
568
|
-
const index = this.
|
|
611
|
+
const index = this._queryQueue.indexOf(query)
|
|
569
612
|
if (index > -1) {
|
|
570
|
-
this.
|
|
613
|
+
this._queryQueue.splice(index, 1)
|
|
571
614
|
}
|
|
572
615
|
|
|
573
616
|
this._pulseQueryQueue()
|
|
@@ -601,7 +644,7 @@ class Client extends EventEmitter {
|
|
|
601
644
|
return result
|
|
602
645
|
}
|
|
603
646
|
|
|
604
|
-
this.
|
|
647
|
+
this._queryQueue.push(query)
|
|
605
648
|
this._pulseQueryQueue()
|
|
606
649
|
return result
|
|
607
650
|
}
|
|
@@ -626,7 +669,7 @@ class Client extends EventEmitter {
|
|
|
626
669
|
}
|
|
627
670
|
}
|
|
628
671
|
|
|
629
|
-
if (this.
|
|
672
|
+
if (this._getActiveQuery() || !this._queryable) {
|
|
630
673
|
// if we have an active query we need to force a disconnect
|
|
631
674
|
// on the socket - otherwise a hung query could block end forever
|
|
632
675
|
this.connection.stream.destroy()
|
|
@@ -642,6 +685,10 @@ class Client extends EventEmitter {
|
|
|
642
685
|
})
|
|
643
686
|
}
|
|
644
687
|
}
|
|
688
|
+
get queryQueue() {
|
|
689
|
+
queryQueueDeprecationNotice()
|
|
690
|
+
return this._queryQueue
|
|
691
|
+
}
|
|
645
692
|
}
|
|
646
693
|
|
|
647
694
|
// expose a Query constructor
|
|
@@ -7,6 +7,10 @@ const defaults = require('./defaults')
|
|
|
7
7
|
const parse = require('pg-connection-string').parse // parses a connection string
|
|
8
8
|
|
|
9
9
|
const val = function (key, config, envVar) {
|
|
10
|
+
if (config[key]) {
|
|
11
|
+
return config[key]
|
|
12
|
+
}
|
|
13
|
+
|
|
10
14
|
if (envVar === undefined) {
|
|
11
15
|
envVar = process.env['PG' + key.toUpperCase()]
|
|
12
16
|
} else if (envVar === false) {
|
|
@@ -15,7 +19,7 @@ const val = function (key, config, envVar) {
|
|
|
15
19
|
envVar = process.env[envVar]
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
return
|
|
22
|
+
return envVar || defaults[key]
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
const readSSLConfigFromEnvironment = function () {
|
package/lib/defaults.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
let user
|
|
4
|
+
try {
|
|
5
|
+
user = process.platform === 'win32' ? process.env.USERNAME : process.env.USER
|
|
6
|
+
} catch {
|
|
7
|
+
// ignore, e.g., Deno without --allow-env
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
module.exports = {
|
|
4
11
|
// database host. defaults to localhost
|
|
5
12
|
host: 'localhost',
|
|
6
13
|
|
|
7
14
|
// database user's name
|
|
8
|
-
user
|
|
15
|
+
user,
|
|
9
16
|
|
|
10
17
|
// name of database to connect
|
|
11
18
|
database: undefined,
|
package/lib/index.js
CHANGED
|
@@ -34,31 +34,40 @@ const PG = function (clientConstructor) {
|
|
|
34
34
|
this.utils = utils
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
module.exports = new PG(require('./native'))
|
|
39
|
-
} else {
|
|
40
|
-
module.exports = new PG(Client)
|
|
37
|
+
let clientConstructor = Client
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
let forceNative = false
|
|
40
|
+
try {
|
|
41
|
+
forceNative = !!process.env.NODE_PG_FORCE_NATIVE
|
|
42
|
+
} catch {
|
|
43
|
+
// ignore, e.g., Deno without --allow-env
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (forceNative) {
|
|
47
|
+
clientConstructor = require('./native')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = new PG(clientConstructor)
|
|
51
|
+
|
|
52
|
+
// lazy require native module...the native module may not have installed
|
|
53
|
+
Object.defineProperty(module.exports, 'native', {
|
|
54
|
+
configurable: true,
|
|
55
|
+
enumerable: false,
|
|
56
|
+
get() {
|
|
57
|
+
let native = null
|
|
58
|
+
try {
|
|
59
|
+
native = new PG(require('./native'))
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (err.code !== 'MODULE_NOT_FOUND') {
|
|
62
|
+
throw err
|
|
54
63
|
}
|
|
64
|
+
}
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
// overwrite module.exports.native so that getter is never called again
|
|
67
|
+
Object.defineProperty(module.exports, 'native', {
|
|
68
|
+
value: native,
|
|
69
|
+
})
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
71
|
+
return native
|
|
72
|
+
},
|
|
73
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.17.1",
|
|
4
4
|
"description": "PostgreSQL client - pure javascript & libpq with the same API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"./lib/*.js": "./lib/*.js"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"pg-connection-string": "^2.
|
|
36
|
-
"pg-pool": "^3.
|
|
37
|
-
"pg-protocol": "^1.
|
|
35
|
+
"pg-connection-string": "^2.10.0",
|
|
36
|
+
"pg-pool": "^3.11.0",
|
|
37
|
+
"pg-protocol": "^1.11.0",
|
|
38
38
|
"pg-types": "2.2.0",
|
|
39
39
|
"pgpass": "1.0.5"
|
|
40
40
|
},
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"wrangler": "^3.x"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"pg-cloudflare": "^1.
|
|
53
|
+
"pg-cloudflare": "^1.3.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"pg-native": ">=3.0.1"
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"engines": {
|
|
73
73
|
"node": ">= 16.0.0"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "4eb7529a5906f2000faf72b5452e10d95bde2f9e"
|
|
76
76
|
}
|