pg 8.15.6 → 8.16.0
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 +23 -23
- package/lib/connection-parameters.js +10 -10
- package/lib/connection.js +6 -6
- package/lib/crypto/cert-signatures.js +1 -1
- package/lib/crypto/sasl.js +12 -12
- package/lib/crypto/utils-legacy.js +2 -2
- package/lib/crypto/utils-webcrypto.js +2 -2
- package/lib/defaults.js +3 -3
- package/lib/index.js +2 -2
- package/lib/native/client.js +19 -19
- package/lib/native/query.js +12 -15
- package/lib/query.js +0 -1
- package/lib/result.js +13 -13
- package/lib/stream.js +1 -1
- package/lib/type-overrides.js +1 -1
- package/lib/utils.js +18 -18
- package/package.json +8 -9
package/lib/client.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
const EventEmitter = require('events').EventEmitter
|
|
4
|
+
const utils = require('./utils')
|
|
5
|
+
const sasl = require('./crypto/sasl')
|
|
6
|
+
const TypeOverrides = require('./type-overrides')
|
|
7
|
+
|
|
8
|
+
const ConnectionParameters = require('./connection-parameters')
|
|
9
|
+
const Query = require('./query')
|
|
10
|
+
const defaults = require('./defaults')
|
|
11
|
+
const Connection = require('./connection')
|
|
12
12
|
const crypto = require('./crypto/utils')
|
|
13
13
|
|
|
14
14
|
class Client extends EventEmitter {
|
|
@@ -32,7 +32,7 @@ class Client extends EventEmitter {
|
|
|
32
32
|
|
|
33
33
|
this.replication = this.connectionParameters.replication
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const c = config || {}
|
|
36
36
|
|
|
37
37
|
this._Promise = c.Promise || global.Promise
|
|
38
38
|
this._types = new TypeOverrides(c.types)
|
|
@@ -87,8 +87,8 @@ class Client extends EventEmitter {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
_connect(callback) {
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
const self = this
|
|
91
|
+
const con = this.connection
|
|
92
92
|
this._connectionCallback = callback
|
|
93
93
|
|
|
94
94
|
if (this._connecting || this._connected) {
|
|
@@ -427,14 +427,14 @@ class Client extends EventEmitter {
|
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
getStartupConf() {
|
|
430
|
-
|
|
430
|
+
const params = this.connectionParameters
|
|
431
431
|
|
|
432
|
-
|
|
432
|
+
const data = {
|
|
433
433
|
user: params.user,
|
|
434
434
|
database: params.database,
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
-
|
|
437
|
+
const appName = params.application_name || params.fallback_application_name
|
|
438
438
|
if (appName) {
|
|
439
439
|
data.application_name = appName
|
|
440
440
|
}
|
|
@@ -459,7 +459,7 @@ class Client extends EventEmitter {
|
|
|
459
459
|
|
|
460
460
|
cancel(client, query) {
|
|
461
461
|
if (client.activeQuery === query) {
|
|
462
|
-
|
|
462
|
+
const con = this.connection
|
|
463
463
|
|
|
464
464
|
if (this.host && this.host.indexOf('/') === 0) {
|
|
465
465
|
con.connect(this.host + '/.s.PGSQL.' + this.port)
|
|
@@ -519,11 +519,11 @@ class Client extends EventEmitter {
|
|
|
519
519
|
|
|
520
520
|
query(config, values, callback) {
|
|
521
521
|
// can take in strings, config object or query object
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
522
|
+
let query
|
|
523
|
+
let result
|
|
524
|
+
let readTimeout
|
|
525
|
+
let readTimeoutTimer
|
|
526
|
+
let queryCallback
|
|
527
527
|
|
|
528
528
|
if (config === null || config === undefined) {
|
|
529
529
|
throw new TypeError('Client was passed a null or undefined query')
|
|
@@ -552,7 +552,7 @@ class Client extends EventEmitter {
|
|
|
552
552
|
queryCallback = query.callback
|
|
553
553
|
|
|
554
554
|
readTimeoutTimer = setTimeout(() => {
|
|
555
|
-
|
|
555
|
+
const error = new Error('Query read timeout')
|
|
556
556
|
|
|
557
557
|
process.nextTick(() => {
|
|
558
558
|
query.handleError(error, this.connection)
|
|
@@ -565,7 +565,7 @@ class Client extends EventEmitter {
|
|
|
565
565
|
query.callback = () => {}
|
|
566
566
|
|
|
567
567
|
// Remove from queue
|
|
568
|
-
|
|
568
|
+
const index = this.queryQueue.indexOf(query)
|
|
569
569
|
if (index > -1) {
|
|
570
570
|
this.queryQueue.splice(index, 1)
|
|
571
571
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const dns = require('dns')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const defaults = require('./defaults')
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const parse = require('pg-connection-string').parse // parses a connection string
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
const val = function (key, config, envVar) {
|
|
10
10
|
if (envVar === undefined) {
|
|
11
11
|
envVar = process.env['PG' + key.toUpperCase()]
|
|
12
12
|
} else if (envVar === false) {
|
|
@@ -18,7 +18,7 @@ var val = function (key, config, envVar) {
|
|
|
18
18
|
return config[key] || envVar || defaults[key]
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const readSSLConfigFromEnvironment = function () {
|
|
22
22
|
switch (process.env.PGSSLMODE) {
|
|
23
23
|
case 'disable':
|
|
24
24
|
return false
|
|
@@ -34,12 +34,12 @@ var readSSLConfigFromEnvironment = function () {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
// Convert arg to a string, surround in single quotes, and escape single quotes and backslashes
|
|
37
|
-
|
|
37
|
+
const quoteParamValue = function (value) {
|
|
38
38
|
return "'" + ('' + value).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
const add = function (params, config, paramName) {
|
|
42
|
+
const value = config[paramName]
|
|
43
43
|
if (value !== undefined && value !== null) {
|
|
44
44
|
params.push(paramName + '=' + quoteParamValue(value))
|
|
45
45
|
}
|
|
@@ -125,7 +125,7 @@ class ConnectionParameters {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
getLibpqConnectionString(cb) {
|
|
128
|
-
|
|
128
|
+
const params = []
|
|
129
129
|
add(params, this, 'user')
|
|
130
130
|
add(params, this, 'password')
|
|
131
131
|
add(params, this, 'port')
|
|
@@ -134,7 +134,7 @@ class ConnectionParameters {
|
|
|
134
134
|
add(params, this, 'connect_timeout')
|
|
135
135
|
add(params, this, 'options')
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
const ssl = typeof this.ssl === 'object' ? this.ssl : this.ssl ? { sslmode: this.ssl } : {}
|
|
138
138
|
add(params, ssl, 'sslmode')
|
|
139
139
|
add(params, ssl, 'sslca')
|
|
140
140
|
add(params, ssl, 'sslkey')
|
package/lib/connection.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const EventEmitter = require('events').EventEmitter
|
|
4
4
|
|
|
5
5
|
const { parse, serialize } = require('pg-protocol')
|
|
6
6
|
const { getStream, getSecureStream } = require('./stream')
|
|
@@ -27,7 +27,7 @@ class Connection extends EventEmitter {
|
|
|
27
27
|
this.ssl = config.ssl || false
|
|
28
28
|
this._ending = false
|
|
29
29
|
this._emitMessage = false
|
|
30
|
-
|
|
30
|
+
const self = this
|
|
31
31
|
this.on('newListener', function (eventName) {
|
|
32
32
|
if (eventName === 'message') {
|
|
33
33
|
self._emitMessage = true
|
|
@@ -36,7 +36,7 @@ class Connection extends EventEmitter {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
connect(port, host) {
|
|
39
|
-
|
|
39
|
+
const self = this
|
|
40
40
|
|
|
41
41
|
this._connecting = true
|
|
42
42
|
this.stream.setNoDelay(true)
|
|
@@ -67,7 +67,7 @@ class Connection extends EventEmitter {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
this.stream.once('data', function (buffer) {
|
|
70
|
-
|
|
70
|
+
const responseCode = buffer.toString('utf8')
|
|
71
71
|
switch (responseCode) {
|
|
72
72
|
case 'S': // Server supports SSL connections, continue with a secure connection
|
|
73
73
|
break
|
|
@@ -91,7 +91,7 @@ class Connection extends EventEmitter {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
const net = require('net')
|
|
95
95
|
if (net.isIP && net.isIP(host) === 0) {
|
|
96
96
|
options.servername = host
|
|
97
97
|
}
|
|
@@ -109,7 +109,7 @@ class Connection extends EventEmitter {
|
|
|
109
109
|
|
|
110
110
|
attachListeners(stream) {
|
|
111
111
|
parse(stream, (msg) => {
|
|
112
|
-
|
|
112
|
+
const eventName = msg.name === 'error' ? 'errorMessage' : msg.name
|
|
113
113
|
if (this._emitMessage) {
|
|
114
114
|
this.emit('message', msg)
|
|
115
115
|
}
|
|
@@ -22,7 +22,7 @@ function readASN1OID(data, index) {
|
|
|
22
22
|
|
|
23
23
|
const { length: OIDLength, index: indexAfterOIDLength } = readASN1Length(data, index)
|
|
24
24
|
index = indexAfterOIDLength
|
|
25
|
-
|
|
25
|
+
const lastIndex = index + OIDLength
|
|
26
26
|
|
|
27
27
|
const byte1 = data[index++]
|
|
28
28
|
let oid = ((byte1 / 40) >> 0) + '.' + (byte1 % 40)
|
package/lib/crypto/sasl.js
CHANGED
|
@@ -50,8 +50,8 @@ async function continueSession(session, password, serverData, stream) {
|
|
|
50
50
|
throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: server nonce is too short')
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const clientFirstMessageBare = 'n=*,r=' + session.clientNonce
|
|
54
|
+
const serverFirstMessage = 'r=' + sv.nonce + ',s=' + sv.salt + ',i=' + sv.iteration
|
|
55
55
|
|
|
56
56
|
// without channel binding:
|
|
57
57
|
let channelBinding = stream ? 'eSws' : 'biws' // 'y,,' or 'n,,', base64-encoded
|
|
@@ -66,17 +66,17 @@ async function continueSession(session, password, serverData, stream) {
|
|
|
66
66
|
channelBinding = bindingData.toString('base64')
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
const clientFinalMessageWithoutProof = 'c=' + channelBinding + ',r=' + sv.nonce
|
|
70
|
+
const authMessage = clientFirstMessageBare + ',' + serverFirstMessage + ',' + clientFinalMessageWithoutProof
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
const saltBytes = Buffer.from(sv.salt, 'base64')
|
|
73
|
+
const saltedPassword = await crypto.deriveKey(password, saltBytes, sv.iteration)
|
|
74
|
+
const clientKey = await crypto.hmacSha256(saltedPassword, 'Client Key')
|
|
75
|
+
const storedKey = await crypto.sha256(clientKey)
|
|
76
|
+
const clientSignature = await crypto.hmacSha256(storedKey, authMessage)
|
|
77
|
+
const clientProof = xorBuffers(Buffer.from(clientKey), Buffer.from(clientSignature)).toString('base64')
|
|
78
|
+
const serverKey = await crypto.hmacSha256(saltedPassword, 'Server Key')
|
|
79
|
+
const serverSignatureBytes = await crypto.hmacSha256(serverKey, authMessage)
|
|
80
80
|
|
|
81
81
|
session.message = 'SASLResponse'
|
|
82
82
|
session.serverSignature = Buffer.from(serverSignatureBytes).toString('base64')
|
|
@@ -10,8 +10,8 @@ function md5(string) {
|
|
|
10
10
|
|
|
11
11
|
// See AuthenticationMD5Password at https://www.postgresql.org/docs/current/static/protocol-flow.html
|
|
12
12
|
function postgresMd5PasswordHash(user, password, salt) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const inner = md5(password + user)
|
|
14
|
+
const outer = md5(Buffer.concat([Buffer.from(inner), salt]))
|
|
15
15
|
return 'md5' + outer
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -49,8 +49,8 @@ async function md5(string) {
|
|
|
49
49
|
|
|
50
50
|
// See AuthenticationMD5Password at https://www.postgresql.org/docs/current/static/protocol-flow.html
|
|
51
51
|
async function postgresMd5PasswordHash(user, password, salt) {
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const inner = await md5(password + user)
|
|
53
|
+
const outer = await md5(Buffer.concat([Buffer.from(inner), salt]))
|
|
54
54
|
return 'md5' + outer
|
|
55
55
|
}
|
|
56
56
|
|
package/lib/defaults.js
CHANGED
|
@@ -72,10 +72,10 @@ module.exports = {
|
|
|
72
72
|
keepalives_idle: 0,
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
const pgTypes = require('pg-types')
|
|
76
76
|
// save default parsers
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const parseBigInteger = pgTypes.getTypeParser(20, 'text')
|
|
78
|
+
const parseBigIntegerArray = pgTypes.getTypeParser(1016, 'text')
|
|
79
79
|
|
|
80
80
|
// parse int8 so you can get your count values as actual numbers
|
|
81
81
|
module.exports.__defineSetter__('parseInt8', function (val) {
|
package/lib/index.js
CHANGED
|
@@ -18,7 +18,7 @@ const poolFactory = (Client) => {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
const PG = function (clientConstructor) {
|
|
22
22
|
this.defaults = defaults
|
|
23
23
|
this.Client = clientConstructor
|
|
24
24
|
this.Query = this.Client.Query
|
|
@@ -44,7 +44,7 @@ if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
|
|
|
44
44
|
configurable: true,
|
|
45
45
|
enumerable: false,
|
|
46
46
|
get() {
|
|
47
|
-
|
|
47
|
+
let native = null
|
|
48
48
|
try {
|
|
49
49
|
native = new PG(require('./native'))
|
|
50
50
|
} catch (err) {
|
package/lib/native/client.js
CHANGED
|
@@ -9,14 +9,14 @@ try {
|
|
|
9
9
|
} catch (e) {
|
|
10
10
|
throw e
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const TypeOverrides = require('../type-overrides')
|
|
13
|
+
const EventEmitter = require('events').EventEmitter
|
|
14
|
+
const util = require('util')
|
|
15
|
+
const ConnectionParameters = require('../connection-parameters')
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const NativeQuery = require('./query')
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const Client = (module.exports = function (config) {
|
|
20
20
|
EventEmitter.call(this)
|
|
21
21
|
config = config || {}
|
|
22
22
|
|
|
@@ -35,7 +35,7 @@ var Client = (module.exports = function (config) {
|
|
|
35
35
|
|
|
36
36
|
// keep these on the object for legacy reasons
|
|
37
37
|
// for the time being. TODO: deprecate all this jazz
|
|
38
|
-
|
|
38
|
+
const cp = (this.connectionParameters = new ConnectionParameters(config))
|
|
39
39
|
if (config.nativeConnectionString) cp.nativeConnectionString = config.nativeConnectionString
|
|
40
40
|
this.user = cp.user
|
|
41
41
|
|
|
@@ -80,7 +80,7 @@ Client.prototype._errorAllQueries = function (err) {
|
|
|
80
80
|
// pass an optional callback to be called once connected
|
|
81
81
|
// or with an error if there was a connection error
|
|
82
82
|
Client.prototype._connect = function (cb) {
|
|
83
|
-
|
|
83
|
+
const self = this
|
|
84
84
|
|
|
85
85
|
if (this._connecting) {
|
|
86
86
|
process.nextTick(() => cb(new Error('Client has already been connected. You cannot reuse a client.')))
|
|
@@ -152,11 +152,11 @@ Client.prototype.connect = function (callback) {
|
|
|
152
152
|
// optional string rowMode = 'array' for an array of results
|
|
153
153
|
// }
|
|
154
154
|
Client.prototype.query = function (config, values, callback) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
let query
|
|
156
|
+
let result
|
|
157
|
+
let readTimeout
|
|
158
|
+
let readTimeoutTimer
|
|
159
|
+
let queryCallback
|
|
160
160
|
|
|
161
161
|
if (config === null || config === undefined) {
|
|
162
162
|
throw new TypeError('Client was passed a null or undefined query')
|
|
@@ -187,7 +187,7 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
187
187
|
queryCallback = query.callback
|
|
188
188
|
|
|
189
189
|
readTimeoutTimer = setTimeout(() => {
|
|
190
|
-
|
|
190
|
+
const error = new Error('Query read timeout')
|
|
191
191
|
|
|
192
192
|
process.nextTick(() => {
|
|
193
193
|
query.handleError(error, this.connection)
|
|
@@ -200,7 +200,7 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
200
200
|
query.callback = () => {}
|
|
201
201
|
|
|
202
202
|
// Remove from queue
|
|
203
|
-
|
|
203
|
+
const index = this._queryQueue.indexOf(query)
|
|
204
204
|
if (index > -1) {
|
|
205
205
|
this._queryQueue.splice(index, 1)
|
|
206
206
|
}
|
|
@@ -237,14 +237,14 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
237
237
|
|
|
238
238
|
// disconnect from the backend server
|
|
239
239
|
Client.prototype.end = function (cb) {
|
|
240
|
-
|
|
240
|
+
const self = this
|
|
241
241
|
|
|
242
242
|
this._ending = true
|
|
243
243
|
|
|
244
244
|
if (!this._connected) {
|
|
245
245
|
this.once('connect', this.end.bind(this, cb))
|
|
246
246
|
}
|
|
247
|
-
|
|
247
|
+
let result
|
|
248
248
|
if (!cb) {
|
|
249
249
|
result = new this._Promise(function (resolve, reject) {
|
|
250
250
|
cb = (err) => (err ? reject(err) : resolve())
|
|
@@ -272,7 +272,7 @@ Client.prototype._pulseQueryQueue = function (initialConnection) {
|
|
|
272
272
|
if (this._hasActiveQuery()) {
|
|
273
273
|
return
|
|
274
274
|
}
|
|
275
|
-
|
|
275
|
+
const query = this._queryQueue.shift()
|
|
276
276
|
if (!query) {
|
|
277
277
|
if (!initialConnection) {
|
|
278
278
|
this.emit('drain')
|
|
@@ -281,7 +281,7 @@ Client.prototype._pulseQueryQueue = function (initialConnection) {
|
|
|
281
281
|
}
|
|
282
282
|
this._activeQuery = query
|
|
283
283
|
query.submit(this)
|
|
284
|
-
|
|
284
|
+
const self = this
|
|
285
285
|
query.once('_done', function () {
|
|
286
286
|
self._pulseQueryQueue()
|
|
287
287
|
})
|
package/lib/native/query.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const EventEmitter = require('events').EventEmitter
|
|
4
|
+
const util = require('util')
|
|
5
|
+
const utils = require('../utils')
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const NativeQuery = (module.exports = function (config, values, callback) {
|
|
8
8
|
EventEmitter.call(this)
|
|
9
9
|
config = utils.normalizeQueryConfig(config, values, callback)
|
|
10
10
|
this.text = config.text
|
|
@@ -31,8 +31,7 @@ var NativeQuery = (module.exports = function (config, values, callback) {
|
|
|
31
31
|
|
|
32
32
|
util.inherits(NativeQuery, EventEmitter)
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
/* eslint-disable quote-props */
|
|
34
|
+
const errorFieldMap = {
|
|
36
35
|
sqlState: 'code',
|
|
37
36
|
statementPosition: 'position',
|
|
38
37
|
messagePrimary: 'message',
|
|
@@ -49,10 +48,10 @@ var errorFieldMap = {
|
|
|
49
48
|
|
|
50
49
|
NativeQuery.prototype.handleError = function (err) {
|
|
51
50
|
// copy pq error fields into the error object
|
|
52
|
-
|
|
51
|
+
const fields = this.native.pq.resultErrorFields()
|
|
53
52
|
if (fields) {
|
|
54
|
-
for (
|
|
55
|
-
|
|
53
|
+
for (const key in fields) {
|
|
54
|
+
const normalizedFieldName = errorFieldMap[key] || key
|
|
56
55
|
err[normalizedFieldName] = fields[key]
|
|
57
56
|
}
|
|
58
57
|
}
|
|
@@ -85,11 +84,11 @@ NativeQuery.prototype._getPromise = function () {
|
|
|
85
84
|
|
|
86
85
|
NativeQuery.prototype.submit = function (client) {
|
|
87
86
|
this.state = 'running'
|
|
88
|
-
|
|
87
|
+
const self = this
|
|
89
88
|
this.native = client.native
|
|
90
89
|
client.native.arrayMode = this._arrayMode
|
|
91
90
|
|
|
92
|
-
|
|
91
|
+
let after = function (err, rows, results) {
|
|
93
92
|
client.native.arrayMode = false
|
|
94
93
|
setImmediate(function () {
|
|
95
94
|
self.emit('_done')
|
|
@@ -130,13 +129,11 @@ NativeQuery.prototype.submit = function (client) {
|
|
|
130
129
|
// named query
|
|
131
130
|
if (this.name) {
|
|
132
131
|
if (this.name.length > 63) {
|
|
133
|
-
/* eslint-disable no-console */
|
|
134
132
|
console.error('Warning! Postgres only supports 63 characters for query names.')
|
|
135
133
|
console.error('You supplied %s (%s)', this.name, this.name.length)
|
|
136
134
|
console.error('This can cause conflicts and silent errors executing queries')
|
|
137
|
-
/* eslint-enable no-console */
|
|
138
135
|
}
|
|
139
|
-
|
|
136
|
+
const values = (this.values || []).map(utils.prepareValue)
|
|
140
137
|
|
|
141
138
|
// check if the client has already executed this named query
|
|
142
139
|
// if so...just execute it again - skip the planning phase
|
|
@@ -158,7 +155,7 @@ NativeQuery.prototype.submit = function (client) {
|
|
|
158
155
|
const err = new Error('Query values must be an array')
|
|
159
156
|
return after(err)
|
|
160
157
|
}
|
|
161
|
-
|
|
158
|
+
const vals = this.values.map(utils.prepareValue)
|
|
162
159
|
client.native.query(this.text, vals, after)
|
|
163
160
|
} else if (this.queryMode === 'extended') {
|
|
164
161
|
client.native.query(this.text, [], after)
|
package/lib/query.js
CHANGED
package/lib/result.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const types = require('pg-types')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const matchRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/
|
|
6
6
|
|
|
7
7
|
// result object returned from query
|
|
8
8
|
// in the 'end' event and also
|
|
@@ -26,7 +26,7 @@ class Result {
|
|
|
26
26
|
|
|
27
27
|
// adds a command complete message
|
|
28
28
|
addCommandComplete(msg) {
|
|
29
|
-
|
|
29
|
+
let match
|
|
30
30
|
if (msg.text) {
|
|
31
31
|
// pure javascript
|
|
32
32
|
match = matchRegexp.exec(msg.text)
|
|
@@ -48,9 +48,9 @@ class Result {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
_parseRowAsArray(rowData) {
|
|
51
|
-
|
|
52
|
-
for (
|
|
53
|
-
|
|
51
|
+
const row = new Array(rowData.length)
|
|
52
|
+
for (let i = 0, len = rowData.length; i < len; i++) {
|
|
53
|
+
const rawValue = rowData[i]
|
|
54
54
|
if (rawValue !== null) {
|
|
55
55
|
row[i] = this._parsers[i](rawValue)
|
|
56
56
|
} else {
|
|
@@ -61,10 +61,10 @@ class Result {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
parseRow(rowData) {
|
|
64
|
-
|
|
65
|
-
for (
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const row = { ...this._prebuiltEmptyResultObject }
|
|
65
|
+
for (let i = 0, len = rowData.length; i < len; i++) {
|
|
66
|
+
const rawValue = rowData[i]
|
|
67
|
+
const field = this.fields[i].name
|
|
68
68
|
if (rawValue !== null) {
|
|
69
69
|
row[field] = this._parsers[i](rawValue)
|
|
70
70
|
} else {
|
|
@@ -88,10 +88,10 @@ class Result {
|
|
|
88
88
|
this._parsers = new Array(fieldDescriptions.length)
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
const row = {}
|
|
92
92
|
|
|
93
|
-
for (
|
|
94
|
-
|
|
93
|
+
for (let i = 0; i < fieldDescriptions.length; i++) {
|
|
94
|
+
const desc = fieldDescriptions[i]
|
|
95
95
|
row[desc.name] = null
|
|
96
96
|
|
|
97
97
|
if (this._types) {
|
package/lib/stream.js
CHANGED
package/lib/type-overrides.js
CHANGED
package/lib/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const defaults = require('./defaults')
|
|
4
4
|
|
|
5
5
|
function escapeElement(elementRepresentation) {
|
|
6
|
-
|
|
6
|
+
const escaped = elementRepresentation.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
|
7
7
|
|
|
8
8
|
return '"' + escaped + '"'
|
|
9
9
|
}
|
|
@@ -12,8 +12,8 @@ function escapeElement(elementRepresentation) {
|
|
|
12
12
|
// uses comma separator so won't work for types like box that use
|
|
13
13
|
// a different array separator.
|
|
14
14
|
function arrayString(val) {
|
|
15
|
-
|
|
16
|
-
for (
|
|
15
|
+
let result = '{'
|
|
16
|
+
for (let i = 0; i < val.length; i++) {
|
|
17
17
|
if (i > 0) {
|
|
18
18
|
result = result + ','
|
|
19
19
|
}
|
|
@@ -22,9 +22,9 @@ function arrayString(val) {
|
|
|
22
22
|
} else if (Array.isArray(val[i])) {
|
|
23
23
|
result = result + arrayString(val[i])
|
|
24
24
|
} else if (ArrayBuffer.isView(val[i])) {
|
|
25
|
-
|
|
25
|
+
let item = val[i]
|
|
26
26
|
if (!(item instanceof Buffer)) {
|
|
27
|
-
|
|
27
|
+
const buf = Buffer.from(item.buffer, item.byteOffset, item.byteLength)
|
|
28
28
|
if (buf.length === item.byteLength) {
|
|
29
29
|
item = buf
|
|
30
30
|
} else {
|
|
@@ -44,7 +44,7 @@ function arrayString(val) {
|
|
|
44
44
|
// to their 'raw' counterparts for use as a postgres parameter
|
|
45
45
|
// note: you can override this function to provide your own conversion mechanism
|
|
46
46
|
// for complex types, etc...
|
|
47
|
-
|
|
47
|
+
const prepareValue = function (val, seen) {
|
|
48
48
|
// null and undefined are both null for postgres
|
|
49
49
|
if (val == null) {
|
|
50
50
|
return null
|
|
@@ -54,7 +54,7 @@ var prepareValue = function (val, seen) {
|
|
|
54
54
|
return val
|
|
55
55
|
}
|
|
56
56
|
if (ArrayBuffer.isView(val)) {
|
|
57
|
-
|
|
57
|
+
const buf = Buffer.from(val.buffer, val.byteOffset, val.byteLength)
|
|
58
58
|
if (buf.length === val.byteLength) {
|
|
59
59
|
return buf
|
|
60
60
|
}
|
|
@@ -90,13 +90,13 @@ function prepareObject(val, seen) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function dateToString(date) {
|
|
93
|
-
|
|
93
|
+
let offset = -date.getTimezoneOffset()
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
let year = date.getFullYear()
|
|
96
|
+
const isBCYear = year < 1
|
|
97
97
|
if (isBCYear) year = Math.abs(year) + 1 // negative years are 1 off their BC representation
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
let ret =
|
|
100
100
|
String(year).padStart(4, '0') +
|
|
101
101
|
'-' +
|
|
102
102
|
String(date.getMonth() + 1).padStart(2, '0') +
|
|
@@ -124,11 +124,11 @@ function dateToString(date) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
function dateToStringUTC(date) {
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
let year = date.getUTCFullYear()
|
|
128
|
+
const isBCYear = year < 1
|
|
129
129
|
if (isBCYear) year = Math.abs(year) + 1 // negative years are 1 off their BC representation
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
let ret =
|
|
132
132
|
String(year).padStart(4, '0') +
|
|
133
133
|
'-' +
|
|
134
134
|
String(date.getUTCMonth() + 1).padStart(2, '0') +
|
|
@@ -170,11 +170,11 @@ const escapeIdentifier = function (str) {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
const escapeLiteral = function (str) {
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
let hasBackslash = false
|
|
174
|
+
let escaped = "'"
|
|
175
175
|
|
|
176
|
-
for (
|
|
177
|
-
|
|
176
|
+
for (let i = 0; i < str.length; i++) {
|
|
177
|
+
const c = str[i]
|
|
178
178
|
if (c === "'") {
|
|
179
179
|
escaped += c + c
|
|
180
180
|
} else if (c === '\\') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.16.0",
|
|
4
4
|
"description": "PostgreSQL client - pure javascript & libpq with the same API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"pg-connection-string": "^2.
|
|
36
|
-
"pg-pool": "^3.
|
|
37
|
-
"pg-protocol": "^1.
|
|
38
|
-
"pg-types": "
|
|
39
|
-
"pgpass": "1.
|
|
35
|
+
"pg-connection-string": "^2.9.0",
|
|
36
|
+
"pg-pool": "^3.10.0",
|
|
37
|
+
"pg-protocol": "^1.10.0",
|
|
38
|
+
"pg-types": "2.2.0",
|
|
39
|
+
"pgpass": "1.0.5"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@cloudflare/vitest-pool-workers": "0.8.
|
|
42
|
+
"@cloudflare/vitest-pool-workers": "0.8.23",
|
|
43
43
|
"@cloudflare/workers-types": "^4.20230404.0",
|
|
44
44
|
"async": "2.6.4",
|
|
45
45
|
"bluebird": "3.7.2",
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
"pg-copy-streams": "0.3.0",
|
|
48
48
|
"typescript": "^4.0.3",
|
|
49
49
|
"vitest": "~3.0.9",
|
|
50
|
-
"workerd": "^1.20230419.0",
|
|
51
50
|
"wrangler": "^3.x"
|
|
52
51
|
},
|
|
53
52
|
"optionalDependencies": {
|
|
@@ -73,5 +72,5 @@
|
|
|
73
72
|
"engines": {
|
|
74
73
|
"node": ">= 8.0.0"
|
|
75
74
|
},
|
|
76
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "abff18d6f918c975e8b3dfebc0de3b811ae64bcb"
|
|
77
76
|
}
|