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