Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: brianc/node-postgres
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v7.2.0
Choose a base ref
...
head repository: brianc/node-postgres
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v7.3.0
Choose a head ref

Commits on Aug 26, 2017

  1. Refactor addCommandComplete

    Refactors addCommandComplete to tighten parsing regex start anchor and
    handle edge case where no row count is specified (pre 8.2 COPY).
    sehrope authored and brianc committed Aug 26, 2017
    Copy the full SHA
    884e21e View commit details
  2. Copy the full SHA
    03c2270 View commit details
  3. Copy the full SHA
    7d1342e View commit details

Commits on Aug 27, 2017

  1. capital letters

    minor beautification
    polkadotpioneer authored and brianc committed Aug 27, 2017
    Copy the full SHA
    1b55c7b View commit details

Commits on Aug 28, 2017

  1. Minor improvements

    full stop, capitalized Twitter
    benhc123 authored and brianc committed Aug 28, 2017
    Copy the full SHA
    80d22da View commit details
  2. Update SPONSORS.md

    brianc authored Aug 28, 2017
    Copy the full SHA
    beba66f View commit details

Commits on Aug 30, 2017

  1. Fix reference to md5 helper in test

    Fixes reference to md5 helper and removes reference to js client
    as the md5 function is now provided by utils.
    sehrope authored and brianc committed Aug 30, 2017
    Copy the full SHA
    3ad0680 View commit details
  2. Centralize password md5 hashing logic

    Centralize logic for md5 hashing of passwords for authentication. Adds
    a new function postgresMd5PasswordHash(user, password, salt) to utils
    and updates client.js and tests to use it.
    sehrope authored and brianc committed Aug 30, 2017
    Copy the full SHA
    e74c13d View commit details
  3. Copy the full SHA
    ef3379a View commit details

Commits on Sep 1, 2017

  1. Update Grammatical person

    Update Grammatical person from First Person to Third Person.
    kaue authored and brianc committed Sep 1, 2017
    Copy the full SHA
    ffc7653 View commit details

Commits on Sep 3, 2017

  1. Revert "Update Grammatical person"

    This reverts commit ffc7653.
    charmander authored and brianc committed Sep 3, 2017
    Copy the full SHA
    c961888 View commit details
  2. Copy the full SHA
    27492ef View commit details
  3. Copy the full SHA
    3b3e52c View commit details
  4. Copy the full SHA
    d6e7dfe View commit details
  5. Copy the full SHA
    4936033 View commit details
  6. support statement_timeout

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    ad36063 View commit details
  7. fixed test failure message

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    8839d42 View commit details
  8. remove .idea from gitignore

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    78fc903 View commit details
  9. fixes

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    689bb25 View commit details
  10. remove pg-native from dependencies

    `npm run test` seems to be adding this
    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    175b688 View commit details
  11. new test for actual statement timeout

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    64eb77e View commit details
  12. restore newline at end of file

    Josh authored and brianc committed Sep 3, 2017
    Copy the full SHA
    ecab41c View commit details
  13. Change Makefile to use local eslint

    Changes the Makefile lint target to use the local copy of
    eslint that would be installed in node_modules rather than
    a global copy that may not be installed.
    sehrope authored and brianc committed Sep 3, 2017
    Copy the full SHA
    f1336fc View commit details
  14. Update changelog

    brianc committed Sep 3, 2017
    Copy the full SHA
    dfc7214 View commit details
  15. Bump version

    brianc committed Sep 3, 2017
    Copy the full SHA
    f66379f View commit details
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,10 @@ For richer information consult the commit log on github with referenced pull req

We do not include break-fix version release in this file.

### 7.3.0

