pg 7.9.0 → 7.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -1,6 +1,19 @@
1
1
  {
2
- "extends": "standard",
2
+ "plugins": [
3
+ "node"
4
+ ],
5
+ "extends": [
6
+ "standard",
7
+ "eslint:recommended",
8
+ "plugin:node/recommended"
9
+ ],
10
+ "parserOptions": {
11
+ "ecmaVersion": 2017
12
+ },
13
+ "env": {
14
+ "node": true,
15
+ "es6": true
16
+ },
3
17
  "rules": {
4
- "no-new-func": "off"
5
18
  }
6
19
  }
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ For richer information consult the commit log on github with referenced pull req
4
4
 
5
5
  We do not include break-fix version release in this file.
6
6
 
7
+ ### 7.12.0
8
+
9
+ - Add support for [async password lookup](https://github.com/brianc/node-postgres/pull/1926).
10
+
11
+ ### 7.11.0
12
+
13
+ - Add support for [connection_timeout](https://github.com/brianc/node-postgres/pull/1847/files#diff-5391bde944956870128be1136e7bc176R63) and [keepalives_idle](https://github.com/brianc/node-postgres/pull/1847).
14
+
15
+ ### 7.10.0
16
+
17
+ - Add support for [per-query types](https://github.com/brianc/node-postgres/pull/1825).
18
+
7
19
  ### 7.9.0
8
20
 
9
21
  - Add support for [sasl/scram authentication](https://github.com/brianc/node-postgres/pull/1835).
package/Makefile CHANGED
@@ -62,4 +62,6 @@ test-pool:
62
62
 
63
63
  lint:
64
64
  @echo "***Starting lint***"
65
- node_modules/.bin/eslint lib
65
+ node -e "process.exit(Number(process.versions.node.split('.')[0]) < 8 ? 0 : 1)" \
66
+ && echo "***Skipping lint (node version too old)***" \
67
+ || node_modules/.bin/eslint lib
package/SPONSORS.md CHANGED
@@ -1,10 +1,13 @@
1
1
  node-postgres is made possible by the helpful contributors from the community well as the following generous supporters on [Patreon](https://www.patreon.com/node_postgres).
2
2
 
3
3
  # Leaders
4
+
4
5
  - [MadKudu](https://www.madkudu.com) - [@madkudu](https://twitter.com/madkudu)
5
6
  - [Third Iron](https://thirdiron.com/)
7
+ - [Timescale](https://timescale.com)
6
8
 
7
9
  # Supporters
10
+
8
11
  - John Fawcett
9
12
  - Lalit Kapoor [@lalitkapoor](https://twitter.com/lalitkapoor)
10
13
  - Paul Frazee [@pfrazee](https://twitter.com/pfrazee)
package/lib/client.js CHANGED
@@ -44,6 +44,7 @@ var Client = function (config) {
44
44
  stream: c.stream,
45
45
  ssl: this.connectionParameters.ssl,
46
46
  keepAlive: c.keepAlive || false,
47
+ keepAliveInitialDelayMillis: c.keepAliveInitialDelayMillis || 0,
47
48
  encoding: this.connectionParameters.client_encoding || 'utf8'
48
49
  })
49
50
  this.queryQueue = []
@@ -51,6 +52,7 @@ var Client = function (config) {
51
52
  this.processID = null
52
53
  this.secretKey = null
53
54
  this.ssl = this.connectionParameters.ssl || false
55
+ this._connectionTimeoutMillis = c.connectionTimeoutMillis || 0
54
56
  }
55
57
 
56
58
  util.inherits(Client, EventEmitter)
@@ -83,6 +85,14 @@ Client.prototype._connect = function (callback) {
83
85
  }
84
86
  this._connecting = true
85
87
 
88
+ var connectionTimeoutHandle
89
+ if (this._connectionTimeoutMillis > 0) {
90
+ connectionTimeoutHandle = setTimeout(() => {
91
+ con._ending = true
92
+ con.stream.destroy(new Error('timeout expired'))
93
+ }, this._connectionTimeoutMillis)
94
+ }
95
+
86
96
  if (this.host && this.host.indexOf('/') === 0) {
87
97
  con.connect(this.host + '/.s.PGSQL.' + this.port)
88
98
  } else {
@@ -104,7 +114,24 @@ Client.prototype._connect = function (callback) {
104
114
 
105
115
  function checkPgPass (cb) {
106
116
  return function (msg) {
107
- if (self.password !== null) {
117
+ if (typeof self.password === 'function') {
118
+ self._Promise.resolve()
119
+ .then(() => self.password())
120
+ .then(pass => {
121
+ if (pass !== undefined) {
122
+ if (typeof pass !== 'string') {
123
+ con.emit('error', new TypeError('Password must be a string'))
124
+ return
125
+ }
126
+ self.connectionParameters.password = self.password = pass
127
+ } else {
128
+ self.connectionParameters.password = self.password = null
129
+ }
130
+ cb(msg)
131
+ }).catch(err => {
132
+ con.emit('error', err)
133
+ })
134
+ } else if (self.password !== null) {
108
135
  cb(msg)
109
136
  } else {
110
137
  pgPass(self.connectionParameters, function (pass) {
@@ -159,6 +186,7 @@ Client.prototype._connect = function (callback) {
159
186
  return
160
187
  }
161
188
  this._connectionError = true
189
+ clearTimeout(connectionTimeoutHandle)
162
190
  if (callback) {
163
191
  return callback(err)
164
192
  }
@@ -196,6 +224,7 @@ Client.prototype._connect = function (callback) {
196
224
  con.removeListener('errorMessage', connectingErrorHandler)
197
225
  con.on('error', connectedErrorHandler)
198
226
  con.on('errorMessage', connectedErrorMessageHandler)
227
+ clearTimeout(connectionTimeoutHandle)
199
228
 
200
229
  // process possible callback argument to Client#connect
201
230
  if (callback) {
@@ -280,11 +309,13 @@ Client.prototype._attachListeners = function (con) {
280
309
  })
281
310
 
282
311
  // delegate portalSuspended to active query
312
+ // eslint-disable-next-line no-unused-vars
283
313
  con.on('portalSuspended', function (msg) {
284
314
  self.activeQuery.handlePortalSuspended(con)
285
315
  })
286
316
 
287
- // deletagate emptyQuery to active query
317
+ // delegate emptyQuery to active query
318
+ // eslint-disable-next-line no-unused-vars
288
319
  con.on('emptyQuery', function (msg) {
289
320
  self.activeQuery.handleEmptyQuery(con)
290
321
  })
@@ -297,12 +328,14 @@ Client.prototype._attachListeners = function (con) {
297
328
  // if a prepared statement has a name and properly parses
298
329
  // we track that its already been executed so we don't parse
299
330
  // it again on the same client
331
+ // eslint-disable-next-line no-unused-vars
300
332
  con.on('parseComplete', function (msg) {
301
333
  if (self.activeQuery.name) {
302
334
  con.parsedStatements[self.activeQuery.name] = self.activeQuery.text
303
335
  }
304
336
  })
305
337
 
338
+ // eslint-disable-next-line no-unused-vars
306
339
  con.on('copyInResponse', function (msg) {
307
340
  self.activeQuery.handleCopyInResponse(self.connection)
308
341
  })
@@ -478,8 +511,9 @@ Client.prototype.query = function (config, values, callback) {
478
511
  if (this.binary && !query.binary) {
479
512
  query.binary = true
480
513
  }
481
- if (query._result) {
482
- query._result._getTypeParser = this._types.getTypeParser.bind(this._types)
514
+
515
+ if (query._result && !query._result._types) {
516
+ query._result._types = this._types
483
517
  }
484
518
 
485
519
  if (!this._queryable) {
@@ -15,11 +15,11 @@ var parse = require('pg-connection-string').parse // parses a connection string
15
15
 
16
16
  var val = function (key, config, envVar) {
17
17
  if (envVar === undefined) {
18
- envVar = process.env[ 'PG' + key.toUpperCase() ]
18
+ envVar = process.env['PG' + key.toUpperCase()]
19
19
  } else if (envVar === false) {
20
20
  // do nothing ... use false
21
21
  } else {
22
- envVar = process.env[ envVar ]
22
+ envVar = process.env[envVar]
23
23
  }
24
24
 
25
25
  return config[key] ||
@@ -66,6 +66,22 @@ var ConnectionParameters = function (config) {
66
66
  this.fallback_application_name = val('fallback_application_name', config, false)
67
67
  this.statement_timeout = val('statement_timeout', config, false)
68
68
  this.query_timeout = val('query_timeout', config, false)
69
+
70
+ if (config.connectionTimeoutMillis === undefined) {
71
+ this.connect_timeout = process.env.PGCONNECT_TIMEOUT || 0
72
+ } else {
73
+ this.connect_timeout = Math.floor(config.connectionTimeoutMillis / 1000)
74
+ }
75
+
76
+ if (config.keepAlive === false) {
77
+ this.keepalives = 0
78
+ } else if (config.keepAlive === true) {
79
+ this.keepalives = 1
80
+ }
81
+
82
+ if (typeof config.keepAliveInitialDelayMillis === 'number') {
83
+ this.keepalives_idle = Math.floor(config.keepAliveInitialDelayMillis / 1000)
84
+ }
69
85
  }
70
86
 
71
87
  // Convert arg to a string, surround in single quotes, and escape single quotes and backslashes
@@ -75,7 +91,7 @@ var quoteParamValue = function (value) {
75
91
 
76
92
  var add = function (params, config, paramName) {
77
93
  var value = config[paramName]
78
- if (value) {
94
+ if (value !== undefined && value !== null) {
79
95
  params.push(paramName + '=' + quoteParamValue(value))
80
96
  }
81
97
  }
@@ -87,8 +103,9 @@ ConnectionParameters.prototype.getLibpqConnectionString = function (cb) {
87
103
  add(params, this, 'port')
88
104
  add(params, this, 'application_name')
89
105
  add(params, this, 'fallback_application_name')
106
+ add(params, this, 'connect_timeout')
90
107
 
91
- var ssl = typeof this.ssl === 'object' ? this.ssl : { sslmode: this.ssl }
108
+ var ssl = typeof this.ssl === 'object' ? this.ssl : this.ssl ? { sslmode: this.ssl } : {}
92
109
  add(params, ssl, 'sslmode')
93
110
  add(params, ssl, 'sslca')
94
111
  add(params, ssl, 'sslkey')
package/lib/connection.js CHANGED
@@ -21,6 +21,7 @@ var Connection = function (config) {
21
21
  config = config || {}
22
22
  this.stream = config.stream || new net.Socket()
23
23
  this._keepAlive = config.keepAlive
24
+ this._keepAliveInitialDelayMillis = config.keepAliveInitialDelayMillis
24
25
  this.lastBuffer = false
25
26
  this.lastOffset = 0
26
27
  this.buffer = null
@@ -47,17 +48,17 @@ var Connection = function (config) {
47
48
  util.inherits(Connection, EventEmitter)
48
49
 
49
50
  Connection.prototype.connect = function (port, host) {
51
+ var self = this
52
+
50
53
  if (this.stream.readyState === 'closed') {
51
54
  this.stream.connect(port, host)
52
55
  } else if (this.stream.readyState === 'open') {
53
56
  this.emit('connect')
54
57
  }
55
58
 
56
- var self = this
57
-
58
59
  this.stream.on('connect', function () {
59
60
  if (self._keepAlive) {
60
- self.stream.setKeepAlive(true)
61
+ self.stream.setKeepAlive(true, self._keepAliveInitialDelayMillis)
61
62
  }
62
63
  self.emit('connect')
63
64
  })
@@ -236,9 +237,11 @@ Connection.prototype.parse = function (query, more) {
236
237
  // normalize missing query names to allow for null
237
238
  query.name = query.name || ''
238
239
  if (query.name.length > 63) {
240
+ /* eslint-disable no-console */
239
241
  console.error('Warning! Postgres only supports 63 characters for query names.')
240
- console.error('You supplied', query.name, '(', query.name.length, ')')
242
+ console.error('You supplied %s (%s)', query.name, query.name.length)
241
243
  console.error('This can cause conflicts and silent errors executing queries')
244
+ /* eslint-enable no-console */
242
245
  }
243
246
  // normalize null type array
244
247
  query.types = query.types || []
@@ -601,7 +604,7 @@ Connection.prototype.parseE = function (buffer, length) {
601
604
  msg = new Error(fields.M)
602
605
  for (item in input) {
603
606
  // copy input properties to the error
604
- if (input.hasOwnProperty(item)) {
607
+ if (Object.prototype.hasOwnProperty.call(input, item)) {
605
608
  msg[item] = input[item]
606
609
  }
607
610
  }
package/lib/defaults.js CHANGED
@@ -50,15 +50,23 @@ module.exports = {
50
50
  ssl: false,
51
51
 
52
52
  application_name: undefined,
53
+
53
54
  fallback_application_name: undefined,
54
55
 
55
56
  parseInputDatesAsUTC: false,
56
57
 
57
- // max milliseconds any query using this connection will execute for before timing out in error. false=unlimited
58
+ // max milliseconds any query using this connection will execute for before timing out in error.
59
+ // false=unlimited
58
60
  statement_timeout: false,
59
61
 
60
- // max miliseconds to wait for query to complete (client side)
61
- query_timeout: false
62
+ // max milliseconds to wait for query to complete (client side)
63
+ query_timeout: false,
64
+
65
+ connect_timeout: 0,
66
+
67
+ keepalives: 1,
68
+
69
+ keepalives_idle: 0
62
70
  }
63
71
 
64
72
  var pgTypes = require('pg-types')
package/lib/index.js CHANGED
@@ -49,7 +49,9 @@ if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
49
49
  if (err.code !== 'MODULE_NOT_FOUND') {
50
50
  throw err
51
51
  }
52
+ /* eslint-disable no-console */
52
53
  console.error(err.message)
54
+ /* eslint-enable no-console */
53
55
  }
54
56
  module.exports.native = native
55
57
  return native
@@ -7,6 +7,7 @@
7
7
  * README.md file in the root directory of this source tree.
8
8
  */
9
9
 
10
+ // eslint-disable-next-line
10
11
  var Native = require('pg-native')
11
12
  var TypeOverrides = require('../type-overrides')
12
13
  var semver = require('semver')
@@ -35,6 +35,7 @@ var NativeQuery = module.exports = function (config, values, callback) {
35
35
  util.inherits(NativeQuery, EventEmitter)
36
36
 
37
37
  var errorFieldMap = {
38
+ /* eslint-disable quote-props */
38
39
  'sqlState': 'code',
39
40
  'statementPosition': 'position',
40
41
  'messagePrimary': 'message',
@@ -130,9 +131,11 @@ NativeQuery.prototype.submit = function (client) {
130
131
  // named query
131
132
  if (this.name) {
132
133
  if (this.name.length > 63) {
134
+ /* eslint-disable no-console */
133
135
  console.error('Warning! Postgres only supports 63 characters for query names.')
134
- console.error('You supplied', this.name, '(', this.name.length, ')')
136
+ console.error('You supplied %s (%s)', this.name, this.name.length)
135
137
  console.error('This can cause conflicts and silent errors executing queries')
138
+ /* eslint-enable no-console */
136
139
  }
137
140
  var values = (this.values || []).map(utils.prepareValue)
138
141
 
package/lib/query.js CHANGED
@@ -194,7 +194,12 @@ Query.prototype.prepare = function (connection) {
194
194
  }
195
195
 
196
196
  if (self.values) {
197
- self.values = self.values.map(utils.prepareValue)
197
+ try {
198
+ self.values = self.values.map(utils.prepareValue)
199
+ } catch (err) {
200
+ this.handleError(err, connection)
201
+ return
202
+ }
198
203
  }
199
204
 
200
205
  // http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
@@ -217,6 +222,7 @@ Query.prototype.handleCopyInResponse = function (connection) {
217
222
  connection.sendCopyFail('No source stream defined')
218
223
  }
219
224
 
225
+ // eslint-disable-next-line no-unused-vars
220
226
  Query.prototype.handleCopyData = function (msg, connection) {
221
227
  // noop
222
228
  }
package/lib/result.js CHANGED
@@ -12,13 +12,14 @@ var types = require('pg-types')
12
12
  // result object returned from query
13
13
  // in the 'end' event and also
14
14
  // passed as second argument to provided callback
15
- var Result = function (rowMode) {
15
+ var Result = function (rowMode, types) {
16
16
  this.command = null
17
17
  this.rowCount = null
18
18
  this.oid = null
19
19
  this.rows = []
20
20
  this.fields = []
21
21
  this._parsers = []
22
+ this._types = types
22
23
  this.RowCtor = null
23
24
  this.rowAsArray = rowMode === 'array'
24
25
  if (this.rowAsArray) {
@@ -94,11 +95,9 @@ Result.prototype.addFields = function (fieldDescriptions) {
94
95
  for (var i = 0; i < fieldDescriptions.length; i++) {
95
96
  var desc = fieldDescriptions[i]
96
97
  this.fields.push(desc)
97
- var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text')
98
+ var parser = (this._types || types).getTypeParser(desc.dataTypeID, desc.format || 'text')
98
99
  this._parsers.push(parser)
99
100
  }
100
101
  }
101
102
 
102
- Result.prototype._getTypeParser = types.getTypeParser
103
-
104
103
  module.exports = Result
package/lib/sasl.js CHANGED
@@ -1,3 +1,4 @@
1
+ 'use strict'
1
2
  const crypto = require('crypto')
2
3
 
3
4
  function startSession (mechanisms) {
package/lib/utils.js CHANGED
@@ -97,7 +97,12 @@ function pad (number, digits) {
97
97
 
98
98
  function dateToString (date) {
99
99
  var offset = -date.getTimezoneOffset()
100
- var ret = pad(date.getFullYear(), 4) + '-' +
100
+
101
+ var year = date.getFullYear()
102
+ var isBCYear = year < 1
103
+ if (isBCYear) year = Math.abs(year) + 1 // negative years are 1 off their BC representation
104
+
105
+ var ret = pad(year, 4) + '-' +
101
106
  pad(date.getMonth() + 1, 2) + '-' +
102
107
  pad(date.getDate(), 2) + 'T' +
103
108
  pad(date.getHours(), 2) + ':' +
@@ -110,11 +115,17 @@ function dateToString (date) {
110
115
  offset *= -1
111
116
  } else { ret += '+' }
112
117
 
113
- return ret + pad(Math.floor(offset / 60), 2) + ':' + pad(offset % 60, 2)
118
+ ret += pad(Math.floor(offset / 60), 2) + ':' + pad(offset % 60, 2)
119
+ if (isBCYear) ret += ' BC'
120
+ return ret
114
121
  }
115
122
 
116
123
  function dateToStringUTC (date) {
117
- var ret = pad(date.getUTCFullYear(), 4) + '-' +
124
+ var year = date.getUTCFullYear()
125
+ var isBCYear = year < 1
126
+ if (isBCYear) year = Math.abs(year) + 1 // negative years are 1 off their BC representation
127
+
128
+ var ret = pad(year, 4) + '-' +
118
129
  pad(date.getUTCMonth() + 1, 2) + '-' +
119
130
  pad(date.getUTCDate(), 2) + 'T' +
120
131
  pad(date.getUTCHours(), 2) + ':' +
@@ -122,7 +133,9 @@ function dateToStringUTC (date) {
122
133
  pad(date.getUTCSeconds(), 2) + '.' +
123
134
  pad(date.getUTCMilliseconds(), 3)
124
135
 
125
- return ret + '+00:00'
136
+ ret += '+00:00'
137
+ if (isBCYear) ret += ' BC'
138
+ return ret
126
139
  }
127
140
 
128
141
  function normalizeQueryConfig (config, values, callback) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pg",
3
- "version": "7.9.0",
3
+ "version": "7.12.1",
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-pool": "^2.0.4",
26
- "pg-types": "~2.0.0",
26
+ "pg-types": "^2.1.0",
27
27
  "pgpass": "1.x",
28
28
  "semver": "4.3.2"
29
29
  },
@@ -31,12 +31,12 @@
31
31
  "async": "0.9.0",
32
32
  "bluebird": "3.5.2",
33
33
  "co": "4.6.0",
34
- "eslint": "^4.19.1",
35
- "eslint-config-standard": "^11.0.0",
36
- "eslint-plugin-import": "^2.14.0",
37
- "eslint-plugin-node": "^6.0.1",
38
- "eslint-plugin-promise": "^4.0.1",
39
- "eslint-plugin-standard": "^3.1.0",
34
+ "eslint": "^6.0.1",
35
+ "eslint-config-standard": "^13.0.1",
36
+ "eslint-plugin-import": "^2.18.1",
37
+ "eslint-plugin-node": "^9.1.0",
38
+ "eslint-plugin-promise": "^4.2.1",
39
+ "eslint-plugin-standard": "^4.0.0",
40
40
  "pg-copy-streams": "0.3.0"
41
41
  },
42
42
  "minNativeVersion": "2.0.0",