pg 7.18.2 → 8.0.3
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 +59 -30
- package/lib/connection-fast.js +49 -211
- package/lib/connection-parameters.js +17 -5
- package/lib/connection.js +36 -69
- package/lib/defaults.js +2 -2
- package/lib/index.js +26 -26
- package/lib/native/client.js +16 -8
- package/lib/native/query.js +27 -22
- package/lib/query.js +208 -194
- package/lib/sasl.js +34 -30
- package/lib/type-overrides.js +7 -4
- package/lib/utils.js +43 -27
- package/package.json +6 -13
- 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 || {}
|
|
@@ -43,13 +52,15 @@ var Client = function (config) {
|
|
|
43
52
|
this._connectionError = false
|
|
44
53
|
this._queryable = true
|
|
45
54
|
|
|
46
|
-
this.connection =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
this.connection =
|
|
56
|
+
c.connection ||
|
|
57
|
+
new Connection({
|
|
58
|
+
stream: c.stream,
|
|
59
|
+
ssl: this.connectionParameters.ssl,
|
|
60
|
+
keepAlive: c.keepAlive || false,
|
|
61
|
+
keepAliveInitialDelayMillis: c.keepAliveInitialDelayMillis || 0,
|
|
62
|
+
encoding: this.connectionParameters.client_encoding || 'utf8',
|
|
63
|
+
})
|
|
53
64
|
this.queryQueue = []
|
|
54
65
|
this.binary = c.binary || defaults.binary
|
|
55
66
|
this.processID = null
|
|
@@ -118,9 +129,10 @@ Client.prototype._connect = function (callback) {
|
|
|
118
129
|
function checkPgPass(cb) {
|
|
119
130
|
return function (msg) {
|
|
120
131
|
if (typeof self.password === 'function') {
|
|
121
|
-
self._Promise
|
|
132
|
+
self._Promise
|
|
133
|
+
.resolve()
|
|
122
134
|
.then(() => self.password())
|
|
123
|
-
.then(pass => {
|
|
135
|
+
.then((pass) => {
|
|
124
136
|
if (pass !== undefined) {
|
|
125
137
|
if (typeof pass !== 'string') {
|
|
126
138
|
con.emit('error', new TypeError('Password must be a string'))
|
|
@@ -131,7 +143,8 @@ Client.prototype._connect = function (callback) {
|
|
|
131
143
|
self.connectionParameters.password = self.password = null
|
|
132
144
|
}
|
|
133
145
|
cb(msg)
|
|
134
|
-
})
|
|
146
|
+
})
|
|
147
|
+
.catch((err) => {
|
|
135
148
|
con.emit('error', err)
|
|
136
149
|
})
|
|
137
150
|
} else if (self.password !== null) {
|
|
@@ -148,22 +161,31 @@ Client.prototype._connect = function (callback) {
|
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
// password request handling
|
|
151
|
-
con.on(
|
|
152
|
-
|
|
153
|
-
|
|
164
|
+
con.on(
|
|
165
|
+
'authenticationCleartextPassword',
|
|
166
|
+
checkPgPass(function () {
|
|
167
|
+
con.password(self.password)
|
|
168
|
+
})
|
|
169
|
+
)
|
|
154
170
|
|
|
155
171
|
// password request handling
|
|
156
|
-
con.on(
|
|
157
|
-
|
|
158
|
-
|
|
172
|
+
con.on(
|
|
173
|
+
'authenticationMD5Password',
|
|
174
|
+
checkPgPass(function (msg) {
|
|
175
|
+
con.password(utils.postgresMd5PasswordHash(self.user, self.password, msg.salt))
|
|
176
|
+
})
|
|
177
|
+
)
|
|
159
178
|
|
|
160
179
|
// password request handling (SASL)
|
|
161
180
|
var saslSession
|
|
162
|
-
con.on(
|
|
163
|
-
|
|
181
|
+
con.on(
|
|
182
|
+
'authenticationSASL',
|
|
183
|
+
checkPgPass(function (msg) {
|
|
184
|
+
saslSession = sasl.startSession(msg.mechanisms)
|
|
164
185
|
|
|
165
|
-
|
|
166
|
-
|
|
186
|
+
con.sendSASLInitialResponseMessage(saslSession.mechanism, saslSession.response)
|
|
187
|
+
})
|
|
188
|
+
)
|
|
167
189
|
|
|
168
190
|
// password request handling (SASL)
|
|
169
191
|
con.on('authenticationSASLContinue', function (msg) {
|
|
@@ -250,9 +272,7 @@ Client.prototype._connect = function (callback) {
|
|
|
250
272
|
})
|
|
251
273
|
|
|
252
274
|
con.once('end', () => {
|
|
253
|
-
const error = this._ending
|
|
254
|
-
? new Error('Connection terminated')
|
|
255
|
-
: new Error('Connection terminated unexpectedly')
|
|
275
|
+
const error = this._ending ? new Error('Connection terminated') : new Error('Connection terminated unexpectedly')
|
|
256
276
|
|
|
257
277
|
clearTimeout(connectionTimeoutHandle)
|
|
258
278
|
this._errorAllQueries(error)
|
|
@@ -358,7 +378,7 @@ Client.prototype.getStartupConf = function () {
|
|
|
358
378
|
|
|
359
379
|
var data = {
|
|
360
380
|
user: params.user,
|
|
361
|
-
database: params.database
|
|
381
|
+
database: params.database,
|
|
362
382
|
}
|
|
363
383
|
|
|
364
384
|
var appName = params.application_name || params.fallback_application_name
|
|
@@ -413,11 +433,11 @@ Client.prototype.escapeIdentifier = function (str) {
|
|
|
413
433
|
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
|
|
414
434
|
Client.prototype.escapeLiteral = function (str) {
|
|
415
435
|
var hasBackslash = false
|
|
416
|
-
var escaped = '
|
|
436
|
+
var escaped = "'"
|
|
417
437
|
|
|
418
438
|
for (var i = 0; i < str.length; i++) {
|
|
419
439
|
var c = str[i]
|
|
420
|
-
if (c === '
|
|
440
|
+
if (c === "'") {
|
|
421
441
|
escaped += c + c
|
|
422
442
|
} else if (c === '\\') {
|
|
423
443
|
escaped += c + c
|
|
@@ -427,7 +447,7 @@ Client.prototype.escapeLiteral = function (str) {
|
|
|
427
447
|
}
|
|
428
448
|
}
|
|
429
449
|
|
|
430
|
-
escaped += '
|
|
450
|
+
escaped += "'"
|
|
431
451
|
|
|
432
452
|
if (hasBackslash === true) {
|
|
433
453
|
escaped = ' E' + escaped
|
|
@@ -479,7 +499,7 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
479
499
|
query = new Query(config, values, callback)
|
|
480
500
|
if (!query.callback) {
|
|
481
501
|
result = new this._Promise((resolve, reject) => {
|
|
482
|
-
query.callback = (err, res) => err ? reject(err) : resolve(res)
|
|
502
|
+
query.callback = (err, res) => (err ? reject(err) : resolve(res))
|
|
483
503
|
})
|
|
484
504
|
}
|
|
485
505
|
}
|
|
@@ -498,7 +518,7 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
498
518
|
|
|
499
519
|
// we already returned an error,
|
|
500
520
|
// just do nothing if query completes
|
|
501
|
-
query.callback = () => {
|
|
521
|
+
query.callback = () => {}
|
|
502
522
|
|
|
503
523
|
// Remove from queue
|
|
504
524
|
var index = this.queryQueue.indexOf(query)
|
|
@@ -545,6 +565,15 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
545
565
|
Client.prototype.end = function (cb) {
|
|
546
566
|
this._ending = true
|
|
547
567
|
|
|
568
|
+
// if we have never connected, then end is a noop, callback immediately
|
|
569
|
+
if (!this.connection._connecting) {
|
|
570
|
+
if (cb) {
|
|
571
|
+
cb()
|
|
572
|
+
} else {
|
|
573
|
+
return this._Promise.resolve()
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
548
577
|
if (this.activeQuery || !this._queryable) {
|
|
549
578
|
// if we have an active query we need to force a disconnect
|
|
550
579
|
// on the socket - otherwise a hung query could block end forever
|
package/lib/connection-fast.js
CHANGED
|
@@ -11,17 +11,12 @@ var net = require('net')
|
|
|
11
11
|
var EventEmitter = require('events').EventEmitter
|
|
12
12
|
var util = require('util')
|
|
13
13
|
|
|
14
|
-
var Writer = require('buffer-writer')
|
|
15
14
|
// eslint-disable-next-line
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var warnDeprecation = require('./compat/warn-deprecation')
|
|
19
|
-
|
|
20
|
-
var TEXT_MODE = 0
|
|
15
|
+
const { parse, serialize } = require('../../pg-protocol/dist')
|
|
21
16
|
|
|
22
17
|
// TODO(bmc) support binary mode here
|
|
23
18
|
// var BINARY_MODE = 1
|
|
24
|
-
console.log('using faster connection')
|
|
19
|
+
console.log('***using faster connection***')
|
|
25
20
|
var Connection = function (config) {
|
|
26
21
|
EventEmitter.call(this)
|
|
27
22
|
config = config || {}
|
|
@@ -30,15 +25,9 @@ var Connection = function (config) {
|
|
|
30
25
|
this._keepAlive = config.keepAlive
|
|
31
26
|
this._keepAliveInitialDelayMillis = config.keepAliveInitialDelayMillis
|
|
32
27
|
this.lastBuffer = false
|
|
33
|
-
this.lastOffset = 0
|
|
34
|
-
this.buffer = null
|
|
35
|
-
this.offset = null
|
|
36
|
-
this.encoding = config.encoding || 'utf8'
|
|
37
28
|
this.parsedStatements = {}
|
|
38
|
-
this.writer = new Writer()
|
|
39
29
|
this.ssl = config.ssl || false
|
|
40
30
|
this._ending = false
|
|
41
|
-
this._mode = TEXT_MODE
|
|
42
31
|
this._emitMessage = false
|
|
43
32
|
var self = this
|
|
44
33
|
this.on('newListener', function (eventName) {
|
|
@@ -53,13 +42,10 @@ util.inherits(Connection, EventEmitter)
|
|
|
53
42
|
Connection.prototype.connect = function (port, host) {
|
|
54
43
|
var self = this
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
} else if (this.stream.readyState === 'open') {
|
|
59
|
-
this.emit('connect')
|
|
60
|
-
}
|
|
45
|
+
this._connecting = true
|
|
46
|
+
this.stream.connect(port, host)
|
|
61
47
|
|
|
62
|
-
this.stream.
|
|
48
|
+
this.stream.once('connect', function () {
|
|
63
49
|
if (self._keepAlive) {
|
|
64
50
|
self.stream.setKeepAlive(true, self._keepAliveInitialDelayMillis)
|
|
65
51
|
}
|
|
@@ -86,30 +72,23 @@ Connection.prototype.connect = function (port, host) {
|
|
|
86
72
|
this.stream.once('data', function (buffer) {
|
|
87
73
|
var responseCode = buffer.toString('utf8')
|
|
88
74
|
switch (responseCode) {
|
|
89
|
-
case 'N': // Server does not support SSL connections
|
|
90
|
-
return self.emit('error', new Error('The server does not support SSL connections'))
|
|
91
75
|
case 'S': // Server supports SSL connections, continue with a secure connection
|
|
92
76
|
break
|
|
77
|
+
case 'N': // Server does not support SSL connections
|
|
78
|
+
self.stream.end()
|
|
79
|
+
return self.emit('error', new Error('The server does not support SSL connections'))
|
|
93
80
|
default:
|
|
94
81
|
// Any other response byte, including 'E' (ErrorResponse) indicating a server error
|
|
82
|
+
self.stream.end()
|
|
95
83
|
return self.emit('error', new Error('There was an error establishing an SSL connection'))
|
|
96
84
|
}
|
|
97
85
|
var tls = require('tls')
|
|
98
|
-
const options =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
}
|
|
86
|
+
const options = Object.assign(
|
|
87
|
+
{
|
|
88
|
+
socket: self.stream,
|
|
89
|
+
},
|
|
90
|
+
self.ssl
|
|
91
|
+
)
|
|
113
92
|
if (net.isIP(host) === 0) {
|
|
114
93
|
options.servername = host
|
|
115
94
|
}
|
|
@@ -122,257 +101,116 @@ Connection.prototype.connect = function (port, host) {
|
|
|
122
101
|
}
|
|
123
102
|
|
|
124
103
|
Connection.prototype.attachListeners = function (stream) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
packetStream.on('data', (msg) => {
|
|
104
|
+
stream.on('end', () => {
|
|
105
|
+
this.emit('end')
|
|
106
|
+
})
|
|
107
|
+
parse(stream, (msg) => {
|
|
130
108
|
var eventName = msg.name === 'error' ? 'errorMessage' : msg.name
|
|
131
|
-
if (
|
|
132
|
-
|
|
109
|
+
if (this._emitMessage) {
|
|
110
|
+
this.emit('message', msg)
|
|
133
111
|
}
|
|
134
|
-
|
|
135
|
-
})
|
|
136
|
-
stream.on('end', function () {
|
|
137
|
-
self.emit('end')
|
|
112
|
+
this.emit(eventName, msg)
|
|
138
113
|
})
|
|
139
114
|
}
|
|
140
115
|
|
|
141
116
|
Connection.prototype.requestSsl = function () {
|
|
142
|
-
|
|
143
|
-
.addInt16(0x04d2)
|
|
144
|
-
.addInt16(0x162f)
|
|
145
|
-
.flush()
|
|
146
|
-
|
|
147
|
-
var length = bodyBuffer.length + 4
|
|
148
|
-
|
|
149
|
-
var buffer = new Writer()
|
|
150
|
-
.addInt32(length)
|
|
151
|
-
.add(bodyBuffer)
|
|
152
|
-
.join()
|
|
153
|
-
this.stream.write(buffer)
|
|
117
|
+
this.stream.write(serialize.requestSsl())
|
|
154
118
|
}
|
|
155
119
|
|
|
156
120
|
Connection.prototype.startup = function (config) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
Object.keys(config).forEach(function (key) {
|
|
160
|
-
var val = config[key]
|
|
161
|
-
writer.addCString(key).addCString(val)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
writer.addCString('client_encoding').addCString("'utf-8'")
|
|
165
|
-
|
|
166
|
-
var bodyBuffer = writer.addCString('').flush()
|
|
167
|
-
// this message is sent without a code
|
|
168
|
-
|
|
169
|
-
var length = bodyBuffer.length + 4
|
|
170
|
-
|
|
171
|
-
var buffer = new Writer()
|
|
172
|
-
.addInt32(length)
|
|
173
|
-
.add(bodyBuffer)
|
|
174
|
-
.join()
|
|
175
|
-
this.stream.write(buffer)
|
|
121
|
+
this.stream.write(serialize.startup(config))
|
|
176
122
|
}
|
|
177
123
|
|
|
178
124
|
Connection.prototype.cancel = function (processID, secretKey) {
|
|
179
|
-
|
|
180
|
-
.addInt16(1234)
|
|
181
|
-
.addInt16(5678)
|
|
182
|
-
.addInt32(processID)
|
|
183
|
-
.addInt32(secretKey)
|
|
184
|
-
.flush()
|
|
185
|
-
|
|
186
|
-
var length = bodyBuffer.length + 4
|
|
187
|
-
|
|
188
|
-
var buffer = new Writer()
|
|
189
|
-
.addInt32(length)
|
|
190
|
-
.add(bodyBuffer)
|
|
191
|
-
.join()
|
|
192
|
-
this.stream.write(buffer)
|
|
125
|
+
this._send(serialize.cancel(processID, secretKey))
|
|
193
126
|
}
|
|
194
127
|
|
|
195
128
|
Connection.prototype.password = function (password) {
|
|
196
|
-
|
|
197
|
-
this._send(0x70, this.writer.addCString(password))
|
|
129
|
+
this._send(serialize.password(password))
|
|
198
130
|
}
|
|
199
131
|
|
|
200
132
|
Connection.prototype.sendSASLInitialResponseMessage = function (mechanism, initialResponse) {
|
|
201
|
-
|
|
202
|
-
this.writer
|
|
203
|
-
.addCString(mechanism)
|
|
204
|
-
.addInt32(Buffer.byteLength(initialResponse))
|
|
205
|
-
.addString(initialResponse)
|
|
206
|
-
|
|
207
|
-
this._send(0x70)
|
|
133
|
+
this._send(serialize.sendSASLInitialResponseMessage(mechanism, initialResponse))
|
|
208
134
|
}
|
|
209
135
|
|
|
210
136
|
Connection.prototype.sendSCRAMClientFinalMessage = function (additionalData) {
|
|
211
|
-
|
|
212
|
-
this.writer.addString(additionalData)
|
|
213
|
-
|
|
214
|
-
this._send(0x70)
|
|
137
|
+
this._send(serialize.sendSCRAMClientFinalMessage(additionalData))
|
|
215
138
|
}
|
|
216
139
|
|
|
217
|
-
Connection.prototype._send = function (
|
|
140
|
+
Connection.prototype._send = function (buffer) {
|
|
218
141
|
if (!this.stream.writable) {
|
|
219
142
|
return false
|
|
220
143
|
}
|
|
221
|
-
return this.stream.write(
|
|
144
|
+
return this.stream.write(buffer)
|
|
222
145
|
}
|
|
223
146
|
|
|
224
147
|
Connection.prototype.query = function (text) {
|
|
225
|
-
|
|
226
|
-
this.stream.write(this.writer.addCString(text).flush(0x51))
|
|
148
|
+
this._send(serialize.query(text))
|
|
227
149
|
}
|
|
228
150
|
|
|
229
151
|
// send parse message
|
|
230
152
|
Connection.prototype.parse = function (query) {
|
|
231
|
-
|
|
232
|
-
// { name: 'queryName',
|
|
233
|
-
// text: 'select * from blah',
|
|
234
|
-
// types: ['int8', 'bool'] }
|
|
235
|
-
|
|
236
|
-
// normalize missing query names to allow for null
|
|
237
|
-
query.name = query.name || ''
|
|
238
|
-
if (query.name.length > 63) {
|
|
239
|
-
/* eslint-disable no-console */
|
|
240
|
-
console.error('Warning! Postgres only supports 63 characters for query names.')
|
|
241
|
-
console.error('You supplied %s (%s)', query.name, query.name.length)
|
|
242
|
-
console.error('This can cause conflicts and silent errors executing queries')
|
|
243
|
-
/* eslint-enable no-console */
|
|
244
|
-
}
|
|
245
|
-
// normalize null type array
|
|
246
|
-
query.types = query.types || []
|
|
247
|
-
var len = query.types.length
|
|
248
|
-
var buffer = this.writer
|
|
249
|
-
.addCString(query.name) // name of query
|
|
250
|
-
.addCString(query.text) // actual query text
|
|
251
|
-
.addInt16(len)
|
|
252
|
-
for (var i = 0; i < len; i++) {
|
|
253
|
-
buffer.addInt32(query.types[i])
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
var code = 0x50
|
|
257
|
-
this._send(code)
|
|
258
|
-
this.flush()
|
|
153
|
+
this._send(serialize.parse(query))
|
|
259
154
|
}
|
|
260
155
|
|
|
261
156
|
// send bind message
|
|
262
157
|
// "more" === true to buffer the message until flush() is called
|
|
263
158
|
Connection.prototype.bind = function (config) {
|
|
264
|
-
|
|
265
|
-
config = config || {}
|
|
266
|
-
config.portal = config.portal || ''
|
|
267
|
-
config.statement = config.statement || ''
|
|
268
|
-
config.binary = config.binary || false
|
|
269
|
-
var values = config.values || []
|
|
270
|
-
var len = values.length
|
|
271
|
-
var useBinary = false
|
|
272
|
-
for (var j = 0; j < len; j++) {
|
|
273
|
-
useBinary |= values[j] instanceof Buffer
|
|
274
|
-
}
|
|
275
|
-
var buffer = this.writer.addCString(config.portal).addCString(config.statement)
|
|
276
|
-
if (!useBinary) {
|
|
277
|
-
buffer.addInt16(0)
|
|
278
|
-
} else {
|
|
279
|
-
buffer.addInt16(len)
|
|
280
|
-
for (j = 0; j < len; j++) {
|
|
281
|
-
buffer.addInt16(values[j] instanceof Buffer)
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
buffer.addInt16(len)
|
|
285
|
-
for (var i = 0; i < len; i++) {
|
|
286
|
-
var val = values[i]
|
|
287
|
-
if (val === null || typeof val === 'undefined') {
|
|
288
|
-
buffer.addInt32(-1)
|
|
289
|
-
} else if (val instanceof Buffer) {
|
|
290
|
-
buffer.addInt32(val.length)
|
|
291
|
-
buffer.add(val)
|
|
292
|
-
} else {
|
|
293
|
-
buffer.addInt32(Buffer.byteLength(val))
|
|
294
|
-
buffer.addString(val)
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (config.binary) {
|
|
299
|
-
buffer.addInt16(1) // format codes to use binary
|
|
300
|
-
buffer.addInt16(1)
|
|
301
|
-
} else {
|
|
302
|
-
buffer.addInt16(0) // format codes to use text
|
|
303
|
-
}
|
|
304
|
-
// 0x42 = 'B'
|
|
305
|
-
this._send(0x42)
|
|
306
|
-
this.flush()
|
|
159
|
+
this._send(serialize.bind(config))
|
|
307
160
|
}
|
|
308
161
|
|
|
309
162
|
// send execute message
|
|
310
163
|
// "more" === true to buffer the message until flush() is called
|
|
311
164
|
Connection.prototype.execute = function (config) {
|
|
312
|
-
config
|
|
313
|
-
config.portal = config.portal || ''
|
|
314
|
-
config.rows = config.rows || ''
|
|
315
|
-
this.writer.addCString(config.portal).addInt32(config.rows)
|
|
316
|
-
|
|
317
|
-
// 0x45 = 'E'
|
|
318
|
-
this._send(0x45)
|
|
319
|
-
this.flush()
|
|
165
|
+
this._send(serialize.execute(config))
|
|
320
166
|
}
|
|
321
167
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
const flushBuffer = Buffer.from([0x48, 0x00, 0x00, 0x00, 0x04])
|
|
168
|
+
const flushBuffer = serialize.flush()
|
|
325
169
|
Connection.prototype.flush = function () {
|
|
326
170
|
if (this.stream.writable) {
|
|
327
171
|
this.stream.write(flushBuffer)
|
|
328
172
|
}
|
|
329
173
|
}
|
|
330
174
|
|
|
331
|
-
const syncBuffer =
|
|
175
|
+
const syncBuffer = serialize.sync()
|
|
332
176
|
Connection.prototype.sync = function () {
|
|
333
177
|
this._ending = true
|
|
334
|
-
|
|
335
|
-
this.
|
|
336
|
-
if (this.stream.writable) {
|
|
337
|
-
this.stream.write(syncBuffer)
|
|
338
|
-
this.stream.write(flushBuffer)
|
|
339
|
-
}
|
|
178
|
+
this._send(syncBuffer)
|
|
179
|
+
this._send(flushBuffer)
|
|
340
180
|
}
|
|
341
181
|
|
|
342
|
-
const
|
|
182
|
+
const endBuffer = serialize.end()
|
|
343
183
|
|
|
344
184
|
Connection.prototype.end = function () {
|
|
345
185
|
// 0x58 = 'X'
|
|
346
|
-
this.writer.clear()
|
|
347
186
|
this._ending = true
|
|
348
|
-
|
|
187
|
+
if (!this._connecting || !this.stream.writable) {
|
|
188
|
+
this.stream.end()
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
return this.stream.write(endBuffer, () => {
|
|
349
192
|
this.stream.end()
|
|
350
193
|
})
|
|
351
194
|
}
|
|
352
195
|
|
|
353
196
|
Connection.prototype.close = function (msg) {
|
|
354
|
-
this.
|
|
355
|
-
this._send(0x43)
|
|
197
|
+
this._send(serialize.close(msg))
|
|
356
198
|
}
|
|
357
199
|
|
|
358
200
|
Connection.prototype.describe = function (msg) {
|
|
359
|
-
this.
|
|
360
|
-
this._send(0x44)
|
|
361
|
-
this.flush()
|
|
201
|
+
this._send(serialize.describe(msg))
|
|
362
202
|
}
|
|
363
203
|
|
|
364
204
|
Connection.prototype.sendCopyFromChunk = function (chunk) {
|
|
365
|
-
this.
|
|
205
|
+
this._send(serialize.copyData(chunk))
|
|
366
206
|
}
|
|
367
207
|
|
|
368
208
|
Connection.prototype.endCopyFrom = function () {
|
|
369
|
-
this.
|
|
209
|
+
this._send(serialize.copyDone())
|
|
370
210
|
}
|
|
371
211
|
|
|
372
212
|
Connection.prototype.sendCopyFail = function (msg) {
|
|
373
|
-
|
|
374
|
-
this.writer.addCString(msg)
|
|
375
|
-
this._send(0x66)
|
|
213
|
+
this._send(serialize.copyFail(msg))
|
|
376
214
|
}
|
|
377
215
|
|
|
378
216
|
module.exports = Connection
|
|
@@ -22,9 +22,7 @@ var val = function (key, config, envVar) {
|
|
|
22
22
|
envVar = process.env[envVar]
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
return config[key] ||
|
|
26
|
-
envVar ||
|
|
27
|
-
defaults[key]
|
|
25
|
+
return config[key] || envVar || defaults[key]
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
var useSsl = function () {
|
|
@@ -52,15 +50,29 @@ var ConnectionParameters = function (config) {
|
|
|
52
50
|
|
|
53
51
|
this.user = val('user', config)
|
|
54
52
|
this.database = val('database', config)
|
|
53
|
+
|
|
54
|
+
if (this.database === undefined) {
|
|
55
|
+
this.database = this.user
|
|
56
|
+
}
|
|
57
|
+
|
|
55
58
|
this.port = parseInt(val('port', config), 10)
|
|
56
59
|
this.host = val('host', config)
|
|
57
|
-
|
|
60
|
+
|
|
61
|
+
// "hiding" the password so it doesn't show up in stack traces
|
|
62
|
+
// or if the client is console.logged
|
|
63
|
+
Object.defineProperty(this, 'password', {
|
|
64
|
+
configurable: true,
|
|
65
|
+
enumerable: false,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: val('password', config),
|
|
68
|
+
})
|
|
69
|
+
|
|
58
70
|
this.binary = val('binary', config)
|
|
59
71
|
this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl
|
|
60
72
|
this.client_encoding = val('client_encoding', config)
|
|
61
73
|
this.replication = val('replication', config)
|
|
62
74
|
// a domain socket begins with '/'
|
|
63
|
-
this.isDomainSocket =
|
|
75
|
+
this.isDomainSocket = !(this.host || '').indexOf('/')
|
|
64
76
|
|
|
65
77
|
this.application_name = val('application_name', config, 'PGAPPNAME')
|
|
66
78
|
this.fallback_application_name = val('fallback_application_name', config, false)
|