pg 7.18.2 → 8.0.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 +19 -1
- package/lib/connection-fast.js +3 -17
- package/lib/connection-parameters.js +15 -1
- package/lib/connection.js +7 -21
- package/lib/defaults.js +1 -1
- package/lib/index.js +25 -25
- package/lib/native/client.js +9 -1
- package/lib/query.js +184 -190
- package/package.json +4 -4
- package/lib/compat/check-constructor.js +0 -22
- package/lib/compat/warn-deprecation.js +0 -19
package/lib/client.js
CHANGED
|
@@ -30,7 +30,16 @@ var Client = function (config) {
|
|
|
30
30
|
this.database = this.connectionParameters.database
|
|
31
31
|
this.port = this.connectionParameters.port
|
|
32
32
|
this.host = this.connectionParameters.host
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
// "hiding" the password so it doesn't show up in stack traces
|
|
35
|
+
// or if the client is console.logged
|
|
36
|
+
Object.defineProperty(this, 'password', {
|
|
37
|
+
configurable: true,
|
|
38
|
+
enumerable: false,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: this.connectionParameters.password
|
|
41
|
+
})
|
|
42
|
+
|
|
34
43
|
this.replication = this.connectionParameters.replication
|
|
35
44
|
|
|
36
45
|
var c = config || {}
|
|
@@ -545,6 +554,15 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
545
554
|
Client.prototype.end = function (cb) {
|
|
546
555
|
this._ending = true
|
|
547
556
|
|
|
557
|
+
// if we have never connected, then end is a noop, callback immediately
|
|
558
|
+
if (this.connection.stream.readyState === 'closed') {
|
|
559
|
+
if (cb) {
|
|
560
|
+
cb()
|
|
561
|
+
} else {
|
|
562
|
+
return this._Promise.resolve()
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
548
566
|
if (this.activeQuery || !this._queryable) {
|
|
549
567
|
// if we have an active query we need to force a disconnect
|
|
550
568
|
// on the socket - otherwise a hung query could block end forever
|
package/lib/connection-fast.js
CHANGED
|
@@ -15,8 +15,6 @@ var Writer = require('buffer-writer')
|
|
|
15
15
|
// eslint-disable-next-line
|
|
16
16
|
var PacketStream = require('pg-packet-stream')
|
|
17
17
|
|
|
18
|
-
var warnDeprecation = require('./compat/warn-deprecation')
|
|
19
|
-
|
|
20
18
|
var TEXT_MODE = 0
|
|
21
19
|
|
|
22
20
|
// TODO(bmc) support binary mode here
|
|
@@ -95,21 +93,9 @@ Connection.prototype.connect = function (port, host) {
|
|
|
95
93
|
return self.emit('error', new Error('There was an error establishing an SSL connection'))
|
|
96
94
|
}
|
|
97
95
|
var tls = require('tls')
|
|
98
|
-
const options = {
|
|
99
|
-
socket: self.stream
|
|
100
|
-
|
|
101
|
-
rejectUnauthorized: self.ssl.rejectUnauthorized,
|
|
102
|
-
ca: self.ssl.ca,
|
|
103
|
-
pfx: self.ssl.pfx,
|
|
104
|
-
key: self.ssl.key,
|
|
105
|
-
passphrase: self.ssl.passphrase,
|
|
106
|
-
cert: self.ssl.cert,
|
|
107
|
-
secureOptions: self.ssl.secureOptions,
|
|
108
|
-
NPNProtocols: self.ssl.NPNProtocols
|
|
109
|
-
}
|
|
110
|
-
if (typeof self.ssl.rejectUnauthorized !== 'boolean') {
|
|
111
|
-
warnDeprecation('Implicit disabling of certificate verification is deprecated and will be removed in pg 8. Specify `rejectUnauthorized: true` to require a valid CA or `rejectUnauthorized: false` to explicitly opt out of MITM protection.', 'PG-SSL-VERIFY')
|
|
112
|
-
}
|
|
96
|
+
const options = Object.assign({
|
|
97
|
+
socket: self.stream
|
|
98
|
+
}, self.ssl)
|
|
113
99
|
if (net.isIP(host) === 0) {
|
|
114
100
|
options.servername = host
|
|
115
101
|
}
|
|
@@ -52,9 +52,23 @@ var ConnectionParameters = function (config) {
|
|
|
52
52
|
|
|
53
53
|
this.user = val('user', config)
|
|
54
54
|
this.database = val('database', config)
|
|
55
|
+
|
|
56
|
+
if (this.database === undefined) {
|
|
57
|
+
this.database = this.user
|
|
58
|
+
}
|
|
59
|
+
|
|
55
60
|
this.port = parseInt(val('port', config), 10)
|
|
56
61
|
this.host = val('host', config)
|
|
57
|
-
|
|
62
|
+
|
|
63
|
+
// "hiding" the password so it doesn't show up in stack traces
|
|
64
|
+
// or if the client is console.logged
|
|
65
|
+
Object.defineProperty(this, 'password', {
|
|
66
|
+
configurable: true,
|
|
67
|
+
enumerable: false,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: val('password', config)
|
|
70
|
+
})
|
|
71
|
+
|
|
58
72
|
this.binary = val('binary', config)
|
|
59
73
|
this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl
|
|
60
74
|
this.client_encoding = val('client_encoding', config)
|
package/lib/connection.js
CHANGED
|
@@ -14,8 +14,6 @@ var util = require('util')
|
|
|
14
14
|
var Writer = require('buffer-writer')
|
|
15
15
|
var Reader = require('packet-reader')
|
|
16
16
|
|
|
17
|
-
var warnDeprecation = require('./compat/warn-deprecation')
|
|
18
|
-
|
|
19
17
|
var TEXT_MODE = 0
|
|
20
18
|
var BINARY_MODE = 1
|
|
21
19
|
var Connection = function (config) {
|
|
@@ -95,21 +93,9 @@ Connection.prototype.connect = function (port, host) {
|
|
|
95
93
|
return self.emit('error', new Error('There was an error establishing an SSL connection'))
|
|
96
94
|
}
|
|
97
95
|
var tls = require('tls')
|
|
98
|
-
const options = {
|
|
99
|
-
socket: self.stream
|
|
100
|
-
|
|
101
|
-
rejectUnauthorized: self.ssl.rejectUnauthorized,
|
|
102
|
-
ca: self.ssl.ca,
|
|
103
|
-
pfx: self.ssl.pfx,
|
|
104
|
-
key: self.ssl.key,
|
|
105
|
-
passphrase: self.ssl.passphrase,
|
|
106
|
-
cert: self.ssl.cert,
|
|
107
|
-
secureOptions: self.ssl.secureOptions,
|
|
108
|
-
NPNProtocols: self.ssl.NPNProtocols
|
|
109
|
-
}
|
|
110
|
-
if (typeof self.ssl.rejectUnauthorized !== 'boolean') {
|
|
111
|
-
warnDeprecation('Implicit disabling of certificate verification is deprecated and will be removed in pg 8. Specify `rejectUnauthorized: true` to require a valid CA or `rejectUnauthorized: false` to explicitly opt out of MITM protection.', 'PG-SSL-VERIFY')
|
|
112
|
-
}
|
|
96
|
+
const options = Object.assign({
|
|
97
|
+
socket: self.stream
|
|
98
|
+
}, self.ssl)
|
|
113
99
|
if (net.isIP(host) === 0) {
|
|
114
100
|
options.servername = host
|
|
115
101
|
}
|
|
@@ -602,7 +588,7 @@ Connection.prototype._readValue = function (buffer) {
|
|
|
602
588
|
}
|
|
603
589
|
|
|
604
590
|
// parses error
|
|
605
|
-
Connection.prototype.parseE = function (buffer, length) {
|
|
591
|
+
Connection.prototype.parseE = function (buffer, length, isNotice) {
|
|
606
592
|
var fields = {}
|
|
607
593
|
var fieldType = this.readString(buffer, 1)
|
|
608
594
|
while (fieldType !== '\0') {
|
|
@@ -611,10 +597,10 @@ Connection.prototype.parseE = function (buffer, length) {
|
|
|
611
597
|
}
|
|
612
598
|
|
|
613
599
|
// the msg is an Error instance
|
|
614
|
-
var msg = new Error(fields.M)
|
|
600
|
+
var msg = isNotice ? { message: fields.M } : new Error(fields.M)
|
|
615
601
|
|
|
616
602
|
// for compatibility with Message
|
|
617
|
-
msg.name = 'error'
|
|
603
|
+
msg.name = isNotice ? 'notice' : 'error'
|
|
618
604
|
msg.length = length
|
|
619
605
|
|
|
620
606
|
msg.severity = fields.S
|
|
@@ -638,7 +624,7 @@ Connection.prototype.parseE = function (buffer, length) {
|
|
|
638
624
|
|
|
639
625
|
// same thing, different name
|
|
640
626
|
Connection.prototype.parseN = function (buffer, length) {
|
|
641
|
-
var msg = this.parseE(buffer, length)
|
|
627
|
+
var msg = this.parseE(buffer, length, true)
|
|
642
628
|
msg.name = 'notice'
|
|
643
629
|
return msg
|
|
644
630
|
}
|
package/lib/defaults.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = {
|
|
|
15
15
|
user: process.platform === 'win32' ? process.env.USERNAME : process.env.USER,
|
|
16
16
|
|
|
17
17
|
// name of database to connect
|
|
18
|
-
database:
|
|
18
|
+
database: undefined,
|
|
19
19
|
|
|
20
20
|
// database user's password
|
|
21
21
|
password: null,
|
package/lib/index.js
CHANGED
|
@@ -7,25 +7,17 @@
|
|
|
7
7
|
* README.md file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
var util = require('util')
|
|
11
10
|
var Client = require('./client')
|
|
12
11
|
var defaults = require('./defaults')
|
|
13
12
|
var Connection = require('./connection')
|
|
14
13
|
var Pool = require('pg-pool')
|
|
15
|
-
const checkConstructor = require('./compat/check-constructor')
|
|
16
14
|
|
|
17
15
|
const poolFactory = (Client) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var config = Object.assign({ Client: Client }, options)
|
|
23
|
-
return new Pool(config)
|
|
16
|
+
return class BoundPool extends Pool {
|
|
17
|
+
constructor (options) {
|
|
18
|
+
super(options, Client)
|
|
19
|
+
}
|
|
24
20
|
}
|
|
25
|
-
|
|
26
|
-
util.inherits(BoundPool, Pool)
|
|
27
|
-
|
|
28
|
-
return BoundPool
|
|
29
21
|
}
|
|
30
22
|
|
|
31
23
|
var PG = function (clientConstructor) {
|
|
@@ -44,20 +36,28 @@ if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
|
|
|
44
36
|
module.exports = new PG(Client)
|
|
45
37
|
|
|
46
38
|
// lazy require native module...the native module may not have installed
|
|
47
|
-
module.exports
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
native =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
39
|
+
Object.defineProperty(module.exports, 'native', {
|
|
40
|
+
configurable: true,
|
|
41
|
+
enumerable: false,
|
|
42
|
+
get() {
|
|
43
|
+
var native = null
|
|
44
|
+
try {
|
|
45
|
+
native = new PG(require('./native'))
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err.code !== 'MODULE_NOT_FOUND') {
|
|
48
|
+
throw err
|
|
49
|
+
}
|
|
50
|
+
/* eslint-disable no-console */
|
|
51
|
+
console.error(err.message)
|
|
52
|
+
/* eslint-enable no-console */
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
|
|
55
|
+
// overwrite module.exports.native so that getter is never called again
|
|
56
|
+
Object.defineProperty(module.exports, 'native', {
|
|
57
|
+
value: native
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
return native
|
|
59
61
|
}
|
|
60
|
-
module.exports.native = native
|
|
61
|
-
return native
|
|
62
62
|
})
|
|
63
63
|
}
|
package/lib/native/client.js
CHANGED
|
@@ -43,7 +43,15 @@ var Client = module.exports = function (config) {
|
|
|
43
43
|
// for the time being. TODO: deprecate all this jazz
|
|
44
44
|
var cp = this.connectionParameters = new ConnectionParameters(config)
|
|
45
45
|
this.user = cp.user
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
// "hiding" the password so it doesn't show up in stack traces
|
|
48
|
+
// or if the client is console.logged
|
|
49
|
+
Object.defineProperty(this, 'password', {
|
|
50
|
+
configurable: true,
|
|
51
|
+
enumerable: false,
|
|
52
|
+
writable: true,
|
|
53
|
+
value: cp.password
|
|
54
|
+
})
|
|
47
55
|
this.database = cp.database
|
|
48
56
|
this.host = cp.host
|
|
49
57
|
this.port = cp.port
|
package/lib/query.js
CHANGED
|
@@ -7,226 +7,220 @@
|
|
|
7
7
|
* README.md file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.callback = config.callback
|
|
34
|
-
this._rowMode = config.rowMode
|
|
35
|
-
if (process.domain && config.callback) {
|
|
36
|
-
this.callback = process.domain.bind(config.callback)
|
|
37
|
-
}
|
|
38
|
-
this._result = new Result(this._rowMode, this.types)
|
|
39
|
-
|
|
40
|
-
// potential for multiple results
|
|
41
|
-
this._results = this._result
|
|
42
|
-
this.isPreparedStatement = false
|
|
43
|
-
this._canceledDueToError = false
|
|
44
|
-
this._promise = null
|
|
45
|
-
EventEmitter.call(this)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
util.inherits(Query, EventEmitter)
|
|
49
|
-
|
|
50
|
-
Query.prototype.requiresPreparation = function () {
|
|
51
|
-
// named queries must always be prepared
|
|
52
|
-
if (this.name) { return true }
|
|
53
|
-
// always prepare if there are max number of rows expected per
|
|
54
|
-
// portal execution
|
|
55
|
-
if (this.rows) { return true }
|
|
56
|
-
// don't prepare empty text queries
|
|
57
|
-
if (!this.text) { return false }
|
|
58
|
-
// prepare if there are values
|
|
59
|
-
if (!this.values) { return false }
|
|
60
|
-
return this.values.length > 0
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
Query.prototype._checkForMultirow = function () {
|
|
64
|
-
// if we already have a result with a command property
|
|
65
|
-
// then we've already executed one query in a multi-statement simple query
|
|
66
|
-
// turn our results into an array of results
|
|
67
|
-
if (this._result.command) {
|
|
68
|
-
if (!Array.isArray(this._results)) {
|
|
69
|
-
this._results = [this._result]
|
|
10
|
+
const { EventEmitter } = require('events')
|
|
11
|
+
|
|
12
|
+
const Result = require('./result')
|
|
13
|
+
const utils = require('./utils')
|
|
14
|
+
|
|
15
|
+
class Query extends EventEmitter {
|
|
16
|
+
constructor(config, values, callback) {
|
|
17
|
+
super()
|
|
18
|
+
|
|
19
|
+
config = utils.normalizeQueryConfig(config, values, callback)
|
|
20
|
+
|
|
21
|
+
this.text = config.text
|
|
22
|
+
this.values = config.values
|
|
23
|
+
this.rows = config.rows
|
|
24
|
+
this.types = config.types
|
|
25
|
+
this.name = config.name
|
|
26
|
+
this.binary = config.binary
|
|
27
|
+
// use unique portal name each time
|
|
28
|
+
this.portal = config.portal || ''
|
|
29
|
+
this.callback = config.callback
|
|
30
|
+
this._rowMode = config.rowMode
|
|
31
|
+
if (process.domain && config.callback) {
|
|
32
|
+
this.callback = process.domain.bind(config.callback)
|
|
70
33
|
}
|
|
71
34
|
this._result = new Result(this._rowMode, this.types)
|
|
72
|
-
|
|
35
|
+
|
|
36
|
+
// potential for multiple results
|
|
37
|
+
this._results = this._result
|
|
38
|
+
this.isPreparedStatement = false
|
|
39
|
+
this._canceledDueToError = false
|
|
40
|
+
this._promise = null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
requiresPreparation() {
|
|
44
|
+
// named queries must always be prepared
|
|
45
|
+
if (this.name) { return true }
|
|
46
|
+
// always prepare if there are max number of rows expected per
|
|
47
|
+
// portal execution
|
|
48
|
+
if (this.rows) { return true }
|
|
49
|
+
// don't prepare empty text queries
|
|
50
|
+
if (!this.text) { return false }
|
|
51
|
+
// prepare if there are values
|
|
52
|
+
if (!this.values) { return false }
|
|
53
|
+
return this.values.length > 0
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_checkForMultirow() {
|
|
57
|
+
// if we already have a result with a command property
|
|
58
|
+
// then we've already executed one query in a multi-statement simple query
|
|
59
|
+
// turn our results into an array of results
|
|
60
|
+
if (this._result.command) {
|
|
61
|
+
if (!Array.isArray(this._results)) {
|
|
62
|
+
this._results = [this._result]
|
|
63
|
+
}
|
|
64
|
+
this._result = new Result(this._rowMode, this.types)
|
|
65
|
+
this._results.push(this._result)
|
|
66
|
+
}
|
|
73
67
|
}
|
|
74
|
-
}
|
|
75
68
|
|
|
76
|
-
// associates row metadata from the supplied
|
|
77
|
-
// message with this query object
|
|
78
|
-
// metadata used when parsing row results
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
69
|
+
// associates row metadata from the supplied
|
|
70
|
+
// message with this query object
|
|
71
|
+
// metadata used when parsing row results
|
|
72
|
+
handleRowDescription(msg) {
|
|
73
|
+
this._checkForMultirow()
|
|
74
|
+
this._result.addFields(msg.fields)
|
|
75
|
+
this._accumulateRows = this.callback || !this.listeners('row').length
|
|
76
|
+
}
|
|
84
77
|
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
handleDataRow(msg) {
|
|
79
|
+
let row
|
|
87
80
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
if (this._canceledDueToError) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
91
84
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
85
|
+
try {
|
|
86
|
+
row = this._result.parseRow(msg.fields)
|
|
87
|
+
} catch (err) {
|
|
88
|
+
this._canceledDueToError = err
|
|
89
|
+
return
|
|
90
|
+
}
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
this.emit('row', row, this._result)
|
|
93
|
+
if (this._accumulateRows) {
|
|
94
|
+
this._result.addRow(row)
|
|
95
|
+
}
|
|
102
96
|
}
|
|
103
|
-
}
|
|
104
97
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
handleCommandComplete(msg, con) {
|
|
99
|
+
this._checkForMultirow()
|
|
100
|
+
this._result.addCommandComplete(msg)
|
|
101
|
+
// need to sync after each command complete of a prepared statement
|
|
102
|
+
if (this.isPreparedStatement) {
|
|
103
|
+
con.sync()
|
|
104
|
+
}
|
|
111
105
|
}
|
|
112
|
-
}
|
|
113
106
|
|
|
114
|
-
// if a named prepared statement is created with empty query text
|
|
115
|
-
// the backend will send an emptyQuery message but *not* a command complete message
|
|
116
|
-
// execution on the connection will hang until the backend receives a sync message
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
// if a named prepared statement is created with empty query text
|
|
108
|
+
// the backend will send an emptyQuery message but *not* a command complete message
|
|
109
|
+
// execution on the connection will hang until the backend receives a sync message
|
|
110
|
+
handleEmptyQuery(con) {
|
|
111
|
+
if (this.isPreparedStatement) {
|
|
112
|
+
con.sync()
|
|
113
|
+
}
|
|
120
114
|
}
|
|
121
|
-
}
|
|
122
115
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
handleReadyForQuery(con) {
|
|
117
|
+
if (this._canceledDueToError) {
|
|
118
|
+
return this.handleError(this._canceledDueToError, con)
|
|
119
|
+
}
|
|
120
|
+
if (this.callback) {
|
|
121
|
+
this.callback(null, this._results)
|
|
122
|
+
}
|
|
123
|
+
this.emit('end', this._results)
|
|
129
124
|
}
|
|
130
|
-
this.emit('end', this._results)
|
|
131
|
-
}
|
|
132
125
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
126
|
+
handleError(err, connection) {
|
|
127
|
+
// need to sync after error during a prepared statement
|
|
128
|
+
if (this.isPreparedStatement) {
|
|
129
|
+
connection.sync()
|
|
130
|
+
}
|
|
131
|
+
if (this._canceledDueToError) {
|
|
132
|
+
err = this._canceledDueToError
|
|
133
|
+
this._canceledDueToError = false
|
|
134
|
+
}
|
|
135
|
+
// if callback supplied do not emit error event as uncaught error
|
|
136
|
+
// events will bubble up to node process
|
|
137
|
+
if (this.callback) {
|
|
138
|
+
return this.callback(err)
|
|
139
|
+
}
|
|
140
|
+
this.emit('error', err)
|
|
146
141
|
}
|
|
147
|
-
this.emit('error', err)
|
|
148
|
-
}
|
|
149
142
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
143
|
+
submit(connection) {
|
|
144
|
+
if (typeof this.text !== 'string' && typeof this.name !== 'string') {
|
|
145
|
+
return new Error('A query must have either text or a name. Supplying neither is unsupported.')
|
|
146
|
+
}
|
|
147
|
+
const previous = connection.parsedStatements[this.name]
|
|
148
|
+
if (this.text && previous && this.text !== previous) {
|
|
149
|
+
return new Error(`Prepared statements must be unique - '${this.name}' was used for a different statement`)
|
|
150
|
+
}
|
|
151
|
+
if (this.values && !Array.isArray(this.values)) {
|
|
152
|
+
return new Error('Query values must be an array')
|
|
153
|
+
}
|
|
154
|
+
if (this.requiresPreparation()) {
|
|
155
|
+
this.prepare(connection)
|
|
156
|
+
} else {
|
|
157
|
+
connection.query(this.text)
|
|
158
|
+
}
|
|
159
|
+
return null
|
|
157
160
|
}
|
|
158
|
-
|
|
159
|
-
|
|
161
|
+
|
|
162
|
+
hasBeenParsed(connection) {
|
|
163
|
+
return this.name && connection.parsedStatements[this.name]
|
|
160
164
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
connection.query(this.text)
|
|
165
|
+
|
|
166
|
+
handlePortalSuspended(connection) {
|
|
167
|
+
this._getRows(connection, this.rows)
|
|
165
168
|
}
|
|
166
|
-
return null
|
|
167
|
-
}
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
_getRows(connection, rows) {
|
|
171
|
+
connection.execute({
|
|
172
|
+
portal: this.portal,
|
|
173
|
+
rows: rows
|
|
174
|
+
}, true)
|
|
175
|
+
connection.flush()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
prepare(connection) {
|
|
179
|
+
// prepared statements need sync to be called after each command
|
|
180
|
+
// complete or when an error is encountered
|
|
181
|
+
this.isPreparedStatement = true
|
|
182
|
+
// TODO refactor this poor encapsulation
|
|
183
|
+
if (!this.hasBeenParsed(connection)) {
|
|
184
|
+
connection.parse({
|
|
185
|
+
text: this.text,
|
|
186
|
+
name: this.name,
|
|
187
|
+
types: this.types
|
|
188
|
+
}, true)
|
|
189
|
+
}
|
|
172
190
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
191
|
+
if (this.values) {
|
|
192
|
+
try {
|
|
193
|
+
this.values = this.values.map(utils.prepareValue)
|
|
194
|
+
} catch (err) {
|
|
195
|
+
this.handleError(err, connection)
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
}
|
|
176
199
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
200
|
+
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
|
|
201
|
+
connection.bind({
|
|
202
|
+
portal: this.portal,
|
|
203
|
+
statement: this.name,
|
|
204
|
+
values: this.values,
|
|
205
|
+
binary: this.binary
|
|
206
|
+
}, true)
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// complete or when an error is encountered
|
|
189
|
-
this.isPreparedStatement = true
|
|
190
|
-
// TODO refactor this poor encapsulation
|
|
191
|
-
if (!this.hasBeenParsed(connection)) {
|
|
192
|
-
connection.parse({
|
|
193
|
-
text: self.text,
|
|
194
|
-
name: self.name,
|
|
195
|
-
types: self.types
|
|
208
|
+
connection.describe({
|
|
209
|
+
type: 'P',
|
|
210
|
+
name: this.portal || ''
|
|
196
211
|
}, true)
|
|
197
|
-
}
|
|
198
212
|
|
|
199
|
-
|
|
200
|
-
try {
|
|
201
|
-
self.values = self.values.map(utils.prepareValue)
|
|
202
|
-
} catch (err) {
|
|
203
|
-
this.handleError(err, connection)
|
|
204
|
-
return
|
|
205
|
-
}
|
|
213
|
+
this._getRows(connection, this.rows)
|
|
206
214
|
}
|
|
207
215
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
statement: self.name,
|
|
212
|
-
values: self.values,
|
|
213
|
-
binary: self.binary
|
|
214
|
-
}, true)
|
|
215
|
-
|
|
216
|
-
connection.describe({
|
|
217
|
-
type: 'P',
|
|
218
|
-
name: self.portal || ''
|
|
219
|
-
}, true)
|
|
220
|
-
|
|
221
|
-
this._getRows(connection, this.rows)
|
|
222
|
-
}
|
|
216
|
+
handleCopyInResponse(connection) {
|
|
217
|
+
connection.sendCopyFail('No source stream defined')
|
|
218
|
+
}
|
|
223
219
|
|
|
224
|
-
|
|
225
|
-
|
|
220
|
+
// eslint-disable-next-line no-unused-vars
|
|
221
|
+
handleCopyData(msg, connection) {
|
|
222
|
+
// noop
|
|
223
|
+
}
|
|
226
224
|
}
|
|
227
225
|
|
|
228
|
-
// eslint-disable-next-line no-unused-vars
|
|
229
|
-
Query.prototype.handleCopyData = function (msg, connection) {
|
|
230
|
-
// noop
|
|
231
|
-
}
|
|
232
226
|
module.exports = Query
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "PostgreSQL client - pure javascript & libpq with the same API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"packet-reader": "1.0.0",
|
|
24
24
|
"pg-connection-string": "0.1.3",
|
|
25
25
|
"pg-packet-stream": "^1.1.0",
|
|
26
|
-
"pg-pool": "^
|
|
26
|
+
"pg-pool": "^3.0.0",
|
|
27
27
|
"pg-types": "^2.1.0",
|
|
28
28
|
"pgpass": "1.x",
|
|
29
29
|
"semver": "4.3.2"
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
],
|
|
52
52
|
"license": "MIT",
|
|
53
53
|
"engines": {
|
|
54
|
-
"node": ">=
|
|
54
|
+
"node": ">= 8.0.0"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "a227d3e8d47e1eb53296a3a013f2e7514cd152c3"
|
|
57
57
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const warnDeprecation = require('./warn-deprecation')
|
|
4
|
-
|
|
5
|
-
// Node 4 doesn’t support new.target.
|
|
6
|
-
let hasNewTarget
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
// eslint-disable-next-line no-eval
|
|
10
|
-
eval('(function () { new.target })')
|
|
11
|
-
hasNewTarget = true
|
|
12
|
-
} catch (error) {
|
|
13
|
-
hasNewTarget = false
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const checkConstructor = (name, code, getNewTarget) => {
|
|
17
|
-
if (hasNewTarget && getNewTarget() === undefined) {
|
|
18
|
-
warnDeprecation(`Constructing a ${name} without new is deprecated and will stop working in pg 8.`, code)
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
module.exports = checkConstructor
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const util = require('util')
|
|
4
|
-
|
|
5
|
-
const dummyFunctions = new Map()
|
|
6
|
-
|
|
7
|
-
// Node 4 doesn’t support process.emitWarning(message, 'DeprecationWarning', code).
|
|
8
|
-
const warnDeprecation = (message, code) => {
|
|
9
|
-
let dummy = dummyFunctions.get(code)
|
|
10
|
-
|
|
11
|
-
if (dummy === undefined) {
|
|
12
|
-
dummy = util.deprecate(() => {}, message)
|
|
13
|
-
dummyFunctions.set(code, dummy)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
dummy()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
module.exports = warnDeprecation
|