- Add support for [statement timeout](https://github.com/brianc/node-postgres/pull/1436).

### 7.2.0

- Pinned pg-pool and pg-types to a tighter semver range. This is likely not a noticable change for you unless you were specifically installing older versions of those libraries for some reason, but making it a minor bump here just in case it could cause any confusion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -62,4 +62,4 @@ test-pool:

lint:
@echo "***Starting lint***"
eslint lib
node_modules/.bin/eslint lib
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -19,19 +19,19 @@ $ npm install pg

### Features

* pure JavaScript client and native libpq bindings share _the same api_
* connection pooling
* extensible js<->postgresql data-type coercion
* supported PostgreSQL features
* parameterized queries
* named statements with query plan caching
* async notifications with `LISTEN/NOTIFY`
* bulk import & export with `COPY TO/COPY FROM`
* Pure JavaScript client and native libpq bindings share _the same api_
* Connection pooling
* Extensible js<->postgresql data-type coercion
* Supported PostgreSQL features
* Parameterized queries
* Named statements with query plan caching
* Async notifications with `LISTEN/NOTIFY`
* Bulk import & export with `COPY TO/COPY FROM`

### Extras

node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture.
Entire list can be found on [wiki](https://github.com/brianc/node-postgres/wiki/Extras)
The entire list can be found on our [wiki](https://github.com/brianc/node-postgres/wiki/Extras).

## Support

@@ -42,7 +42,7 @@ When you open an issue please provide:
- version of postgres
- smallest possible snippet of code to reproduce the problem

You can also follow me [@briancarlson](https://twitter.com/briancarlson) if that's your thing. I try to always announce noteworthy changes & developments with node-postgres on twitter.
You can also follow me [@briancarlson](https://twitter.com/briancarlson) if that's your thing. I try to always announce noteworthy changes & developments with node-postgres on Twitter.

### Professional Support

2 changes: 1 addition & 1 deletion SPONSORS.md
Original file line number Diff line number Diff line change
@@ -8,4 +8,4 @@ node-postgres is made possible by the helpful contributors from the community we
- Lalit Kapoor [@lalitkapoor](https://twitter.com/lalitkapoor)
- Paul Frazee [@pfrazee](https://twitter.com/pfrazee)
- Rein Petersen
- Arnaud Benhamdine
- Arnaud Benhamdine [@abenhamdine](https://twitter.com/abenhamdine)
8 changes: 4 additions & 4 deletions lib/client.js
Original file line number Diff line number Diff line change
@@ -106,10 +106,7 @@ Client.prototype.connect = function (callback) {

// password request handling
con.on('authenticationMD5Password', checkPgPass(function (msg) {
var inner = utils.md5(self.password + self.user)
var outer = utils.md5(Buffer.concat([Buffer.from(inner), msg.salt]))
var md5password = 'md5' + outer
con.password(md5password)
con.password(utils.postgresMd5PasswordHash(self.user, self.password, msg.salt))
}))

con.once('backendKeyData', function (msg) {
@@ -272,6 +269,9 @@ Client.prototype.getStartupConf = function () {
if (params.replication) {
data.replication = '' + params.replication
}
if (params.statement_timeout) {
data.statement_timeout = String(parseInt(params.statement_timeout, 10))
}

return data
}
2 changes: 2 additions & 0 deletions lib/connection-parameters.js
Original file line number Diff line number Diff line change
@@ -64,6 +64,7 @@ var ConnectionParameters = function (config) {

this.application_name = val('application_name', config, 'PGAPPNAME')
this.fallback_application_name = val('fallback_application_name', config, false)
this.statement_timeout = val('statement_timeout', config, false)
}

// Convert arg to a string, surround in single quotes, and escape single quotes and backslashes
@@ -91,6 +92,7 @@ ConnectionParameters.prototype.getLibpqConnectionString = function (cb) {
add(params, ssl, 'sslca')
add(params, ssl, 'sslkey')
add(params, ssl, 'sslcert')
add(params, ssl, 'sslrootcert')

if (this.database) {
params.push('dbname=' + quoteParamValue(this.database))
21 changes: 8 additions & 13 deletions lib/defaults.js
Original file line number Diff line number Diff line change
@@ -35,23 +35,15 @@ module.exports = {
// binary result mode
binary: false,

// Connection pool options - see https://github.com/coopernurse/node-pool
// Connection pool options - see https://github.com/brianc/node-pg-pool

// number of connections to use in connection pool
// 0 will disable connection pooling
poolSize: 10,
max: 10,

// max milliseconds a client can go unused before it is removed
// from the pool and destroyed
poolIdleTimeout: 30000,

// frequency to check for idle clients within the client pool
reapIntervalMillis: 1000,

// if true the most recently released resources will be the first to be allocated
returnToHead: false,

// pool log function / boolean
poolLog: false,
idleTimeoutMillis: 30000,

client_encoding: '',

@@ -60,7 +52,10 @@ module.exports = {
application_name: undefined,
fallback_application_name: undefined,

parseInputDatesAsUTC: false
parseInputDatesAsUTC: false,

// max milliseconds any query using this connection will execute for before timing out in error. false=unlimited
statement_timeout: false
}

var pgTypes = require('pg-types')
10 changes: 5 additions & 5 deletions lib/result.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ var Result = function (rowMode) {
}
}

var matchRegexp = /([A-Za-z]+) ?(\d+ )?(\d+)?/
var matchRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/

// adds a command complete message
Result.prototype.addCommandComplete = function (msg) {
@@ -41,12 +41,12 @@ Result.prototype.addCommandComplete = function (msg) {
}
if (match) {
this.command = match[1]
// match 3 will only be existing on insert commands
if (match[3]) {
// msg.value is from native bindings
this.rowCount = parseInt(match[3] || msg.value, 10)
// COMMMAND OID ROWS
this.oid = parseInt(match[2], 10)
} else {
this.rowCount = parseInt(match[3], 10)
} else if (match[2]) {
// COMMAND ROWS
this.rowCount = parseInt(match[2], 10)
}
}
12 changes: 10 additions & 2 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -138,12 +138,20 @@ const md5 = function (string) {
return crypto.createHash('md5').update(string, 'utf-8').digest('hex')
}

// See AuthenticationMD5Password at https://www.postgresql.org/docs/current/static/protocol-flow.html
const postgresMd5PasswordHash = function (user, password, salt) {
var inner = md5(password + user)
var outer = md5(Buffer.concat([Buffer.from(inner), salt]))
return 'md5' + outer
}

module.exports = {
prepareValue: function prepareValueWrapper (value) {
// this ensures that extra arguments do not get passed into prepareValue
// by accident, eg: from calling values.map(utils.prepareValue)
return prepareValue(value)
},
normalizeQueryConfig: normalizeQueryConfig,
md5: md5
normalizeQueryConfig,
postgresMd5PasswordHash,
md5
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pg",
"version": "7.2.0",
"version": "7.3.0",
"description": "PostgreSQL client - pure javascript & libpq with the same API",
"keywords": [
"postgres",
@@ -19,8 +19,8 @@
"main": "./lib",
"dependencies": {
"buffer-writer": "1.0.1",
"packet-reader": "0.3.1",
"js-string-escape": "1.0.1",
"packet-reader": "0.3.1",
"pg-connection-string": "0.1.3",
"pg-pool": "~2.0.3",
"pg-types": "~1.12.1",
9 changes: 1 addition & 8 deletions test/integration/client/appname-tests.js
Original file line number Diff line number Diff line change
@@ -7,14 +7,7 @@ var suite = new helper.Suite()
var conInfo = helper.config

function getConInfo (override) {
var newConInfo = {}
Object.keys(conInfo).forEach(function (k) {
newConInfo[k] = conInfo[k]
})
Object.keys(override || {}).forEach(function (k) {
newConInfo[k] = override[k]
})
return newConInfo
return Object.assign({}, conInfo, override )
}

function getAppName (conf, cb) {
9 changes: 8 additions & 1 deletion test/integration/client/configuration-tests.js
Original file line number Diff line number Diff line change
@@ -18,7 +18,14 @@ suite.test('default values are used in new clients', function () {
password: null,
port: 5432,
rows: 0,
poolSize: 10
max: 10,
binary: false,
idleTimeoutMillis: 30000,
client_encoding: '',
ssl: false,
application_name: undefined,
fallback_application_name: undefined,
parseInputDatesAsUTC: false
})

var client = new pg.Client()
77 changes: 77 additions & 0 deletions test/integration/client/statement_timeout-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict'
var helper = require('./test-helper')
var Client = helper.Client

var suite = new helper.Suite()

var conInfo = helper.config

function getConInfo (override) {
return Object.assign({}, conInfo, override )
}

function getStatementTimeout (conf, cb) {
var client = new Client(conf)
client.connect(assert.success(function () {
client.query('SHOW statement_timeout', assert.success(function (res) {
var statementTimeout = res.rows[0].statement_timeout
cb(statementTimeout)
client.end()
}))
}))
}

if (!helper.args.native) { // statement_timeout is not supported with the native client
suite.test('No default statement_timeout ', function (done) {
getConInfo()
getStatementTimeout({}, function (res) {
assert.strictEqual(res, '0') // 0 = no timeout
done()
})
})

suite.test('statement_timeout integer is used', function (done) {
var conf = getConInfo({
'statement_timeout': 3000
})
getStatementTimeout(conf, function (res) {
assert.strictEqual(res, '3s')
done()
})
})

suite.test('statement_timeout float is used', function (done) {
var conf = getConInfo({
'statement_timeout': 3000.7
})
getStatementTimeout(conf, function (res) {
assert.strictEqual(res, '3s')
done()
})
})

suite.test('statement_timeout string is used', function (done) {
var conf = getConInfo({
'statement_timeout': '3000'
})
getStatementTimeout(conf, function (res) {
assert.strictEqual(res, '3s')
done()
})
})

suite.test('statement_timeout actually cancels long running queries', function (done) {
var conf = getConInfo({
'statement_timeout': '10' // 10ms to keep tests running fast
})
var client = new Client(conf)
client.connect(assert.success(function () {
client.query('SELECT pg_sleep( 1 )', function ( error ) {
client.end()
assert.strictEqual( error.code, '57014' ) // query_cancelled
done()
})
}))
})

}
7 changes: 2 additions & 5 deletions test/integration/connection/test-helper.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
var net = require('net')
var helper = require(__dirname + '/../test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
var utils = require(__dirname + '/../../../lib/utils')
var connect = function (callback) {
var username = helper.args.user
var database = helper.args.database
@@ -20,11 +21,7 @@ var connect = function (callback) {
con.password(helper.args.password)
})
con.once('authenticationMD5Password', function (msg) {
// need js client even if native client is included
var client = require(__dirname + '/../../../lib/client')
var inner = client.md5(helper.args.password + helper.args.user)
var outer = client.md5(inner + msg.salt.toString('binary'))
con.password('md5' + outer)
con.password(utils.postgresMd5PasswordHash(helper.args.user, helper.args.password, msg.salt));
})
con.once('readyForQuery', function () {
con.query('create temp table ids(id integer)')
4 changes: 1 addition & 3 deletions test/unit/client/md5-password-tests.js
Original file line number Diff line number Diff line change
@@ -11,9 +11,7 @@ test('md5 authentication', function () {
test('responds', function () {
assert.lengthIs(client.connection.stream.packets, 1)
test('should have correct encrypted data', function () {
var encrypted = utils.md5(client.password + client.user)
encrypted = utils.md5(encrypted + salt.toString('binary'))
var password = 'md5' + encrypted
var password = utils.postgresMd5PasswordHash(client.user, client.password, salt)
// how do we want to test this?
assert.equalBuffers(client.connection.stream.packets[0], new BufferList()
.addCString(password).join(true, 'p'))
2 changes: 2 additions & 0 deletions test/unit/client/result-metadata-tests.js
Original file line number Diff line number Diff line change
@@ -35,3 +35,5 @@ testForTag('INSERT 841 1', check(841, 1, 'INSERT'))
testForTag('DELETE 10', check(null, 10, 'DELETE'))
testForTag('UPDATE 11', check(null, 11, 'UPDATE'))
testForTag('SELECT 20', check(null, 20, 'SELECT'))
testForTag('COPY', check(null, null, 'COPY'))
testForTag('COPY 12345', check(null, 12345, 'COPY'))
Loading