Re-enable eslint with standard format (#1367)

* Work on converting lib to standard

* Finish updating lib

* Finish linting lib

* Format test files

* Add .eslintrc with standard format

* Supply full path to eslint bin

* Move lint command to package.json

* Add eslint as dev dependency
This commit is contained in:
Brian C 2017-07-15 12:05:58 -05:00 committed by GitHub
parent f7de9ce820
commit 8798e50ad3
104 changed files with 4788 additions and 4880 deletions

6
.eslintrc Normal file
View File

@ -0,0 +1,6 @@
{
"extends": "standard",
"rules": {
"no-new-func": "off"
}
}

View File

@ -1,5 +0,0 @@
{
"trailing": true,
"indent": 2,
"evil": true
}

View File

@ -7,7 +7,7 @@ params := $(connectionString)
node-command := xargs -n 1 -I file node file $(params)
.PHONY : test test-connection test-integration bench test-native \
jshint publish test-missing-native update-npm
lint publish test-missing-native update-npm
all:
npm install
@ -17,7 +17,7 @@ help:
test: test-unit
test-all: jshint test-missing-native test-unit test-integration test-native
test-all: lint test-missing-native test-unit test-integration test-native
update-npm:
@ -60,5 +60,6 @@ test-binary: test-connection
test-pool:
@find test/integration/connection-pool -name "*.js" | $(node-command) binary
jshint:
@echo "***Starting jshint***"
lint:
@echo "***Starting lint***"
eslint lib

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,54 +7,54 @@
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var EventEmitter = require('events').EventEmitter
var util = require('util')
var utils = require('./utils')
var pgPass = require('pgpass');
var TypeOverrides = require('./type-overrides');
var pgPass = require('pgpass')
var TypeOverrides = require('./type-overrides')
var ConnectionParameters = require('./connection-parameters');
var Query = require('./query');
var defaults = require('./defaults');
var Connection = require('./connection');
var ConnectionParameters = require('./connection-parameters')
var Query = require('./query')
var defaults = require('./defaults')
var Connection = require('./connection')
var Client = function(config) {
EventEmitter.call(this);
var Client = function (config) {
EventEmitter.call(this)
this.connectionParameters = new ConnectionParameters(config);
this.user = this.connectionParameters.user;
this.database = this.connectionParameters.database;
this.port = this.connectionParameters.port;
this.host = this.connectionParameters.host;
this.password = this.connectionParameters.password;
this.replication = this.connectionParameters.replication;
this.connectionParameters = new ConnectionParameters(config)
this.user = this.connectionParameters.user
this.database = this.connectionParameters.database
this.port = this.connectionParameters.port
this.host = this.connectionParameters.host
this.password = this.connectionParameters.password
this.replication = this.connectionParameters.replication
var c = config || {};
var c = config || {}
this._types = new TypeOverrides(c.types);
this._ending = false;
this._connecting = false;
this._connected = false;
this._connectionError = false;
this._types = new TypeOverrides(c.types)
this._ending = false
this._connecting = false
this._connected = false
this._connectionError = false
this.connection = c.connection || new Connection({
stream: c.stream,
ssl: this.connectionParameters.ssl,
keepAlive: c.keepAlive || false
});
this.queryQueue = [];
this.binary = c.binary || defaults.binary;
this.encoding = 'utf8';
this.processID = null;
this.secretKey = null;
this.ssl = this.connectionParameters.ssl || false;
};
})
this.queryQueue = []
this.binary = c.binary || defaults.binary
this.encoding = 'utf8'
this.processID = null
this.secretKey = null
this.ssl = this.connectionParameters.ssl || false
}
util.inherits(Client, EventEmitter);
util.inherits(Client, EventEmitter)
Client.prototype.connect = function(callback) {
var self = this;
var con = this.connection;
Client.prototype.connect = function (callback) {
var self = this
var con = this.connection
if (this._connecting || this._connected) {
const err = new Error('Client has already been connected. You cannot reuse a client.')
if (callback) {
@ -63,64 +63,63 @@ Client.prototype.connect = function(callback) {
}
return Promise.reject(err)
}
this._connecting = true;
this._connecting = true
if(this.host && this.host.indexOf('/') === 0) {
con.connect(this.host + '/.s.PGSQL.' + this.port);
if (this.host && this.host.indexOf('/') === 0) {
con.connect(this.host + '/.s.PGSQL.' + this.port)
} else {
con.connect(this.port, this.host);
con.connect(this.port, this.host)
}
//once connection is established send startup message
con.on('connect', function() {
if(self.ssl) {
con.requestSsl();
// once connection is established send startup message
con.on('connect', function () {
if (self.ssl) {
con.requestSsl()
} else {
con.startup(self.getStartupConf());
con.startup(self.getStartupConf())
}
});
})
con.on('sslconnect', function() {
con.startup(self.getStartupConf());
});
con.on('sslconnect', function () {
con.startup(self.getStartupConf())
})
function checkPgPass(cb) {
return function(msg) {
if (null !== self.password) {
cb(msg);
function checkPgPass (cb) {
return function (msg) {
if (self.password !== null) {
cb(msg)
} else {
pgPass(self.connectionParameters, function(pass){
pgPass(self.connectionParameters, function (pass) {
if (undefined !== pass) {
self.connectionParameters.password = self.password = pass;
self.connectionParameters.password = self.password = pass
}
cb(msg);
});
cb(msg)
})
}
};
}
}
//password request handling
con.on('authenticationCleartextPassword', checkPgPass(function() {
con.password(self.password);
}));
// password request handling
con.on('authenticationCleartextPassword', checkPgPass(function () {
con.password(self.password)
}))
//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);
}));
// 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.once('backendKeyData', function(msg) {
self.processID = msg.processID;
self.secretKey = msg.secretKey;
});
con.once('backendKeyData', function (msg) {
self.processID = msg.processID
self.secretKey = msg.secretKey
})
const connectingErrorHandler = (err) => {
if (this._connectionError) {
return;
return
}
this._connectionError = true
if (callback) {
@ -130,50 +129,50 @@ Client.prototype.connect = function(callback) {
}
const connectedErrorHandler = (err) => {
if(this.activeQuery) {
var activeQuery = self.activeQuery;
this.activeQuery = null;
return activeQuery.handleError(err, con);
if (this.activeQuery) {
var activeQuery = self.activeQuery
this.activeQuery = null
return activeQuery.handleError(err, con)
}
this.emit('error', err)
}
con.on('error', connectingErrorHandler)
//hook up query handling events to connection
//after the connection initially becomes ready for queries
con.once('readyForQuery', function() {
self._connecting = false;
self._connected = true;
self._attachListeners(con);
con.removeListener('error', connectingErrorHandler);
// hook up query handling events to connection
// after the connection initially becomes ready for queries
con.once('readyForQuery', function () {
self._connecting = false
self._connected = true
self._attachListeners(con)
con.removeListener('error', connectingErrorHandler)
con.on('error', connectedErrorHandler)
//process possible callback argument to Client#connect
// process possible callback argument to Client#connect
if (callback) {
callback(null, self);
//remove callback for proper error handling
//after the connect event
callback = null;
callback(null, self)
// remove callback for proper error handling
// after the connect event
callback = null
}
self.emit('connect');
});
self.emit('connect')
})
con.on('readyForQuery', function() {
var activeQuery = self.activeQuery;
self.activeQuery = null;
self.readyForQuery = true;
if(activeQuery) {
activeQuery.handleReadyForQuery(con);
con.on('readyForQuery', function () {
var activeQuery = self.activeQuery
self.activeQuery = null
self.readyForQuery = true
if (activeQuery) {
activeQuery.handleReadyForQuery(con)
}
self._pulseQueryQueue();
});
self._pulseQueryQueue()
})
con.once('end', () => {
if(this.activeQuery) {
var disconnectError = new Error('Connection terminated');
this.activeQuery.handleError(disconnectError, con);
this.activeQuery = null;
if (this.activeQuery) {
var disconnectError = new Error('Connection terminated')
this.activeQuery.handleError(disconnectError, con)
this.activeQuery = null
}
if (!this._ending) {
// if the connection is ended without us calling .end()
@ -188,16 +187,15 @@ Client.prototype.connect = function(callback) {
this.emit('error', error)
}
} else if (!this._connectionError) {
this.emit('error', error);
this.emit('error', error)
}
}
this.emit('end');
});
this.emit('end')
})
con.on('notice', function(msg) {
self.emit('notice', msg);
});
con.on('notice', function (msg) {
self.emit('notice', msg)
})
if (!callback) {
return new global.Promise((resolve, reject) => {
@ -208,216 +206,214 @@ Client.prototype.connect = function(callback) {
})
})
}
};
}
Client.prototype._attachListeners = function(con) {
Client.prototype._attachListeners = function (con) {
const self = this
//delegate rowDescription to active query
// delegate rowDescription to active query
con.on('rowDescription', function (msg) {
self.activeQuery.handleRowDescription(msg);
});
self.activeQuery.handleRowDescription(msg)
})
//delegate dataRow to active query
// delegate dataRow to active query
con.on('dataRow', function (msg) {
self.activeQuery.handleDataRow(msg);
});
self.activeQuery.handleDataRow(msg)
})
//delegate portalSuspended to active query
// delegate portalSuspended to active query
con.on('portalSuspended', function (msg) {
self.activeQuery.handlePortalSuspended(con);
});
self.activeQuery.handlePortalSuspended(con)
})
//deletagate emptyQuery to active query
// deletagate emptyQuery to active query
con.on('emptyQuery', function (msg) {
self.activeQuery.handleEmptyQuery(con);
});
self.activeQuery.handleEmptyQuery(con)
})
//delegate commandComplete to active query
// delegate commandComplete to active query
con.on('commandComplete', function (msg) {
self.activeQuery.handleCommandComplete(msg, con);
});
self.activeQuery.handleCommandComplete(msg, con)
})
//if a prepared statement has a name and properly parses
//we track that its already been executed so we don't parse
//it again on the same client
// if a prepared statement has a name and properly parses
// we track that its already been executed so we don't parse
// it again on the same client
con.on('parseComplete', function (msg) {
if (self.activeQuery.name) {
con.parsedStatements[self.activeQuery.name] = true;
con.parsedStatements[self.activeQuery.name] = true
}
});
})
con.on('copyInResponse', function (msg) {
self.activeQuery.handleCopyInResponse(self.connection);
});
self.activeQuery.handleCopyInResponse(self.connection)
})
con.on('copyData', function (msg) {
self.activeQuery.handleCopyData(msg, self.connection);
});
self.activeQuery.handleCopyData(msg, self.connection)
})
con.on('notification', function (msg) {
self.emit('notification', msg);
});
self.emit('notification', msg)
})
}
Client.prototype.getStartupConf = function () {
var params = this.connectionParameters;
var params = this.connectionParameters
var data = {
user: params.user,
database: params.database
};
}
var appName = params.application_name || params.fallback_application_name;
var appName = params.application_name || params.fallback_application_name
if (appName) {
data.application_name = appName;
data.application_name = appName
}
if (params.replication) {
data.replication = '' + params.replication;
data.replication = '' + params.replication
}
return data;
};
return data
}
Client.prototype.cancel = function (client, query) {
if (client.activeQuery == query) {
var con = this.connection;
if (client.activeQuery === query) {
var con = this.connection
if (this.host && this.host.indexOf('/') === 0) {
con.connect(this.host + '/.s.PGSQL.' + this.port);
con.connect(this.host + '/.s.PGSQL.' + this.port)
} else {
con.connect(this.port, this.host);
con.connect(this.port, this.host)
}
//once connection is established send cancel message
// once connection is established send cancel message
con.on('connect', function () {
con.cancel(client.processID, client.secretKey);
});
} else if (client.queryQueue.indexOf(query) != -1) {
client.queryQueue.splice(client.queryQueue.indexOf(query), 1);
con.cancel(client.processID, client.secretKey)
})
} else if (client.queryQueue.indexOf(query) !== -1) {
client.queryQueue.splice(client.queryQueue.indexOf(query), 1)
}
};
}
Client.prototype.setTypeParser = function (oid, format, parseFn) {
return this._types.setTypeParser(oid, format, parseFn);
};
return this._types.setTypeParser(oid, format, parseFn)
}
Client.prototype.getTypeParser = function (oid, format) {
return this._types.getTypeParser(oid, format);
};
return this._types.getTypeParser(oid, format)
}
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
Client.prototype.escapeIdentifier = function (str) {
var escaped = '"';
var escaped = '"'
for (var i = 0; i < str.length; i++) {
var c = str[i];
var c = str[i]
if (c === '"') {
escaped += c + c;
escaped += c + c
} else {
escaped += c;
escaped += c
}
}
escaped += '"';
escaped += '"'
return escaped;
};
return escaped
}
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
Client.prototype.escapeLiteral = function (str) {
var hasBackslash = false;
var escaped = '\'';
var hasBackslash = false
var escaped = '\''
for (var i = 0; i < str.length; i++) {
var c = str[i];
var c = str[i]
if (c === '\'') {
escaped += c + c;
escaped += c + c
} else if (c === '\\') {
escaped += c + c;
hasBackslash = true;
escaped += c + c
hasBackslash = true
} else {
escaped += c;
escaped += c
}
}
escaped += '\'';
escaped += '\''
if (hasBackslash === true) {
escaped = ' E' + escaped;
escaped = ' E' + escaped
}
return escaped;
};
return escaped
}
Client.prototype._pulseQueryQueue = function () {
if (this.readyForQuery === true) {
this.activeQuery = this.queryQueue.shift();
this.activeQuery = this.queryQueue.shift()
if (this.activeQuery) {
this.readyForQuery = false;
this.hasExecuted = true;
this.activeQuery.submit(this.connection);
this.readyForQuery = false
this.hasExecuted = true
this.activeQuery.submit(this.connection)
} else if (this.hasExecuted) {
this.activeQuery = null;
this.emit('drain');
this.activeQuery = null
this.emit('drain')
}
}
};
}
Client.prototype.query = function (config, values, callback) {
//can take in strings, config object or query object
var query;
var result;
if (typeof config.submit == 'function') {
// can take in strings, config object or query object
var query
var result
if (typeof config.submit === 'function') {
result = query = config
if (typeof values == 'function') {
if (typeof values === 'function') {
query.callback = query.callback || values
}
} else {
query = new Query(config, values, callback)
if (!query.callback) {
let resolve, reject;
result = new Promise((res, rej) => {
resolve = res
reject = rej
let resolveOut, rejectOut
result = new Promise((resolve, reject) => {
resolveOut = resolve
rejectOut = reject
})
query.callback = (err, res) => err ? reject(err) : resolve(res)
query.callback = (err, res) => err ? rejectOut(err) : resolveOut(res)
}
}
if (this.binary && !query.binary) {
query.binary = true;
query.binary = true
}
if (query._result) {
query._result._getTypeParser = this._types.getTypeParser.bind(this._types);
query._result._getTypeParser = this._types.getTypeParser.bind(this._types)
}
this.queryQueue.push(query);
this._pulseQueryQueue();
this.queryQueue.push(query)
this._pulseQueryQueue()
return result
};
}
Client.prototype.end = function (cb) {
this._ending = true;
this._ending = true
if (this.activeQuery) {
// if we have an active query we need to force a disconnect
// on the socket - otherwise a hung query could block end forever
this.connection.stream.destroy(new Error('Connection terminated by user'))
return;
return
}
if (cb) {
this.connection.end();
this.connection.once('end', cb);
this.connection.end()
this.connection.once('end', cb)
} else {
return new global.Promise((resolve, reject) => {
this.connection.end()
this.connection.once('end', resolve)
})
}
};
}
// expose a Query constructor
Client.Query = Query;
Client.Query = Query
module.exports = Client;
module.exports = Client

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,111 +7,110 @@
* README.md file in the root directory of this source tree.
*/
var url = require('url');
var dns = require('dns');
var dns = require('dns')
var defaults = require('./defaults');
var defaults = require('./defaults')
var val = function(key, config, envVar) {
var val = function (key, config, envVar) {
if (envVar === undefined) {
envVar = process.env[ 'PG' + key.toUpperCase() ];
envVar = process.env[ 'PG' + key.toUpperCase() ]
} else if (envVar === false) {
// do nothing ... use false
} else {
envVar = process.env[ envVar ];
envVar = process.env[ envVar ]
}
return config[key] ||
envVar ||
defaults[key];
};
defaults[key]
}
//parses a connection string
var parse = require('pg-connection-string').parse;
// parses a connection string
var parse = require('pg-connection-string').parse
var useSsl = function() {
switch(process.env.PGSSLMODE) {
case "disable":
return false;
case "prefer":
case "require":
case "verify-ca":
case "verify-full":
return true;
var useSsl = function () {
switch (process.env.PGSSLMODE) {
case 'disable':
return false
case 'prefer':
case 'require':
case 'verify-ca':
case 'verify-full':
return true
}
return defaults.ssl;
};
return defaults.ssl
}
var ConnectionParameters = function(config) {
//if a string is passed, it is a raw connection string so we parse it into a config
config = typeof config == 'string' ? parse(config) : (config || {});
//if the config has a connectionString defined, parse IT into the config we use
//this will override other default values with what is stored in connectionString
if(config.connectionString) {
config = parse(config.connectionString);
var ConnectionParameters = function (config) {
// if a string is passed, it is a raw connection string so we parse it into a config
config = typeof config === 'string' ? parse(config) : (config || {})
// if the config has a connectionString defined, parse IT into the config we use
// this will override other default values with what is stored in connectionString
if (config.connectionString) {
config = parse(config.connectionString)
}
this.user = val('user', config);
this.database = val('database', config);
this.port = parseInt(val('port', config), 10);
this.host = val('host', config);
this.password = val('password', config);
this.binary = val('binary', config);
this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl;
this.client_encoding = val("client_encoding", config);
this.replication = val("replication", config);
//a domain socket begins with '/'
this.isDomainSocket = (!(this.host||'').indexOf('/'));
this.user = val('user', config)
this.database = val('database', config)
this.port = parseInt(val('port', config), 10)
this.host = val('host', config)
this.password = val('password', config)
this.binary = val('binary', config)
this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl
this.client_encoding = val('client_encoding', config)
this.replication = val('replication', config)
// a domain socket begins with '/'
this.isDomainSocket = (!(this.host || '').indexOf('/'))
this.application_name = val('application_name', config, 'PGAPPNAME');
this.fallback_application_name = val('fallback_application_name', config, false);
};
this.application_name = val('application_name', config, 'PGAPPNAME')
this.fallback_application_name = val('fallback_application_name', config, false)
}
// Convert arg to a string, surround in single quotes, and escape single quotes and backslashes
var quoteParamValue = function(value) {
return "'" + ('' + value).replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
};
var quoteParamValue = function (value) {
return "'" + ('' + value).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"
}
var add = function(params, config, paramName) {
var value = config[paramName];
if(value) {
params.push(paramName + "=" + quoteParamValue(value));
var add = function (params, config, paramName) {
var value = config[paramName]
if (value) {
params.push(paramName + '=' + quoteParamValue(value))
}
};
}
ConnectionParameters.prototype.getLibpqConnectionString = function(cb) {
var params = [];
add(params, this, 'user');
add(params, this, 'password');
add(params, this, 'port');
add(params, this, 'application_name');
add(params, this, 'fallback_application_name');
ConnectionParameters.prototype.getLibpqConnectionString = function (cb) {
var params = []
add(params, this, 'user')
add(params, this, 'password')
add(params, this, 'port')
add(params, this, 'application_name')
add(params, this, 'fallback_application_name')
var ssl = typeof this.ssl === 'object' ? this.ssl : {sslmode: this.ssl};
add(params, ssl, 'sslmode');
add(params, ssl, 'sslca');
add(params, ssl, 'sslkey');
add(params, ssl, 'sslcert');
if(this.database) {
params.push("dbname=" + quoteParamValue(this.database));
}
if(this.replication) {
params.push("replication=" + quoteParamValue(this.replication));
}
if(this.host) {
params.push("host=" + quoteParamValue(this.host));
}
if(this.isDomainSocket) {
return cb(null, params.join(' '));
}
if(this.client_encoding) {
params.push("client_encoding=" + quoteParamValue(this.client_encoding));
}
dns.lookup(this.host, function(err, address) {
if(err) return cb(err, null);
params.push("hostaddr=" + quoteParamValue(address));
return cb(null, params.join(' '));
});
};
var ssl = typeof this.ssl === 'object' ? this.ssl : {sslmode: this.ssl}
add(params, ssl, 'sslmode')
add(params, ssl, 'sslca')
add(params, ssl, 'sslkey')
add(params, ssl, 'sslcert')
module.exports = ConnectionParameters;
if (this.database) {
params.push('dbname=' + quoteParamValue(this.database))
}
if (this.replication) {
params.push('replication=' + quoteParamValue(this.replication))
}
if (this.host) {
params.push('host=' + quoteParamValue(this.host))
}
if (this.isDomainSocket) {
return cb(null, params.join(' '))
}
if (this.client_encoding) {
params.push('client_encoding=' + quoteParamValue(this.client_encoding))
}
dns.lookup(this.host, function (err, address) {
if (err) return cb(err, null)
params.push('hostaddr=' + quoteParamValue(address))
return cb(null, params.join(' '))
})
}
module.exports = ConnectionParameters

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,53 +7,53 @@
* README.md file in the root directory of this source tree.
*/
var defaults = module.exports = {
module.exports = {
// database host. defaults to localhost
host: 'localhost',
//database user's name
// database user's name
user: process.platform === 'win32' ? process.env.USERNAME : process.env.USER,
//name of database to connect
// name of database to connect
database: process.platform === 'win32' ? process.env.USERNAME : process.env.USER,
//database user's password
// database user's password
password: null,
// a Postgres connection string to be used instead of setting individual connection items
// NOTE: Setting this value will cause it to override any other value (such as database or user) defined
// in the defaults object.
connectionString : undefined,
connectionString: undefined,
//database port
// database port
port: 5432,
//number of rows to return at a time from a prepared statement's
//portal. 0 will return all rows at once
// number of rows to return at a time from a prepared statement's
// portal. 0 will return all rows at once
rows: 0,
// binary result mode
binary: false,
//Connection pool options - see https://github.com/coopernurse/node-pool
//number of connections to use in connection pool
//0 will disable connection pooling
// Connection pool options - see https://github.com/coopernurse/node-pool
// number of connections to use in connection pool
// 0 will disable connection pooling
poolSize: 10,
//max milliseconds a client can go unused before it is removed
//from the pool and destroyed
// 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
// 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
// if true the most recently released resources will be the first to be allocated
returnToHead: false,
//pool log function / boolean
// pool log function / boolean
poolLog: false,
client_encoding: "",
client_encoding: '',
ssl: false,
@ -61,15 +61,15 @@ var defaults = module.exports = {
fallback_application_name: undefined,
parseInputDatesAsUTC: false
};
}
var pgTypes = require('pg-types');
var pgTypes = require('pg-types')
// save default parsers
var parseBigInteger = pgTypes.getTypeParser(20, 'text');
var parseBigIntegerArray = pgTypes.getTypeParser(1016, 'text');
var parseBigInteger = pgTypes.getTypeParser(20, 'text')
var parseBigIntegerArray = pgTypes.getTypeParser(1016, 'text')
//parse int8 so you can get your count values as actual numbers
module.exports.__defineSetter__("parseInt8", function(val) {
pgTypes.setTypeParser(20, 'text', val ? pgTypes.getTypeParser(23, 'text') : parseBigInteger);
pgTypes.setTypeParser(1016, 'text', val ? pgTypes.getTypeParser(1007, 'text') : parseBigIntegerArray);
});
// parse int8 so you can get your count values as actual numbers
module.exports.__defineSetter__('parseInt8', function (val) {
pgTypes.setTypeParser(20, 'text', val ? pgTypes.getTypeParser(23, 'text') : parseBigInteger)
pgTypes.setTypeParser(1016, 'text', val ? pgTypes.getTypeParser(1007, 'text') : parseBigIntegerArray)
})

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,57 +7,54 @@
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Client = require('./client');
var defaults = require('./defaults');
var Connection = require('./connection');
var ConnectionParameters = require('./connection-parameters');
var Pool = require('pg-pool');
var util = require('util')
var Client = require('./client')
var defaults = require('./defaults')
var Connection = require('./connection')
var Pool = require('pg-pool')
const poolFactory = (Client) => {
var BoundPool = function(options) {
var config = { Client: Client };
var BoundPool = function (options) {
var config = { Client: Client }
for (var key in options) {
config[key] = options[key];
config[key] = options[key]
}
return new Pool(config)
};
}
util.inherits(BoundPool, Pool);
util.inherits(BoundPool, Pool)
return BoundPool;
};
return BoundPool
}
var PG = function (clientConstructor) {
this.defaults = defaults
this.Client = clientConstructor
this.Query = this.Client.Query
this.Pool = poolFactory(this.Client)
this._pools = []
this.Connection = Connection
this.types = require('pg-types')
}
var PG = function(clientConstructor) {
this.defaults = defaults;
this.Client = clientConstructor;
this.Query = this.Client.Query;
this.Pool = poolFactory(this.Client);
this._pools = [];
this.Connection = Connection;
this.types = require('pg-types');
};
if(typeof process.env.NODE_PG_FORCE_NATIVE != 'undefined') {
module.exports = new PG(require('./native'));
if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
module.exports = new PG(require('./native'))
} else {
module.exports = new PG(Client);
module.exports = new PG(Client)
//lazy require native module...the native module may not have installed
module.exports.__defineGetter__("native", function() {
delete module.exports.native;
var native = null;
// lazy require native module...the native module may not have installed
module.exports.__defineGetter__('native', function () {
delete module.exports.native
var native = null
try {
native = new PG(require('./native'));
native = new PG(require('./native'))
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err;
throw err
}
console.error(err.message);
console.error(err.message)
}
module.exports.native = native;
return native;
});
module.exports.native = native
return native
})
}

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,71 +7,71 @@
* README.md file in the root directory of this source tree.
*/
var Native = require('pg-native');
var TypeOverrides = require('../type-overrides');
var semver = require('semver');
var pkg = require('../../package.json');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var ConnectionParameters = require('../connection-parameters');
var Native = require('pg-native')
var TypeOverrides = require('../type-overrides')
var semver = require('semver')
var pkg = require('../../package.json')
var assert = require('assert')
var EventEmitter = require('events').EventEmitter
var util = require('util')
var ConnectionParameters = require('../connection-parameters')
var msg = 'Version >= ' + pkg.minNativeVersion + ' of pg-native required.';
assert(semver.gte(Native.version, pkg.minNativeVersion), msg);
var msg = 'Version >= ' + pkg.minNativeVersion + ' of pg-native required.'
assert(semver.gte(Native.version, pkg.minNativeVersion), msg)
var NativeQuery = require('./query');
var NativeQuery = require('./query')
var Client = module.exports = function(config) {
EventEmitter.call(this);
config = config || {};
var Client = module.exports = function (config) {
EventEmitter.call(this)
config = config || {}
this._types = new TypeOverrides(config.types);
this._types = new TypeOverrides(config.types)
this.native = new Native({
types: this._types
});
})
this._queryQueue = [];
this._connected = false;
this._connecting = false;
this._queryQueue = []
this._connected = false
this._connecting = false
//keep these on the object for legacy reasons
//for the time being. TODO: deprecate all this jazz
var cp = this.connectionParameters = new ConnectionParameters(config);
this.user = cp.user;
this.password = cp.password;
this.database = cp.database;
this.host = cp.host;
this.port = cp.port;
// keep these on the object for legacy reasons
// for the time being. TODO: deprecate all this jazz
var cp = this.connectionParameters = new ConnectionParameters(config)
this.user = cp.user
this.password = cp.password
this.database = cp.database
this.host = cp.host
this.port = cp.port
//a hash to hold named queries
this.namedQueries = {};
};
// a hash to hold named queries
this.namedQueries = {}
}
Client.Query = NativeQuery;
Client.Query = NativeQuery
util.inherits(Client, EventEmitter);
util.inherits(Client, EventEmitter)
//connect to the backend
//pass an optional callback to be called once connected
//or with an error if there was a connection error
//if no callback is passed and there is a connection error
//the client will emit an error event.
Client.prototype.connect = function(cb) {
var self = this;
// connect to the backend
// pass an optional callback to be called once connected
// or with an error if there was a connection error
// if no callback is passed and there is a connection error
// the client will emit an error event.
Client.prototype.connect = function (cb) {
var self = this
var onError = function(err) {
if(cb) return cb(err);
return self.emit('error', err);
};
var onError = function (err) {
if (cb) return cb(err)
return self.emit('error', err)
}
var result
if (!cb) {
var resolve, reject
cb = (err) => err ? reject(err) : resolve()
result = new global.Promise(function(res, rej) {
resolve = res
reject = rej
var resolveOut, rejectOut
cb = (err) => err ? rejectOut(err) : resolveOut()
result = new global.Promise(function (resolve, reject) {
resolveOut = resolve
rejectOut = reject
})
}
@ -82,145 +82,145 @@ Client.prototype.connect = function(cb) {
this._connecting = true
this.connectionParameters.getLibpqConnectionString(function(err, conString) {
if(err) return onError(err);
self.native.connect(conString, function(err) {
if(err) return onError(err);
this.connectionParameters.getLibpqConnectionString(function (err, conString) {
if (err) return onError(err)
self.native.connect(conString, function (err) {
if (err) return onError(err)
//set internal states to connected
self._connected = true;
// set internal states to connected
self._connected = true
//handle connection errors from the native layer
self.native.on('error', function(err) {
//error will be handled by active query
if(self._activeQuery && self._activeQuery.state != 'end') {
return;
// handle connection errors from the native layer
self.native.on('error', function (err) {
// error will be handled by active query
if (self._activeQuery && self._activeQuery.state !== 'end') {
return
}
self.emit('error', err);
});
self.emit('error', err)
})
self.native.on('notification', function(msg) {
self.native.on('notification', function (msg) {
self.emit('notification', {
channel: msg.relname,
payload: msg.extra
});
});
})
})
//signal we are connected now
self.emit('connect');
self._pulseQueryQueue(true);
// signal we are connected now
self.emit('connect')
self._pulseQueryQueue(true)
//possibly call the optional callback
if(cb) cb();
});
});
// possibly call the optional callback
if (cb) cb()
})
})
return result
};
}
//send a query to the server
//this method is highly overloaded to take
//1) string query, optional array of parameters, optional function callback
//2) object query with {
// send a query to the server
// this method is highly overloaded to take
// 1) string query, optional array of parameters, optional function callback
// 2) object query with {
// string query
// optional array values,
// optional function callback instead of as a separate parameter
// optional string name to name & cache the query plan
// optional string rowMode = 'array' for an array of results
// }
Client.prototype.query = function(config, values, callback) {
if (typeof config.submit == 'function') {
Client.prototype.query = function (config, values, callback) {
if (typeof config.submit === 'function') {
// accept query(new Query(...), (err, res) => { }) style
if (typeof values == 'function') {
config.callback = values;
if (typeof values === 'function') {
config.callback = values
}
this._queryQueue.push(config);
this._pulseQueryQueue();
return config;
this._queryQueue.push(config)
this._pulseQueryQueue()
return config
}
var query = new NativeQuery(config, values, callback);
var query = new NativeQuery(config, values, callback)
var result
if (!query.callback) {
let resolve, reject;
result = new Promise((res, rej) => {
resolve = res
reject = rej
let resolveOut, rejectOut
result = new Promise((resolve, reject) => {
resolveOut = resolve
rejectOut = reject
})
query.callback = (err, res) => err ? reject(err) : resolve(res)
query.callback = (err, res) => err ? rejectOut(err) : resolveOut(res)
}
this._queryQueue.push(query);
this._pulseQueryQueue();
return result;
};
this._queryQueue.push(query)
this._pulseQueryQueue()
return result
}
//disconnect from the backend server
Client.prototype.end = function(cb) {
var self = this;
if(!this._connected) {
this.once('connect', this.end.bind(this, cb));
// disconnect from the backend server
Client.prototype.end = function (cb) {
var self = this
if (!this._connected) {
this.once('connect', this.end.bind(this, cb))
}
var result;
var result
if (!cb) {
var resolve, reject
cb = (err) => err ? reject(err) : resolve()
result = new global.Promise(function(res, rej) {
result = new global.Promise(function (res, rej) {
resolve = res
reject = rej
})
}
this.native.end(function() {
//send an error to the active query
if(self._hasActiveQuery()) {
var msg = 'Connection terminated';
self._queryQueue.length = 0;
self._activeQuery.handleError(new Error(msg));
this.native.end(function () {
// send an error to the active query
if (self._hasActiveQuery()) {
var msg = 'Connection terminated'
self._queryQueue.length = 0
self._activeQuery.handleError(new Error(msg))
}
self.emit('end');
if(cb) cb();
});
self.emit('end')
if (cb) cb()
})
return result
};
}
Client.prototype._hasActiveQuery = function() {
return this._activeQuery && this._activeQuery.state != 'error' && this._activeQuery.state != 'end';
};
Client.prototype._hasActiveQuery = function () {
return this._activeQuery && this._activeQuery.state !== 'error' && this._activeQuery.state !== 'end'
}
Client.prototype._pulseQueryQueue = function(initialConnection) {
if(!this._connected) {
return;
Client.prototype._pulseQueryQueue = function (initialConnection) {
if (!this._connected) {
return
}
if(this._hasActiveQuery()) {
return;
if (this._hasActiveQuery()) {
return
}
var query = this._queryQueue.shift();
if(!query) {
if(!initialConnection) {
this.emit('drain');
var query = this._queryQueue.shift()
if (!query) {
if (!initialConnection) {
this.emit('drain')
}
return;
return
}
this._activeQuery = query;
query.submit(this);
var self = this;
query.once('_done', function() {
self._pulseQueryQueue();
});
};
this._activeQuery = query
query.submit(this)
var self = this
query.once('_done', function () {
self._pulseQueryQueue()
})
}
//attempt to cancel an in-progress query
Client.prototype.cancel = function(query) {
if(this._activeQuery == query) {
this.native.cancel(function() {});
} else if (this._queryQueue.indexOf(query) != -1) {
this._queryQueue.splice(this._queryQueue.indexOf(query), 1);
// attempt to cancel an in-progress query
Client.prototype.cancel = function (query) {
if (this._activeQuery === query) {
this.native.cancel(function () {})
} else if (this._queryQueue.indexOf(query) !== -1) {
this._queryQueue.splice(this._queryQueue.indexOf(query), 1)
}
};
}
Client.prototype.setTypeParser = function(oid, format, parseFn) {
return this._types.setTypeParser(oid, format, parseFn);
};
Client.prototype.setTypeParser = function (oid, format, parseFn) {
return this._types.setTypeParser(oid, format, parseFn)
}
Client.prototype.getTypeParser = function(oid, format) {
return this._types.getTypeParser(oid, format);
};
Client.prototype.getTypeParser = function (oid, format) {
return this._types.getTypeParser(oid, format)
}

View File

@ -1,2 +1,2 @@
"use strict";
'use strict'
module.exports = require('./client')

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,33 +7,33 @@
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var utils = require('../utils');
var NativeResult = require('./result');
var EventEmitter = require('events').EventEmitter
var util = require('util')
var utils = require('../utils')
var NativeResult = require('./result')
var NativeQuery = module.exports = function(config, values, callback) {
EventEmitter.call(this);
config = utils.normalizeQueryConfig(config, values, callback);
this.text = config.text;
this.values = config.values;
this.name = config.name;
this.callback = config.callback;
this.state = 'new';
this._arrayMode = config.rowMode == 'array';
var NativeQuery = module.exports = function (config, values, callback) {
EventEmitter.call(this)
config = utils.normalizeQueryConfig(config, values, callback)
this.text = config.text
this.values = config.values
this.name = config.name
this.callback = config.callback
this.state = 'new'
this._arrayMode = config.rowMode === 'array'
//if the 'row' event is listened for
//then emit them as they come in
//without setting singleRowMode to true
//this has almost no meaning because libpq
//reads all rows into memory befor returning any
this._emitRowEvents = false;
this.on('newListener', function(event) {
if(event === 'row') this._emitRowEvents = true;
}.bind(this));
};
// if the 'row' event is listened for
// then emit them as they come in
// without setting singleRowMode to true
// this has almost no meaning because libpq
// reads all rows into memory befor returning any
this._emitRowEvents = false
this.on('newListener', function (event) {
if (event === 'row') this._emitRowEvents = true
}.bind(this))
}
util.inherits(NativeQuery, EventEmitter);
util.inherits(NativeQuery, EventEmitter)
var errorFieldMap = {
'sqlState': 'code',
@ -47,113 +47,112 @@ var errorFieldMap = {
'constraintName': 'constraint',
'sourceFile': 'file',
'sourceLine': 'line',
'sourceFunction': 'routine',
};
'sourceFunction': 'routine'
}
NativeQuery.prototype.handleError = function(err) {
var self = this;
//copy pq error fields into the error object
var fields = self.native.pq.resultErrorFields();
if(fields) {
for(var key in fields) {
var normalizedFieldName = errorFieldMap[key] || key;
err[normalizedFieldName] = fields[key];
NativeQuery.prototype.handleError = function (err) {
var self = this
// copy pq error fields into the error object
var fields = self.native.pq.resultErrorFields()
if (fields) {
for (var key in fields) {
var normalizedFieldName = errorFieldMap[key] || key
err[normalizedFieldName] = fields[key]
}
}
if(self.callback) {
self.callback(err);
if (self.callback) {
self.callback(err)
} else {
self.emit('error', err);
self.emit('error', err)
}
self.state = 'error';
};
self.state = 'error'
}
NativeQuery.prototype.then = function(onSuccess, onFailure) {
return this._getPromise().then(onSuccess, onFailure);
};
NativeQuery.prototype.then = function (onSuccess, onFailure) {
return this._getPromise().then(onSuccess, onFailure)
}
NativeQuery.prototype.catch = function(callback) {
return this._getPromise().catch(callback);
};
NativeQuery.prototype.catch = function (callback) {
return this._getPromise().catch(callback)
}
NativeQuery.prototype._getPromise = function() {
if (this._promise) return this._promise;
this._promise = new Promise(function(resolve, reject) {
this._once('end', resolve);
this._once('error', reject);
}.bind(this));
return this._promise;
};
NativeQuery.prototype._getPromise = function () {
if (this._promise) return this._promise
this._promise = new Promise(function (resolve, reject) {
this._once('end', resolve)
this._once('error', reject)
}.bind(this))
return this._promise
}
NativeQuery.prototype.submit = function(client) {
this.state = 'running';
var self = this;
this.native = client.native;
client.native.arrayMode = this._arrayMode;
NativeQuery.prototype.submit = function (client) {
this.state = 'running'
var self = this
this.native = client.native
client.native.arrayMode = this._arrayMode
var after = function(err, rows) {
client.native.arrayMode = false;
setImmediate(function() {
self.emit('_done');
});
var after = function (err, rows) {
client.native.arrayMode = false
setImmediate(function () {
self.emit('_done')
})
//handle possible query error
if(err) {
return self.handleError(err);
// handle possible query error
if (err) {
return self.handleError(err)
}
var result = new NativeResult();
result.addCommandComplete(self.native.pq);
result.rows = rows;
var result = new NativeResult()
result.addCommandComplete(self.native.pq)
result.rows = rows
//emit row events for each row in the result
if(self._emitRowEvents) {
rows.forEach(function(row) {
self.emit('row', row, result);
});
// emit row events for each row in the result
if (self._emitRowEvents) {
rows.forEach(function (row) {
self.emit('row', row, result)
})
}
//handle successful result
self.state = 'end';
self.emit('end', result);
if(self.callback) {
self.callback(null, result);
// handle successful result
self.state = 'end'
self.emit('end', result)
if (self.callback) {
self.callback(null, result)
}
};
if(process.domain) {
after = process.domain.bind(after);
}
//named query
if(this.name) {
if (process.domain) {
after = process.domain.bind(after)
}
// named query
if (this.name) {
if (this.name.length > 63) {
console.error('Warning! Postgres only supports 63 characters for query names.');
console.error('You supplied', this.name, '(', this.name.length, ')');
console.error('This can cause conflicts and silent errors executing queries');
console.error('Warning! Postgres only supports 63 characters for query names.')
console.error('You supplied', this.name, '(', this.name.length, ')')
console.error('This can cause conflicts and silent errors executing queries')
}
var values = (this.values||[]).map(utils.prepareValue);
var values = (this.values || []).map(utils.prepareValue)
//check if the client has already executed this named query
//if so...just execute it again - skip the planning phase
if(client.namedQueries[this.name]) {
return client.native.execute(this.name, values, after);
// check if the client has already executed this named query
// if so...just execute it again - skip the planning phase
if (client.namedQueries[this.name]) {
return client.native.execute(this.name, values, after)
}
//plan the named query the first time, then execute it
return client.native.prepare(this.name, this.text, values.length, function(err) {
if(err) return after(err);
client.namedQueries[self.name] = true;
return self.native.execute(self.name, values, after);
});
} else if(this.values) {
// plan the named query the first time, then execute it
return client.native.prepare(this.name, this.text, values.length, function (err) {
if (err) return after(err)
client.namedQueries[self.name] = true
return self.native.execute(self.name, values, after)
})
} else if (this.values) {
if (!Array.isArray(this.values)) {
const err = new Error('Query values must be an array')
return after(err)
}
var vals = this.values.map(utils.prepareValue);
client.native.query(this.text, vals, after);
var vals = this.values.map(utils.prepareValue)
client.native.query(this.text, vals, after)
} else {
client.native.query(this.text, after);
client.native.query(this.text, after)
}
};
}

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,31 +7,31 @@
* README.md file in the root directory of this source tree.
*/
var NativeResult = module.exports = function(pq) {
this.command = null;
this.rowCount = 0;
this.rows = null;
this.fields = null;
};
var NativeResult = module.exports = function (pq) {
this.command = null
this.rowCount = 0
this.rows = null
this.fields = null
}
NativeResult.prototype.addCommandComplete = function(pq) {
this.command = pq.cmdStatus().split(' ')[0];
this.rowCount = parseInt(pq.cmdTuples(), 10);
var nfields = pq.nfields();
if(nfields < 1) return;
NativeResult.prototype.addCommandComplete = function (pq) {
this.command = pq.cmdStatus().split(' ')[0]
this.rowCount = parseInt(pq.cmdTuples(), 10)
var nfields = pq.nfields()
if (nfields < 1) return
this.fields = [];
for(var i = 0; i < nfields; i++) {
this.fields = []
for (var i = 0; i < nfields; i++) {
this.fields.push({
name: pq.fname(i),
dataTypeID: pq.ftype(i)
});
})
}
};
}
NativeResult.prototype.addRow = function(row) {
NativeResult.prototype.addRow = function (row) {
// This is empty to ensure pg code doesn't break when switching to pg-native
// pg-native loads all rows into the final result object by default.
// This is because libpg loads all rows into memory before passing the result
// to pg-native.
};
}

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,127 +7,127 @@
* README.md file in the root directory of this source tree.
*/
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var EventEmitter = require('events').EventEmitter
var util = require('util')
var Result = require('./result');
var utils = require('./utils');
var Result = require('./result')
var utils = require('./utils')
var Query = function(config, values, callback) {
var Query = function (config, values, callback) {
// use of "new" optional
if(!(this instanceof Query)) { return new Query(config, values, callback); }
if (!(this instanceof Query)) { return new Query(config, values, callback) }
config = utils.normalizeQueryConfig(config, values, callback);
config = utils.normalizeQueryConfig(config, values, callback)
this.text = config.text;
this.values = config.values;
this.rows = config.rows;
this.types = config.types;
this.name = config.name;
this.binary = config.binary;
this.stream = config.stream;
//use unique portal name each time
this.portal = config.portal || "";
this.callback = config.callback;
if(process.domain && config.callback) {
this.callback = process.domain.bind(config.callback);
this.text = config.text
this.values = config.values
this.rows = config.rows
this.types = config.types
this.name = config.name
this.binary = config.binary
this.stream = config.stream
// use unique portal name each time
this.portal = config.portal || ''
this.callback = config.callback
if (process.domain && config.callback) {
this.callback = process.domain.bind(config.callback)
}
this._result = new Result(config.rowMode, config.types);
this.isPreparedStatement = false;
this._canceledDueToError = false;
this._promise = null;
EventEmitter.call(this);
};
this._result = new Result(config.rowMode, config.types)
this.isPreparedStatement = false
this._canceledDueToError = false
this._promise = null
EventEmitter.call(this)
}
util.inherits(Query, EventEmitter);
util.inherits(Query, EventEmitter)
Query.prototype.requiresPreparation = function() {
//named queries must always be prepared
if(this.name) { return true; }
//always prepare if there are max number of rows expected per
//portal execution
if(this.rows) { return true; }
//don't prepare empty text queries
if(!this.text) { return false; }
//prepare if there are values
if(!this.values) { return false; }
return this.values.length > 0;
};
Query.prototype.requiresPreparation = function () {
// named queries must always be prepared
if (this.name) { return true }
// always prepare if there are max number of rows expected per
// portal execution
if (this.rows) { return true }
// don't prepare empty text queries
if (!this.text) { return false }
// prepare if there are values
if (!this.values) { return false }
return this.values.length > 0
}
//associates row metadata from the supplied
//message with this query object
//metadata used when parsing row results
Query.prototype.handleRowDescription = function(msg) {
this._result.addFields(msg.fields);
this._accumulateRows = this.callback || !this.listeners('row').length;
};
// associates row metadata from the supplied
// message with this query object
// metadata used when parsing row results
Query.prototype.handleRowDescription = function (msg) {
this._result.addFields(msg.fields)
this._accumulateRows = this.callback || !this.listeners('row').length
}
Query.prototype.handleDataRow = function(msg) {
var row;
Query.prototype.handleDataRow = function (msg) {
var row
if (this._canceledDueToError) {
return;
return
}
try {
row = this._result.parseRow(msg.fields);
row = this._result.parseRow(msg.fields)
} catch (err) {
this._canceledDueToError = err;
return;
this._canceledDueToError = err
return
}
this.emit('row', row, this._result);
this.emit('row', row, this._result)
if (this._accumulateRows) {
this._result.addRow(row);
this._result.addRow(row)
}
};
}
Query.prototype.handleCommandComplete = function(msg, con) {
this._result.addCommandComplete(msg);
//need to sync after each command complete of a prepared statement
if(this.isPreparedStatement) {
con.sync();
}
};
//if a named prepared statement is created with empty query text
//the backend will send an emptyQuery message but *not* a command complete message
//execution on the connection will hang until the backend receives a sync message
Query.prototype.handleEmptyQuery = function(con) {
Query.prototype.handleCommandComplete = function (msg, con) {
this._result.addCommandComplete(msg)
// need to sync after each command complete of a prepared statement
if (this.isPreparedStatement) {
con.sync();
con.sync()
}
};
}
Query.prototype.handleReadyForQuery = function(con) {
if(this._canceledDueToError) {
return this.handleError(this._canceledDueToError, con);
// if a named prepared statement is created with empty query text
// the backend will send an emptyQuery message but *not* a command complete message
// execution on the connection will hang until the backend receives a sync message
Query.prototype.handleEmptyQuery = function (con) {
if (this.isPreparedStatement) {
con.sync()
}
if(this.callback) {
this.callback(null, this._result);
}
this.emit('end', this._result);
};
}
Query.prototype.handleError = function(err, connection) {
//need to sync after error during a prepared statement
if(this.isPreparedStatement) {
connection.sync();
Query.prototype.handleReadyForQuery = function (con) {
if (this._canceledDueToError) {
return this.handleError(this._canceledDueToError, con)
}
if(this._canceledDueToError) {
err = this._canceledDueToError;
this._canceledDueToError = false;
if (this.callback) {
this.callback(null, this._result)
}
//if callback supplied do not emit error event as uncaught error
//events will bubble up to node process
if(this.callback) {
return this.callback(err);
}
this.emit('error', err);
};
this.emit('end', this._result)
}
Query.prototype.submit = function(connection) {
if (typeof this.text != 'string' && typeof this.name != 'string') {
Query.prototype.handleError = function (err, connection) {
// need to sync after error during a prepared statement
if (this.isPreparedStatement) {
connection.sync()
}
if (this._canceledDueToError) {
err = this._canceledDueToError
this._canceledDueToError = false
}
// if callback supplied do not emit error event as uncaught error
// events will bubble up to node process
if (this.callback) {
return this.callback(err)
}
this.emit('error', err)
}
Query.prototype.submit = function (connection) {
if (typeof this.text !== 'string' && typeof this.name !== 'string') {
const err = new Error('A query must have either text or a name. Supplying neither is unsupported.')
connection.emit('error', err)
connection.emit('readyForQuery')
@ -139,75 +139,75 @@ Query.prototype.submit = function(connection) {
connection.emit('readyForQuery')
return
}
if(this.requiresPreparation()) {
this.prepare(connection);
if (this.requiresPreparation()) {
this.prepare(connection)
} else {
connection.query(this.text);
connection.query(this.text)
}
};
}
Query.prototype.hasBeenParsed = function(connection) {
return this.name && connection.parsedStatements[this.name];
};
Query.prototype.hasBeenParsed = function (connection) {
return this.name && connection.parsedStatements[this.name]
}
Query.prototype.handlePortalSuspended = function(connection) {
this._getRows(connection, this.rows);
};
Query.prototype.handlePortalSuspended = function (connection) {
this._getRows(connection, this.rows)
}
Query.prototype._getRows = function(connection, rows) {
Query.prototype._getRows = function (connection, rows) {
connection.execute({
portal: this.portalName,
rows: rows
}, true);
connection.flush();
};
}, true)
connection.flush()
}
Query.prototype.prepare = function(connection) {
var self = this;
//prepared statements need sync to be called after each command
//complete or when an error is encountered
this.isPreparedStatement = true;
//TODO refactor this poor encapsulation
if(!this.hasBeenParsed(connection)) {
Query.prototype.prepare = function (connection) {
var self = this
// prepared statements need sync to be called after each command
// complete or when an error is encountered
this.isPreparedStatement = true
// TODO refactor this poor encapsulation
if (!this.hasBeenParsed(connection)) {
connection.parse({
text: self.text,
name: self.name,
types: self.types
}, true);
}, true)
}
if(self.values) {
self.values = self.values.map(utils.prepareValue);
if (self.values) {
self.values = self.values.map(utils.prepareValue)
}
//http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
connection.bind({
portal: self.portalName,
statement: self.name,
values: self.values,
binary: self.binary
}, true);
}, true)
connection.describe({
type: 'P',
name: self.portalName || ""
}, true);
name: self.portalName || ''
}, true)
this._getRows(connection, this.rows);
};
this._getRows(connection, this.rows)
}
Query.prototype.handleCopyInResponse = function (connection) {
if(this.stream) this.stream.startStreamingToConnection(connection);
else connection.sendCopyFail('No source stream defined');
};
if (this.stream) this.stream.startStreamingToConnection(connection)
else connection.sendCopyFail('No source stream defined')
}
Query.prototype.handleCopyData = function (msg, connection) {
var chunk = msg.chunk;
if(this.stream) {
this.stream.handleChunk(chunk);
var chunk = msg.chunk
if (this.stream) {
this.stream.handleChunk(chunk)
}
//if there are no stream (for example when copy to query was sent by
//query method instead of copyTo) error will be handled
//on copyOutResponse event, so silently ignore this error here
};
module.exports = Query;
// if there are no stream (for example when copy to query was sent by
// query method instead of copyTo) error will be handled
// on copyOutResponse event, so silently ignore this error here
}
module.exports = Query

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,110 +7,110 @@
* README.md file in the root directory of this source tree.
*/
var types = require('pg-types');
var types = require('pg-types')
//result object returned from query
//in the 'end' event and also
//passed as second argument to provided callback
var Result = function(rowMode) {
this.command = null;
this.rowCount = null;
this.oid = null;
this.rows = [];
this.fields = [];
this._parsers = [];
this.RowCtor = null;
this.rowAsArray = rowMode == "array";
if(this.rowAsArray) {
this.parseRow = this._parseRowAsArray;
// result object returned from query
// in the 'end' event and also
// passed as second argument to provided callback
var Result = function (rowMode) {
this.command = null
this.rowCount = null
this.oid = null
this.rows = []
this.fields = []
this._parsers = []
this.RowCtor = null
this.rowAsArray = rowMode === 'array'
if (this.rowAsArray) {
this.parseRow = this._parseRowAsArray
}
};
}
var matchRegexp = /([A-Za-z]+) ?(\d+ )?(\d+)?/;
var matchRegexp = /([A-Za-z]+) ?(\d+ )?(\d+)?/
//adds a command complete message
Result.prototype.addCommandComplete = function(msg) {
var match;
if(msg.text) {
//pure javascript
match = matchRegexp.exec(msg.text);
// adds a command complete message
Result.prototype.addCommandComplete = function (msg) {
var match
if (msg.text) {
// pure javascript
match = matchRegexp.exec(msg.text)
} else {
//native bindings
match = matchRegexp.exec(msg.command);
// native bindings
match = matchRegexp.exec(msg.command)
}
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);
this.oid = parseInt(match[2], 10);
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)
this.oid = parseInt(match[2], 10)
} else {
this.rowCount = parseInt(match[2], 10);
this.rowCount = parseInt(match[2], 10)
}
}
};
}
Result.prototype._parseRowAsArray = function(rowData) {
var row = [];
for(var i = 0, len = rowData.length; i < len; i++) {
var rawValue = rowData[i];
if(rawValue !== null) {
row.push(this._parsers[i](rawValue));
Result.prototype._parseRowAsArray = function (rowData) {
var row = []
for (var i = 0, len = rowData.length; i < len; i++) {
var rawValue = rowData[i]
if (rawValue !== null) {
row.push(this._parsers[i](rawValue))
} else {
row.push(null);
row.push(null)
}
}
return row;
};
return row
}
//rowData is an array of text or binary values
//this turns the row into a JavaScript object
Result.prototype.parseRow = function(rowData) {
return new this.RowCtor(this._parsers, rowData);
};
// rowData is an array of text or binary values
// this turns the row into a JavaScript object
Result.prototype.parseRow = function (rowData) {
return new this.RowCtor(this._parsers, rowData)
}
Result.prototype.addRow = function(row) {
this.rows.push(row);
};
Result.prototype.addRow = function (row) {
this.rows.push(row)
}
var inlineParser = function(fieldName, i) {
var inlineParser = function (fieldName, i) {
return "\nthis['" +
//fields containing single quotes will break
//the evaluated javascript unless they are escaped
//see https://github.com/brianc/node-postgres/issues/507
//Addendum: However, we need to make sure to replace all
//occurences of apostrophes, not just the first one.
//See https://github.com/brianc/node-postgres/issues/934
// fields containing single quotes will break
// the evaluated javascript unless they are escaped
// see https://github.com/brianc/node-postgres/issues/507
// Addendum: However, we need to make sure to replace all
// occurences of apostrophes, not just the first one.
// See https://github.com/brianc/node-postgres/issues/934
fieldName.replace(/'/g, "\\'") +
"'] = " +
"rowData[" + i + "] == null ? null : parsers[" + i + "](rowData[" + i + "]);";
};
'rowData[' + i + '] == null ? null : parsers[' + i + '](rowData[' + i + ']);'
}
Result.prototype.addFields = function(fieldDescriptions) {
//clears field definitions
//multiple query statements in 1 action can result in multiple sets
//of rowDescriptions...eg: 'select NOW(); select 1::int;'
//you need to reset the fields
if(this.fields.length) {
this.fields = [];
this._parsers = [];
Result.prototype.addFields = function (fieldDescriptions) {
// clears field definitions
// multiple query statements in 1 action can result in multiple sets
// of rowDescriptions...eg: 'select NOW(); select 1::int;'
// you need to reset the fields
if (this.fields.length) {
this.fields = []
this._parsers = []
}
var ctorBody = "";
for(var i = 0; i < fieldDescriptions.length; i++) {
var desc = fieldDescriptions[i];
this.fields.push(desc);
var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text');
this._parsers.push(parser);
//this is some craziness to compile the row result parsing
//results in ~60% speedup on large query result sets
ctorBody += inlineParser(desc.name, i);
var ctorBody = ''
for (var i = 0; i < fieldDescriptions.length; i++) {
var desc = fieldDescriptions[i]
this.fields.push(desc)
var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text')
this._parsers.push(parser)
// this is some craziness to compile the row result parsing
// results in ~60% speedup on large query result sets
ctorBody += inlineParser(desc.name, i)
}
if(!this.rowAsArray) {
this.RowCtor = Function("parsers", "rowData", ctorBody);
if (!this.rowAsArray) {
this.RowCtor = Function('parsers', 'rowData', ctorBody)
}
};
}
Result.prototype._getTypeParser = types.getTypeParser;
Result.prototype._getTypeParser = types.getTypeParser
module.exports = Result;
module.exports = Result

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,33 +7,33 @@
* README.md file in the root directory of this source tree.
*/
var types = require('pg-types');
var types = require('pg-types')
function TypeOverrides(userTypes) {
this._types = userTypes || types;
this.text = {};
this.binary = {};
function TypeOverrides (userTypes) {
this._types = userTypes || types
this.text = {}
this.binary = {}
}
TypeOverrides.prototype.getOverrides = function(format) {
switch(format) {
case 'text': return this.text;
case 'binary': return this.binary;
default: return {};
TypeOverrides.prototype.getOverrides = function (format) {
switch (format) {
case 'text': return this.text
case 'binary': return this.binary
default: return {}
}
};
}
TypeOverrides.prototype.setTypeParser = function(oid, format, parseFn) {
if(typeof format == 'function') {
parseFn = format;
format = 'text';
TypeOverrides.prototype.setTypeParser = function (oid, format, parseFn) {
if (typeof format === 'function') {
parseFn = format
format = 'text'
}
this.getOverrides(format)[oid] = parseFn;
};
this.getOverrides(format)[oid] = parseFn
}
TypeOverrides.prototype.getTypeParser = function(oid, format) {
format = format || 'text';
return this.getOverrides(format)[oid] || this._types.getTypeParser(oid, format);
};
TypeOverrides.prototype.getTypeParser = function (oid, format) {
format = format || 'text'
return this.getOverrides(format)[oid] || this._types.getTypeParser(oid, format)
}
module.exports = TypeOverrides;
module.exports = TypeOverrides

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
/**
* Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com)
* All rights reserved.
@ -7,151 +7,141 @@
* README.md file in the root directory of this source tree.
*/
const util = require('util')
const crypto = require('crypto');
const crypto = require('crypto')
const defaults = require('./defaults');
const defaults = require('./defaults')
function escapeElement(elementRepresentation) {
function escapeElement (elementRepresentation) {
var escaped = elementRepresentation
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"');
.replace(/"/g, '\\"')
return '"' + escaped + '"';
return '"' + escaped + '"'
}
// convert a JS array to a postgres array literal
// uses comma separator so won't work for types like box that use
// a different array separator.
function arrayString(val) {
var result = '{';
for (var i = 0 ; i < val.length; i++) {
if(i > 0) {
result = result + ',';
function arrayString (val) {
var result = '{'
for (var i = 0; i < val.length; i++) {
if (i > 0) {
result = result + ','
}
if(val[i] === null || typeof val[i] === 'undefined') {
result = result + 'NULL';
}
else if(Array.isArray(val[i])) {
result = result + arrayString(val[i]);
}
else
{
result += escapeElement(prepareValue(val[i]));
}
}
result = result + '}';
return result;
}
//converts values from javascript types
//to their 'raw' counterparts for use as a postgres parameter
//note: you can override this function to provide your own conversion mechanism
//for complex types, etc...
var prepareValue = function(val, seen) {
if (val instanceof Buffer) {
return val;
}
if(val instanceof Date) {
if(defaults.parseInputDatesAsUTC) {
return dateToStringUTC(val);
if (val[i] === null || typeof val[i] === 'undefined') {
result = result + 'NULL'
} else if (Array.isArray(val[i])) {
result = result + arrayString(val[i])
} else {
return dateToString(val);
result += escapeElement(prepareValue(val[i]))
}
}
if(Array.isArray(val)) {
return arrayString(val);
}
if(val === null || typeof val === 'undefined') {
return null;
}
if(typeof val === 'object') {
return prepareObject(val, seen);
}
return val.toString();
};
result = result + '}'
return result
}
function prepareObject(val, seen) {
if(val.toPostgres && typeof val.toPostgres === 'function') {
seen = seen || [];
// converts values from javascript types
// to their 'raw' counterparts for use as a postgres parameter
// note: you can override this function to provide your own conversion mechanism
// for complex types, etc...
var prepareValue = function (val, seen) {
if (val instanceof Buffer) {
return val
}
if (val instanceof Date) {
if (defaults.parseInputDatesAsUTC) {
return dateToStringUTC(val)
} else {
return dateToString(val)
}
}
if (Array.isArray(val)) {
return arrayString(val)
}
if (val === null || typeof val === 'undefined') {
return null
}
if (typeof val === 'object') {
return prepareObject(val, seen)
}
return val.toString()
}
function prepareObject (val, seen) {
if (val.toPostgres && typeof val.toPostgres === 'function') {
seen = seen || []
if (seen.indexOf(val) !== -1) {
throw new Error('circular reference detected while preparing "' + val + '" for query');
throw new Error('circular reference detected while preparing "' + val + '" for query')
}
seen.push(val);
seen.push(val)
return prepareValue(val.toPostgres(prepareValue), seen);
return prepareValue(val.toPostgres(prepareValue), seen)
}
return JSON.stringify(val);
return JSON.stringify(val)
}
function pad(number, digits) {
number = "" +number;
while(number.length < digits)
number = "0" + number;
return number;
function pad (number, digits) {
number = '' + number
while (number.length < digits) { number = '0' + number }
return number
}
function dateToString(date) {
var offset = -date.getTimezoneOffset();
function dateToString (date) {
var offset = -date.getTimezoneOffset()
var ret = pad(date.getFullYear(), 4) + '-' +
pad(date.getMonth() + 1, 2) + '-' +
pad(date.getDate(), 2) + 'T' +
pad(date.getHours(), 2) + ':' +
pad(date.getMinutes(), 2) + ':' +
pad(date.getSeconds(), 2) + '.' +
pad(date.getMilliseconds(), 3);
pad(date.getMilliseconds(), 3)
if(offset < 0) {
ret += "-";
offset *= -1;
}
else
ret += "+";
if (offset < 0) {
ret += '-'
offset *= -1
} else { ret += '+' }
return ret + pad(Math.floor(offset/60), 2) + ":" + pad(offset%60, 2);
return ret + pad(Math.floor(offset / 60), 2) + ':' + pad(offset % 60, 2)
}
function dateToStringUTC(date) {
function dateToStringUTC (date) {
var ret = pad(date.getUTCFullYear(), 4) + '-' +
pad(date.getUTCMonth() + 1, 2) + '-' +
pad(date.getUTCDate(), 2) + 'T' +
pad(date.getUTCHours(), 2) + ':' +
pad(date.getUTCMinutes(), 2) + ':' +
pad(date.getUTCSeconds(), 2) + '.' +
pad(date.getUTCMilliseconds(), 3);
pad(date.getUTCMilliseconds(), 3)
return ret + "+00:00";
return ret + '+00:00'
}
function normalizeQueryConfig (config, values, callback) {
//can take in strings or config objects
config = (typeof(config) == 'string') ? { text: config } : config;
if(values) {
if(typeof values === 'function') {
config.callback = values;
// can take in strings or config objects
config = (typeof (config) === 'string') ? { text: config } : config
if (values) {
if (typeof values === 'function') {
config.callback = values
} else {
config.values = values;
config.values = values
}
}
if(callback) {
config.callback = callback;
if (callback) {
config.callback = callback
}
return config;
return config
}
const md5 = function (string) {
return crypto.createHash('md5').update(string, 'utf-8').digest('hex');
};
return crypto.createHash('md5').update(string, 'utf-8').digest('hex')
}
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);
// 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,
};
md5: md5
}

View File

@ -29,13 +29,17 @@
"devDependencies": {
"async": "0.9.0",
"co": "4.6.0",
"jshint": "2.5.2",
"eslint": "4.2.0",
"eslint-config-standard": "10.2.1",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-node": "5.1.0",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "3.0.1",
"pg-copy-streams": "0.3.0"
},
"minNativeVersion": "1.7.0",
"scripts": {
"changelog": "npm i github-changes && ./node_modules/.bin/github-changes -o brianc -r node-postgres -d pulls -a -v",
"test": "make test-all connectionString=postgres://postgres@localhost:5432/postgres"
"test": "make test-all"
},
"license": "MIT",
"engines": {

View File

@ -1,33 +1,33 @@
"use strict";
var args = require(__dirname + '/../test/cli');
var pg = require(__dirname + '/../lib');
'use strict'
var args = require(__dirname + '/../test/cli')
var pg = require(__dirname + '/../lib')
var people = [
{name: 'Aaron', age: 10},
{name: 'Brian', age: 20},
{name: 'Chris', age: 30},
{name: 'David', age: 40},
{name: 'Elvis', age: 50},
{name: 'Frank', age: 60},
{name: 'Grace', age: 70},
{name: 'Haley', age: 80},
{name: 'Irma', age: 90},
{name: 'Jenny', age: 100},
{name: 'Kevin', age: 110},
{name: 'Larry', age: 120},
{name: 'Aaron', age: 10},
{name: 'Brian', age: 20},
{name: 'Chris', age: 30},
{name: 'David', age: 40},
{name: 'Elvis', age: 50},
{name: 'Frank', age: 60},
{name: 'Grace', age: 70},
{name: 'Haley', age: 80},
{name: 'Irma', age: 90},
{name: 'Jenny', age: 100},
{name: 'Kevin', age: 110},
{name: 'Larry', age: 120},
{name: 'Michelle', age: 130},
{name: 'Nancy', age: 140},
{name: 'Olivia', age: 150},
{name: 'Peter', age: 160},
{name: 'Quinn', age: 170},
{name: 'Ronda', age: 180},
{name: 'Shelley', age: 190},
{name: 'Tobias', age: 200},
{name: 'Uma', age: 210},
{name: 'Veena', age: 220},
{name: 'Wanda', age: 230},
{name: 'Xavier', age: 240},
{name: 'Yoyo', age: 250},
{name: 'Nancy', age: 140},
{name: 'Olivia', age: 150},
{name: 'Peter', age: 160},
{name: 'Quinn', age: 170},
{name: 'Ronda', age: 180},
{name: 'Shelley', age: 190},
{name: 'Tobias', age: 200},
{name: 'Uma', age: 210},
{name: 'Veena', age: 220},
{name: 'Wanda', age: 230},
{name: 'Xavier', age: 240},
{name: 'Yoyo', age: 250},
{name: 'Zanzabar', age: 260}
]
@ -37,16 +37,16 @@ var con = new pg.Client({
user: args.user,
password: args.password,
database: args.database
});
con.connect();
var query = con.query("drop table if exists person");
con.query("create table person(id serial, name varchar(10), age integer)", (err, res) => {
console.log("Created table person");
console.log("Filling it with people");
})
people.map(function(person) {
return con.query(new pg.Query("insert into person(name, age) values('"+person.name + "', '" + person.age + "')"));
}).pop().on('end', function(){
console.log("Inserted 26 people");
con.end();
});
con.connect()
var query = con.query('drop table if exists person')
con.query('create table person(id serial, name varchar(10), age integer)', (err, res) => {
console.log('Created table person')
console.log('Filling it with people')
})
people.map(function (person) {
return con.query(new pg.Query("insert into person(name, age) values('" + person.name + "', '" + person.age + "')"))
}).pop().on('end', function () {
console.log('Inserted 26 people')
con.end()
})

View File

@ -1,24 +1,23 @@
"use strict";
var pg = require(__dirname + '/../lib');
var args = require(__dirname + '/../test/cli');
'use strict'
var pg = require(__dirname + '/../lib')
var args = require(__dirname + '/../test/cli')
var queries = [
"select CURRENT_TIMESTAMP",
'select CURRENT_TIMESTAMP',
"select interval '1 day' + interval '1 hour'",
"select TIMESTAMP 'today'"];
queries.forEach(function(query) {
"select TIMESTAMP 'today'"]
queries.forEach(function (query) {
var client = new pg.Client({
user: args.user,
database: args.database,
password: args.password
});
client.connect();
})
client.connect()
client
.query(query)
.on('row', function(row) {
console.log(row);
client.end();
});
});
.on('row', function (row) {
console.log(row)
client.end()
})
})

View File

@ -1,7 +1,7 @@
"use strict";
var helper = require(__dirname + "/../test/integration/test-helper");
var pg = helper.pg;
pg.connect(helper.config, assert.success(function(client) {
var query = client.query('select oid, typname from pg_type where typtype = \'b\' order by oid');
query.on('row', console.log);
'use strict'
var helper = require(__dirname + '/../test/integration/test-helper')
var pg = helper.pg
pg.connect(helper.config, assert.success(function (client) {
var query = client.query('select oid, typname from pg_type where typtype = \'b\' order by oid')
query.on('row', console.log)
}))

View File

@ -1,70 +1,70 @@
"use strict";
global.BufferList = function() {
this.buffers = [];
};
var p = BufferList.prototype;
'use strict'
global.BufferList = function () {
this.buffers = []
}
var p = BufferList.prototype
p.add = function(buffer, front) {
this.buffers[front ? "unshift" : "push"](buffer);
return this;
};
p.add = function (buffer, front) {
this.buffers[front ? 'unshift' : 'push'](buffer)
return this
}
p.addInt16 = function(val, front) {
return this.add(Buffer.from([(val >>> 8),(val >>> 0)]),front);
};
p.addInt16 = function (val, front) {
return this.add(Buffer.from([(val >>> 8), (val >>> 0)]), front)
}
p.getByteLength = function(initial) {
return this.buffers.reduce(function(previous, current){
return previous + current.length;
},initial || 0);
};
p.getByteLength = function (initial) {
return this.buffers.reduce(function (previous, current) {
return previous + current.length
}, initial || 0)
}
p.addInt32 = function(val, first) {
p.addInt32 = function (val, first) {
return this.add(Buffer.from([
(val >>> 24 & 0xFF),
(val >>> 16 & 0xFF),
(val >>> 8 & 0xFF),
(val >>> 0 & 0xFF)
]),first);
};
]), first)
}
p.addCString = function(val, front) {
var len = Buffer.byteLength(val);
var buffer = Buffer.alloc(len+1);
buffer.write(val);
buffer[len] = 0;
return this.add(buffer, front);
};
p.addCString = function (val, front) {
var len = Buffer.byteLength(val)
var buffer = Buffer.alloc(len + 1)
buffer.write(val)
buffer[len] = 0
return this.add(buffer, front)
}
p.addChar = function(char, first) {
return this.add(Buffer.from(char,'utf8'), first);
};
p.addChar = function (char, first) {
return this.add(Buffer.from(char, 'utf8'), first)
}
p.join = function(appendLength, char) {
var length = this.getByteLength();
if(appendLength) {
this.addInt32(length+4, true);
return this.join(false, char);
p.join = function (appendLength, char) {
var length = this.getByteLength()
if (appendLength) {
this.addInt32(length + 4, true)
return this.join(false, char)
}
if(char) {
this.addChar(char, true);
length++;
if (char) {
this.addChar(char, true)
length++
}
var result = Buffer.alloc(length);
var index = 0;
this.buffers.forEach(function(buffer) {
buffer.copy(result, index, 0);
index += buffer.length;
});
return result;
};
var result = Buffer.alloc(length)
var index = 0
this.buffers.forEach(function (buffer) {
buffer.copy(result, index, 0)
index += buffer.length
})
return result
}
BufferList.concat = function() {
var total = new BufferList();
for(var i = 0; i < arguments.length; i++) {
total.add(arguments[i]);
BufferList.concat = function () {
var total = new BufferList()
for (var i = 0; i < arguments.length; i++) {
total.add(arguments[i])
}
return total.join();
};
return total.join()
}
module.exports = BufferList;
module.exports = BufferList

View File

@ -1,25 +1,25 @@
"use strict";
var ConnectionParameters = require(__dirname + '/../lib/connection-parameters');
var config = new ConnectionParameters(process.argv[2]);
'use strict'
var ConnectionParameters = require(__dirname + '/../lib/connection-parameters')
var config = new ConnectionParameters(process.argv[2])
for(var i = 0; i < process.argv.length; i++) {
switch(process.argv[i].toLowerCase()) {
case 'native':
config.native = true;
break;
case 'binary':
config.binary = true;
break;
case 'down':
config.down = true;
break;
default:
break;
for (var i = 0; i < process.argv.length; i++) {
switch (process.argv[i].toLowerCase()) {
case 'native':
config.native = true
break
case 'binary':
config.binary = true
break
case 'down':
config.down = true
break
default:
break
}
}
if(process.env['PG_TEST_NATIVE']) {
config.native = true;
if (process.env['PG_TEST_NATIVE']) {
config.native = true
}
module.exports = config;
module.exports = config

View File

@ -1,208 +1,208 @@
"use strict";
var helper = require(__dirname + "/../test-helper");
var pg = helper.pg;
'use strict'
var helper = require(__dirname + '/../test-helper')
var pg = helper.pg
var suite = new helper.Suite();
var suite = new helper.Suite()
suite.test("pool callback behavior", done => {
//test weird callback behavior with node-pool
const pool = new pg.Pool();
pool.connect(function(err) {
assert(!err);
arguments[1].emit("drain");
arguments[2]();
pool.end(done);
});
});
suite.test('pool callback behavior', done => {
// test weird callback behavior with node-pool
const pool = new pg.Pool()
pool.connect(function (err) {
assert(!err)
arguments[1].emit('drain')
arguments[2]()
pool.end(done)
})
})
suite.test("callback API", done => {
const client = new helper.Client();
client.query("CREATE TEMP TABLE peep(name text)");
client.query("INSERT INTO peep(name) VALUES ($1)", ["brianc"]);
suite.test('callback API', done => {
const client = new helper.Client()
client.query('CREATE TEMP TABLE peep(name text)')
client.query('INSERT INTO peep(name) VALUES ($1)', ['brianc'])
const config = {
text: "INSERT INTO peep(name) VALUES ($1)",
values: ["brian"]
};
client.query(config);
client.query("INSERT INTO peep(name) VALUES ($1)", ["aaron"]);
text: 'INSERT INTO peep(name) VALUES ($1)',
values: ['brian']
}
client.query(config)
client.query('INSERT INTO peep(name) VALUES ($1)', ['aaron'])
client.query("SELECT * FROM peep ORDER BY name", (err, res) => {
assert(!err);
assert.equal(res.rowCount, 3);
client.query('SELECT * FROM peep ORDER BY name', (err, res) => {
assert(!err)
assert.equal(res.rowCount, 3)
assert.deepEqual(res.rows, [
{
name: "aaron"
name: 'aaron'
},
{
name: "brian"
name: 'brian'
},
{
name: "brianc"
name: 'brianc'
}
]);
done();
});
])
done()
})
client.connect(err => {
assert(!err);
client.once("drain", () => client.end());
});
});
assert(!err)
client.once('drain', () => client.end())
})
})
suite.test("executing nested queries", function(done) {
const pool = new pg.Pool();
suite.test('executing nested queries', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
assert.calls(function (err, client, release) {
assert(!err)
client.query(
"select now as now from NOW()",
assert.calls(function(err, result) {
assert.equal(new Date().getYear(), result.rows[0].now.getYear());
'select now as now from NOW()',
assert.calls(function (err, result) {
assert.equal(new Date().getYear(), result.rows[0].now.getYear())
client.query(
"select now as now_again FROM NOW()",
assert.calls(function() {
'select now as now_again FROM NOW()',
assert.calls(function () {
client.query(
"select * FROM NOW()",
assert.calls(function() {
assert.ok("all queries hit");
release();
pool.end(done);
'select * FROM NOW()',
assert.calls(function () {
assert.ok('all queries hit')
release()
pool.end(done)
})
);
)
})
);
)
})
);
)
})
);
});
)
})
suite.test("raises error if cannot connect", function() {
var connectionString = "pg://sfalsdkf:asdf@localhost/ieieie";
const pool = new pg.Pool({ connectionString: connectionString });
suite.test('raises error if cannot connect', function () {
var connectionString = 'pg://sfalsdkf:asdf@localhost/ieieie'
const pool = new pg.Pool({ connectionString: connectionString })
pool.connect(
assert.calls(function(err, client, done) {
assert.ok(err, "should have raised an error");
done();
assert.calls(function (err, client, done) {
assert.ok(err, 'should have raised an error')
done()
})
);
});
)
})
suite.test("query errors are handled and do not bubble if callback is provded", function(done) {
const pool = new pg.Pool();
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
suite.test('query errors are handled and do not bubble if callback is provded', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function (err, client, release) {
assert(!err)
client.query(
"SELECT OISDJF FROM LEIWLISEJLSE",
assert.calls(function(err, result) {
assert.ok(err);
'SELECT OISDJF FROM LEIWLISEJLSE',
assert.calls(function (err, result) {
assert.ok(err)
release()
pool.end(done)
})
);
)
})
);
}
);
)
}
)
suite.test("callback is fired once and only once", function(done) {
suite.test('callback is fired once and only once', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
client.query("CREATE TEMP TABLE boom(name varchar(10))");
var callCount = 0;
assert.calls(function (err, client, release) {
assert(!err)
client.query('CREATE TEMP TABLE boom(name varchar(10))')
var callCount = 0
client.query(
[
"INSERT INTO boom(name) VALUES('hai')",
"INSERT INTO boom(name) VALUES('boom')",
"INSERT INTO boom(name) VALUES('zoom')"
].join(";"),
function(err, callback) {
].join(';'),
function (err, callback) {
assert.equal(
callCount++,
0,
"Call count should be 0. More means this callback fired more than once."
);
'Call count should be 0. More means this callback fired more than once.'
)
release()
pool.end(done)
}
);
)
})
);
});
)
})
suite.test("can provide callback and config object", function(done) {
suite.test('can provide callback and config object', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
assert.calls(function (err, client, release) {
assert(!err)
client.query(
{
name: "boom",
text: "select NOW()"
name: 'boom',
text: 'select NOW()'
},
assert.calls(function(err, result) {
assert(!err);
assert.equal(result.rows[0].now.getYear(), new Date().getYear());
release();
pool.end(done)
})
);
})
);
});
suite.test("can provide callback and config and parameters", function(done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
var config = {
text: "select $1::text as val"
};
client.query(
config,
["hi"],
assert.calls(function(err, result) {
assert(!err);
assert.equal(result.rows.length, 1);
assert.equal(result.rows[0].val, "hi");
assert.calls(function (err, result) {
assert(!err)
assert.equal(result.rows[0].now.getYear(), new Date().getYear())
release()
pool.end(done)
})
);
)
})
);
});
)
})
suite.test("null and undefined are both inserted as NULL", function(done) {
suite.test('can provide callback and config and parameters', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function(err, client, release) {
assert(!err);
assert.calls(function (err, client, release) {
assert(!err)
var config = {
text: 'select $1::text as val'
}
client.query(
"CREATE TEMP TABLE my_nulls(a varchar(1), b varchar(1), c integer, d integer, e date, f date)"
);
client.query(
"INSERT INTO my_nulls(a,b,c,d,e,f) VALUES ($1,$2,$3,$4,$5,$6)",
[null, undefined, null, undefined, null, undefined]
);
client.query(
"SELECT * FROM my_nulls",
assert.calls(function(err, result) {
assert(!err);
assert.equal(result.rows.length, 1);
assert.isNull(result.rows[0].a);
assert.isNull(result.rows[0].b);
assert.isNull(result.rows[0].c);
assert.isNull(result.rows[0].d);
assert.isNull(result.rows[0].e);
assert.isNull(result.rows[0].f);
config,
['hi'],
assert.calls(function (err, result) {
assert(!err)
assert.equal(result.rows.length, 1)
assert.equal(result.rows[0].val, 'hi')
release()
pool.end(done)
release();
})
);
)
})
);
});
)
})
suite.test('null and undefined are both inserted as NULL', function (done) {
const pool = new pg.Pool()
pool.connect(
assert.calls(function (err, client, release) {
assert(!err)
client.query(
'CREATE TEMP TABLE my_nulls(a varchar(1), b varchar(1), c integer, d integer, e date, f date)'
)
client.query(
'INSERT INTO my_nulls(a,b,c,d,e,f) VALUES ($1,$2,$3,$4,$5,$6)',
[null, undefined, null, undefined, null, undefined]
)
client.query(
'SELECT * FROM my_nulls',
assert.calls(function (err, result) {
assert(!err)
assert.equal(result.rows.length, 1)
assert.isNull(result.rows[0].a)
assert.isNull(result.rows[0].b)
assert.isNull(result.rows[0].c)
assert.isNull(result.rows[0].d)
assert.isNull(result.rows[0].e)
assert.isNull(result.rows[0].f)
pool.end(done)
release()
})
)
})
)
})

View File

@ -1,101 +1,99 @@
"use strict";
var helper = require('./test-helper');
var Client = helper.Client;
'use strict'
var helper = require('./test-helper')
var Client = helper.Client
var suite = new helper.Suite();
var suite = new helper.Suite()
var conInfo = helper.config;
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;
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
}
function getAppName(conf, cb) {
var client = new Client(conf);
client.connect(assert.success(function(){
client.query('SHOW application_name', assert.success(function(res){
var appName = res.rows[0].application_name;
cb(appName);
client.end();
}));
}));
function getAppName (conf, cb) {
var client = new Client(conf)
client.connect(assert.success(function () {
client.query('SHOW application_name', assert.success(function (res) {
var appName = res.rows[0].application_name
cb(appName)
client.end()
}))
}))
}
suite.test('No default appliation_name ', function(done) {
var conf = getConInfo();
getAppName({ }, function(res){
assert.strictEqual(res, '');
suite.test('No default appliation_name ', function (done) {
var conf = getConInfo()
getAppName({ }, function (res) {
assert.strictEqual(res, '')
done()
});
});
})
})
suite.test('fallback_application_name is used', function(done) {
var fbAppName = 'this is my app';
suite.test('fallback_application_name is used', function (done) {
var fbAppName = 'this is my app'
var conf = getConInfo({
'fallback_application_name' : fbAppName
});
getAppName(conf, function(res){
assert.strictEqual(res, fbAppName);
'fallback_application_name': fbAppName
})
getAppName(conf, function (res) {
assert.strictEqual(res, fbAppName)
done()
});
});
})
})
suite.test('application_name is used', function(done) {
var appName = 'some wired !@#$% application_name';
suite.test('application_name is used', function (done) {
var appName = 'some wired !@#$% application_name'
var conf = getConInfo({
'application_name' : appName
});
getAppName(conf, function(res){
assert.strictEqual(res, appName);
'application_name': appName
})
getAppName(conf, function (res) {
assert.strictEqual(res, appName)
done()
});
});
})
})
suite.test('application_name has precedence over fallback_application_name', function(done) {
var appName = 'some wired !@#$% application_name';
var fbAppName = 'some other strange $$test$$ appname';
suite.test('application_name has precedence over fallback_application_name', function (done) {
var appName = 'some wired !@#$% application_name'
var fbAppName = 'some other strange $$test$$ appname'
var conf = getConInfo({
'application_name' : appName ,
'fallback_application_name' : fbAppName
});
getAppName(conf, function(res){
assert.strictEqual(res, appName);
'application_name': appName,
'fallback_application_name': fbAppName
})
getAppName(conf, function (res) {
assert.strictEqual(res, appName)
done()
});
});
})
})
suite.test('application_name from connection string', function(done) {
var appName = 'my app';
var conParams = require(__dirname + '/../../../lib/connection-parameters');
var conf;
suite.test('application_name from connection string', function (done) {
var appName = 'my app'
var conParams = require(__dirname + '/../../../lib/connection-parameters')
var conf
if (process.argv[2]) {
conf = new conParams(process.argv[2]+'?application_name='+appName);
conf = new conParams(process.argv[2] + '?application_name=' + appName)
} else {
conf = 'postgres://?application_name='+appName;
conf = 'postgres://?application_name=' + appName
}
getAppName(conf, function(res){
assert.strictEqual(res, appName);
getAppName(conf, function (res) {
assert.strictEqual(res, appName)
done()
});
});
})
})
// TODO: make the test work for native client too
if (!helper.args.native) {
suite.test('application_name is read from the env', function(done) {
var appName = process.env.PGAPPNAME = 'testest';
getAppName({ }, function(res){
delete process.env.PGAPPNAME;
assert.strictEqual(res, appName);
suite.test('application_name is read from the env', function (done) {
var appName = process.env.PGAPPNAME = 'testest'
getAppName({ }, function (res) {
delete process.env.PGAPPNAME
assert.strictEqual(res, appName)
done()
});
});
})
})
}

View File

@ -1,177 +1,177 @@
"use strict";
var helper = require(__dirname + "/test-helper");
var pg = helper.pg;
'use strict'
var helper = require(__dirname + '/test-helper')
var pg = helper.pg
var suite = new helper.Suite()
const pool = new pg.Pool()
pool.connect(assert.calls(function(err, client, release) {
assert(!err);
pool.connect(assert.calls(function (err, client, release) {
assert(!err)
suite.test('nulls', function(done) {
client.query('SELECT $1::text[] as array', [[null]], assert.success(function(result) {
var array = result.rows[0].array;
assert.lengthIs(array, 1);
assert.isNull(array[0]);
suite.test('nulls', function (done) {
client.query('SELECT $1::text[] as array', [[null]], assert.success(function (result) {
var array = result.rows[0].array
assert.lengthIs(array, 1)
assert.isNull(array[0])
done()
}));
});
}))
})
suite.test('elements containing JSON-escaped characters', function(done) {
var param = '\\"\\"';
suite.test('elements containing JSON-escaped characters', function (done) {
var param = '\\"\\"'
for (var i = 1; i <= 0x1f; i++) {
param += String.fromCharCode(i);
param += String.fromCharCode(i)
}
client.query('SELECT $1::text[] as array', [[param]], assert.success(function(result) {
var array = result.rows[0].array;
assert.lengthIs(array, 1);
assert.equal(array[0], param);
client.query('SELECT $1::text[] as array', [[param]], assert.success(function (result) {
var array = result.rows[0].array
assert.lengthIs(array, 1)
assert.equal(array[0], param)
done()
}));
});
}))
})
suite.test('cleanup', () => release())
pool.connect(assert.calls(function (err, client, release) {
assert(!err);
client.query("CREATE TEMP TABLE why(names text[], numbors integer[])");
client.query(new pg.Query('INSERT INTO why(names, numbors) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\')')).on('error', console.log);
assert(!err)
client.query('CREATE TEMP TABLE why(names text[], numbors integer[])')
client.query(new pg.Query('INSERT INTO why(names, numbors) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\')')).on('error', console.log)
suite.test('numbers', function (done) {
// client.connection.on('message', console.log)
client.query('SELECT numbors FROM why', assert.success(function (result) {
assert.lengthIs(result.rows[0].numbors, 3);
assert.equal(result.rows[0].numbors[0], 1);
assert.equal(result.rows[0].numbors[1], 2);
assert.equal(result.rows[0].numbors[2], 3);
assert.lengthIs(result.rows[0].numbors, 3)
assert.equal(result.rows[0].numbors[0], 1)
assert.equal(result.rows[0].numbors[1], 2)
assert.equal(result.rows[0].numbors[2], 3)
done()
}))
})
suite.test('parses string arrays', function (done) {
client.query('SELECT names FROM why', assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 3);
assert.equal(names[0], 'aaron');
assert.equal(names[1], 'brian');
assert.equal(names[2], "a b c");
var names = result.rows[0].names
assert.lengthIs(names, 3)
assert.equal(names[0], 'aaron')
assert.equal(names[1], 'brian')
assert.equal(names[2], 'a b c')
done()
}))
})
suite.test('empty array', function (done) {
client.query("SELECT '{}'::text[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 0);
var names = result.rows[0].names
assert.lengthIs(names, 0)
done()
}))
})
suite.test('element containing comma', function (done) {
client.query("SELECT '{\"joe,bob\",jim}'::text[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 2);
assert.equal(names[0], 'joe,bob');
assert.equal(names[1], 'jim');
var names = result.rows[0].names
assert.lengthIs(names, 2)
assert.equal(names[0], 'joe,bob')
assert.equal(names[1], 'jim')
done()
}))
})
suite.test('bracket in quotes', function (done) {
client.query("SELECT '{\"{\",\"}\"}'::text[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 2);
assert.equal(names[0], '{');
assert.equal(names[1], '}');
var names = result.rows[0].names
assert.lengthIs(names, 2)
assert.equal(names[0], '{')
assert.equal(names[1], '}')
done()
}))
})
suite.test('null value', function (done) {
client.query("SELECT '{joe,null,bob,\"NULL\"}'::text[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 4);
assert.equal(names[0], 'joe');
assert.equal(names[1], null);
assert.equal(names[2], 'bob');
assert.equal(names[3], 'NULL');
var names = result.rows[0].names
assert.lengthIs(names, 4)
assert.equal(names[0], 'joe')
assert.equal(names[1], null)
assert.equal(names[2], 'bob')
assert.equal(names[3], 'NULL')
done()
}))
})
suite.test('element containing quote char', function (done) {
client.query("SELECT ARRAY['joe''', 'jim', 'bob\"'] AS names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 3);
assert.equal(names[0], 'joe\'');
assert.equal(names[1], 'jim');
assert.equal(names[2], 'bob"');
var names = result.rows[0].names
assert.lengthIs(names, 3)
assert.equal(names[0], 'joe\'')
assert.equal(names[1], 'jim')
assert.equal(names[2], 'bob"')
done()
}))
})
suite.test('nested array', function (done) {
client.query("SELECT '{{1,joe},{2,bob}}'::text[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 2);
var names = result.rows[0].names
assert.lengthIs(names, 2)
assert.lengthIs(names[0], 2);
assert.equal(names[0][0], '1');
assert.equal(names[0][1], 'joe');
assert.lengthIs(names[0], 2)
assert.equal(names[0][0], '1')
assert.equal(names[0][1], 'joe')
assert.lengthIs(names[1], 2);
assert.equal(names[1][0], '2');
assert.equal(names[1][1], 'bob');
assert.lengthIs(names[1], 2)
assert.equal(names[1][0], '2')
assert.equal(names[1][1], 'bob')
done()
}))
})
suite.test('integer array', function (done) {
client.query("SELECT '{1,2,3}'::integer[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 3);
assert.equal(names[0], 1);
assert.equal(names[1], 2);
assert.equal(names[2], 3);
var names = result.rows[0].names
assert.lengthIs(names, 3)
assert.equal(names[0], 1)
assert.equal(names[1], 2)
assert.equal(names[2], 3)
done()
}))
})
suite.test('integer nested array', function (done) {
client.query("SELECT '{{1,100},{2,100},{3,100}}'::integer[] as names", assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 3);
assert.equal(names[0][0], 1);
assert.equal(names[0][1], 100);
var names = result.rows[0].names
assert.lengthIs(names, 3)
assert.equal(names[0][0], 1)
assert.equal(names[0][1], 100)
assert.equal(names[1][0], 2);
assert.equal(names[1][1], 100);
assert.equal(names[1][0], 2)
assert.equal(names[1][1], 100)
assert.equal(names[2][0], 3);
assert.equal(names[2][1], 100);
assert.equal(names[2][0], 3)
assert.equal(names[2][1], 100)
done()
}))
})
suite.test('JS array parameter', function (done) {
client.query("SELECT $1::integer[] as names", [[[1, 100], [2, 100], [3, 100]]], assert.success(function (result) {
var names = result.rows[0].names;
assert.lengthIs(names, 3);
assert.equal(names[0][0], 1);
assert.equal(names[0][1], 100);
client.query('SELECT $1::integer[] as names', [[[1, 100], [2, 100], [3, 100]]], assert.success(function (result) {
var names = result.rows[0].names
assert.lengthIs(names, 3)
assert.equal(names[0][0], 1)
assert.equal(names[0][1], 100)
assert.equal(names[1][0], 2);
assert.equal(names[1][1], 100);
assert.equal(names[1][0], 2)
assert.equal(names[1][1], 100)
assert.equal(names[2][0], 3);
assert.equal(names[2][1], 100);
release();
assert.equal(names[2][0], 3)
assert.equal(names[2][1], 100)
release()
pool.end(() => {
done()
})
}))
})
}))
}));
}))

File diff suppressed because one or more lines are too long

View File

@ -1,17 +1,17 @@
"use strict";
var helper = require('./test-helper');
var pg = helper.pg;
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
var suite = new helper.Suite();
var suite = new helper.Suite()
//clear process.env
var realEnv = {};
for(var key in process.env) {
realEnv[key] = process.env[key];
if(!key.indexOf('PG')) delete process.env[key];
// clear process.env
var realEnv = {}
for (var key in process.env) {
realEnv[key] = process.env[key]
if (!key.indexOf('PG')) delete process.env[key]
}
suite.test('default values are used in new clients', function() {
suite.test('default values are used in new clients', function () {
assert.same(pg.defaults, {
user: process.env.USER,
database: process.env.USER,
@ -21,7 +21,7 @@ suite.test('default values are used in new clients', function() {
poolSize: 10
})
var client = new pg.Client();
var client = new pg.Client()
assert.same(client, {
user: process.env.USER,
database: process.env.USER,
@ -30,16 +30,15 @@ suite.test('default values are used in new clients', function() {
})
})
suite.test('modified values are passed to created clients', function() {
suite.test('modified values are passed to created clients', function () {
pg.defaults.user = 'boom'
pg.defaults.password = 'zap'
pg.defaults.database = 'pow'
pg.defaults.port = 1234
pg.defaults.host = 'blam'
var client = new Client();
assert.same(client,{
var client = new Client()
assert.same(client, {
user: 'boom',
password: 'zap',
database: 'pow',
@ -49,8 +48,8 @@ suite.test('modified values are passed to created clients', function() {
})
suite.test('cleanup', () => {
//restore process.env
// restore process.env
for (var key in realEnv) {
process.env[key] = realEnv[key];
process.env[key] = realEnv[key]
}
})

View File

@ -1,6 +1,6 @@
"use strict";
const helper = require('./test-helper');
const Client = helper.pg.Client;
'use strict'
const helper = require('./test-helper')
const Client = helper.pg.Client
const suite = new helper.Suite()
const client = new Client({
@ -13,8 +13,8 @@ suite.test('custom type parser in client config', (done) => {
client.connect()
.then(() => {
client.query('SELECT NOW() as val', assert.success(function (res) {
assert.equal(res.rows[0].val, 'okay!');
client.end().then(done);
}));
assert.equal(res.rows[0].val, 'okay!')
client.end().then(done)
}))
})
})

View File

@ -1,21 +1,20 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
suite.test("empty query message handling", function(done) {
const client = helper.client();
assert.emits(client, 'drain', function() {
client.end(done);
});
client.query({text: ""});
});
suite.test('empty query message handling', function (done) {
const client = helper.client()
assert.emits(client, 'drain', function () {
client.end(done)
})
client.query({text: ''})
})
suite.test('callback supported', function(done) {
const client = helper.client();
client.query("", function(err, result) {
assert(!err);
assert.empty(result.rows);
suite.test('callback supported', function (done) {
const client = helper.client()
client.query('', function (err, result) {
assert(!err)
assert.empty(result.rows)
client.end(done)
})
})

View File

@ -1,19 +1,19 @@
"use strict";
'use strict'
var helper = require('./test-helper');
var util = require('util');
var helper = require('./test-helper')
var util = require('util')
var pg = helper.pg
const Client = pg.Client
var createErorrClient = function() {
var client = helper.client();
client.once('error', function(err) {
assert.fail('Client shoud not throw error during query execution');
});
client.on('drain', client.end.bind(client));
return client;
};
var createErorrClient = function () {
var client = helper.client()
client.once('error', function (err) {
assert.fail('Client shoud not throw error during query execution')
})
client.on('drain', client.end.bind(client))
return client
}
const suite = new helper.Suite('error handling')
@ -50,131 +50,129 @@ suite.test('re-using connections results in promise rejection', (done) => {
})
})
suite.test('query receives error on client shutdown', function(done) {
var client = new Client();
client.connect(assert.success(function() {
suite.test('query receives error on client shutdown', function (done) {
var client = new Client()
client.connect(assert.success(function () {
const config = {
text: 'select pg_sleep(5)',
name: 'foobar'
}
let queryError;
client.query(new pg.Query(config), assert.calls(function(err, res) {
let queryError
client.query(new pg.Query(config), assert.calls(function (err, res) {
assert(err instanceof Error)
queryError = err
}));
}))
setTimeout(() => client.end(), 50)
client.once('end', () => {
assert(queryError instanceof Error)
done()
})
}));
});
}))
})
var ensureFuture = function (testClient, done) {
var goodQuery = testClient.query(new pg.Query("select age from boom"));
assert.emits(goodQuery, 'row', function (row) {
assert.equal(row.age, 28);
done();
});
};
var ensureFuture = function (testClient, done) {
var goodQuery = testClient.query(new pg.Query('select age from boom'))
assert.emits(goodQuery, 'row', function (row) {
assert.equal(row.age, 28)
done()
})
}
suite.test("when query is parsing", (done) => {
var client = createErorrClient();
suite.test('when query is parsing', (done) => {
var client = createErorrClient()
var q = client.query({ text: "CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);" });
var q = client.query({ text: 'CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);' })
// this query wont parse since there isn't a table named bang
var query = client.query(new pg.Query({
text: 'select * from bang where name = $1',
values: ['0']
}))
//this query wont parse since there isn't a table named bang
var query = client.query(new pg.Query({
text: "select * from bang where name = $1",
values: ['0']
}));
assert.emits(query, 'error', function (err) {
ensureFuture(client, done)
})
})
assert.emits(query, 'error', function (err) {
ensureFuture(client, done);
});
});
suite.test('when a query is binding', function (done) {
var client = createErorrClient()
suite.test("when a query is binding", function (done) {
var client = createErorrClient();
var q = client.query({ text: 'CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);' })
var q = client.query({ text: "CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);" });
var query = client.query(new pg.Query({
text: 'select * from boom where age = $1',
values: ['asldkfjasdf']
}))
assert.emits(query, 'error', function (err) {
assert.equal(err.severity, 'ERROR')
ensureFuture(client, done)
})
})
var query = client.query(new pg.Query({
text: 'select * from boom where age = $1',
values: ['asldkfjasdf']
}));
assert.emits(query, 'error', function (err) {
assert.equal(err.severity, "ERROR");
ensureFuture(client, done);
});
});
suite.test('non-query error with callback', function(done) {
suite.test('non-query error with callback', function (done) {
var client = new Client({
user:'asldkfjsadlfkj'
});
client.connect(assert.calls(function(error, client) {
user: 'asldkfjsadlfkj'
})
client.connect(assert.calls(function (error, client) {
assert(error instanceof Error)
done()
}));
});
}))
})
suite.test('non-error calls supplied callback', function(done) {
suite.test('non-error calls supplied callback', function (done) {
var client = new Client({
user: helper.args.user,
password: helper.args.password,
host: helper.args.host,
port: helper.args.port,
database: helper.args.database
});
})
client.connect(assert.calls(function(err) {
assert.ifError(err);
client.end(done);
client.connect(assert.calls(function (err) {
assert.ifError(err)
client.end(done)
}))
});
})
suite.test('when connecting to an invalid host with callback', function (done) {
var client = new Client({
user: 'very invalid username',
});
client.connect(function(error, client) {
assert(error instanceof Error);
done();
});
});
user: 'very invalid username'
})
client.connect(function (error, client) {
assert(error instanceof Error)
done()
})
})
suite.test('when connecting to invalid host with promise', function(done) {
suite.test('when connecting to invalid host with promise', function (done) {
var client = new Client({
user: 'very invalid username'
});
client.connect().catch((e) => done());
});
})
client.connect().catch((e) => done())
})
suite.test('non-query error', function(done) {
suite.test('non-query error', function (done) {
var client = new Client({
user:'asldkfjsadlfkj'
});
user: 'asldkfjsadlfkj'
})
client.connect()
.catch(e => {
assert(e instanceof Error)
done()
})
});
})
suite.test('within a simple query', (done) => {
var client = createErorrClient();
var client = createErorrClient()
var query = client.query(new pg.Query("select eeeee from yodas_dsflsd where pixistix = 'zoiks!!!'"));
var query = client.query(new pg.Query("select eeeee from yodas_dsflsd where pixistix = 'zoiks!!!'"))
assert.emits(query, 'error', function(error) {
assert.equal(error.severity, "ERROR");
done();
});
});
assert.emits(query, 'error', function (error) {
assert.equal(error.severity, 'ERROR')
done()
})
})
suite.test('connected, idle client error', (done) => {
const client = new Client()

View File

@ -1,22 +1,22 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
const pool = new helper.pg.Pool()
pool.connect(assert.success(function(client, done) {
var types = require('pg-types');
//1231 = numericOID
types.setTypeParser(1700, function(){
return 'yes';
pool.connect(assert.success(function (client, done) {
var types = require('pg-types')
// 1231 = numericOID
types.setTypeParser(1700, function () {
return 'yes'
})
types.setTypeParser(1700, 'binary', function(){
return 'yes';
types.setTypeParser(1700, 'binary', function () {
return 'yes'
})
var bignum = '294733346389144765940638005275322203805';
client.query('CREATE TEMP TABLE bignumz(id numeric)');
client.query('INSERT INTO bignumz(id) VALUES ($1)', [bignum]);
client.query('SELECT * FROM bignumz', assert.success(function(result) {
var bignum = '294733346389144765940638005275322203805'
client.query('CREATE TEMP TABLE bignumz(id numeric)')
client.query('INSERT INTO bignumz(id) VALUES ($1)', [bignum])
client.query('SELECT * FROM bignumz', assert.success(function (result) {
assert.equal(result.rows[0].id, 'yes')
done();
done()
pool.end()
}))
}));
}))

View File

@ -1,28 +1,28 @@
"use strict";
var helper = require('./test-helper');
var assert = require('assert');
'use strict'
var helper = require('./test-helper')
var assert = require('assert')
const pool = new helper.pg.Pool()
pool.connect(assert.success(function (client, done) {
helper.versionGTE(client, '9.2.0', assert.success(function (jsonSupported) {
if (!jsonSupported) {
console.log('skip json test on older versions of postgres');
done();
return pool.end();
console.log('skip json test on older versions of postgres')
done()
return pool.end()
}
client.query('CREATE TEMP TABLE stuff(id SERIAL PRIMARY KEY, data JSON)');
var value = { name: 'Brian', age: 250, alive: true, now: new Date() };
client.query('INSERT INTO stuff (data) VALUES ($1)', [value]);
client.query('CREATE TEMP TABLE stuff(id SERIAL PRIMARY KEY, data JSON)')
var value = { name: 'Brian', age: 250, alive: true, now: new Date() }
client.query('INSERT INTO stuff (data) VALUES ($1)', [value])
client.query('SELECT * FROM stuff', assert.success(function (result) {
assert.equal(result.rows.length, 1);
assert.equal(typeof result.rows[0].data, 'object');
var row = result.rows[0].data;
assert.strictEqual(row.name, value.name);
assert.strictEqual(row.age, value.age);
assert.strictEqual(row.alive, value.alive);
assert.equal(JSON.stringify(row.now), JSON.stringify(value.now));
done();
assert.equal(result.rows.length, 1)
assert.equal(typeof result.rows[0].data, 'object')
var row = result.rows[0].data
assert.strictEqual(row.name, value.name)
assert.strictEqual(row.age, value.age)
assert.strictEqual(row.alive, value.alive)
assert.equal(JSON.stringify(row.now), JSON.stringify(value.now))
done()
pool.end()
}));
}));
}));
}))
}))
}))

View File

@ -1,11 +1,11 @@
"use strict";
'use strict'
var buffers = require('../../test-buffers')
var helper = require('./test-helper')
var suite = new helper.Suite()
var net = require('net')
var Server = function(response) {
var Server = function (response) {
this.server = undefined
this.socket = undefined
this.response = response
@ -38,7 +38,7 @@ Server.prototype.start = function (cb) {
var options = {
host: 'localhost',
port: port,
port: port
}
this.server.listen(options.port, options.host, function () {
cb(options)
@ -55,7 +55,7 @@ Server.prototype.close = function (cb) {
var testServer = function (server, cb) {
// wait for our server to start
server.start(function(options) {
server.start(function (options) {
// connect a client to it
var client = new helper.Client(options)
client.connect()
@ -66,7 +66,7 @@ var testServer = function (server, cb) {
})
// after 50 milliseconds, drop the client
setTimeout(function() {
setTimeout(function () {
server.drop()
}, 50)

View File

@ -1,32 +1,30 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
suite.test("noData message handling", function() {
var client = helper.client();
suite.test('noData message handling', function () {
var client = helper.client()
var q = client.query({
name: 'boom',
text: 'create temp table boom(id serial, size integer)'
});
})
client.query({
name: 'insert',
text: 'insert into boom(size) values($1)',
values: [100]
}, function(err, result) {
if(err) {
console.log(err);
throw err;
}, function (err, result) {
if (err) {
console.log(err)
throw err
}
});
})
client.query({
name: 'insert',
values: [101]
});
})
var query = client.query({
name: 'fetch',
@ -35,7 +33,7 @@ suite.test("noData message handling", function() {
}, (err, res) => {
var row = res.rows[0]
assert.strictEqual(row.size, 100)
});
})
client.on('drain', client.end.bind(client));
});
client.on('drain', client.end.bind(client))
})

View File

@ -1,28 +1,28 @@
"use strict";
var helper = require("./test-helper");
var pg = helper.pg;
const suite = new helper.Suite();
const pool = new pg.Pool();
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
const suite = new helper.Suite()
const pool = new pg.Pool()
suite.test("can access results when no rows are returned", function (done) {
suite.test('can access results when no rows are returned', function (done) {
var checkResult = function (result) {
assert(result.fields, "should have fields definition");
assert.equal(result.fields.length, 1);
assert.equal(result.fields[0].name, "val");
assert.equal(result.fields[0].dataTypeID, 25);
};
assert(result.fields, 'should have fields definition')
assert.equal(result.fields.length, 1)
assert.equal(result.fields[0].name, 'val')
assert.equal(result.fields[0].dataTypeID, 25)
}
pool.connect(
assert.success(function (client, release) {
const q = new pg.Query("select $1::text as val limit 0", ["hi"]);
const q = new pg.Query('select $1::text as val limit 0', ['hi'])
var query = client.query(q, assert.success(function (result) {
checkResult(result);
release();
pool.end(done);
checkResult(result)
release()
pool.end(done)
})
);
)
assert.emits(query, "end", checkResult);
assert.emits(query, 'end', checkResult)
})
);
});
)
})

View File

@ -1,34 +1,34 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
suite.test('emits notify message', function (done) {
var client = helper.client();
var client = helper.client()
client.query('LISTEN boom', assert.calls(function () {
var otherClient = helper.client();
var otherClient = helper.client()
var bothEmitted = -1
otherClient.query('LISTEN boom', assert.calls(function () {
assert.emits(client, 'notification', function (msg) {
//make sure PQfreemem doesn't invalidate string pointers
// make sure PQfreemem doesn't invalidate string pointers
setTimeout(function () {
assert.equal(msg.channel, 'boom');
assert.ok(msg.payload == 'omg!' /*9.x*/ || msg.payload == '' /*8.x*/, "expected blank payload or correct payload but got " + msg.message)
assert.equal(msg.channel, 'boom')
assert.ok(msg.payload == 'omg!' /* 9.x */ || msg.payload == '' /* 8.x */, 'expected blank payload or correct payload but got ' + msg.message)
client.end(++bothEmitted ? done : undefined)
}, 100)
});
})
assert.emits(otherClient, 'notification', function (msg) {
assert.equal(msg.channel, 'boom');
otherClient.end(++bothEmitted ? done : undefined);
});
assert.equal(msg.channel, 'boom')
otherClient.end(++bothEmitted ? done : undefined)
})
client.query("NOTIFY boom, 'omg!'", function (err, q) {
if (err) {
//notify not supported with payload on 8.x
client.query("NOTIFY boom")
// notify not supported with payload on 8.x
client.query('NOTIFY boom')
}
});
}));
}));
})
}))
}))
})
// this test fails on travis due to their config
@ -37,8 +37,8 @@ suite.test('emits notice message', false, function (done) {
console.error('need to get notice message working on native')
return done()
}
//TODO this doesn't work on all versions of postgres
var client = helper.client();
// TODO this doesn't work on all versions of postgres
var client = helper.client()
const text = `
DO language plpgsql $$
BEGIN
@ -47,10 +47,10 @@ END
$$;
`
client.query(text, () => {
client.end();
});
client.end()
})
assert.emits(client, 'notice', function (notice) {
assert.ok(notice != null);
done();
});
assert.ok(notice != null)
done()
})
})

View File

@ -1,29 +1,29 @@
"use strict";
'use strict'
var helper = require('../test-helper');
var pg = helper.pg;
var helper = require('../test-helper')
var pg = helper.pg
const suite = new helper.Suite()
const pool = new pg.Pool(helper.config)
suite.test('ability to turn on and off parser', function() {
if(helper.args.binary) return false;
pool.connect(assert.success(function(client, done) {
pg.defaults.parseInt8 = true;
client.query('CREATE TEMP TABLE asdf(id SERIAL PRIMARY KEY)');
client.query('SELECT COUNT(*) as "count", \'{1,2,3}\'::bigint[] as array FROM asdf', assert.success(function(res) {
assert.strictEqual(0, res.rows[0].count);
assert.strictEqual(1, res.rows[0].array[0]);
assert.strictEqual(2, res.rows[0].array[1]);
assert.strictEqual(3, res.rows[0].array[2]);
pg.defaults.parseInt8 = false;
client.query('SELECT COUNT(*) as "count", \'{1,2,3}\'::bigint[] as array FROM asdf', assert.success(function(res) {
done();
assert.strictEqual('0', res.rows[0].count);
assert.strictEqual('1', res.rows[0].array[0]);
assert.strictEqual('2', res.rows[0].array[1]);
assert.strictEqual('3', res.rows[0].array[2]);
pool.end();
}));
}));
}));
});
suite.test('ability to turn on and off parser', function () {
if (helper.args.binary) return false
pool.connect(assert.success(function (client, done) {
pg.defaults.parseInt8 = true
client.query('CREATE TEMP TABLE asdf(id SERIAL PRIMARY KEY)')
client.query('SELECT COUNT(*) as "count", \'{1,2,3}\'::bigint[] as array FROM asdf', assert.success(function (res) {
assert.strictEqual(0, res.rows[0].count)
assert.strictEqual(1, res.rows[0].array[0])
assert.strictEqual(2, res.rows[0].array[1])
assert.strictEqual(3, res.rows[0].array[2])
pg.defaults.parseInt8 = false
client.query('SELECT COUNT(*) as "count", \'{1,2,3}\'::bigint[] as array FROM asdf', assert.success(function (res) {
done()
assert.strictEqual('0', res.rows[0].count)
assert.strictEqual('1', res.rows[0].array[0])
assert.strictEqual('2', res.rows[0].array[1])
assert.strictEqual('3', res.rows[0].array[2])
pool.end()
}))
}))
}))
})

View File

@ -1,136 +1,132 @@
"use strict";
var helper = require('./test-helper');
var Query = helper.pg.Query;
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
var suite = new helper.Suite()
;(function() {
;(function () {
var client = helper.client()
client.on('drain', client.end.bind(client))
var client = helper.client();
client.on('drain', client.end.bind(client));
var queryName = 'user by age and like name'
var parseCount = 0
var queryName = "user by age and like name";
var parseCount = 0;
suite.test("first named prepared statement", function(done) {
suite.test('first named prepared statement', function (done) {
var query = client.query(new Query({
text: 'select name from person where age <= $1 and name LIKE $2',
values: [20, 'Bri%'],
name: queryName
}));
}))
assert.emits(query, 'row', function(row) {
assert.equal(row.name, 'Brian');
});
assert.emits(query, 'row', function (row) {
assert.equal(row.name, 'Brian')
})
query.on('end', () => done())
});
})
suite.test("second named prepared statement with same name & text", function(done) {
suite.test('second named prepared statement with same name & text', function (done) {
var cachedQuery = client.query(new Query({
text: 'select name from person where age <= $1 and name LIKE $2',
name: queryName,
values: [10, 'A%']
}));
}))
assert.emits(cachedQuery, 'row', function(row) {
assert.equal(row.name, 'Aaron');
});
assert.emits(cachedQuery, 'row', function (row) {
assert.equal(row.name, 'Aaron')
})
cachedQuery.on('end', () => done())
});
})
suite.test("with same name, but without query text", function(done) {
suite.test('with same name, but without query text', function (done) {
var q = client.query(new Query({
name: queryName,
values: [30, '%n%']
}));
}))
assert.emits(q, 'row', function(row) {
assert.equal(row.name, "Aaron");
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Aaron')
// test second row is emitted as well
assert.emits(q, 'row', function(row) {
assert.equal(row.name, "Brian");
});
});
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Brian')
})
})
q.on('end', () => done())
});
})();
})
})()
;(function() {
var statementName = "differ";
var statement1 = "select count(*)::int4 as count from person";
var statement2 = "select count(*)::int4 as count from person where age < $1";
;(function () {
var statementName = 'differ'
var statement1 = 'select count(*)::int4 as count from person'
var statement2 = 'select count(*)::int4 as count from person where age < $1'
var client1 = helper.client();
var client2 = helper.client();
suite.test("client 1 execution", function(done) {
var client1 = helper.client()
var client2 = helper.client()
suite.test('client 1 execution', function (done) {
var query = client1.query({
name: statementName,
text: statement1
}, (err, res) => {
assert(!err);
assert.equal(res.rows[0].count, 26);
assert(!err)
assert.equal(res.rows[0].count, 26)
done()
});
});
})
})
suite.test('client 2 execution', function(done) {
suite.test('client 2 execution', function (done) {
var query = client2.query(new Query({
name: statementName,
text: statement2,
values: [11]
}));
}))
assert.emits(query, 'row', function(row) {
assert.equal(row.count, 1);
});
assert.emits(query, 'row', function (row) {
assert.equal(row.count, 1)
})
assert.emits(query, 'end', function() {
done();
});
});
assert.emits(query, 'end', function () {
done()
})
})
suite.test('clean up clients', () => {
return client1.end().then(() => client2.end())
});
})
})()
})();
;(function() {
var client = helper.client();
client.query('CREATE TEMP TABLE zoom(name varchar(100));');
client.query("INSERT INTO zoom (name) VALUES ('zed')");
client.query("INSERT INTO zoom (name) VALUES ('postgres')");
client.query("INSERT INTO zoom (name) VALUES ('node postgres')");
;(function () {
var client = helper.client()
client.query('CREATE TEMP TABLE zoom(name varchar(100));')
client.query("INSERT INTO zoom (name) VALUES ('zed')")
client.query("INSERT INTO zoom (name) VALUES ('postgres')")
client.query("INSERT INTO zoom (name) VALUES ('node postgres')")
var checkForResults = function (q) {
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'node postgres');
assert.equal(row.name, 'node postgres')
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'postgres');
assert.equal(row.name, 'postgres')
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'zed');
assert.equal(row.name, 'zed')
})
});
})
})
};
}
suite.test('with small row count', function (done) {
var query = client.query(new Query({
name: 'get names',
text: "SELECT name FROM zoom ORDER BY name",
text: 'SELECT name FROM zoom ORDER BY name',
rows: 1
}, done));
checkForResults(query);
}, done))
checkForResults(query)
})
suite.test('with large row count', function (done) {
@ -139,7 +135,7 @@ var suite = new helper.Suite()
text: 'SELECT name FROM zoom ORDER BY name',
rows: 1000
}, done))
checkForResults(query);
checkForResults(query)
})
suite.test('cleanup', () => client.end())

View File

@ -1,8 +1,8 @@
"use strict";
'use strict';
'use strict'
'use strict'
const helper = require('./test-helper')
const pg = helper.pg;
const pg = helper.pg
const suite = new helper.Suite()
@ -24,7 +24,6 @@ suite.test('valid connection completes promise', () => {
})
})
suite.test('invalid connection rejects promise', (done) => {
const client = new pg.Client({ host: 'alksdjflaskdfj' })
return client.connect()

View File

@ -1,8 +1,8 @@
"use strict";
var helper = require(__dirname + '/../test-helper');
var pg = helper.pg;
'use strict'
var helper = require(__dirname + '/../test-helper')
var pg = helper.pg
process.on('unhandledRejection', function(e) {
process.on('unhandledRejection', function (e) {
console.error(e, e.stack)
process.exit(1)
})

View File

@ -1,15 +1,15 @@
"use strict";
var helper = require(__dirname + '/../test-helper');
var pg = helper.pg;
'use strict'
var helper = require(__dirname + '/../test-helper')
var pg = helper.pg
new helper.Suite().test('support for complex column names', function () {
const pool = new pg.Pool()
pool.connect(assert.success(function (client, done) {
client.query("CREATE TEMP TABLE t ( \"complex''column\" TEXT )");
client.query("CREATE TEMP TABLE t ( \"complex''column\" TEXT )")
client.query('SELECT * FROM t', assert.success(function (res) {
done();
assert.strictEqual(res.fields[0].name, "complex''column");
pool.end();
}));
}));
});
done()
assert.strictEqual(res.fields[0].name, "complex''column")
pool.end()
}))
}))
})

View File

@ -1,99 +1,98 @@
"use strict";
var helper = require('./test-helper');
var Query = helper.pg.Query;
var util = require('util');
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
var util = require('util')
var suite = new helper.Suite();
var suite = new helper.Suite()
suite.test('client end during query execution of prepared statement', function(done) {
var client = new Client();
client.connect(assert.success(function() {
var sleepQuery = 'select pg_sleep($1)';
suite.test('client end during query execution of prepared statement', function (done) {
var client = new Client()
client.connect(assert.success(function () {
var sleepQuery = 'select pg_sleep($1)'
var queryConfig = {
name: 'sleep query',
text: sleepQuery,
values: [5],
values: [5]
}
var queryInstance = new Query(queryConfig, assert.calls(function (err, result) {
assert.equal(err.message, 'Connection terminated');
done();
assert.equal(err.message, 'Connection terminated')
done()
}))
var query1 = client.query(queryInstance);
var query1 = client.query(queryInstance)
query1.on('error', function (err) {
assert.fail('Prepared statement should not emit error');
});
assert.fail('Prepared statement should not emit error')
})
query1.on('row', function (row) {
assert.fail('Prepared statement should not emit row');
});
assert.fail('Prepared statement should not emit row')
})
query1.on('end', function (err) {
assert.fail('Prepared statement when executed should not return before being killed');
});
assert.fail('Prepared statement when executed should not return before being killed')
})
client.end();
}));
});
client.end()
}))
})
function killIdleQuery(targetQuery, cb) {
var client2 = new Client(helper.args);
function killIdleQuery (targetQuery, cb) {
var client2 = new Client(helper.args)
var pidColName = 'procpid'
var queryColName = 'current_query';
client2.connect(assert.success(function() {
helper.versionGTE(client2, '9.2.0', assert.success(function(isGreater) {
if(isGreater) {
pidColName = 'pid';
queryColName = 'query';
var queryColName = 'current_query'
client2.connect(assert.success(function () {
helper.versionGTE(client2, '9.2.0', assert.success(function (isGreater) {
if (isGreater) {
pidColName = 'pid'
queryColName = 'query'
}
var killIdleQuery = "SELECT " + pidColName + ", (SELECT pg_terminate_backend(" + pidColName + ")) AS killed FROM pg_stat_activity WHERE " + queryColName + " = $1";
client2.query(killIdleQuery, [targetQuery], assert.calls(function(err, res) {
assert.ifError(err);
assert.equal(res.rows.length, 1);
client2.end(cb);
assert.emits(client2, 'end');
}));
}));
}));
var killIdleQuery = 'SELECT ' + pidColName + ', (SELECT pg_terminate_backend(' + pidColName + ')) AS killed FROM pg_stat_activity WHERE ' + queryColName + ' = $1'
client2.query(killIdleQuery, [targetQuery], assert.calls(function (err, res) {
assert.ifError(err)
assert.equal(res.rows.length, 1)
client2.end(cb)
assert.emits(client2, 'end')
}))
}))
}))
}
suite.test('query killed during query execution of prepared statement', function(done) {
if(helper.args.native) {
return done();
suite.test('query killed during query execution of prepared statement', function (done) {
if (helper.args.native) {
return done()
}
var client = new Client(helper.args);
client.connect(assert.success(function() {
var sleepQuery = 'select pg_sleep($1)';
var client = new Client(helper.args)
client.connect(assert.success(function () {
var sleepQuery = 'select pg_sleep($1)'
const queryConfig = {
name: 'sleep query',
text: sleepQuery,
values: [5],
};
values: [5]
}
// client should emit an error because it is unexpectedly disconnected
assert.emits(client, 'error')
var query1 = client.query(new Query(queryConfig), assert.calls(function(err, result) {
assert.equal(err.message, 'terminating connection due to administrator command');
}));
var query1 = client.query(new Query(queryConfig), assert.calls(function (err, result) {
assert.equal(err.message, 'terminating connection due to administrator command')
}))
query1.on('error', function(err) {
assert.fail('Prepared statement should not emit error');
});
query1.on('error', function (err) {
assert.fail('Prepared statement should not emit error')
})
query1.on('row', function(row) {
assert.fail('Prepared statement should not emit row');
});
query1.on('row', function (row) {
assert.fail('Prepared statement should not emit row')
})
query1.on('end', function(err) {
assert.fail('Prepared statement when executed should not return before being killed');
});
query1.on('end', function (err) {
assert.fail('Prepared statement when executed should not return before being killed')
})
killIdleQuery(sleepQuery, done);
}));
});
killIdleQuery(sleepQuery, done)
}))
})

View File

@ -1,8 +1,8 @@
"use strict";
//test for issue #320
'use strict'
// test for issue #320
//
var helper = require('./test-helper');
var helper = require('./test-helper')
var client = new helper.pg.Client(helper.config);
client.connect();
client.end();
var client = new helper.pg.Client(helper.config)
client.connect()
client.end()

View File

@ -1,32 +1,32 @@
"use strict";
var helper = require("./test-helper");
var pg = helper.pg;
'use strict'
var helper = require('./test-helper')
var pg = helper.pg
const pool = new pg.Pool()
new helper.Suite().test('should return insert metadata', function() {
pool.connect(assert.calls(function(err, client, done) {
assert(!err);
new helper.Suite().test('should return insert metadata', function () {
pool.connect(assert.calls(function (err, client, done) {
assert(!err)
helper.versionGTE(client, '9.0.0', assert.success(function(hasRowCount) {
client.query("CREATE TEMP TABLE zugzug(name varchar(10))", assert.calls(function(err, result) {
assert(!err);
assert.equal(result.oid, null);
assert.equal(result.command, 'CREATE');
helper.versionGTE(client, '9.0.0', assert.success(function (hasRowCount) {
client.query('CREATE TEMP TABLE zugzug(name varchar(10))', assert.calls(function (err, result) {
assert(!err)
assert.equal(result.oid, null)
assert.equal(result.command, 'CREATE')
var q = client.query("INSERT INTO zugzug(name) VALUES('more work?')", assert.calls(function(err, result) {
assert(!err);
assert.equal(result.command, "INSERT");
assert.equal(result.rowCount, 1);
var q = client.query("INSERT INTO zugzug(name) VALUES('more work?')", assert.calls(function (err, result) {
assert(!err)
assert.equal(result.command, 'INSERT')
assert.equal(result.rowCount, 1)
client.query('SELECT * FROM zugzug', assert.calls(function(err, result) {
assert(!err);
if(hasRowCount) assert.equal(result.rowCount, 1);
assert.equal(result.command, 'SELECT');
done();
process.nextTick(pool.end.bind(pool));
}));
}));
}));
}));
}));
});
client.query('SELECT * FROM zugzug', assert.calls(function (err, result) {
assert(!err)
if (hasRowCount) assert.equal(result.rowCount, 1)
assert.equal(result.command, 'SELECT')
done()
process.nextTick(pool.end.bind(pool))
}))
}))
}))
}))
}))
})

View File

@ -1,31 +1,31 @@
"use strict";
var util = require('util');
var helper = require('./test-helper');
'use strict'
var util = require('util')
var helper = require('./test-helper')
var Client = helper.Client;
var Client = helper.Client
var conInfo = helper.config;
var conInfo = helper.config
test('returns results as array', function() {
var client = new Client(conInfo);
var checkRow = function(row) {
assert(util.isArray(row), 'row should be an array');
assert.equal(row.length, 4);
assert.equal(row[0].getFullYear(), new Date().getFullYear());
assert.strictEqual(row[1], 1);
assert.strictEqual(row[2], 'hai');
assert.strictEqual(row[3], null);
test('returns results as array', function () {
var client = new Client(conInfo)
var checkRow = function (row) {
assert(util.isArray(row), 'row should be an array')
assert.equal(row.length, 4)
assert.equal(row[0].getFullYear(), new Date().getFullYear())
assert.strictEqual(row[1], 1)
assert.strictEqual(row[2], 'hai')
assert.strictEqual(row[3], null)
}
client.connect(assert.success(function() {
client.connect(assert.success(function () {
var config = {
text: 'SELECT NOW(), 1::int, $1::text, null',
values: ['hai'],
rowMode: 'array'
};
var query = client.query(config, assert.success(function(result) {
assert.equal(result.rows.length, 1);
checkRow(result.rows[0]);
client.end();
}));
}));
});
}
var query = client.query(config, assert.success(function (result) {
assert.equal(result.rows.length, 1)
checkRow(result.rows[0])
client.end()
}))
}))
})

View File

@ -1,38 +1,38 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
var Client = helper.Client;
var Client = helper.Client
var conInfo = helper.config;
var conInfo = helper.config
var checkResult = function(result) {
assert(result.fields);
assert.equal(result.fields.length, 3);
var fields = result.fields;
assert.equal(fields[0].name, 'now');
assert.equal(fields[1].name, 'num');
assert.equal(fields[2].name, 'texty');
assert.equal(fields[0].dataTypeID, 1184);
assert.equal(fields[1].dataTypeID, 23);
assert.equal(fields[2].dataTypeID, 25);
};
var checkResult = function (result) {
assert(result.fields)
assert.equal(result.fields.length, 3)
var fields = result.fields
assert.equal(fields[0].name, 'now')
assert.equal(fields[1].name, 'num')
assert.equal(fields[2].name, 'texty')
assert.equal(fields[0].dataTypeID, 1184)
assert.equal(fields[1].dataTypeID, 23)
assert.equal(fields[2].dataTypeID, 25)
}
test('row descriptions on result object', function() {
var client = new Client(conInfo);
client.connect(assert.success(function() {
client.query('SELECT NOW() as now, 1::int as num, $1::text as texty', ["hello"], assert.success(function(result) {
checkResult(result);
client.end();
}));
}));
});
test('row descriptions on result object', function () {
var client = new Client(conInfo)
client.connect(assert.success(function () {
client.query('SELECT NOW() as now, 1::int as num, $1::text as texty', ['hello'], assert.success(function (result) {
checkResult(result)
client.end()
}))
}))
})
test('row description on no rows', function() {
var client = new Client(conInfo);
client.connect(assert.success(function() {
client.query('SELECT NOW() as now, 1::int as num, $1::text as texty LIMIT 0', ["hello"], assert.success(function(result) {
checkResult(result);
client.end();
}));
}));
});
test('row description on no rows', function () {
var client = new Client(conInfo)
client.connect(assert.success(function () {
client.query('SELECT NOW() as now, 1::int as num, $1::text as texty LIMIT 0', ['hello'], assert.success(function (result) {
checkResult(result)
client.end()
}))
}))
})

View File

@ -1,93 +1,91 @@
"use strict";
var helper = require("./test-helper");
var Query = helper.pg.Query;
'use strict'
var helper = require('./test-helper')
var Query = helper.pg.Query
//before running this test make sure you run the script create-test-tables
test("simple query interface", function() {
// before running this test make sure you run the script create-test-tables
test('simple query interface', function () {
var client = helper.client()
var client = helper.client();
var query = client.query(new Query('select name from person order by name'))
var query = client.query(new Query("select name from person order by name"));
client.on('drain', client.end.bind(client))
client.on('drain', client.end.bind(client));
var rows = [];
query.on('row', function(row, result) {
assert.ok(result);
rows.push(row['name']);
});
query.once('row', function(row) {
var rows = []
query.on('row', function (row, result) {
assert.ok(result)
rows.push(row['name'])
})
query.once('row', function (row) {
test('Can iterate through columns', function () {
var columnCount = 0;
var columnCount = 0
for (var column in row) {
columnCount++;
columnCount++
}
if ('length' in row) {
assert.lengthIs(row, columnCount, 'Iterating through the columns gives a different length from calling .length.');
assert.lengthIs(row, columnCount, 'Iterating through the columns gives a different length from calling .length.')
}
});
});
})
})
assert.emits(query, 'end', function() {
test("returned right number of rows", function() {
assert.lengthIs(rows, 26);
});
test("row ordering", function(){
assert.equal(rows[0], "Aaron");
assert.equal(rows[25], "Zanzabar");
});
});
});
assert.emits(query, 'end', function () {
test('returned right number of rows', function () {
assert.lengthIs(rows, 26)
})
test('row ordering', function () {
assert.equal(rows[0], 'Aaron')
assert.equal(rows[25], 'Zanzabar')
})
})
})
test("prepared statements do not mutate params", function() {
var client = helper.client();
test('prepared statements do not mutate params', function () {
var client = helper.client()
var params = [1]
var query = client.query(new Query("select name from person where $1 = 1 order by name", params));
var query = client.query(new Query('select name from person where $1 = 1 order by name', params))
assert.deepEqual(params, [1])
client.on('drain', client.end.bind(client));
client.on('drain', client.end.bind(client))
query.on('row', function(row, result) {
assert.ok(result);
result.addRow(row);
});
query.on('row', function (row, result) {
assert.ok(result)
result.addRow(row)
})
query.on('end', function(result) {
assert.lengthIs(result.rows, 26, "result returned wrong number of rows");
assert.lengthIs(result.rows, result.rowCount);
assert.equal(result.rows[0].name, "Aaron");
assert.equal(result.rows[25].name, "Zanzabar");
});
});
query.on('end', function (result) {
assert.lengthIs(result.rows, 26, 'result returned wrong number of rows')
assert.lengthIs(result.rows, result.rowCount)
assert.equal(result.rows[0].name, 'Aaron')
assert.equal(result.rows[25].name, 'Zanzabar')
})
})
test("multiple simple queries", function() {
var client = helper.client();
test('multiple simple queries', function () {
var client = helper.client()
client.query({ text: "create temp table bang(id serial, name varchar(5));insert into bang(name) VALUES('boom');"})
client.query("insert into bang(name) VALUES ('yes');");
var query = client.query(new Query("select name from bang"));
assert.emits(query, 'row', function(row) {
assert.equal(row['name'], 'boom');
assert.emits(query, 'row', function(row) {
assert.equal(row['name'],'yes');
});
});
client.on('drain', client.end.bind(client));
});
client.query("insert into bang(name) VALUES ('yes');")
var query = client.query(new Query('select name from bang'))
assert.emits(query, 'row', function (row) {
assert.equal(row['name'], 'boom')
assert.emits(query, 'row', function (row) {
assert.equal(row['name'], 'yes')
})
})
client.on('drain', client.end.bind(client))
})
test("multiple select statements", function() {
var client = helper.client();
client.query("create temp table boom(age integer); insert into boom(age) values(1); insert into boom(age) values(2); insert into boom(age) values(3)");
client.query({text: "create temp table bang(name varchar(5)); insert into bang(name) values('zoom');"});
var result = client.query(new Query({text: "select age from boom where age < 2; select name from bang"}));
assert.emits(result, 'row', function(row) {
assert.strictEqual(row['age'], 1);
assert.emits(result, 'row', function(row) {
assert.strictEqual(row['name'], 'zoom');
});
});
client.on('drain', client.end.bind(client));
});
test('multiple select statements', function () {
var client = helper.client()
client.query('create temp table boom(age integer); insert into boom(age) values(1); insert into boom(age) values(2); insert into boom(age) values(3)')
client.query({text: "create temp table bang(name varchar(5)); insert into bang(name) values('zoom');"})
var result = client.query(new Query({text: 'select age from boom where age < 2; select name from bang'}))
assert.emits(result, 'row', function (row) {
assert.strictEqual(row['age'], 1)
assert.emits(result, 'row', function (row) {
assert.strictEqual(row['name'], 'zoom')
})
})
client.on('drain', client.end.bind(client))
})

View File

@ -1,15 +1,15 @@
"use strict";
var pg = require(__dirname + '/../../../lib');
var config = require(__dirname + '/test-helper').config;
test('can connect with ssl', function() {
return false;
'use strict'
var pg = require(__dirname + '/../../../lib')
var config = require(__dirname + '/test-helper').config
test('can connect with ssl', function () {
return false
config.ssl = {
rejectUnauthorized: false
};
pg.connect(config, assert.success(function(client) {
return false;
client.query('SELECT NOW()', assert.success(function() {
pg.end();
}));
}));
});
}
pg.connect(config, assert.success(function (client) {
return false
client.query('SELECT NOW()', assert.success(function () {
pg.end()
}))
}))
})

View File

@ -1,4 +1,4 @@
"use strict";
var helper = require('./../test-helper');
'use strict'
var helper = require('./../test-helper')
module.exports = helper;
module.exports = helper

View File

@ -1,34 +1,34 @@
"use strict";
var helper = require('./../test-helper');
var exec = require('child_process').exec;
'use strict'
var helper = require('./../test-helper')
var exec = require('child_process').exec
var oldTz = process.env.TZ;
process.env.TZ = 'Europe/Berlin';
var oldTz = process.env.TZ
process.env.TZ = 'Europe/Berlin'
var date = new Date();
var date = new Date()
const pool = new helper.pg.Pool()
const suite = new helper.Suite()
pool.connect(function (err, client, done) {
assert(!err);
assert(!err)
suite.test('timestamp without time zone', function (cb) {
client.query("SELECT CAST($1 AS TIMESTAMP WITHOUT TIME ZONE) AS \"val\"", [date], function (err, result) {
assert(!err);
assert.equal(result.rows[0].val.getTime(), date.getTime());
client.query('SELECT CAST($1 AS TIMESTAMP WITHOUT TIME ZONE) AS "val"', [date], function (err, result) {
assert(!err)
assert.equal(result.rows[0].val.getTime(), date.getTime())
cb()
})
})
suite.test('timestamp with time zone', function (cb) {
client.query("SELECT CAST($1 AS TIMESTAMP WITH TIME ZONE) AS \"val\"", [date], function (err, result) {
assert(!err);
assert.equal(result.rows[0].val.getTime(), date.getTime());
client.query('SELECT CAST($1 AS TIMESTAMP WITH TIME ZONE) AS "val"', [date], function (err, result) {
assert(!err)
assert.equal(result.rows[0].val.getTime(), date.getTime())
done();
done()
pool.end(cb)
process.env.TZ = oldTz;
});
});
});
process.env.TZ = oldTz
})
})
})

View File

@ -1,49 +1,48 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
const suite = new helper.Suite()
const pg = helper.pg
const client = new pg.Client()
client.connect(assert.success(function () {
client.query('begin');
client.query('begin')
var getZed = {
text: 'SELECT * FROM person WHERE name = $1',
values: ['Zed']
};
}
suite.test('name should not exist in the database', function (done) {
client.query(getZed, assert.calls(function (err, result) {
assert(!err);
assert.empty(result.rows);
assert(!err)
assert.empty(result.rows)
done()
}))
})
suite.test('can insert name', (done) => {
client.query("INSERT INTO person(name, age) VALUES($1, $2)", ['Zed', 270], assert.calls(function (err, result) {
client.query('INSERT INTO person(name, age) VALUES($1, $2)', ['Zed', 270], assert.calls(function (err, result) {
assert(!err)
done()
}));
}))
})
suite.test('name should exist in the database', function (done) {
client.query(getZed, assert.calls(function (err, result) {
assert(!err);
assert.equal(result.rows[0].name, 'Zed');
assert(!err)
assert.equal(result.rows[0].name, 'Zed')
done()
}))
})
suite.test('rollback', (done) => {
client.query('rollback', done);
client.query('rollback', done)
})
suite.test('name should not exist in the database', function (done) {
client.query(getZed, assert.calls(function (err, result) {
assert(!err);
assert.empty(result.rows);
assert(!err)
assert.empty(result.rows)
client.end(done)
}))
})
@ -52,26 +51,26 @@ client.connect(assert.success(function () {
suite.test('gh#36', function (cb) {
const pool = new pg.Pool()
pool.connect(assert.success(function (client, done) {
client.query("BEGIN");
client.query('BEGIN')
client.query({
name: 'X',
text: "SELECT $1::INTEGER",
text: 'SELECT $1::INTEGER',
values: [0]
}, assert.calls(function (err, result) {
if (err) throw err;
assert.equal(result.rows.length, 1);
if (err) throw err
assert.equal(result.rows.length, 1)
}))
client.query({
name: 'X',
text: "SELECT $1::INTEGER",
text: 'SELECT $1::INTEGER',
values: [0]
}, assert.calls(function (err, result) {
if (err) throw err;
assert.equal(result.rows.length, 1);
if (err) throw err
assert.equal(result.rows.length, 1)
}))
client.query("COMMIT", function () {
done();
client.query('COMMIT', function () {
done()
pool.end(cb)
})
}));
}))
})

View File

@ -1,51 +1,49 @@
"use strict";
var helper = require(__dirname + '/test-helper');
var pg = helper.pg;
var sink;
'use strict'
var helper = require(__dirname + '/test-helper')
var pg = helper.pg
var sink
const suite = new helper.Suite()
var testForTypeCoercion = function (type) {
const pool = new pg.Pool()
suite.test(`test type coercion ${type.name}`, (cb) => {
pool.connect(function (err, client, done) {
assert(!err);
client.query("create temp table test_type(col " + type.name + ")", assert.calls(function (err, result) {
assert(!err);
assert(!err)
client.query('create temp table test_type(col ' + type.name + ')', assert.calls(function (err, result) {
assert(!err)
type.values.forEach(function (val) {
var insertQuery = client.query('insert into test_type(col) VALUES($1)', [val], assert.calls(function (err, result) {
assert(!err);
}));
assert(!err)
}))
var query = client.query(new pg.Query({
name: 'get type ' + type.name,
text: 'select col from test_type'
}));
}))
query.on('error', function (err) {
console.log(err);
throw err;
});
console.log(err)
throw err
})
assert.emits(query, 'row', function (row) {
var expected = val + " (" + typeof val + ")";
var returned = row.col + " (" + typeof row.col + ")";
assert.strictEqual(row.col, val, "expected " + type.name + " of " + expected + " but got " + returned);
}, "row should have been called for " + type.name + " of " + val);
var expected = val + ' (' + typeof val + ')'
var returned = row.col + ' (' + typeof row.col + ')'
assert.strictEqual(row.col, val, 'expected ' + type.name + ' of ' + expected + ' but got ' + returned)
}, 'row should have been called for ' + type.name + ' of ' + val)
client.query('delete from test_type');
});
client.query('delete from test_type')
})
client.query('drop table test_type', function () {
done();
done()
pool.end(cb)
});
}));
})
}))
})
})
};
}
var types = [{
name: 'integer',
@ -101,96 +99,95 @@ var types = [{
}, {
name: 'time',
values: ['13:12:12.321', null]
}];
}]
// ignore some tests in binary mode
if (helper.config.binary) {
types = types.filter(function (type) {
return !(type.name in { 'real': 1, 'timetz': 1, 'time': 1, 'numeric': 1, 'bigint': 1 });
});
return !(type.name in { 'real': 1, 'timetz': 1, 'time': 1, 'numeric': 1, 'bigint': 1 })
})
}
var valueCount = 0;
var valueCount = 0
types.forEach(function (type) {
testForTypeCoercion(type)
});
})
suite.test("timestampz round trip", function (cb) {
var now = new Date();
var client = helper.client();
client.query("create temp table date_tests(name varchar(10), tstz timestamptz(3))");
suite.test('timestampz round trip', function (cb) {
var now = new Date()
var client = helper.client()
client.query('create temp table date_tests(name varchar(10), tstz timestamptz(3))')
client.query({
text: "insert into date_tests(name, tstz)VALUES($1, $2)",
text: 'insert into date_tests(name, tstz)VALUES($1, $2)',
name: 'add date',
values: ['now', now]
});
})
var result = client.query(new pg.Query({
name: 'get date',
text: 'select * from date_tests where name = $1',
values: ['now']
}));
}))
assert.emits(result, 'row', function (row) {
var date = row.tstz;
assert.equal(date.getYear(), now.getYear());
assert.equal(date.getMonth(), now.getMonth());
assert.equal(date.getDate(), now.getDate());
assert.equal(date.getHours(), now.getHours());
assert.equal(date.getMinutes(), now.getMinutes());
assert.equal(date.getSeconds(), now.getSeconds());
assert.equal(date.getMilliseconds(), now.getMilliseconds());
});
var date = row.tstz
assert.equal(date.getYear(), now.getYear())
assert.equal(date.getMonth(), now.getMonth())
assert.equal(date.getDate(), now.getDate())
assert.equal(date.getHours(), now.getHours())
assert.equal(date.getMinutes(), now.getMinutes())
assert.equal(date.getSeconds(), now.getSeconds())
assert.equal(date.getMilliseconds(), now.getMilliseconds())
})
client.on('drain', () => {
client.end(cb)
});
});
})
})
suite.test('selecting nulls', cb => {
const pool = new pg.Pool()
pool.connect(assert.calls(function (err, client, done) {
assert.ifError(err);
assert.ifError(err)
client.query('select null as res;', assert.calls(function (err, res) {
assert(!err);
assert(!err)
assert.strictEqual(res.rows[0].res, null)
}))
client.query('select 7 <> $1 as res;', [null], function (err, res) {
assert(!err);
assert.strictEqual(res.rows[0].res, null);
done();
assert(!err)
assert.strictEqual(res.rows[0].res, null)
done()
pool.end(cb)
})
}))
})
suite.test('date range extremes', function (done) {
var client = helper.client();
var client = helper.client()
// Set the server timeszone to the same as used for the test,
// otherwise (if server's timezone is ahead of GMT) in
// textParsers.js::parseDate() the timezone offest is added to the date;
// in the case of "275760-09-13 00:00:00 GMT" the timevalue overflows.
client.query('SET TIMEZONE TO GMT', assert.success(function (res) {
// PostgreSQL supports date range of 4713 BCE to 294276 CE
// http://www.postgresql.org/docs/9.2/static/datatype-datetime.html
// ECMAScript supports date range of Apr 20 271821 BCE to Sep 13 275760 CE
// http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1
client.query('SELECT $1::TIMESTAMPTZ as when', ["275760-09-13 00:00:00 GMT"], assert.success(function (res) {
assert.equal(res.rows[0].when.getFullYear(), 275760);
}));
client.query('SELECT $1::TIMESTAMPTZ as when', ['275760-09-13 00:00:00 GMT'], assert.success(function (res) {
assert.equal(res.rows[0].when.getFullYear(), 275760)
}))
client.query('SELECT $1::TIMESTAMPTZ as when', ["4713-12-31 12:31:59 BC GMT"], assert.success(function (res) {
assert.equal(res.rows[0].when.getFullYear(), -4713);
}));
client.query('SELECT $1::TIMESTAMPTZ as when', ['4713-12-31 12:31:59 BC GMT'], assert.success(function (res) {
assert.equal(res.rows[0].when.getFullYear(), -4713)
}))
client.query('SELECT $1::TIMESTAMPTZ as when', ["275760-09-13 00:00:00 -15:00"], assert.success(function (res) {
assert(isNaN(res.rows[0].when.getTime()));
}));
client.query('SELECT $1::TIMESTAMPTZ as when', ['275760-09-13 00:00:00 -15:00'], assert.success(function (res) {
assert(isNaN(res.rows[0].when.getTime()))
}))
client.on('drain', () => {
client.end(done)
});
}));
});
})
}))
})

View File

@ -1,37 +1,37 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
function testTypeParser(client, expectedResult, done) {
var boolValue = true;
client.query('CREATE TEMP TABLE parserOverrideTest(id bool)');
client.query('INSERT INTO parserOverrideTest(id) VALUES ($1)', [boolValue]);
client.query('SELECT * FROM parserOverrideTest', assert.success(function(result) {
assert.equal(result.rows[0].id, expectedResult);
done();
}));
function testTypeParser (client, expectedResult, done) {
var boolValue = true
client.query('CREATE TEMP TABLE parserOverrideTest(id bool)')
client.query('INSERT INTO parserOverrideTest(id) VALUES ($1)', [boolValue])
client.query('SELECT * FROM parserOverrideTest', assert.success(function (result) {
assert.equal(result.rows[0].id, expectedResult)
done()
}))
}
const pool = new helper.pg.Pool(helper.config)
pool.connect(assert.success(function(client1, done1) {
pool.connect(assert.success(function(client2, done2) {
var boolTypeOID = 16;
client1.setTypeParser(boolTypeOID, function(){
return 'first client';
});
client2.setTypeParser(boolTypeOID, function(){
return 'second client';
});
pool.connect(assert.success(function (client1, done1) {
pool.connect(assert.success(function (client2, done2) {
var boolTypeOID = 16
client1.setTypeParser(boolTypeOID, function () {
return 'first client'
})
client2.setTypeParser(boolTypeOID, function () {
return 'second client'
})
client1.setTypeParser(boolTypeOID, 'binary', function(){
return 'first client binary';
});
client2.setTypeParser(boolTypeOID, 'binary', function(){
return 'second client binary';
});
client1.setTypeParser(boolTypeOID, 'binary', function () {
return 'first client binary'
})
client2.setTypeParser(boolTypeOID, 'binary', function () {
return 'second client binary'
})
testTypeParser(client1, 'first client', () => {
done1()
testTypeParser(client2, 'second client', () => done2(), pool.end());
});
}));
}));
testTypeParser(client2, 'second client', () => done2(), pool.end())
})
}))
}))

View File

@ -1,10 +1,10 @@
"use strict";
var helper = require("./test-helper")
'use strict'
var helper = require('./test-helper')
helper.testPoolSize(1);
helper.testPoolSize(1)
helper.testPoolSize(2);
helper.testPoolSize(2)
helper.testPoolSize(40);
helper.testPoolSize(40)
helper.testPoolSize(200);
helper.testPoolSize(200)

View File

@ -1,9 +1,9 @@
"use strict";
var helper = require("./test-helper");
'use strict'
var helper = require('./test-helper')
const pg = helper.pg
//first make pool hold 2 clients
pg.defaults.poolSize = 2;
// first make pool hold 2 clients
pg.defaults.poolSize = 2
const pool = new pg.Pool()
@ -14,39 +14,37 @@ suite.test('connecting to invalid port', (cb) => {
})
suite.test('errors emitted on pool', (cb) => {
//get first client
// get first client
pool.connect(assert.success(function (client, done) {
client.id = 1;
client.id = 1
client.query('SELECT NOW()', function () {
pool.connect(assert.success(function (client2, done2) {
client2.id = 2;
var pidColName = 'procpid';
client2.id = 2
var pidColName = 'procpid'
helper.versionGTE(client2, '9.2.0', assert.success(function (isGreater) {
var killIdleQuery = 'SELECT pid, (SELECT pg_terminate_backend(pid)) AS killed FROM pg_stat_activity WHERE state = $1';
var params = ['idle'];
var killIdleQuery = 'SELECT pid, (SELECT pg_terminate_backend(pid)) AS killed FROM pg_stat_activity WHERE state = $1'
var params = ['idle']
if (!isGreater) {
killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE $1';
killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE $1'
params = ['%IDLE%']
}
pool.once('error', (err, brokenClient) => {
assert.ok(err);
assert.ok(brokenClient);
assert.equal(client.id, brokenClient.id);
assert.ok(err)
assert.ok(brokenClient)
assert.equal(client.id, brokenClient.id)
cb()
})
//kill the connection from client
// kill the connection from client
client2.query(killIdleQuery, params, assert.success(function (res) {
//check to make sure client connection actually was killed
//return client2 to the pool
done2();
pool.end();
}));
}));
}));
// check to make sure client connection actually was killed
// return client2 to the pool
done2()
pool.end()
}))
}))
}))
})
}));
}))
})

View File

@ -1,13 +1,12 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
new helper.Suite().test('idle timeout', function () {
const config = Object.assign({}, helper.config, { idleTimeoutMillis: 50 })
const pool = new helper.pg.Pool(config)
pool.connect(assert.calls(function (err, client, done) {
assert(!err);
client.query('SELECT NOW()');
done();
}));
});
assert(!err)
client.query('SELECT NOW()')
done()
}))
})

View File

@ -1,11 +1,11 @@
"use strict";
var helper = require("./../test-helper")
'use strict'
var helper = require('./../test-helper')
var pg = helper.pg
var native = helper.args.native
var pool = new pg.Pool()
pool.connect(assert.calls(function(err, client, done) {
pool.connect(assert.calls(function (err, client, done) {
if (native) {
assert(client.native)
} else {

View File

@ -1,5 +1,5 @@
"use strict";
var helper = require("./../test-helper");
'use strict'
var helper = require('./../test-helper')
const suite = new helper.Suite()
@ -9,19 +9,19 @@ helper.testPoolSize = function (max) {
var sink = new helper.Sink(max, function () {
pool.end(cb)
});
})
for (var i = 0; i < max; i++) {
pool.connect(function (err, client, done) {
assert(!err);
client.query("SELECT * FROM NOW()")
client.query("select generate_series(0, 25)", function (err, result) {
assert(!err)
client.query('SELECT * FROM NOW()')
client.query('select generate_series(0, 25)', function (err, result) {
assert.equal(result.rows.length, 26)
})
var query = client.query("SELECT * FROM NOW()", (err) => {
var query = client.query('SELECT * FROM NOW()', (err) => {
assert(!err)
sink.add();
done();
sink.add()
done()
})
})
}
@ -29,4 +29,3 @@ helper.testPoolSize = function (max) {
}
module.exports = Object.assign({}, helper, { suite: suite })

View File

@ -1,9 +1,9 @@
"use strict";
'use strict'
var helper = require('./test-helper')
var co = require('co')
const pool = new helper.pg.Pool()
new helper.Suite().test('using coroutines works with promises', co.wrap(function* () {
new helper.Suite().test('using coroutines works with promises', co.wrap(function * () {
var client = yield pool.connect()
var res = yield client.query('SELECT $1::text as name', ['foo'])
assert.equal(res.rows[0].name, 'foo')

View File

@ -1,61 +1,58 @@
"use strict";
var helper = require(__dirname + '/test-helper');
//http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
'use strict'
var helper = require(__dirname + '/test-helper')
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
test('flushing once', function() {
helper.connect(function(con) {
test('flushing once', function () {
helper.connect(function (con) {
con.parse({
text: 'select * from ids'
});
})
con.bind();
con.execute();
con.flush();
con.bind()
con.execute()
con.flush()
assert.emits(con, 'parseComplete');
assert.emits(con, 'bindComplete');
assert.emits(con, 'dataRow');
assert.emits(con, 'commandComplete', function(){
con.sync();
});
assert.emits(con, 'readyForQuery', function(){
con.end();
});
assert.emits(con, 'parseComplete')
assert.emits(con, 'bindComplete')
assert.emits(con, 'dataRow')
assert.emits(con, 'commandComplete', function () {
con.sync()
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
});
});
test('sending many flushes', function () {
helper.connect(function (con) {
assert.emits(con, 'parseComplete', function () {
con.bind()
con.flush()
})
test("sending many flushes", function() {
helper.connect(function(con) {
assert.emits(con, 'bindComplete', function () {
con.execute()
con.flush()
})
assert.emits(con, 'parseComplete', function(){
con.bind();
con.flush();
});
assert.emits(con, 'bindComplete', function(){
con.execute();
con.flush();
});
assert.emits(con, 'dataRow', function(msg){
assert.equal(msg.fields[0], 1);
assert.emits(con, 'dataRow', function(msg){
assert.equal(msg.fields[0], 2);
assert.emits(con, 'commandComplete', function(){
con.sync();
});
assert.emits(con, 'readyForQuery', function(){
con.end();
});
});
});
assert.emits(con, 'dataRow', function (msg) {
assert.equal(msg.fields[0], 1)
assert.emits(con, 'dataRow', function (msg) {
assert.equal(msg.fields[0], 2)
assert.emits(con, 'commandComplete', function () {
con.sync()
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
con.parse({
text: "select * from ids order by id"
});
text: 'select * from ids order by id'
})
con.flush();
});
});
con.flush()
})
})

View File

@ -1,45 +1,45 @@
"use strict";
var helper = require(__dirname+"/test-helper");
var assert = require('assert');
'use strict'
var helper = require(__dirname + '/test-helper')
var assert = require('assert')
test('COPY FROM events check', function () {
helper.connect(function (con) {
var stdinStream = con.query('COPY person FROM STDIN');
helper.connect(function (con) {
var stdinStream = con.query('COPY person FROM STDIN')
con.on('copyInResponse', function () {
con.endCopyFrom();
});
con.endCopyFrom()
})
assert.emits(con, 'copyInResponse',
function () {
con.endCopyFrom();
con.endCopyFrom()
},
"backend should emit copyInResponse after COPY FROM query"
);
'backend should emit copyInResponse after COPY FROM query'
)
assert.emits(con, 'commandComplete',
function () {
con.end();
con.end()
},
"backend should emit commandComplete after COPY FROM stream ends"
'backend should emit commandComplete after COPY FROM stream ends'
)
});
});
})
})
test('COPY TO events check', function () {
helper.connect(function (con) {
var stdoutStream = con.query('COPY person TO STDOUT');
var stdoutStream = con.query('COPY person TO STDOUT')
assert.emits(con, 'copyOutResponse',
function () {
},
"backend should emit copyOutResponse after COPY TO query"
);
'backend should emit copyOutResponse after COPY TO query'
)
assert.emits(con, 'copyData',
function () {
},
"backend should emit copyData on every data row"
);
'backend should emit copyData on every data row'
)
assert.emits(con, 'copyDone',
function () {
con.end();
con.end()
},
"backend should emit copyDone after all data rows"
);
});
});
'backend should emit copyDone after all data rows'
)
})
})

View File

@ -1,16 +1,16 @@
"use strict";
var helper = require(__dirname + '/test-helper');
//http://www.postgresql.org/docs/8.3/static/libpq-notify.html
test('recieves notification from same connection with no payload', function() {
helper.connect(function(con) {
con.query('LISTEN boom');
assert.emits(con, 'readyForQuery', function() {
con.query("NOTIFY boom");
assert.emits(con, 'notification', function(msg) {
assert.equal(msg.payload, "");
'use strict'
var helper = require(__dirname + '/test-helper')
// http://www.postgresql.org/docs/8.3/static/libpq-notify.html
test('recieves notification from same connection with no payload', function () {
helper.connect(function (con) {
con.query('LISTEN boom')
assert.emits(con, 'readyForQuery', function () {
con.query('NOTIFY boom')
assert.emits(con, 'notification', function (msg) {
assert.equal(msg.payload, '')
assert.equal(msg.channel, 'boom')
con.end();
});
});
});
});
con.end()
})
})
})
})

View File

@ -1,26 +1,26 @@
"use strict";
var helper = require(__dirname+"/test-helper");
var assert = require('assert');
'use strict'
var helper = require(__dirname + '/test-helper')
var assert = require('assert')
var rows = [];
//testing the low level 1-1 mapping api of client to postgres messages
//it's cumbersome to use the api this way
test('simple query', function() {
helper.connect(function(con) {
con.query('select * from ids');
assert.emits(con, 'dataRow');
con.on('dataRow', function(msg) {
rows.push(msg.fields);
});
assert.emits(con, 'readyForQuery', function() {
con.end();
});
});
});
var rows = []
// testing the low level 1-1 mapping api of client to postgres messages
// it's cumbersome to use the api this way
test('simple query', function () {
helper.connect(function (con) {
con.query('select * from ids')
assert.emits(con, 'dataRow')
con.on('dataRow', function (msg) {
rows.push(msg.fields)
})
assert.emits(con, 'readyForQuery', function () {
con.end()
})
})
})
process.on('exit', function() {
assert.equal(rows.length, 2);
assert.equal(rows[0].length, 1);
assert.strictEqual(String(rows[0] [0]), '1');
assert.strictEqual(String(rows[1] [0]), '2');
});
process.on('exit', function () {
assert.equal(rows.length, 2)
assert.equal(rows[0].length, 1)
assert.strictEqual(String(rows[0][0]), '1')
assert.strictEqual(String(rows[1][0]), '2')
})

View File

@ -1,43 +1,43 @@
"use strict";
var net = require('net');
var helper = require(__dirname+'/../test-helper');
var Connection = require(__dirname + '/../../../lib/connection');
var connect = function(callback) {
var username = helper.args.user;
var database = helper.args.database;
var con = new Connection({stream: new net.Stream()});
con.on('error', function(error){
console.log(error);
throw new Error("Connection error");
});
con.connect(helper.args.port || '5432', helper.args.host || 'localhost');
con.once('connect', function() {
'use strict'
var net = require('net')
var helper = require(__dirname + '/../test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
var connect = function (callback) {
var username = helper.args.user
var database = helper.args.database
var con = new Connection({stream: new net.Stream()})
con.on('error', function (error) {
console.log(error)
throw new Error('Connection error')
})
con.connect(helper.args.port || '5432', helper.args.host || 'localhost')
con.once('connect', function () {
con.startup({
user: username,
database: database
});
con.once('authenticationCleartextPassword', function(){
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.once('readyForQuery', function() {
con.query('create temp table ids(id integer)');
con.once('readyForQuery', function() {
con.query('insert into ids(id) values(1); insert into ids(id) values(2);');
con.once('readyForQuery', function() {
callback(con);
});
});
});
});
};
})
con.once('authenticationCleartextPassword', function () {
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.once('readyForQuery', function () {
con.query('create temp table ids(id integer)')
con.once('readyForQuery', function () {
con.query('insert into ids(id) values(1); insert into ids(id) values(2);')
con.once('readyForQuery', function () {
callback(con)
})
})
})
})
}
module.exports = {
connect: connect
};
}

View File

@ -1,4 +1,4 @@
"use strict";
'use strict'
var async = require('async')
var helper = require('./test-helper')

View File

@ -1,23 +1,23 @@
"use strict";
var helper = require(__dirname + '/../test-helper');
var exec = require('child_process').exec;
'use strict'
var helper = require(__dirname + '/../test-helper')
var exec = require('child_process').exec
helper.pg.defaults.poolIdleTimeout = 1000;
helper.pg.defaults.poolIdleTimeout = 1000
const pool = new helper.pg.Pool()
pool.connect(function(err,client) {
client.query("SELECT pg_backend_pid()", function(err, result) {
var pid = result.rows[0].pg_backend_pid;
var psql = 'psql';
if (helper.args.host) psql = psql+' -h '+helper.args.host;
if (helper.args.port) psql = psql+' -p '+helper.args.port;
if (helper.args.user) psql = psql+' -U '+helper.args.user;
exec(psql+' -c "select pg_terminate_backend('+pid+')" template1', assert.calls(function (error, stdout, stderr) {
assert.isNull(error);
}));
});
});
pool.connect(function (err, client) {
client.query('SELECT pg_backend_pid()', function (err, result) {
var pid = result.rows[0].pg_backend_pid
var psql = 'psql'
if (helper.args.host) psql = psql + ' -h ' + helper.args.host
if (helper.args.port) psql = psql + ' -p ' + helper.args.port
if (helper.args.user) psql = psql + ' -U ' + helper.args.user
exec(psql + ' -c "select pg_terminate_backend(' + pid + ')" template1', assert.calls(function (error, stdout, stderr) {
assert.isNull(error)
}))
})
})
pool.on('error', function(err, client) {
//swallow errors
});
pool.on('error', function (err, client) {
// swallow errors
})

View File

@ -1,20 +1,20 @@
"use strict";
var helper = require('../test-helper');
var pg = helper.pg;
'use strict'
var helper = require('../test-helper')
var pg = helper.pg
var suite = new helper.Suite()
suite.test('parsing array decimal results', function (done) {
const pool = new pg.Pool()
pool.connect(assert.calls(function (err, client, release) {
assert(!err);
client.query("CREATE TEMP TABLE why(names text[], numbors integer[], decimals double precision[])");
client.query(new pg.Query('INSERT INTO why(names, numbors, decimals) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\', \'{.1, 0.05, 3.654}\')')).on('error', console.log);
assert(!err)
client.query('CREATE TEMP TABLE why(names text[], numbors integer[], decimals double precision[])')
client.query(new pg.Query('INSERT INTO why(names, numbors, decimals) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\', \'{.1, 0.05, 3.654}\')')).on('error', console.log)
client.query('SELECT decimals FROM why', assert.success(function (result) {
assert.lengthIs(result.rows[0].decimals, 3);
assert.equal(result.rows[0].decimals[0], 0.1);
assert.equal(result.rows[0].decimals[1], 0.05);
assert.equal(result.rows[0].decimals[2], 3.654);
assert.lengthIs(result.rows[0].decimals, 3)
assert.equal(result.rows[0].decimals[0], 0.1)
assert.equal(result.rows[0].decimals[1], 0.05)
assert.equal(result.rows[0].decimals[2], 3.654)
release()
pool.end(done)
}))

View File

@ -1,22 +1,22 @@
"use strict";
var helper = require('../test-helper');
var client = helper.client();
'use strict'
var helper = require('../test-helper')
var client = helper.client()
client.query('CREATE TEMP TABLE arrtest (n integer, s varchar)');
client.query("INSERT INTO arrtest VALUES (4, 'foo'), (5, 'bar'), (6, 'baz');");
client.query('CREATE TEMP TABLE arrtest (n integer, s varchar)')
client.query("INSERT INTO arrtest VALUES (4, 'foo'), (5, 'bar'), (6, 'baz');")
var qText = "SELECT \
ARRAY[1, 2, 3] AS b,\
ARRAY['xx', 'yy', 'zz'] AS c,\
ARRAY(SELECT n FROM arrtest) AS d,\
ARRAY(SELECT s FROM arrtest) AS e;";
ARRAY(SELECT s FROM arrtest) AS e;"
client.query(qText, function(err, result) {
if(err) throw err;
var row = result.rows[0];
for(var key in row) {
assert.equal(typeof row[key], 'object');
assert.equal(row[key].length, 3);
client.query(qText, function (err, result) {
if (err) throw err
var row = result.rows[0]
for (var key in row) {
assert.equal(typeof row[key], 'object')
assert.equal(row[key].length, 3)
}
client.end();
});
client.end()
})

View File

@ -1,13 +1,13 @@
"use strict";
var helper = require(__dirname + "/../test-helper");
var pg = helper.pg;
'use strict'
var helper = require(__dirname + '/../test-helper')
var pg = helper.pg
new helper.Suite().test('parsing array results', function(cb) {
new helper.Suite().test('parsing array results', function (cb) {
const pool = new pg.Pool()
pool.connect(assert.success(function(client, done) {
pool.connect(assert.success(function (client, done) {
client.query('CREATE TEMP TABLE test_table(bar integer, "baz\'s" integer)')
client.query('INSERT INTO test_table(bar, "baz\'s") VALUES(1, 1), (2, 2)')
client.query('SELECT * FROM test_table', function(err, res) {
client.query('SELECT * FROM test_table', function (err, res) {
assert.equal(res.rows[0]["baz's"], 1)
assert.equal(res.rows[1]["baz's"], 2)
done()

View File

@ -1,51 +1,51 @@
"use strict";
var async = require('async');
var helper = require('../test-helper');
'use strict'
var async = require('async')
var helper = require('../test-helper')
const suite = new helper.Suite()
var db = helper.client();
var db = helper.client()
function createTableFoo(callback){
db.query("create temp table foo(column1 int, column2 int)", callback);
function createTableFoo (callback) {
db.query('create temp table foo(column1 int, column2 int)', callback)
}
function createTableBar(callback){
db.query("create temp table bar(column1 text, column2 text)", callback);
function createTableBar (callback) {
db.query('create temp table bar(column1 text, column2 text)', callback)
}
function insertDataFoo(callback){
db.query({
name: 'insertFoo',
text: 'insert into foo values($1,$2)',
values:['one','two']
}, callback );
function insertDataFoo (callback) {
db.query({
name: 'insertFoo',
text: 'insert into foo values($1,$2)',
values: ['one', 'two']
}, callback)
}
function insertDataBar(callback){
db.query({
name: 'insertBar',
text: 'insert into bar values($1,$2)',
values:['one','two']
}, callback );
function insertDataBar (callback) {
db.query({
name: 'insertBar',
text: 'insert into bar values($1,$2)',
values: ['one', 'two']
}, callback)
}
function startTransaction(callback) {
db.query('BEGIN', callback);
function startTransaction (callback) {
db.query('BEGIN', callback)
}
function endTransaction(callback) {
db.query('COMMIT', callback);
function endTransaction (callback) {
db.query('COMMIT', callback)
}
function doTransaction(callback) {
function doTransaction (callback) {
// The transaction runs startTransaction, then all queries, then endTransaction,
// no matter if there has been an error in a query in the middle.
startTransaction(function() {
insertDataFoo(function() {
insertDataBar(function() {
endTransaction( callback );
});
});
});
startTransaction(function () {
insertDataFoo(function () {
insertDataBar(function () {
endTransaction(callback)
})
})
})
}
var steps = [
@ -55,27 +55,26 @@ var steps = [
insertDataBar
]
suite.test('test if query fails', function(done) {
async.series(steps, assert.success(function() {
suite.test('test if query fails', function (done) {
async.series(steps, assert.success(function () {
db.end()
done()
}))
})
suite.test('test if prepare works but bind fails', function(done) {
var client = helper.client();
suite.test('test if prepare works but bind fails', function (done) {
var client = helper.client()
var q = {
text: 'SELECT $1::int as name',
values: ['brian'],
name: 'test'
};
client.query(q, assert.calls(function(err, res) {
q.values = [1];
client.query(q, assert.calls(function(err, res) {
assert.ifError(err);
client.end();
}
client.query(q, assert.calls(function (err, res) {
q.values = [1]
client.query(q, assert.calls(function (err, res) {
assert.ifError(err)
client.end()
done()
}));
}));
});
}))
}))
})

View File

@ -1,30 +1,30 @@
"use strict";
var helper = require('../test-helper');
var assert = require('assert');
'use strict'
var helper = require('../test-helper')
var assert = require('assert')
const pool = new helper.pg.Pool()
pool.connect(function(err, client, done) {
if (err) throw err;
pool.connect(function (err, client, done) {
if (err) throw err
var c = 'CREATE TEMP TABLE posts (body TEXT)';
var c = 'CREATE TEMP TABLE posts (body TEXT)'
client.query(c, function(err) {
if (err) throw err;
client.query(c, function (err) {
if (err) throw err
c = 'INSERT INTO posts (body) VALUES ($1) RETURNING *';
c = 'INSERT INTO posts (body) VALUES ($1) RETURNING *'
var body = Buffer.from('foo');
client.query(c, [body], function(err) {
if (err) throw err;
var body = Buffer.from('foo')
client.query(c, [body], function (err) {
if (err) throw err
body = Buffer.from([]);
client.query(c, [body], function(err, res) {
done();
body = Buffer.from([])
client.query(c, [body], function (err, res) {
done()
if (err) throw err;
if (err) throw err
assert.equal(res.rows[0].body, '')
pool.end();
});
});
});
});
pool.end()
})
})
})
})

View File

@ -1,13 +1,13 @@
"use strict";
var helper = require('../test-helper');
'use strict'
var helper = require('../test-helper')
const pool = new helper.pg.Pool()
pool.connect(function(err,client) {
pool.connect(function (err, client) {
var q = {
name: 'This is a super long query name just so I can test that an error message is properly spit out to console.error without throwing an exception or anything',
text: 'SELECT NOW()'
};
client.query(q, function() {
client.end();
});
});
}
client.query(q, function () {
client.end()
})
})

View File

@ -1,9 +1,9 @@
"use strict";
//client should not hang on an empty query
var helper = require('../test-helper');
var client = helper.client();
client.query({ name: 'foo1', text: null});
client.query({ name: 'foo2', text: ' ' });
client.query({ name: 'foo3', text: '' }, function(err, res) {
client.end();
});
'use strict'
// client should not hang on an empty query
var helper = require('../test-helper')
var client = helper.client()
client.query({ name: 'foo1', text: null})
client.query({ name: 'foo2', text: ' ' })
client.query({ name: 'foo3', text: '' }, function (err, res) {
client.end()
})

View File

@ -1,28 +1,27 @@
"use strict";
var helper = require('./../test-helper');
'use strict'
var helper = require('./../test-helper')
if(helper.args.native) {
Client = require('./../../lib/native');
helper.Client = Client;
helper.pg = helper.pg.native;
if (helper.args.native) {
Client = require('./../../lib/native')
helper.Client = Client
helper.pg = helper.pg.native
}
//creates a client from cli parameters
helper.client = function(cb) {
var client = new Client();
client.connect(cb);
return client;
};
// creates a client from cli parameters
helper.client = function (cb) {
var client = new Client()
client.connect(cb)
return client
}
var semver = require('semver');
helper.versionGTE = function(client, versionString, callback) {
client.query('SELECT version()', assert.calls(function(err, result) {
if(err) return callback(err);
var version = result.rows[0].version.split(' ')[1];
return callback(null, semver.gte(version, versionString));
}));
};
//export parent helper stuffs
module.exports = helper;
var semver = require('semver')
helper.versionGTE = function (client, versionString, callback) {
client.query('SELECT version()', assert.calls(function (err, result) {
if (err) return callback(err)
var version = result.rows[0].version.split(' ')[1]
return callback(null, semver.gte(version, versionString))
}))
}
// export parent helper stuffs
module.exports = helper

View File

@ -1,34 +1,34 @@
"use strict";
var domain = require('domain');
var helper = require("./../test-helper");
var Client = require("./../../lib/native");
'use strict'
var domain = require('domain')
var helper = require('./../test-helper')
var Client = require('./../../lib/native')
const suite = new helper.Suite()
suite.test('fires callback with results', function(done) {
var client = new Client(helper.config);
client.connect();
client.query('SELECT 1 as num', assert.calls(function(err, result) {
assert(!err);
assert.equal(result.rows[0].num, 1);
assert.strictEqual(result.rowCount, 1);
client.query('SELECT * FROM person WHERE name = $1', ['Brian'], assert.calls(function(err, result) {
assert(!err);
assert.equal(result.rows[0].name, 'Brian');
client.end(done);
suite.test('fires callback with results', function (done) {
var client = new Client(helper.config)
client.connect()
client.query('SELECT 1 as num', assert.calls(function (err, result) {
assert(!err)
assert.equal(result.rows[0].num, 1)
assert.strictEqual(result.rowCount, 1)
client.query('SELECT * FROM person WHERE name = $1', ['Brian'], assert.calls(function (err, result) {
assert(!err)
assert.equal(result.rows[0].name, 'Brian')
client.end(done)
}))
}));
}))
})
suite.test('preserves domain', function(done) {
var dom = domain.create();
suite.test('preserves domain', function (done) {
var dom = domain.create()
dom.run(function() {
var client = new Client(helper.config);
assert.ok(dom === require('domain').active, 'domain is active');
dom.run(function () {
var client = new Client(helper.config)
assert.ok(dom === require('domain').active, 'domain is active')
client.connect()
client.query('select 1', function() {
assert.ok(dom === require('domain').active, 'domain is still active');
client.end(done);
});
});
client.query('select 1', function () {
assert.ok(dom === require('domain').active, 'domain is still active')
client.end(done)
})
})
})

View File

@ -1,34 +1,34 @@
"use strict";
var helper = require("../test-helper");
var Client = require("../../lib/native");
var Query = Client.Query;
'use strict'
var helper = require('../test-helper')
var Client = require('../../lib/native')
var Query = Client.Query
var setupClient = function() {
var client = new Client(helper.config);
client.connect();
client.query("CREATE TEMP TABLE boom(name varchar(10), age integer)");
client.query("INSERT INTO boom(name, age) VALUES('Aaron', 26)");
client.query("INSERT INTO boom(name, age) VALUES('Brian', 28)");
return client;
var setupClient = function () {
var client = new Client(helper.config)
client.connect()
client.query('CREATE TEMP TABLE boom(name varchar(10), age integer)')
client.query("INSERT INTO boom(name, age) VALUES('Aaron', 26)")
client.query("INSERT INTO boom(name, age) VALUES('Brian', 28)")
return client
}
test('multiple results', function() {
test('queued queries', function() {
var client = setupClient();
var q = client.query(new Query("SELECT name FROM BOOM"));
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Aaron');
assert.emits(q, 'row', function(row) {
assert.equal(row.name, "Brian");
test('multiple results', function () {
test('queued queries', function () {
var client = setupClient()
var q = client.query(new Query('SELECT name FROM BOOM'))
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Aaron')
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Brian')
})
})
assert.emits(q, 'end', function() {
test('query with config', function() {
var q2 = client.query(new Query({text:'SELECT 1 as num'}));
assert.emits(q2, 'row', function(row) {
assert.strictEqual(row.num, 1);
assert.emits(q2, 'end', function() {
client.end();
assert.emits(q, 'end', function () {
test('query with config', function () {
var q2 = client.query(new Query({text: 'SELECT 1 as num'}))
assert.emits(q2, 'row', function (row) {
assert.strictEqual(row.num, 1)
assert.emits(q2, 'end', function () {
client.end()
})
})
})
@ -36,55 +36,55 @@ test('multiple results', function() {
})
})
test('parameterized queries', function() {
test('with a single string param', function() {
var client = setupClient();
var q = client.query(new Query("SELECT * FROM boom WHERE name = $1", ['Aaron']));
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Aaron');
test('parameterized queries', function () {
test('with a single string param', function () {
var client = setupClient()
var q = client.query(new Query('SELECT * FROM boom WHERE name = $1', ['Aaron']))
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Aaron')
})
assert.emits(q, 'end', function () {
client.end()
})
assert.emits(q, 'end', function() {
client.end();
});
})
test('with object config for query', function() {
var client = setupClient();
test('with object config for query', function () {
var client = setupClient()
var q = client.query(new Query({
text: "SELECT name FROM boom WHERE name = $1",
text: 'SELECT name FROM boom WHERE name = $1',
values: ['Brian']
}));
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Brian');
}))
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Brian')
})
assert.emits(q, 'end', function() {
client.end();
assert.emits(q, 'end', function () {
client.end()
})
})
test('multiple parameters', function() {
var client = setupClient();
var q = client.query(new Query('SELECT name FROM boom WHERE name = $1 or name = $2 ORDER BY name', ['Aaron', 'Brian']));
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Aaron');
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Brian');
assert.emits(q, 'end', function() {
client.end();
test('multiple parameters', function () {
var client = setupClient()
var q = client.query(new Query('SELECT name FROM boom WHERE name = $1 or name = $2 ORDER BY name', ['Aaron', 'Brian']))
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Aaron')
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Brian')
assert.emits(q, 'end', function () {
client.end()
})
})
})
})
test('integer parameters', function() {
var client = setupClient();
var q = client.query(new Query('SELECT * FROM boom WHERE age > $1', [27]));
assert.emits(q, 'row', function(row) {
assert.equal(row.name, 'Brian');
assert.equal(row.age, 28);
});
assert.emits(q, 'end', function() {
client.end();
test('integer parameters', function () {
var client = setupClient()
var q = client.query(new Query('SELECT * FROM boom WHERE age > $1', [27]))
assert.emits(q, 'row', function (row) {
assert.equal(row.name, 'Brian')
assert.equal(row.age, 28)
})
assert.emits(q, 'end', function () {
client.end()
})
})
})

View File

@ -1,7 +1,7 @@
"use strict";
//this test assumes it has been run from the Makefile
//and that node_modules/pg-native has been deleted
'use strict'
// this test assumes it has been run from the Makefile
// and that node_modules/pg-native has been deleted
var assert = require('assert');
var assert = require('assert')
assert.equal(require('../../lib').native, null);
assert.equal(require('../../lib').native, null)

View File

@ -1,21 +1,21 @@
"use strict";
'use strict'
var assert = require('assert')
var Client = require('../../lib/client');
var NativeClient = require('../../lib/native');
var Client = require('../../lib/client')
var NativeClient = require('../../lib/native')
var client = new Client();
var nativeClient = new NativeClient();
var client = new Client()
var nativeClient = new NativeClient()
client.connect();
client.connect()
nativeClient.connect((err) => {
client.query('SELECT alsdkfj', (err) => {
client.end();
client.end()
nativeClient.query('SELECT lkdasjfasd', (nativeErr) => {
for(var key in nativeErr) {
for (var key in nativeErr) {
assert.equal(err[key], nativeErr[key], `Expected err.${key} to equal nativeErr.${key}`)
}
nativeClient.end();
});
});
});
nativeClient.end()
})
})
})

View File

@ -1,51 +1,51 @@
"use strict";
var helper = require(__dirname + "/../test-helper");
var Client = require(__dirname + "/../../lib/native");
var Query = Client.Query;
'use strict'
var helper = require(__dirname + '/../test-helper')
var Client = require(__dirname + '/../../lib/native')
var Query = Client.Query
test('many rows', function() {
var client = new Client(helper.config);
client.connect();
var q = client.query(new Query("SELECT * FROM person"));
var rows = [];
q.on('row', function(row) {
test('many rows', function () {
var client = new Client(helper.config)
client.connect()
var q = client.query(new Query('SELECT * FROM person'))
var rows = []
q.on('row', function (row) {
rows.push(row)
});
assert.emits(q, 'end', function() {
client.end();
assert.lengthIs(rows, 26);
})
});
assert.emits(q, 'end', function () {
client.end()
assert.lengthIs(rows, 26)
})
})
test('many queries', function() {
var client = new Client(helper.config);
client.connect();
var count = 0;
var expected = 100;
for(var i = 0; i < expected; i++) {
var q = client.query(new Query("SELECT * FROM person"));
assert.emits(q, 'end', function() {
count++;
});
test('many queries', function () {
var client = new Client(helper.config)
client.connect()
var count = 0
var expected = 100
for (var i = 0; i < expected; i++) {
var q = client.query(new Query('SELECT * FROM person'))
assert.emits(q, 'end', function () {
count++
})
}
assert.emits(client, 'drain', function() {
client.end();
assert.equal(count, expected);
});
});
assert.emits(client, 'drain', function () {
client.end()
assert.equal(count, expected)
})
})
test('many clients', function() {
var clients = [];
for(var i = 0; i < 10; i++) {
clients.push(new Client(helper.config));
test('many clients', function () {
var clients = []
for (var i = 0; i < 10; i++) {
clients.push(new Client(helper.config))
}
clients.forEach(function(client) {
client.connect();
for(var i = 0; i < 20; i++) {
client.query('SELECT * FROM person');
clients.forEach(function (client) {
client.connect()
for (var i = 0; i < 20; i++) {
client.query('SELECT * FROM person')
}
assert.emits(client, 'drain', function() {
client.end();
assert.emits(client, 'drain', function () {
client.end()
})
})
})

View File

@ -1,16 +1,16 @@
"use strict";
'use strict';
'use strict'
'use strict'
const async = require('async')
class Test {
constructor(name, cb) {
constructor (name, cb) {
this.name = name
this.action = cb
this.timeout = 5000
}
run(cb) {
run (cb) {
try {
this._run(cb)
} catch (e) {
@ -18,7 +18,7 @@ class Test {
}
}
_run(cb) {
_run (cb) {
if (!this.action) {
console.log(`${this.name} skipped`)
return cb()
@ -38,13 +38,13 @@ class Test {
}
class Suite {
constructor(name) {
constructor (name) {
console.log('')
this._queue = async.queue(this.run.bind(this), 1)
this._queue.drain = () => { }
}
run(test, cb) {
run (test, cb) {
process.stdout.write(' ' + test.name + ' ')
if (!test.action) {
process.stdout.write('? - SKIPPED\n')
@ -69,7 +69,7 @@ class Suite {
})
}
test(name, cb) {
test (name, cb) {
const test = new Test(name, cb)
this._queue.push(test)
}

View File

@ -1,58 +1,58 @@
"use strict";
require(__dirname+'/test-helper');
//http://developer.postgresql.org/pgdocs/postgres/protocol-message-formats.html
'use strict'
require(__dirname + '/test-helper')
// http://developer.postgresql.org/pgdocs/postgres/protocol-message-formats.html
var buffers = {};
buffers.readyForQuery = function() {
var buffers = {}
buffers.readyForQuery = function () {
return new BufferList()
.add(Buffer.from('I'))
.join(true,'Z');
};
.join(true, 'Z')
}
buffers.authenticationOk = function() {
buffers.authenticationOk = function () {
return new BufferList()
.addInt32(0)
.join(true, 'R');
};
.join(true, 'R')
}
buffers.authenticationCleartextPassword = function() {
buffers.authenticationCleartextPassword = function () {
return new BufferList()
.addInt32(3)
.join(true, 'R');
};
.join(true, 'R')
}
buffers.authenticationMD5Password = function() {
buffers.authenticationMD5Password = function () {
return new BufferList()
.addInt32(5)
.add(Buffer.from([1,2,3,4]))
.join(true, 'R');
};
.add(Buffer.from([1, 2, 3, 4]))
.join(true, 'R')
}
buffers.parameterStatus = function(name, value) {
buffers.parameterStatus = function (name, value) {
return new BufferList()
.addCString(name)
.addCString(value)
.join(true, 'S');
};
.join(true, 'S')
}
buffers.backendKeyData = function(processID, secretKey) {
buffers.backendKeyData = function (processID, secretKey) {
return new BufferList()
.addInt32(processID)
.addInt32(secretKey)
.join(true, 'K');
};
.join(true, 'K')
}
buffers.commandComplete = function(string) {
buffers.commandComplete = function (string) {
return new BufferList()
.addCString(string)
.join(true, 'C');
};
.join(true, 'C')
}
buffers.rowDescription = function(fields) {
fields = fields || [];
var buf = new BufferList();
buf.addInt16(fields.length);
fields.forEach(function(field) {
buffers.rowDescription = function (fields) {
fields = fields || []
var buf = new BufferList()
buf.addInt16(fields.length)
fields.forEach(function (field) {
buf.addCString(field.name)
.addInt32(field.tableID || 0)
.addInt16(field.attributeNumber || 0)
@ -60,66 +60,66 @@ buffers.rowDescription = function(fields) {
.addInt16(field.dataTypeSize || 0)
.addInt32(field.typeModifier || 0)
.addInt16(field.formatCode || 0)
});
return buf.join(true, 'T');
};
buffers.dataRow = function(columns) {
columns = columns || [];
var buf = new BufferList();
buf.addInt16(columns.length);
columns.forEach(function(col) {
if(col == null) {
buf.addInt32(-1);
} else {
var strBuf = Buffer.from(col, 'utf8');
buf.addInt32(strBuf.length);
buf.add(strBuf);
}
});
return buf.join(true, 'D');
};
buffers.error = function(fields) {
return errorOrNotice(fields).join(true, 'E');
};
buffers.notice = function(fields) {
return errorOrNotice(fields).join(true, 'N');
};
var errorOrNotice = function(fields) {
fields = fields || [];
var buf = new BufferList();
fields.forEach(function(field) {
buf.addChar(field.type);
buf.addCString(field.value);
});
return buf.add(Buffer.from([0]));//terminator
})
return buf.join(true, 'T')
}
buffers.parseComplete = function() {
return new BufferList().join(true, '1');
};
buffers.dataRow = function (columns) {
columns = columns || []
var buf = new BufferList()
buf.addInt16(columns.length)
columns.forEach(function (col) {
if (col == null) {
buf.addInt32(-1)
} else {
var strBuf = Buffer.from(col, 'utf8')
buf.addInt32(strBuf.length)
buf.add(strBuf)
}
})
return buf.join(true, 'D')
}
buffers.bindComplete = function() {
return new BufferList().join(true, '2');
};
buffers.error = function (fields) {
return errorOrNotice(fields).join(true, 'E')
}
buffers.notification = function(id, channel, payload) {
buffers.notice = function (fields) {
return errorOrNotice(fields).join(true, 'N')
}
var errorOrNotice = function (fields) {
fields = fields || []
var buf = new BufferList()
fields.forEach(function (field) {
buf.addChar(field.type)
buf.addCString(field.value)
})
return buf.add(Buffer.from([0]))// terminator
}
buffers.parseComplete = function () {
return new BufferList().join(true, '1')
}
buffers.bindComplete = function () {
return new BufferList().join(true, '2')
}
buffers.notification = function (id, channel, payload) {
return new BufferList()
.addInt32(id)
.addCString(channel)
.addCString(payload)
.join(true, 'A')
};
}
buffers.emptyQuery = function() {
return new BufferList().join(true, 'I');
};
buffers.emptyQuery = function () {
return new BufferList().join(true, 'I')
}
buffers.portalSuspended = function() {
return new BufferList().join(true, 's');
};
buffers.portalSuspended = function () {
return new BufferList().join(true, 's')
}
module.exports = buffers;
module.exports = buffers

View File

@ -1,171 +1,170 @@
"use strict";
//make assert a global...
global.assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var sys = require('util');
'use strict'
// make assert a global...
global.assert = require('assert')
var EventEmitter = require('events').EventEmitter
var sys = require('util')
var BufferList = require('./buffer-list')
const Suite = require('./suite')
const args = require('./cli');
const args = require('./cli')
var Connection = require('./../lib/connection');
var Connection = require('./../lib/connection')
global.Client = require('./../lib').Client;
global.Client = require('./../lib').Client
process.on('uncaughtException', function(d) {
process.on('uncaughtException', function (d) {
if ('stack' in d && 'message' in d) {
console.log("Message: " + d.message);
console.log(d.stack);
console.log('Message: ' + d.message)
console.log(d.stack)
} else {
console.log(d);
console.log(d)
}
process.exit(-1);
});
process.exit(-1)
})
assert.same = function(actual, expected) {
for(var key in expected) {
assert.equal(actual[key], expected[key]);
assert.same = function (actual, expected) {
for (var key in expected) {
assert.equal(actual[key], expected[key])
}
};
}
assert.emits = function(item, eventName, callback, message) {
var called = false;
var id = setTimeout(function() {
test("Should have called '" + eventName + "' event", function() {
assert.emits = function (item, eventName, callback, message) {
var called = false
var id = setTimeout(function () {
test("Should have called '" + eventName + "' event", function () {
assert.ok(called, message || "Expected '" + eventName + "' to be called.")
});
},5000);
})
}, 5000)
item.once(eventName, function() {
item.once(eventName, function () {
if (eventName === 'error') {
// belt and braces test to ensure all error events return an error
assert.ok(arguments[0] instanceof Error,
"Expected error events to throw instances of Error but found: " + sys.inspect(arguments[0]));
'Expected error events to throw instances of Error but found: ' + sys.inspect(arguments[0]))
}
called = true;
clearTimeout(id);
assert.ok(true);
if(callback) {
callback.apply(item, arguments);
called = true
clearTimeout(id)
assert.ok(true)
if (callback) {
callback.apply(item, arguments)
}
});
};
})
}
assert.UTCDate = function(actual, year, month, day, hours, min, sec, milisecond) {
var actualYear = actual.getUTCFullYear();
assert.equal(actualYear, year, "expected year " + year + " but got " + actualYear);
assert.UTCDate = function (actual, year, month, day, hours, min, sec, milisecond) {
var actualYear = actual.getUTCFullYear()
assert.equal(actualYear, year, 'expected year ' + year + ' but got ' + actualYear)
var actualMonth = actual.getUTCMonth();
assert.equal(actualMonth, month, "expected month " + month + " but got " + actualMonth);
var actualMonth = actual.getUTCMonth()
assert.equal(actualMonth, month, 'expected month ' + month + ' but got ' + actualMonth)
var actualDate = actual.getUTCDate();
assert.equal(actualDate, day, "expected day " + day + " but got " + actualDate);
var actualDate = actual.getUTCDate()
assert.equal(actualDate, day, 'expected day ' + day + ' but got ' + actualDate)
var actualHours = actual.getUTCHours();
assert.equal(actualHours, hours, "expected hours " + hours + " but got " + actualHours);
var actualHours = actual.getUTCHours()
assert.equal(actualHours, hours, 'expected hours ' + hours + ' but got ' + actualHours)
var actualMin = actual.getUTCMinutes();
assert.equal(actualMin, min, "expected min " + min + " but got " + actualMin);
var actualMin = actual.getUTCMinutes()
assert.equal(actualMin, min, 'expected min ' + min + ' but got ' + actualMin)
var actualSec = actual.getUTCSeconds();
assert.equal(actualSec, sec, "expected sec " + sec + " but got " + actualSec);
var actualSec = actual.getUTCSeconds()
assert.equal(actualSec, sec, 'expected sec ' + sec + ' but got ' + actualSec)
var actualMili = actual.getUTCMilliseconds();
assert.equal(actualMili, milisecond, "expected milisecond " + milisecond + " but got " + actualMili);
};
var actualMili = actual.getUTCMilliseconds()
assert.equal(actualMili, milisecond, 'expected milisecond ' + milisecond + ' but got ' + actualMili)
}
assert.equalBuffers = function(actual, expected) {
if(actual.length != expected.length) {
assert.equalBuffers = function (actual, expected) {
if (actual.length != expected.length) {
spit(actual, expected)
assert.equal(actual.length, expected.length);
assert.equal(actual.length, expected.length)
}
for(var i = 0; i < actual.length; i++) {
if(actual[i] != expected[i]) {
for (var i = 0; i < actual.length; i++) {
if (actual[i] != expected[i]) {
spit(actual, expected)
}
assert.equal(actual[i],expected[i]);
assert.equal(actual[i], expected[i])
}
};
}
assert.empty = function(actual) {
assert.lengthIs(actual, 0);
};
assert.empty = function (actual) {
assert.lengthIs(actual, 0)
}
assert.success = function(callback) {
if(callback.length === 1 || callback.length === 0) {
return assert.calls(function(err, arg) {
if(err) {
console.log(err);
assert.success = function (callback) {
if (callback.length === 1 || callback.length === 0) {
return assert.calls(function (err, arg) {
if (err) {
console.log(err)
}
assert(!err);
callback(arg);
});
assert(!err)
callback(arg)
})
} else if (callback.length === 2) {
return assert.calls(function(err, arg1, arg2) {
if(err) {
console.log(err);
return assert.calls(function (err, arg1, arg2) {
if (err) {
console.log(err)
}
assert(!err);
callback(arg1, arg2);
});
assert(!err)
callback(arg1, arg2)
})
} else {
throw new Error('need to preserve arrity of wrapped function');
throw new Error('need to preserve arrity of wrapped function')
}
}
assert.throws = function(offender) {
assert.throws = function (offender) {
try {
offender();
offender()
} catch (e) {
assert.ok(e instanceof Error, "Expected " + offender + " to throw instances of Error");
return;
assert.ok(e instanceof Error, 'Expected ' + offender + ' to throw instances of Error')
return
}
assert.ok(false, "Expected " + offender + " to throw exception");
assert.ok(false, 'Expected ' + offender + ' to throw exception')
}
assert.lengthIs = function(actual, expectedLength) {
assert.equal(actual.length, expectedLength);
};
assert.lengthIs = function (actual, expectedLength) {
assert.equal(actual.length, expectedLength)
}
var expect = function(callback, timeout) {
var executed = false;
timeout = timeout || parseInt(process.env.TEST_TIMEOUT) || 5000;
var id = setTimeout(function() {
var expect = function (callback, timeout) {
var executed = false
timeout = timeout || parseInt(process.env.TEST_TIMEOUT) || 5000
var id = setTimeout(function () {
assert.ok(executed,
"Expected execution of function to be fired within " + timeout
+ " milliseconds " +
+ " (hint: export TEST_TIMEOUT=<timeout in milliseconds>"
+ " to change timeout globally)"
+ callback.toString());
'Expected execution of function to be fired within ' + timeout +
' milliseconds ' +
+' (hint: export TEST_TIMEOUT=<timeout in milliseconds>' +
' to change timeout globally)' +
callback.toString())
}, timeout)
if(callback.length < 3) {
return function(err, queryResult) {
clearTimeout(id);
if (callback.length < 3) {
return function (err, queryResult) {
clearTimeout(id)
if (err) {
assert.ok(err instanceof Error, "Expected errors to be instances of Error: " + sys.inspect(err));
assert.ok(err instanceof Error, 'Expected errors to be instances of Error: ' + sys.inspect(err))
}
callback.apply(this, arguments)
}
} else if(callback.length == 3) {
return function(err, arg1, arg2) {
clearTimeout(id);
} else if (callback.length == 3) {
return function (err, arg1, arg2) {
clearTimeout(id)
if (err) {
assert.ok(err instanceof Error, "Expected errors to be instances of Error: " + sys.inspect(err));
assert.ok(err instanceof Error, 'Expected errors to be instances of Error: ' + sys.inspect(err))
}
callback.apply(this, arguments)
}
} else {
throw new Error("Unsupported arrity " + callback.length);
throw new Error('Unsupported arrity ' + callback.length)
}
}
assert.calls = expect;
assert.calls = expect
assert.isNull = function(item, message) {
message = message || "expected " + item + " to be null";
assert.ok(item === null, message);
};
assert.isNull = function (item, message) {
message = message || 'expected ' + item + ' to be null'
assert.ok(item === null, message)
}
const getMode = () => {
if (args.native) return 'native'
@ -173,70 +172,69 @@ const getMode = () => {
return ''
}
global.test = function(name, action) {
test.testCount ++;
test[name] = action;
var result = test[name]();
if(result === false) {
process.stdout.write('?');
}else{
process.stdout.write('.');
global.test = function (name, action) {
test.testCount ++
test[name] = action
var result = test[name]()
if (result === false) {
process.stdout.write('?')
} else {
process.stdout.write('.')
}
};
}
//print out the filename
process.stdout.write(require('path').basename(process.argv[1]));
if(args.binary) process.stdout.write(' (binary)');
if(args.native) process.stdout.write(' (native)');
// print out the filename
process.stdout.write(require('path').basename(process.argv[1]))
if (args.binary) process.stdout.write(' (binary)')
if (args.native) process.stdout.write(' (native)')
process.on('exit', function() {
process.on('exit', function () {
console.log('')
})
process.on('uncaughtException', function(err) {
console.error("\n %s", err.stack || err.toString())
//causes xargs to abort right away
process.exit(255);
});
process.on('uncaughtException', function (err) {
console.error('\n %s', err.stack || err.toString())
// causes xargs to abort right away
process.exit(255)
})
var count = 0;
var count = 0
var Sink = function(expected, timeout, callback) {
var defaultTimeout = 5000;
if(typeof timeout == 'function') {
callback = timeout;
timeout = defaultTimeout;
var Sink = function (expected, timeout, callback) {
var defaultTimeout = 5000
if (typeof timeout === 'function') {
callback = timeout
timeout = defaultTimeout
}
timeout = timeout || defaultTimeout;
var internalCount = 0;
var kill = function() {
assert.ok(false, "Did not reach expected " + expected + " with an idle timeout of " + timeout);
timeout = timeout || defaultTimeout
var internalCount = 0
var kill = function () {
assert.ok(false, 'Did not reach expected ' + expected + ' with an idle timeout of ' + timeout)
}
var killTimeout = setTimeout(kill, timeout);
var killTimeout = setTimeout(kill, timeout)
return {
add: function(count) {
count = count || 1;
internalCount += count;
add: function (count) {
count = count || 1
internalCount += count
clearTimeout(killTimeout)
if(internalCount < expected) {
if (internalCount < expected) {
killTimeout = setTimeout(kill, timeout)
}
else {
assert.equal(internalCount, expected);
callback();
} else {
assert.equal(internalCount, expected)
callback()
}
}
}
}
var getTimezoneOffset = Date.prototype.getTimezoneOffset;
var getTimezoneOffset = Date.prototype.getTimezoneOffset
var setTimezoneOffset = function(minutesOffset) {
Date.prototype.getTimezoneOffset = function () { return minutesOffset; };
var setTimezoneOffset = function (minutesOffset) {
Date.prototype.getTimezoneOffset = function () { return minutesOffset }
}
var resetTimezoneOffset = function() {
Date.prototype.getTimezoneOffset = getTimezoneOffset;
var resetTimezoneOffset = function () {
Date.prototype.getTimezoneOffset = getTimezoneOffset
}
module.exports = {
@ -249,6 +247,4 @@ module.exports = {
Client: Client,
setTimezoneOffset: setTimezoneOffset,
resetTimezoneOffset: resetTimezoneOffset
};
}

View File

@ -1,23 +1,21 @@
"use strict";
'use strict'
const createClient = require('./test-helper').createClient;
const createClient = require('./test-helper').createClient
/*
* TODO: Add _some_ comments to explain what it is we're testing, and how the
* code-being-tested works behind the scenes.
*/
test('cleartext password authentication', function(){
var client = createClient();
client.password = "!";
client.connection.stream.packets = [];
client.connection.emit('authenticationCleartextPassword');
test('responds with password', function() {
var packets = client.connection.stream.packets;
assert.lengthIs(packets, 1);
var packet = packets[0];
assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0]);
});
});
test('cleartext password authentication', function () {
var client = createClient()
client.password = '!'
client.connection.stream.packets = []
client.connection.emit('authenticationCleartextPassword')
test('responds with password', function () {
var packets = client.connection.stream.packets
assert.lengthIs(packets, 1)
var packet = packets[0]
assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0])
})
})

View File

@ -1,171 +1,167 @@
"use strict";
require(__dirname+'/test-helper');
'use strict'
require(__dirname + '/test-helper')
var pguser = process.env['PGUSER'] || process.env.USER;
var pgdatabase = process.env['PGDATABASE'] || process.env.USER;
var pgport = process.env['PGPORT'] || 5432;
var pguser = process.env['PGUSER'] || process.env.USER
var pgdatabase = process.env['PGDATABASE'] || process.env.USER
var pgport = process.env['PGPORT'] || 5432
test('client settings', function() {
test('client settings', function () {
test('defaults', function () {
var client = new Client()
assert.equal(client.user, pguser)
assert.equal(client.database, pgdatabase)
assert.equal(client.port, pgport)
assert.equal(client.ssl, false)
})
test('defaults', function() {
var client = new Client();
assert.equal(client.user, pguser);
assert.equal(client.database, pgdatabase);
assert.equal(client.port, pgport);
assert.equal(client.ssl, false);
});
test('custom', function() {
var user = 'brian';
var database = 'pgjstest';
var password = 'boom';
test('custom', function () {
var user = 'brian'
var database = 'pgjstest'
var password = 'boom'
var client = new Client({
user: user,
database: database,
port: 321,
password: password,
ssl: true
});
})
assert.equal(client.user, user);
assert.equal(client.database, database);
assert.equal(client.port, 321);
assert.equal(client.password, password);
assert.equal(client.ssl, true);
});
assert.equal(client.user, user)
assert.equal(client.database, database)
assert.equal(client.port, 321)
assert.equal(client.password, password)
assert.equal(client.ssl, true)
})
test('custom ssl default on', function() {
var old = process.env.PGSSLMODE;
process.env.PGSSLMODE = "prefer";
test('custom ssl default on', function () {
var old = process.env.PGSSLMODE
process.env.PGSSLMODE = 'prefer'
var client = new Client();
process.env.PGSSLMODE = old;
var client = new Client()
process.env.PGSSLMODE = old
assert.equal(client.ssl, true);
});
assert.equal(client.ssl, true)
})
test('custom ssl force off', function() {
var old = process.env.PGSSLMODE;
process.env.PGSSLMODE = "prefer";
test('custom ssl force off', function () {
var old = process.env.PGSSLMODE
process.env.PGSSLMODE = 'prefer'
var client = new Client({
ssl: false
});
process.env.PGSSLMODE = old;
})
process.env.PGSSLMODE = old
assert.equal(client.ssl, false);
});
});
test('initializing from a config string', function() {
assert.equal(client.ssl, false)
})
})
test('initializing from a config string', function () {
test('uses connectionString property', function () {
var client = new Client({
connectionString: 'postgres://brian:pass@host1:333/databasename'
})
assert.equal(client.user, 'brian');
assert.equal(client.password, "pass");
assert.equal(client.host, "host1");
assert.equal(client.port, 333);
assert.equal(client.database, "databasename");
assert.equal(client.user, 'brian')
assert.equal(client.password, 'pass')
assert.equal(client.host, 'host1')
assert.equal(client.port, 333)
assert.equal(client.database, 'databasename')
})
test('uses the correct values from the config string', function() {
var client = new Client("postgres://brian:pass@host1:333/databasename")
assert.equal(client.user, 'brian');
assert.equal(client.password, "pass");
assert.equal(client.host, "host1");
assert.equal(client.port, 333);
assert.equal(client.database, "databasename");
});
test('uses the correct values from the config string', function () {
var client = new Client('postgres://brian:pass@host1:333/databasename')
assert.equal(client.user, 'brian')
assert.equal(client.password, 'pass')
assert.equal(client.host, 'host1')
assert.equal(client.port, 333)
assert.equal(client.database, 'databasename')
})
test('uses the correct values from the config string with space in password', function() {
var client = new Client("postgres://brian:pass word@host1:333/databasename")
assert.equal(client.user, 'brian');
assert.equal(client.password, "pass word");
assert.equal(client.host, "host1");
assert.equal(client.port, 333);
assert.equal(client.database, "databasename");
});
test('uses the correct values from the config string with space in password', function () {
var client = new Client('postgres://brian:pass word@host1:333/databasename')
assert.equal(client.user, 'brian')
assert.equal(client.password, 'pass word')
assert.equal(client.host, 'host1')
assert.equal(client.port, 333)
assert.equal(client.database, 'databasename')
})
test('when not including all values the defaults are used', function() {
var client = new Client("postgres://host1");
assert.equal(client.user, process.env['PGUSER'] || process.env.USER);
assert.equal(client.password, process.env['PGPASSWORD'] || null);
assert.equal(client.host, "host1");
assert.equal(client.port, process.env['PGPORT'] || 5432);
assert.equal(client.database, process.env['PGDATABASE'] || process.env.USER);
});
test('when not including all values the defaults are used', function () {
var client = new Client('postgres://host1')
assert.equal(client.user, process.env['PGUSER'] || process.env.USER)
assert.equal(client.password, process.env['PGPASSWORD'] || null)
assert.equal(client.host, 'host1')
assert.equal(client.port, process.env['PGPORT'] || 5432)
assert.equal(client.database, process.env['PGDATABASE'] || process.env.USER)
})
test('when not including all values the environment variables are used', function() {
var envUserDefined = process.env['PGUSER'] !== undefined;
var envPasswordDefined = process.env['PGPASSWORD'] !== undefined;
var envDBDefined = process.env['PGDATABASE'] !== undefined;
var envHostDefined = process.env['PGHOST'] !== undefined;
var envPortDefined = process.env['PGPORT'] !== undefined;
test('when not including all values the environment variables are used', function () {
var envUserDefined = process.env['PGUSER'] !== undefined
var envPasswordDefined = process.env['PGPASSWORD'] !== undefined
var envDBDefined = process.env['PGDATABASE'] !== undefined
var envHostDefined = process.env['PGHOST'] !== undefined
var envPortDefined = process.env['PGPORT'] !== undefined
var savedEnvUser = process.env['PGUSER'];
var savedEnvPassword = process.env['PGPASSWORD'];
var savedEnvDB = process.env['PGDATABASE'];
var savedEnvHost = process.env['PGHOST'];
var savedEnvPort = process.env['PGPORT'];
var savedEnvUser = process.env['PGUSER']
var savedEnvPassword = process.env['PGPASSWORD']
var savedEnvDB = process.env['PGDATABASE']
var savedEnvHost = process.env['PGHOST']
var savedEnvPort = process.env['PGPORT']
process.env['PGUSER'] = 'utUser1';
process.env['PGPASSWORD'] = 'utPass1';
process.env['PGDATABASE'] = 'utDB1';
process.env['PGHOST'] = 'utHost1';
process.env['PGPORT'] = 5464;
process.env['PGUSER'] = 'utUser1'
process.env['PGPASSWORD'] = 'utPass1'
process.env['PGDATABASE'] = 'utDB1'
process.env['PGHOST'] = 'utHost1'
process.env['PGPORT'] = 5464
var client = new Client("postgres://host1");
assert.equal(client.user, process.env['PGUSER']);
assert.equal(client.password, process.env['PGPASSWORD']);
assert.equal(client.host, "host1");
assert.equal(client.port, process.env['PGPORT']);
assert.equal(client.database, process.env['PGDATABASE']);
var client = new Client('postgres://host1')
assert.equal(client.user, process.env['PGUSER'])
assert.equal(client.password, process.env['PGPASSWORD'])
assert.equal(client.host, 'host1')
assert.equal(client.port, process.env['PGPORT'])
assert.equal(client.database, process.env['PGDATABASE'])
if (envUserDefined) {
process.env['PGUSER'] = savedEnvUser;
process.env['PGUSER'] = savedEnvUser
} else {
delete process.env['PGUSER'];
delete process.env['PGUSER']
}
if (envPasswordDefined) {
process.env['PGPASSWORD'] = savedEnvPassword;
process.env['PGPASSWORD'] = savedEnvPassword
} else {
delete process.env['PGPASSWORD'];
delete process.env['PGPASSWORD']
}
if (envDBDefined) {
process.env['PGDATABASE'] = savedEnvDB;
process.env['PGDATABASE'] = savedEnvDB
} else {
delete process.env['PGDATABASE'];
delete process.env['PGDATABASE']
}
if (envHostDefined) {
process.env['PGHOST'] = savedEnvHost;
process.env['PGHOST'] = savedEnvHost
} else {
delete process.env['PGHOST'];
delete process.env['PGHOST']
}
if (envPortDefined) {
process.env['PGPORT'] = savedEnvPort;
process.env['PGPORT'] = savedEnvPort
} else {
delete process.env['PGPORT'];
delete process.env['PGPORT']
}
});
});
test('calls connect correctly on connection', function() {
var client = new Client("/tmp");
var usedPort = "";
var usedHost = "";
client.connection.connect = function(port, host) {
usedPort = port;
usedHost = host;
};
client.connect();
assert.equal(usedPort, "/tmp/.s.PGSQL." + pgport);
assert.strictEqual(usedHost, undefined);
});
})
})
test('calls connect correctly on connection', function () {
var client = new Client('/tmp')
var usedPort = ''
var usedHost = ''
client.connection.connect = function (port, host) {
usedPort = port
usedHost = host
}
client.connect()
assert.equal(usedPort, '/tmp/.s.PGSQL.' + pgport)
assert.strictEqual(usedHost, undefined)
})

View File

@ -1,17 +1,17 @@
"use strict";
var helper = require('./test-helper');
var net = require('net');
var pg = require('../../../lib/index.js');
'use strict'
var helper = require('./test-helper')
var net = require('net')
var pg = require('../../../lib/index.js')
/* console.log() messages show up in `make test` output. TODO: fix it. */
var server = net.createServer(function(c) {
c.destroy();
server.close();
});
var server = net.createServer(function (c) {
c.destroy()
server.close()
})
server.listen(7777, function() {
var client = new pg.Client('postgres://localhost:7777');
client.connect(assert.calls(function(err) {
assert(err);
}));
});
server.listen(7777, function () {
var client = new pg.Client('postgres://localhost:7777')
client.connect(assert.calls(function (err) {
assert(err)
}))
})

View File

@ -1,73 +1,73 @@
"use strict";
var helper = require(__dirname + '/test-helper');
'use strict'
var helper = require(__dirname + '/test-helper')
function createClient(callback) {
var client = new Client(helper.config);
client.connect(function(err) {
return callback(client);
});
function createClient (callback) {
var client = new Client(helper.config)
client.connect(function (err) {
return callback(client)
})
}
var testLit = function(testName, input, expected) {
test(testName, function(){
var client = new Client(helper.config);
var actual = client.escapeLiteral(input);
assert.equal(expected, actual);
});
};
var testLit = function (testName, input, expected) {
test(testName, function () {
var client = new Client(helper.config)
var actual = client.escapeLiteral(input)
assert.equal(expected, actual)
})
}
var testIdent = function(testName, input, expected) {
test(testName, function(){
var client = new Client(helper.config);
var actual = client.escapeIdentifier(input);
assert.equal(expected, actual);
});
};
var testIdent = function (testName, input, expected) {
test(testName, function () {
var client = new Client(helper.config)
var actual = client.escapeIdentifier(input)
assert.equal(expected, actual)
})
}
testLit('escapeLiteral: no special characters',
'hello world', "'hello world'");
'hello world', "'hello world'")
testLit('escapeLiteral: contains double quotes only',
'hello " world', "'hello \" world'");
'hello " world', "'hello \" world'")
testLit('escapeLiteral: contains single quotes only',
'hello \' world', "'hello \'\' world'");
'hello \' world', "'hello \'\' world'")
testLit('escapeLiteral: contains backslashes only',
'hello \\ world', " E'hello \\\\ world'");
'hello \\ world', " E'hello \\\\ world'")
testLit('escapeLiteral: contains single quotes and double quotes',
'hello \' " world', "'hello '' \" world'");
'hello \' " world', "'hello '' \" world'")
testLit('escapeLiteral: contains double quotes and backslashes',
'hello \\ " world', " E'hello \\\\ \" world'");
'hello \\ " world', " E'hello \\\\ \" world'")
testLit('escapeLiteral: contains single quotes and backslashes',
'hello \\ \' world', " E'hello \\\\ '' world'");
'hello \\ \' world', " E'hello \\\\ '' world'")
testLit('escapeLiteral: contains single quotes, double quotes, and backslashes',
'hello \\ \' " world', " E'hello \\\\ '' \" world'");
'hello \\ \' " world', " E'hello \\\\ '' \" world'")
testIdent('escapeIdentifier: no special characters',
'hello world', '"hello world"');
'hello world', '"hello world"')
testIdent('escapeIdentifier: contains double quotes only',
'hello " world', '"hello "" world"');
'hello " world', '"hello "" world"')
testIdent('escapeIdentifier: contains single quotes only',
'hello \' world', '"hello \' world"');
'hello \' world', '"hello \' world"')
testIdent('escapeIdentifier: contains backslashes only',
'hello \\ world', '"hello \\ world"');
'hello \\ world', '"hello \\ world"')
testIdent('escapeIdentifier: contains single quotes and double quotes',
'hello \' " world', '"hello \' "" world"');
'hello \' " world', '"hello \' "" world"')
testIdent('escapeIdentifier: contains double quotes and backslashes',
'hello \\ " world', '"hello \\ "" world"');
'hello \\ " world', '"hello \\ "" world"')
testIdent('escapeIdentifier: contains single quotes and backslashes',
'hello \\ \' world', '"hello \\ \' world"');
'hello \\ \' world', '"hello \\ \' world"')
testIdent('escapeIdentifier: contains single quotes, double quotes, and backslashes',
'hello \\ \' " world', '"hello \\ \' "" world"');
'hello \\ \' " world', '"hello \\ \' "" world"')

View File

@ -1,26 +1,26 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
var utils = require('../../../lib/utils')
test('md5 authentication', function() {
var client = helper.createClient();
client.password = "!";
var salt = Buffer.from([1, 2, 3, 4]);
client.connection.emit('authenticationMD5Password', {salt: salt});
test('md5 authentication', function () {
var client = helper.createClient()
client.password = '!'
var salt = Buffer.from([1, 2, 3, 4])
client.connection.emit('authenticationMD5Password', {salt: salt})
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
//how do we want to test this?
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
// how do we want to test this?
assert.equalBuffers(client.connection.stream.packets[0], new BufferList()
.addCString(password).join(true,'p'));
});
});
});
.addCString(password).join(true, 'p'))
})
})
})
test('md5 of utf-8 strings', function() {
assert.equal(utils.md5('😊'), '5deda34cd95f304948d2bc1b4a62c11e');
});
test('md5 of utf-8 strings', function () {
assert.equal(utils.md5('😊'), '5deda34cd95f304948d2bc1b4a62c11e')
})

View File

@ -1,11 +1,10 @@
"use strict";
var helper = require(__dirname + "/test-helper");
'use strict'
var helper = require(__dirname + '/test-helper')
test('passes connection notification', function() {
var client = helper.client();
assert.emits(client, 'notice', function(msg) {
assert.equal(msg, "HAY!!");
test('passes connection notification', function () {
var client = helper.client()
assert.emits(client, 'notice', function (msg) {
assert.equal(msg, 'HAY!!')
})
client.connection.emit('notice', "HAY!!");
client.connection.emit('notice', 'HAY!!')
})

View File

@ -1,88 +1,88 @@
"use strict";
var helper = require('./test-helper');
'use strict'
var helper = require('./test-helper')
var Query = require('../../../lib/query')
var client = helper.client();
var con = client.connection;
var parseArg = null;
con.parse = function(arg) {
parseArg = arg;
process.nextTick(function() {
con.emit('parseComplete');
});
};
var client = helper.client()
var con = client.connection
var parseArg = null
con.parse = function (arg) {
parseArg = arg
process.nextTick(function () {
con.emit('parseComplete')
})
}
var bindArg = null;
con.bind = function(arg) {
bindArg = arg;
process.nextTick(function(){
con.emit('bindComplete');
});
};
var bindArg = null
con.bind = function (arg) {
bindArg = arg
process.nextTick(function () {
con.emit('bindComplete')
})
}
var executeArg = null;
con.execute = function(arg) {
executeArg = arg;
process.nextTick(function() {
con.emit('rowData',{ fields: [] });
con.emit('commandComplete', { text: "" });
});
};
var executeArg = null
con.execute = function (arg) {
executeArg = arg
process.nextTick(function () {
con.emit('rowData', { fields: [] })
con.emit('commandComplete', { text: '' })
})
}
var describeArg = null;
con.describe = function(arg) {
describeArg = arg;
process.nextTick(function() {
con.emit('rowDescription', { fields: [] });
});
};
var describeArg = null
con.describe = function (arg) {
describeArg = arg
process.nextTick(function () {
con.emit('rowDescription', { fields: [] })
})
}
var syncCalled = false;
con.flush = function() {
};
con.sync = function() {
syncCalled = true;
process.nextTick(function() {
con.emit('readyForQuery');
});
};
var syncCalled = false
con.flush = function () {
}
con.sync = function () {
syncCalled = true
process.nextTick(function () {
con.emit('readyForQuery')
})
}
test('bound command', function() {
test('simple, unnamed bound command', function() {
assert.ok(client.connection.emit('readyForQuery'));
test('bound command', function () {
test('simple, unnamed bound command', function () {
assert.ok(client.connection.emit('readyForQuery'))
var query = client.query(new Query({
text: 'select * from X where name = $1',
values: ['hi']
}));
}))
assert.emits(query,'end', function() {
test('parse argument', function() {
assert.equal(parseArg.name, null);
assert.equal(parseArg.text, 'select * from X where name = $1');
assert.equal(parseArg.types, null);
});
assert.emits(query, 'end', function () {
test('parse argument', function () {
assert.equal(parseArg.name, null)
assert.equal(parseArg.text, 'select * from X where name = $1')
assert.equal(parseArg.types, null)
})
test('bind argument', function() {
assert.equal(bindArg.statement, null);
assert.equal(bindArg.portal, null);
assert.lengthIs(bindArg.values, 1);
test('bind argument', function () {
assert.equal(bindArg.statement, null)
assert.equal(bindArg.portal, null)
assert.lengthIs(bindArg.values, 1)
assert.equal(bindArg.values[0], 'hi')
});
})
test('describe argument', function() {
assert.equal(describeArg.type, 'P');
assert.equal(describeArg.name, "");
});
test('describe argument', function () {
assert.equal(describeArg.type, 'P')
assert.equal(describeArg.name, '')
})
test('execute argument', function() {
assert.equal(executeArg.portal, null);
assert.equal(executeArg.rows, null);
});
test('execute argument', function () {
assert.equal(executeArg.portal, null)
assert.equal(executeArg.rows, null)
})
test('sync called', function() {
assert.ok(syncCalled);
});
});
});
});
test('sync called', function () {
assert.ok(syncCalled)
})
})
})
})

View File

@ -1,53 +1,53 @@
"use strict";
var helper = require(__dirname + '/test-helper');
var Connection = require(__dirname + '/../../../lib/connection');
'use strict'
var helper = require(__dirname + '/test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
test('drain', function() {
var con = new Connection({stream: "NO"});
var client = new Client({connection:con});
con.connect = function() {
con.emit('connect');
};
con.query = function() {
};
client.connect();
test('drain', function () {
var con = new Connection({stream: 'NO'})
var client = new Client({connection: con})
con.connect = function () {
con.emit('connect')
}
con.query = function () {
}
client.connect()
var raisedDrain = false;
client.on('drain', function() {
raisedDrain = true;
});
var raisedDrain = false
client.on('drain', function () {
raisedDrain = true
})
client.query("hello");
client.query("sup");
client.query('boom');
client.query('hello')
client.query('sup')
client.query('boom')
test("with pending queries", function() {
test("does not emit drain", function() {
assert.equal(raisedDrain, false);
});
});
test('with pending queries', function () {
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
test("after some queries executed", function() {
con.emit('readyForQuery');
test("does not emit drain", function() {
assert.equal(raisedDrain, false);
});
});
test('after some queries executed', function () {
con.emit('readyForQuery')
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
test("when all queries are sent", function() {
con.emit('readyForQuery');
con.emit('readyForQuery');
test("does not emit drain", function() {
assert.equal(raisedDrain, false);
});
});
test('when all queries are sent', function () {
con.emit('readyForQuery')
con.emit('readyForQuery')
test('does not emit drain', function () {
assert.equal(raisedDrain, false)
})
})
test("after last query finishes", function() {
con.emit('readyForQuery');
test("emits drain", function() {
process.nextTick(function() {
assert.ok(raisedDrain);
test('after last query finishes', function () {
con.emit('readyForQuery')
test('emits drain', function () {
process.nextTick(function () {
assert.ok(raisedDrain)
})
});
});
});
})
})
})

View File

@ -1,38 +1,37 @@
"use strict";
var helper = require(__dirname + "/test-helper")
'use strict'
var helper = require(__dirname + '/test-helper')
var testForTag = function(tagText, callback) {
test('includes command tag data for tag ' + tagText, function() {
var client = helper.client();
var testForTag = function (tagText, callback) {
test('includes command tag data for tag ' + tagText, function () {
var client = helper.client()
client.connection.emit('readyForQuery')
var query = client.query("whatever", assert.calls((err, result) => {
assert.ok(result != null, "should pass something to this event")
var query = client.query('whatever', assert.calls((err, result) => {
assert.ok(result != null, 'should pass something to this event')
callback(result)
}));
}))
assert.lengthIs(client.connection.queries, 1)
client.connection.emit('commandComplete', {
text: tagText
});
})
client.connection.emit('readyForQuery');
client.connection.emit('readyForQuery')
})
}
var check = function(oid, rowCount, command) {
return function(result) {
if(oid != null) {
assert.equal(result.oid, oid);
var check = function (oid, rowCount, command) {
return function (result) {
if (oid != null) {
assert.equal(result.oid, oid)
}
assert.equal(result.rowCount, rowCount);
assert.equal(result.command, command);
assert.equal(result.rowCount, rowCount)
assert.equal(result.command, command)
}
}
testForTag("INSERT 0 3", check(0, 3, "INSERT"));
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('INSERT 0 3', check(0, 3, 'INSERT'))
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'))

View File

@ -1,129 +1,123 @@
"use strict";
var helper = require(__dirname + "/test-helper");
'use strict'
var helper = require(__dirname + '/test-helper')
var Query = require('../../../lib/query')
test('executing query', function() {
test('executing query', function () {
test('queing query', function () {
test('when connection is ready', function () {
var client = helper.client()
assert.empty(client.connection.queries)
client.connection.emit('readyForQuery')
client.query('yes')
assert.lengthIs(client.connection.queries, 1)
assert.equal(client.connection.queries, 'yes')
})
test("queing query", function() {
test('when connection is not ready', function () {
var client = helper.client()
test('when connection is ready', function() {
var client = helper.client();
assert.empty(client.connection.queries);
client.connection.emit('readyForQuery');
client.query('yes');
assert.lengthIs(client.connection.queries, 1);
assert.equal(client.connection.queries, 'yes');
});
test('query is not sent', function () {
client.query('boom')
assert.empty(client.connection.queries)
})
test('when connection is not ready', function() {
var client = helper.client();
test('sends query to connection once ready', function () {
assert.ok(client.connection.emit('readyForQuery'))
assert.lengthIs(client.connection.queries, 1)
assert.equal(client.connection.queries[0], 'boom')
})
})
test('query is not sent', function() {
client.query('boom');
assert.empty(client.connection.queries);
});
test('multiple in the queue', function () {
var client = helper.client()
var connection = client.connection
var queries = connection.queries
client.query('one')
client.query('two')
client.query('three')
assert.empty(queries)
test('sends query to connection once ready', function() {
assert.ok(client.connection.emit('readyForQuery'));
assert.lengthIs(client.connection.queries, 1);
assert.equal(client.connection.queries[0], "boom");
});
test('after one ready for query', function () {
connection.emit('readyForQuery')
assert.lengthIs(queries, 1)
assert.equal(queries[0], 'one')
})
});
test('after two ready for query', function () {
connection.emit('readyForQuery')
assert.lengthIs(queries, 2)
})
test("multiple in the queue", function() {
var client = helper.client();
var connection = client.connection;
var queries = connection.queries;
client.query('one');
client.query('two');
client.query('three');
assert.empty(queries);
test('after a bunch more', function () {
connection.emit('readyForQuery')
connection.emit('readyForQuery')
connection.emit('readyForQuery')
assert.lengthIs(queries, 3)
assert.equal(queries[0], 'one')
assert.equal(queries[1], 'two')
assert.equal(queries[2], 'three')
})
})
})
test("after one ready for query",function() {
connection.emit('readyForQuery');
assert.lengthIs(queries, 1);
assert.equal(queries[0], "one");
});
test('query event binding and flow', function () {
var client = helper.client()
var con = client.connection
var query = client.query(new Query('whatever'))
test('after two ready for query', function() {
connection.emit('readyForQuery');
assert.lengthIs(queries, 2);
});
test('has no queries sent before ready', function () {
assert.empty(con.queries)
})
test("after a bunch more", function() {
connection.emit('readyForQuery');
connection.emit('readyForQuery');
connection.emit('readyForQuery');
assert.lengthIs(queries, 3);
assert.equal(queries[0], "one");
assert.equal(queries[1], 'two');
assert.equal(queries[2], 'three');
});
});
});
test('sends query on readyForQuery event', function () {
con.emit('readyForQuery')
assert.lengthIs(con.queries, 1)
assert.equal(con.queries[0], 'whatever')
})
test("query event binding and flow", function() {
var client = helper.client();
var con = client.connection;
var query = client.query(new Query('whatever'));
test("has no queries sent before ready", function() {
assert.empty(con.queries);
});
test('sends query on readyForQuery event', function() {
con.emit('readyForQuery');
assert.lengthIs(con.queries, 1);
assert.equal(con.queries[0], 'whatever');
});
test('handles rowDescription message', function() {
var handled = con.emit('rowDescription',{
test('handles rowDescription message', function () {
var handled = con.emit('rowDescription', {
fields: [{
name: 'boom'
}]
});
assert.ok(handled, "should have handlded rowDescription");
});
})
assert.ok(handled, 'should have handlded rowDescription')
})
test('handles dataRow messages', function() {
assert.emits(query, 'row', function(row) {
assert.equal(row['boom'], "hi");
});
test('handles dataRow messages', function () {
assert.emits(query, 'row', function (row) {
assert.equal(row['boom'], 'hi')
})
var handled = con.emit('dataRow', { fields: ["hi"] });
assert.ok(handled, "should have handled first data row message");
var handled = con.emit('dataRow', { fields: ['hi'] })
assert.ok(handled, 'should have handled first data row message')
assert.emits(query, 'row', function(row) {
assert.equal(row['boom'], "bye");
});
assert.emits(query, 'row', function (row) {
assert.equal(row['boom'], 'bye')
})
var handledAgain = con.emit('dataRow', { fields: ["bye"] });
assert.ok(handledAgain, "should have handled seciond data row message");
});
var handledAgain = con.emit('dataRow', { fields: ['bye'] })
assert.ok(handledAgain, 'should have handled seciond data row message')
})
//multiple command complete messages will be sent
//when multiple queries are in a simple command
test('handles command complete messages', function() {
// multiple command complete messages will be sent
// when multiple queries are in a simple command
test('handles command complete messages', function () {
con.emit('commandComplete', {
text: 'INSERT 31 1'
});
});
test('removes itself after another readyForQuery message', function() {
return false;
assert.emits(query, "end", function(msg) {
//TODO do we want to check the complete messages?
});
con.emit("readyForQuery");
//this would never actually happen
['dataRow','rowDescription', 'commandComplete'].forEach(function(msg) {
assert.equal(con.emit(msg), false, "Should no longer be picking up '"+ msg +"' messages");
});
});
});
});
})
})
test('removes itself after another readyForQuery message', function () {
return false
assert.emits(query, 'end', function (msg) {
// TODO do we want to check the complete messages?
})
con.emit('readyForQuery');
// this would never actually happen
['dataRow', 'rowDescription', 'commandComplete'].forEach(function (msg) {
assert.equal(con.emit(msg), false, "Should no longer be picking up '" + msg + "' messages")
})
})
})
})

View File

@ -1,29 +1,29 @@
"use strict";
var helper = require(__dirname + '/test-helper');
var Connection = require(__dirname + '/../../../lib/connection');
var Client = require(__dirname + '/../../../lib/client');
'use strict'
var helper = require(__dirname + '/test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
var Client = require(__dirname + '/../../../lib/client')
test('emits end when not in query', function() {
var stream = new (require('events').EventEmitter)();
stream.write = function() {
//NOOP
test('emits end when not in query', function () {
var stream = new (require('events').EventEmitter)()
stream.write = function () {
// NOOP
}
var client = new Client({connection: new Connection({stream: stream})});
client.connect(assert.calls(function() {
client.query('SELECT NOW()', assert.calls(function(err, result) {
assert(err);
}));
}));
assert.emits(client, 'error');
assert.emits(client, 'end');
client.connection.emit('connect');
process.nextTick(function() {
client.connection.emit('readyForQuery');
assert.equal(client.queryQueue.length, 0);
assert(client.activeQuery, 'client should have issued query');
process.nextTick(function() {
stream.emit('close');
});
});
});
var client = new Client({connection: new Connection({stream: stream})})
client.connect(assert.calls(function () {
client.query('SELECT NOW()', assert.calls(function (err, result) {
assert(err)
}))
}))
assert.emits(client, 'error')
assert.emits(client, 'end')
client.connection.emit('connect')
process.nextTick(function () {
client.connection.emit('readyForQuery')
assert.equal(client.queryQueue.length, 0)
assert(client.activeQuery, 'client should have issued query')
process.nextTick(function () {
stream.emit('close')
})
})
})

View File

@ -1,21 +1,21 @@
"use strict";
var helper = require('../test-helper');
var Connection = require('../../../lib/connection');
'use strict'
var helper = require('../test-helper')
var Connection = require('../../../lib/connection')
var makeClient = function() {
var connection = new Connection({stream: "no"});
connection.startup = function() {};
connection.connect = function() {};
connection.query = function(text) {
this.queries.push(text);
};
connection.queries = [];
var client = new Client({connection: connection});
client.connect();
client.connection.emit('connect');
return client;
};
var makeClient = function () {
var connection = new Connection({stream: 'no'})
connection.startup = function () {}
connection.connect = function () {}
connection.query = function (text) {
this.queries.push(text)
}
connection.queries = []
var client = new Client({connection: connection})
client.connect()
client.connection.emit('connect')
return client
}
module.exports = Object.assign({
client: makeClient
}, helper);
}, helper)

View File

@ -1,70 +1,69 @@
"use strict";
var helper = require("./test-helper");
var Query = require("../../../lib/query");
var types = require("pg-types");
'use strict'
var helper = require('./test-helper')
var Query = require('../../../lib/query')
var types = require('pg-types')
const suite = new helper.Suite();
const suite = new helper.Suite()
var typeParserError = new Error("TEST: Throw in type parsers");
var typeParserError = new Error('TEST: Throw in type parsers')
types.setTypeParser("special oid that will throw", function() {
throw typeParserError;
});
types.setTypeParser('special oid that will throw', function () {
throw typeParserError
})
const emitFakeEvents = con => {
setImmediate(() => {
con.emit("readyForQuery");
con.emit('readyForQuery')
con.emit("rowDescription", {
con.emit('rowDescription', {
fields: [
{
name: "boom",
dataTypeID: "special oid that will throw"
name: 'boom',
dataTypeID: 'special oid that will throw'
}
]
});
})
con.emit("dataRow", { fields: ["hi"] });
con.emit("dataRow", { fields: ["hi"] });
con.emit("commandComplete", { text: "INSERT 31 1" });
con.emit("readyForQuery");
});
};
con.emit('dataRow', { fields: ['hi'] })
con.emit('dataRow', { fields: ['hi'] })
con.emit('commandComplete', { text: 'INSERT 31 1' })
con.emit('readyForQuery')
})
}
suite.test("emits error", function(done) {
var handled;
var client = helper.client();
var con = client.connection;
var query = client.query(new Query("whatever"));
suite.test('emits error', function (done) {
var handled
var client = helper.client()
var con = client.connection
var query = client.query(new Query('whatever'))
emitFakeEvents(con)
assert.emits(query, "error", function(err) {
assert.equal(err, typeParserError);
done();
});
});
assert.emits(query, 'error', function (err) {
assert.equal(err, typeParserError)
done()
})
})
suite.test("calls callback with error", function(done) {
var handled;
suite.test('calls callback with error', function (done) {
var handled
var callbackCalled = 0;
var callbackCalled = 0
var client = helper.client();
var con = client.connection;
emitFakeEvents(con);
var query = client.query("whatever", function(err) {
assert.equal(err, typeParserError);
done();
});
var client = helper.client()
var con = client.connection
emitFakeEvents(con)
var query = client.query('whatever', function (err) {
assert.equal(err, typeParserError)
done()
})
})
});
suite.test("rejects promise with error", function(done) {
var client = helper.client();
var con = client.connection;
emitFakeEvents(con);
client.query("whatever").catch(err => {
assert.equal(err, typeParserError);
done();
});
});
suite.test('rejects promise with error', function (done) {
var client = helper.client()
var con = client.connection
emitFakeEvents(con)
client.query('whatever').catch(err => {
assert.equal(err, typeParserError)
done()
})
})

View File

@ -1,55 +1,55 @@
"use strict";
var helper = require(__dirname + '/../test-helper');
var assert = require('assert');
var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters');
var defaults = require(__dirname + '/../../../lib').defaults;
'use strict'
var helper = require(__dirname + '/../test-helper')
var assert = require('assert')
var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters')
var defaults = require(__dirname + '/../../../lib').defaults
//clear process.env
for(var key in process.env) {
delete process.env[key];
// clear process.env
for (var key in process.env) {
delete process.env[key]
}
test('ConnectionParameters construction', function() {
assert.ok(new ConnectionParameters(), 'with null config');
assert.ok(new ConnectionParameters({user: 'asdf'}), 'with config object');
assert.ok(new ConnectionParameters('postgres://localhost/postgres'), 'with connection string');
});
test('ConnectionParameters construction', function () {
assert.ok(new ConnectionParameters(), 'with null config')
assert.ok(new ConnectionParameters({user: 'asdf'}), 'with config object')
assert.ok(new ConnectionParameters('postgres://localhost/postgres'), 'with connection string')
})
var compare = function(actual, expected, type) {
assert.equal(actual.user, expected.user, type + ' user');
assert.equal(actual.database, expected.database, type + ' database');
assert.equal(actual.port, expected.port, type + ' port');
assert.equal(actual.host, expected.host, type + ' host');
assert.equal(actual.password, expected.password, type + ' password');
assert.equal(actual.binary, expected.binary, type + ' binary');
};
var compare = function (actual, expected, type) {
assert.equal(actual.user, expected.user, type + ' user')
assert.equal(actual.database, expected.database, type + ' database')
assert.equal(actual.port, expected.port, type + ' port')
assert.equal(actual.host, expected.host, type + ' host')
assert.equal(actual.password, expected.password, type + ' password')
assert.equal(actual.binary, expected.binary, type + ' binary')
}
test('ConnectionParameters initializing from defaults', function() {
var subject = new ConnectionParameters();
compare(subject, defaults, 'defaults');
assert.ok(subject.isDomainSocket === false);
});
test('ConnectionParameters initializing from defaults', function () {
var subject = new ConnectionParameters()
compare(subject, defaults, 'defaults')
assert.ok(subject.isDomainSocket === false)
})
test('ConnectionParameters initializing from defaults with connectionString set', function() {
test('ConnectionParameters initializing from defaults with connectionString set', function () {
var config = {
user : 'brians-are-the-best',
database : 'scoobysnacks',
port : 7777,
password : 'mypassword',
host : 'foo.bar.net',
binary : defaults.binary
};
user: 'brians-are-the-best',
database: 'scoobysnacks',
port: 7777,
password: 'mypassword',
host: 'foo.bar.net',
binary: defaults.binary
}
var original_value = defaults.connectionString;
var original_value = defaults.connectionString
// Just changing this here doesn't actually work because it's no longer in scope when viewed inside of
// of ConnectionParameters() so we have to pass in the defaults explicitly to test it
defaults.connectionString = 'postgres://brians-are-the-best:mypassword@foo.bar.net:7777/scoobysnacks';
var subject = new ConnectionParameters(defaults);
defaults.connectionString = original_value;
compare(subject, config, 'defaults-connectionString');
});
defaults.connectionString = 'postgres://brians-are-the-best:mypassword@foo.bar.net:7777/scoobysnacks'
var subject = new ConnectionParameters(defaults)
defaults.connectionString = original_value
compare(subject, config, 'defaults-connectionString')
})
test('ConnectionParameters initializing from config', function() {
test('ConnectionParameters initializing from config', function () {
var config = {
user: 'brian',
database: 'home',
@ -61,58 +61,58 @@ test('ConnectionParameters initializing from config', function() {
ssl: {
asdf: 'blah'
}
};
var subject = new ConnectionParameters(config);
compare(subject, config, 'config');
assert.ok(subject.isDomainSocket === false);
});
}
var subject = new ConnectionParameters(config)
compare(subject, config, 'config')
assert.ok(subject.isDomainSocket === false)
})
test('escape spaces if present', function() {
var subject = new ConnectionParameters('postgres://localhost/post gres');
assert.equal(subject.database, 'post gres');
});
test('escape spaces if present', function () {
var subject = new ConnectionParameters('postgres://localhost/post gres')
assert.equal(subject.database, 'post gres')
})
test('do not double escape spaces', function() {
var subject = new ConnectionParameters('postgres://localhost/post%20gres');
assert.equal(subject.database, 'post gres');
});
test('do not double escape spaces', function () {
var subject = new ConnectionParameters('postgres://localhost/post%20gres')
assert.equal(subject.database, 'post gres')
})
test('initializing with unix domain socket', function() {
var subject = new ConnectionParameters('/var/run/');
assert.ok(subject.isDomainSocket);
assert.equal(subject.host, '/var/run/');
assert.equal(subject.database, defaults.user);
});
test('initializing with unix domain socket', function () {
var subject = new ConnectionParameters('/var/run/')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/var/run/')
assert.equal(subject.database, defaults.user)
})
test('initializing with unix domain socket and a specific database, the simple way', function() {
var subject = new ConnectionParameters('/var/run/ mydb');
assert.ok(subject.isDomainSocket);
assert.equal(subject.host, '/var/run/');
assert.equal(subject.database, 'mydb');
});
test('initializing with unix domain socket and a specific database, the simple way', function () {
var subject = new ConnectionParameters('/var/run/ mydb')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/var/run/')
assert.equal(subject.database, 'mydb')
})
test('initializing with unix domain socket, the health way', function() {
var subject = new ConnectionParameters('socket:/some path/?db=my[db]&encoding=utf8');
assert.ok(subject.isDomainSocket);
assert.equal(subject.host, '/some path/');
assert.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"');
assert.equal(subject.client_encoding, 'utf8');
});
test('initializing with unix domain socket, the health way', function () {
var subject = new ConnectionParameters('socket:/some path/?db=my[db]&encoding=utf8')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/some path/')
assert.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"')
assert.equal(subject.client_encoding, 'utf8')
})
test('initializing with unix domain socket, the escaped health way', function() {
var subject = new ConnectionParameters('socket:/some%20path/?db=my%2Bdb&encoding=utf8');
assert.ok(subject.isDomainSocket);
assert.equal(subject.host, '/some path/');
assert.equal(subject.database, 'my+db');
assert.equal(subject.client_encoding, 'utf8');
});
test('initializing with unix domain socket, the escaped health way', function () {
var subject = new ConnectionParameters('socket:/some%20path/?db=my%2Bdb&encoding=utf8')
assert.ok(subject.isDomainSocket)
assert.equal(subject.host, '/some path/')
assert.equal(subject.database, 'my+db')
assert.equal(subject.client_encoding, 'utf8')
})
test('libpq connection string building', function() {
var checkForPart = function(array, part) {
assert.ok(array.indexOf(part) > -1, array.join(" ") + " did not contain " + part);
test('libpq connection string building', function () {
var checkForPart = function (array, part) {
assert.ok(array.indexOf(part) > -1, array.join(' ') + ' did not contain ' + part)
}
test('builds simple string', function() {
test('builds simple string', function () {
var config = {
user: 'brian',
password: 'xyz',
@ -120,132 +120,131 @@ test('libpq connection string building', function() {
host: 'localhost',
database: 'bam'
}
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert(!err);
var parts = constring.split(" ");
checkForPart(parts, "user='brian'");
checkForPart(parts, "password='xyz'");
checkForPart(parts, "port='888'");
checkForPart(parts, "hostaddr='127.0.0.1'");
checkForPart(parts, "dbname='bam'");
}));
});
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, "password='xyz'")
checkForPart(parts, "port='888'")
checkForPart(parts, "hostaddr='127.0.0.1'")
checkForPart(parts, "dbname='bam'")
}))
})
test('builds dns string', function() {
test('builds dns string', function () {
var config = {
user: 'brian',
password: 'asdf',
port: 5432,
host: 'localhost'
};
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert(!err);
var parts = constring.split(" ");
checkForPart(parts, "user='brian'");
checkForPart(parts, "hostaddr='127.0.0.1'");
}));
});
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, "hostaddr='127.0.0.1'")
}))
})
test('error when dns fails', function() {
test('error when dns fails', function () {
var config = {
user: 'brian',
password: 'asf',
port: 5432,
host: 'asdlfkjasldfkksfd#!$!!!!..com'
};
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert.ok(err);
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert.ok(err)
assert.isNull(constring)
}));
});
}))
})
test('connecting to unix domain socket', function() {
test('connecting to unix domain socket', function () {
var config = {
user: 'brian',
password: 'asf',
port: 5432,
host: '/tmp/'
};
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert(!err);
var parts = constring.split(" ");
checkForPart(parts, "user='brian'");
checkForPart(parts, "host='/tmp/'");
}));
});
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='brian'")
checkForPart(parts, "host='/tmp/'")
}))
})
test('config contains quotes and backslashes', function() {
test('config contains quotes and backslashes', function () {
var config = {
user: 'not\\brian',
password: 'bad\'chars',
port: 5432,
host: '/tmp/'
};
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert(!err);
var parts = constring.split(" ");
checkForPart(parts, "user='not\\\\brian'");
checkForPart(parts, "password='bad\\'chars'");
}));
});
test("encoding can be specified by config", function() {
var config = {
client_encoding: "utf-8"
}
var subject = new ConnectionParameters(config);
subject.getLibpqConnectionString(assert.calls(function(err, constring) {
assert(!err);
var parts = constring.split(" ");
checkForPart(parts, "client_encoding='utf-8'");
}));
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "user='not\\\\brian'")
checkForPart(parts, "password='bad\\'chars'")
}))
})
test('encoding can be specified by config', function () {
var config = {
client_encoding: 'utf-8'
}
var subject = new ConnectionParameters(config)
subject.getLibpqConnectionString(assert.calls(function (err, constring) {
assert(!err)
var parts = constring.split(' ')
checkForPart(parts, "client_encoding='utf-8'")
}))
})
test('password contains < and/or > characters', function () {
return false;
return false
var sourceConfig = {
user:'brian',
user: 'brian',
password: 'hello<ther>e',
port: 5432,
host: 'localhost',
database: 'postgres'
}
var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database;
var subject = new ConnectionParameters(connectionString);
assert.equal(subject.password, sourceConfig.password);
});
var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database
var subject = new ConnectionParameters(connectionString)
assert.equal(subject.password, sourceConfig.password)
})
test('username or password contains weird characters', function() {
var defaults = require('../../../lib/defaults');
defaults.ssl = true;
var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000';
var subject = new ConnectionParameters(strang);
assert.equal(subject.user, 'my f%irst name');
assert.equal(subject.password, 'is&%awesome!');
assert.equal(subject.host, 'localhost');
assert.equal(subject.ssl, true);
});
test('username or password contains weird characters', function () {
var defaults = require('../../../lib/defaults')
defaults.ssl = true
var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'
var subject = new ConnectionParameters(strang)
assert.equal(subject.user, 'my f%irst name')
assert.equal(subject.password, 'is&%awesome!')
assert.equal(subject.host, 'localhost')
assert.equal(subject.ssl, true)
})
test("url is properly encoded", function() {
var encoded = "pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl";
var subject = new ConnectionParameters(encoded);
assert.equal(subject.user, "bi%na%%ry ");
assert.equal(subject.password, "s@f#");
assert.equal(subject.host, 'localhost');
assert.equal(subject.database, " u%20rl");
});
test('url is properly encoded', function () {
var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'
var subject = new ConnectionParameters(encoded)
assert.equal(subject.user, 'bi%na%%ry ')
assert.equal(subject.password, 's@f#')
assert.equal(subject.host, 'localhost')
assert.equal(subject.database, ' u%20rl')
})
test('ssl is set on client', function() {
test('ssl is set on client', function () {
var Client = require('../../../lib/client')
var defaults = require('../../../lib/defaults');
defaults.ssl = true;
var defaults = require('../../../lib/defaults')
defaults.ssl = true
var c = new Client('postgres://user@password:host/database')
assert(c.ssl, 'Client should have ssl enabled via defaults')
})
});
})

View File

@ -1,115 +1,113 @@
"use strict";
var helper = require(__dirname + '/../test-helper');
var assert = require('assert');
var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters');
var defaults = require(__dirname + '/../../../lib').defaults;
'use strict'
var helper = require(__dirname + '/../test-helper')
var assert = require('assert')
var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters')
var defaults = require(__dirname + '/../../../lib').defaults
//clear process.env
var realEnv = {};
for(var key in process.env) {
realEnv[key] = process.env[key];
delete process.env[key];
// clear process.env
var realEnv = {}
for (var key in process.env) {
realEnv[key] = process.env[key]
delete process.env[key]
}
test('ConnectionParameters initialized from environment variables', function(t) {
process.env['PGHOST'] = 'local';
process.env['PGUSER'] = 'bmc2';
process.env['PGPORT'] = 7890;
process.env['PGDATABASE'] = 'allyerbase';
process.env['PGPASSWORD'] = 'open';
test('ConnectionParameters initialized from environment variables', function (t) {
process.env['PGHOST'] = 'local'
process.env['PGUSER'] = 'bmc2'
process.env['PGPORT'] = 7890
process.env['PGDATABASE'] = 'allyerbase'
process.env['PGPASSWORD'] = 'open'
var subject = new ConnectionParameters();
assert.equal(subject.host, 'local', 'env host');
assert.equal(subject.user, 'bmc2', 'env user');
assert.equal(subject.port, 7890, 'env port');
assert.equal(subject.database, 'allyerbase', 'env database');
assert.equal(subject.password, 'open', 'env password');
});
var subject = new ConnectionParameters()
assert.equal(subject.host, 'local', 'env host')
assert.equal(subject.user, 'bmc2', 'env user')
assert.equal(subject.port, 7890, 'env port')
assert.equal(subject.database, 'allyerbase', 'env database')
assert.equal(subject.password, 'open', 'env password')
})
test('ConnectionParameters initialized from mix', function(t) {
delete process.env['PGPASSWORD'];
delete process.env['PGDATABASE'];
test('ConnectionParameters initialized from mix', function (t) {
delete process.env['PGPASSWORD']
delete process.env['PGDATABASE']
var subject = new ConnectionParameters({
user: 'testing',
database: 'zugzug'
});
assert.equal(subject.host, 'local', 'env host');
assert.equal(subject.user, 'testing', 'config user');
assert.equal(subject.port, 7890, 'env port');
assert.equal(subject.database, 'zugzug', 'config database');
assert.equal(subject.password, defaults.password, 'defaults password');
});
})
assert.equal(subject.host, 'local', 'env host')
assert.equal(subject.user, 'testing', 'config user')
assert.equal(subject.port, 7890, 'env port')
assert.equal(subject.database, 'zugzug', 'config database')
assert.equal(subject.password, defaults.password, 'defaults password')
})
//clear process.env
for(var key in process.env) {
delete process.env[key];
// clear process.env
for (var key in process.env) {
delete process.env[key]
}
test('connection string parsing', function(t) {
var string = 'postgres://brian:pw@boom:381/lala';
var subject = new ConnectionParameters(string);
assert.equal(subject.host, 'boom', 'string host');
assert.equal(subject.user, 'brian', 'string user');
assert.equal(subject.password, 'pw', 'string password');
assert.equal(subject.port, 381, 'string port');
assert.equal(subject.database, 'lala', 'string database');
});
test('connection string parsing', function (t) {
var string = 'postgres://brian:pw@boom:381/lala'
var subject = new ConnectionParameters(string)
assert.equal(subject.host, 'boom', 'string host')
assert.equal(subject.user, 'brian', 'string user')
assert.equal(subject.password, 'pw', 'string password')
assert.equal(subject.port, 381, 'string port')
assert.equal(subject.database, 'lala', 'string database')
})
test('connection string parsing - ssl', function(t) {
var string = 'postgres://brian:pw@boom:381/lala?ssl=true';
var subject = new ConnectionParameters(string);
assert.equal(subject.ssl, true, 'ssl');
test('connection string parsing - ssl', function (t) {
var string = 'postgres://brian:pw@boom:381/lala?ssl=true'
var subject = new ConnectionParameters(string)
assert.equal(subject.ssl, true, 'ssl')
string = 'postgres://brian:pw@boom:381/lala?ssl=1';
subject = new ConnectionParameters(string);
assert.equal(subject.ssl, true, 'ssl');
string = 'postgres://brian:pw@boom:381/lala?ssl=1'
subject = new ConnectionParameters(string)
assert.equal(subject.ssl, true, 'ssl')
string = 'postgres://brian:pw@boom:381/lala?other&ssl=true';
subject = new ConnectionParameters(string);
assert.equal(subject.ssl, true, 'ssl');
string = 'postgres://brian:pw@boom:381/lala?other&ssl=true'
subject = new ConnectionParameters(string)
assert.equal(subject.ssl, true, 'ssl')
string = 'postgres://brian:pw@boom:381/lala?ssl=0';
subject = new ConnectionParameters(string);
assert.equal(!!subject.ssl, false, 'ssl');
string = 'postgres://brian:pw@boom:381/lala?ssl=0'
subject = new ConnectionParameters(string)
assert.equal(!!subject.ssl, false, 'ssl')
string = 'postgres://brian:pw@boom:381/lala';
subject = new ConnectionParameters(string);
assert.equal(!!subject.ssl, false, 'ssl');
});
string = 'postgres://brian:pw@boom:381/lala'
subject = new ConnectionParameters(string)
assert.equal(!!subject.ssl, false, 'ssl')
})
//clear process.env
for(var key in process.env) {
delete process.env[key];
// clear process.env
for (var key in process.env) {
delete process.env[key]
}
test('ssl is false by default', function() {
test('ssl is false by default', function () {
var subject = new ConnectionParameters()
assert.equal(subject.ssl, false)
})
var testVal = function(mode, expected) {
//clear process.env
for(var key in process.env) {
delete process.env[key];
var testVal = function (mode, expected) {
// clear process.env
for (var key in process.env) {
delete process.env[key]
}
process.env.PGSSLMODE = mode;
test('ssl is ' + expected + ' when $PGSSLMODE=' + mode, function() {
var subject = new ConnectionParameters();
assert.equal(subject.ssl, expected);
});
};
testVal('', false);
testVal('disable', false);
testVal('allow', false);
testVal('prefer', true);
testVal('require', true);
testVal('verify-ca', true);
testVal('verify-full', true);
//restore process.env
for(var key in realEnv) {
process.env[key] = realEnv[key];
process.env.PGSSLMODE = mode
test('ssl is ' + expected + ' when $PGSSLMODE=' + mode, function () {
var subject = new ConnectionParameters()
assert.equal(subject.ssl, expected)
})
}
testVal('', false)
testVal('disable', false)
testVal('allow', false)
testVal('prefer', true)
testVal('require', true)
testVal('verify-ca', true)
testVal('verify-full', true)
// restore process.env
for (var key in realEnv) {
process.env[key] = realEnv[key]
}

View File

@ -1,31 +1,31 @@
"use strict";
var helper = require(__dirname + '/test-helper');
var Connection = require(__dirname + '/../../../lib/connection');
test("connection emits stream errors", function() {
var con = new Connection({stream: new MemoryStream()});
assert.emits(con, 'error', function(err) {
assert.equal(err.message, "OMG!");
});
con.connect();
con.stream.emit('error', new Error("OMG!"));
});
'use strict'
var helper = require(__dirname + '/test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
test('connection emits stream errors', function () {
var con = new Connection({stream: new MemoryStream()})
assert.emits(con, 'error', function (err) {
assert.equal(err.message, 'OMG!')
})
con.connect()
con.stream.emit('error', new Error('OMG!'))
})
test('connection emits ECONNRESET errors during normal operation', function() {
var con = new Connection({stream: new MemoryStream()});
con.connect();
assert.emits(con, 'error', function(err) {
assert.equal(err.code, 'ECONNRESET');
});
var e = new Error('Connection Reset');
e.code = 'ECONNRESET';
con.stream.emit('error', e);
});
test('connection emits ECONNRESET errors during normal operation', function () {
var con = new Connection({stream: new MemoryStream()})
con.connect()
assert.emits(con, 'error', function (err) {
assert.equal(err.code, 'ECONNRESET')
})
var e = new Error('Connection Reset')
e.code = 'ECONNRESET'
con.stream.emit('error', e)
})
test('connection does not emit ECONNRESET errors during disconnect', function() {
var con = new Connection({stream: new MemoryStream()});
con.connect();
var e = new Error('Connection Reset');
e.code = 'ECONNRESET';
con.end();
con.stream.emit('error', e);
});
test('connection does not emit ECONNRESET errors during disconnect', function () {
var con = new Connection({stream: new MemoryStream()})
con.connect()
var e = new Error('Connection Reset')
e.code = 'ECONNRESET'
con.end()
con.stream.emit('error', e)
})

View File

@ -1,29 +1,29 @@
"use strict";
require(__dirname+'/test-helper');
var Connection = require(__dirname + '/../../../lib/connection');
var buffers = require(__dirname + '/../../test-buffers');
var PARSE = function(buffer) {
return new Parser(buffer).parse();
};
'use strict'
require(__dirname + '/test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
var buffers = require(__dirname + '/../../test-buffers')
var PARSE = function (buffer) {
return new Parser(buffer).parse()
}
var authOkBuffer = buffers.authenticationOk();
var paramStatusBuffer = buffers.parameterStatus('client_encoding', 'UTF8');
var readyForQueryBuffer = buffers.readyForQuery();
var backendKeyDataBuffer = buffers.backendKeyData(1,2);
var commandCompleteBuffer = buffers.commandComplete("SELECT 3");
var parseCompleteBuffer = buffers.parseComplete();
var bindCompleteBuffer = buffers.bindComplete();
var portalSuspendedBuffer = buffers.portalSuspended();
var authOkBuffer = buffers.authenticationOk()
var paramStatusBuffer = buffers.parameterStatus('client_encoding', 'UTF8')
var readyForQueryBuffer = buffers.readyForQuery()
var backendKeyDataBuffer = buffers.backendKeyData(1, 2)
var commandCompleteBuffer = buffers.commandComplete('SELECT 3')
var parseCompleteBuffer = buffers.parseComplete()
var bindCompleteBuffer = buffers.bindComplete()
var portalSuspendedBuffer = buffers.portalSuspended()
var addRow = function(bufferList, name, offset) {
return bufferList.addCString(name) //field name
.addInt32(offset++) //table id
.addInt16(offset++) //attribute of column number
.addInt32(offset++) //objectId of field's data type
.addInt16(offset++) //datatype size
.addInt32(offset++) //type modifier
.addInt16(0) //format code, 0 => text
};
var addRow = function (bufferList, name, offset) {
return bufferList.addCString(name) // field name
.addInt32(offset++) // table id
.addInt16(offset++) // attribute of column number
.addInt32(offset++) // objectId of field's data type
.addInt16(offset++) // datatype size
.addInt32(offset++) // type modifier
.addInt16(0) // format code, 0 => text
}
var row1 = {
name: 'id',
@ -33,11 +33,11 @@ var row1 = {
dataTypeSize: 4,
typeModifier: 5,
formatCode: 0
};
var oneRowDescBuff = new buffers.rowDescription([row1]);
row1.name = 'bang';
}
var oneRowDescBuff = new buffers.rowDescription([row1])
row1.name = 'bang'
var twoRowBuf = new buffers.rowDescription([row1,{
var twoRowBuf = new buffers.rowDescription([row1, {
name: 'whoah',
tableID: 10,
attributeNumber: 11,
@ -47,144 +47,142 @@ var twoRowBuf = new buffers.rowDescription([row1,{
formatCode: 0
}])
var emptyRowFieldBuf = new BufferList()
.addInt16(0)
.join(true, 'D');
.join(true, 'D')
var emptyRowFieldBuf = buffers.dataRow();
var emptyRowFieldBuf = buffers.dataRow()
var oneFieldBuf = new BufferList()
.addInt16(1) //number of fields
.addInt32(5) //length of bytes of fields
.addInt16(1) // number of fields
.addInt32(5) // length of bytes of fields
.addCString('test')
.join(true, 'D');
var oneFieldBuf = buffers.dataRow(['test']);
.join(true, 'D')
var oneFieldBuf = buffers.dataRow(['test'])
var expectedAuthenticationOkayMessage = {
name: 'authenticationOk',
length: 8
};
}
var expectedParameterStatusMessage = {
name: 'parameterStatus',
parameterName: 'client_encoding',
parameterValue: 'UTF8',
length: 25
};
}
var expectedBackendKeyDataMessage = {
name: 'backendKeyData',
processID: 1,
secretKey: 2
};
}
var expectedReadyForQueryMessage = {
name: 'readyForQuery',
length: 5,
status: 'I'
};
}
var expectedCommandCompleteMessage = {
length: 13,
text: "SELECT 3"
};
text: 'SELECT 3'
}
var emptyRowDescriptionBuffer = new BufferList()
.addInt16(0) //number of fields
.join(true,'T');
.addInt16(0) // number of fields
.join(true, 'T')
var expectedEmptyRowDescriptionMessage = {
name: 'rowDescription',
length: 6,
fieldCount: 0
};
}
var expectedOneRowMessage = {
name: 'rowDescription',
length: 27,
fieldCount: 1
};
}
var expectedTwoRowMessage = {
name: 'rowDescription',
length: 53,
fieldCount: 2
};
}
var testForMessage = function(buffer, expectedMessage) {
var lastMessage = {};
test('recieves and parses ' + expectedMessage.name, function() {
var stream = new MemoryStream();
var testForMessage = function (buffer, expectedMessage) {
var lastMessage = {}
test('recieves and parses ' + expectedMessage.name, function () {
var stream = new MemoryStream()
var client = new Connection({
stream: stream
});
client.connect();
})
client.connect()
client.on('message',function(msg) {
lastMessage = msg;
});
client.on('message', function (msg) {
lastMessage = msg
})
client.on(expectedMessage.name, function() {
client.removeAllListeners(expectedMessage.name);
});
client.on(expectedMessage.name, function () {
client.removeAllListeners(expectedMessage.name)
})
stream.emit('data', buffer);
assert.same(lastMessage, expectedMessage);
});
return lastMessage;
};
stream.emit('data', buffer)
assert.same(lastMessage, expectedMessage)
})
return lastMessage
}
var plainPasswordBuffer = buffers.authenticationCleartextPassword();
var md5PasswordBuffer = buffers.authenticationMD5Password();
var plainPasswordBuffer = buffers.authenticationCleartextPassword()
var md5PasswordBuffer = buffers.authenticationMD5Password()
var expectedPlainPasswordMessage = {
name: 'authenticationCleartextPassword'
};
}
var expectedMD5PasswordMessage = {
name: 'authenticationMD5Password'
};
}
var notificationResponseBuffer = buffers.notification(4, 'hi', 'boom');
var notificationResponseBuffer = buffers.notification(4, 'hi', 'boom')
var expectedNotificationResponseMessage = {
name: 'notification',
processId: 4,
channel: 'hi',
payload: 'boom'
};
}
test('Connection', function() {
testForMessage(authOkBuffer, expectedAuthenticationOkayMessage);
testForMessage(plainPasswordBuffer, expectedPlainPasswordMessage);
var msg = testForMessage(md5PasswordBuffer, expectedMD5PasswordMessage);
test('md5 has right salt', function() {
assert.equalBuffers(msg.salt, Buffer.from([1,2,3,4]));
});
testForMessage(paramStatusBuffer, expectedParameterStatusMessage);
testForMessage(backendKeyDataBuffer, expectedBackendKeyDataMessage);
testForMessage(readyForQueryBuffer, expectedReadyForQueryMessage);
testForMessage(commandCompleteBuffer,expectedCommandCompleteMessage);
testForMessage(notificationResponseBuffer, expectedNotificationResponseMessage);
test('empty row message', function() {
var message = testForMessage(emptyRowDescriptionBuffer, expectedEmptyRowDescriptionMessage);
test('has no fields', function() {
assert.equal(message.fields.length, 0);
});
});
test('Connection', function () {
testForMessage(authOkBuffer, expectedAuthenticationOkayMessage)
testForMessage(plainPasswordBuffer, expectedPlainPasswordMessage)
var msg = testForMessage(md5PasswordBuffer, expectedMD5PasswordMessage)
test('md5 has right salt', function () {
assert.equalBuffers(msg.salt, Buffer.from([1, 2, 3, 4]))
})
testForMessage(paramStatusBuffer, expectedParameterStatusMessage)
testForMessage(backendKeyDataBuffer, expectedBackendKeyDataMessage)
testForMessage(readyForQueryBuffer, expectedReadyForQueryMessage)
testForMessage(commandCompleteBuffer, expectedCommandCompleteMessage)
testForMessage(notificationResponseBuffer, expectedNotificationResponseMessage)
test('empty row message', function () {
var message = testForMessage(emptyRowDescriptionBuffer, expectedEmptyRowDescriptionMessage)
test('has no fields', function () {
assert.equal(message.fields.length, 0)
})
})
test("no data message", function() {
test('no data message', function () {
testForMessage(Buffer.from([0x6e, 0, 0, 0, 4]), {
name: 'noData'
});
});
})
})
test('one row message', function() {
var message = testForMessage(oneRowDescBuff, expectedOneRowMessage);
test('has one field', function() {
assert.equal(message.fields.length, 1);
});
test('has correct field info', function() {
test('one row message', function () {
var message = testForMessage(oneRowDescBuff, expectedOneRowMessage)
test('has one field', function () {
assert.equal(message.fields.length, 1)
})
test('has correct field info', function () {
assert.same(message.fields[0], {
name: 'id',
tableID: 1,
@ -193,16 +191,16 @@ test('Connection', function() {
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text'
});
});
});
})
})
})
test('two row message', function() {
var message = testForMessage(twoRowBuf, expectedTwoRowMessage);
test('has two fields', function() {
assert.equal(message.fields.length, 2);
});
test('has correct first field', function() {
test('two row message', function () {
var message = testForMessage(twoRowBuf, expectedTwoRowMessage)
test('has two fields', function () {
assert.equal(message.fields.length, 2)
})
test('has correct first field', function () {
assert.same(message.fields[0], {
name: 'bang',
tableID: 1,
@ -212,8 +210,8 @@ test('Connection', function() {
dataTypeModifier: 5,
format: 'text'
})
});
test('has correct second field', function() {
})
test('has correct second field', function () {
assert.same(message.fields[1], {
name: 'whoah',
tableID: 10,
@ -222,98 +220,95 @@ test('Connection', function() {
dataTypeSize: 13,
dataTypeModifier: 14,
format: 'text'
});
});
})
})
})
});
test('parsing rows', function() {
test('parsing empty row', function() {
test('parsing rows', function () {
test('parsing empty row', function () {
var message = testForMessage(emptyRowFieldBuf, {
name: 'dataRow',
fieldCount: 0
});
test('has 0 fields', function() {
assert.equal(message.fields.length, 0);
});
});
})
test('has 0 fields', function () {
assert.equal(message.fields.length, 0)
})
})
test('parsing data row with fields', function() {
test('parsing data row with fields', function () {
var message = testForMessage(oneFieldBuf, {
name: 'dataRow',
fieldCount: 1
});
test('has 1 field', function() {
assert.equal(message.fields.length, 1);
});
})
test('has 1 field', function () {
assert.equal(message.fields.length, 1)
})
test('field is correct', function() {
assert.equal(message.fields[0],'test');
});
});
test('field is correct', function () {
assert.equal(message.fields[0], 'test')
})
})
})
});
test('notice message', function() {
//this uses the same logic as error message
var buff = buffers.notice([{type: 'C', value: 'code'}]);
test('notice message', function () {
// this uses the same logic as error message
var buff = buffers.notice([{type: 'C', value: 'code'}])
testForMessage(buff, {
name: 'notice',
code: 'code'
});
});
})
})
test('error messages', function() {
test('with no fields', function() {
var msg = testForMessage(buffers.error(),{
test('error messages', function () {
test('with no fields', function () {
var msg = testForMessage(buffers.error(), {
name: 'error'
});
});
})
})
test('with all the fields', function() {
test('with all the fields', function () {
var buffer = buffers.error([{
type: 'S',
value: 'ERROR'
},{
}, {
type: 'C',
value: 'code'
},{
}, {
type: 'M',
value: 'message'
},{
}, {
type: 'D',
value: 'details'
},{
}, {
type: 'H',
value: 'hint'
},{
}, {
type: 'P',
value: '100'
},{
}, {
type: 'p',
value: '101'
},{
}, {
type: 'q',
value: 'query'
},{
}, {
type: 'W',
value: 'where'
},{
}, {
type: 'F',
value: 'file'
},{
}, {
type: 'L',
value: 'line'
},{
}, {
type: 'R',
value: 'routine'
},{
type: 'Z', //ignored
}, {
type: 'Z', // ignored
value: 'alsdkf'
}]);
}])
testForMessage(buffer,{
testForMessage(buffer, {
name: 'error',
severity: 'ERROR',
code: 'code',
@ -327,150 +322,148 @@ test('Connection', function() {
file: 'file',
line: 'line',
routine: 'routine'
});
});
});
})
})
})
test('parses parse complete command', function() {
test('parses parse complete command', function () {
testForMessage(parseCompleteBuffer, {
name: 'parseComplete'
});
});
})
})
test('parses bind complete command', function() {
test('parses bind complete command', function () {
testForMessage(bindCompleteBuffer, {
name: 'bindComplete'
});
});
})
})
test('parses portal suspended message', function() {
test('parses portal suspended message', function () {
testForMessage(portalSuspendedBuffer, {
name: 'portalSuspended'
});
});
})
})
test('parses replication start message', function() {
test('parses replication start message', function () {
testForMessage(Buffer.from([0x57, 0x00, 0x00, 0x00, 0x04]), {
name: 'replicationStart',
length: 4
});
});
});
})
})
})
//since the data message on a stream can randomly divide the incomming
//tcp packets anywhere, we need to make sure we can parse every single
//split on a tcp message
test('split buffer, single message parsing', function() {
var fullBuffer = buffers.dataRow([null, "bang", "zug zug", null, "!"]);
var stream = new MemoryStream();
stream.readyState = 'open';
// since the data message on a stream can randomly divide the incomming
// tcp packets anywhere, we need to make sure we can parse every single
// split on a tcp message
test('split buffer, single message parsing', function () {
var fullBuffer = buffers.dataRow([null, 'bang', 'zug zug', null, '!'])
var stream = new MemoryStream()
stream.readyState = 'open'
var client = new Connection({
stream: stream
});
client.connect();
var message = null;
client.on('message', function(msg) {
message = msg;
});
})
client.connect()
var message = null
client.on('message', function (msg) {
message = msg
})
test('parses when full buffer comes in', function() {
stream.emit('data', fullBuffer);
assert.lengthIs(message.fields, 5);
assert.equal(message.fields[0], null);
assert.equal(message.fields[1], "bang");
assert.equal(message.fields[2], "zug zug");
assert.equal(message.fields[3], null);
assert.equal(message.fields[4], "!");
});
test('parses when full buffer comes in', function () {
stream.emit('data', fullBuffer)
assert.lengthIs(message.fields, 5)
assert.equal(message.fields[0], null)
assert.equal(message.fields[1], 'bang')
assert.equal(message.fields[2], 'zug zug')
assert.equal(message.fields[3], null)
assert.equal(message.fields[4], '!')
})
var testMessageRecievedAfterSpiltAt = function(split) {
var firstBuffer = Buffer.alloc(fullBuffer.length-split);
var secondBuffer = Buffer.alloc(fullBuffer.length-firstBuffer.length);
fullBuffer.copy(firstBuffer, 0, 0);
fullBuffer.copy(secondBuffer, 0, firstBuffer.length);
stream.emit('data', firstBuffer);
stream.emit('data', secondBuffer);
assert.lengthIs(message.fields, 5);
assert.equal(message.fields[0], null);
assert.equal(message.fields[1], "bang");
assert.equal(message.fields[2], "zug zug");
assert.equal(message.fields[3], null);
assert.equal(message.fields[4], "!");
var testMessageRecievedAfterSpiltAt = function (split) {
var firstBuffer = Buffer.alloc(fullBuffer.length - split)
var secondBuffer = Buffer.alloc(fullBuffer.length - firstBuffer.length)
fullBuffer.copy(firstBuffer, 0, 0)
fullBuffer.copy(secondBuffer, 0, firstBuffer.length)
stream.emit('data', firstBuffer)
stream.emit('data', secondBuffer)
assert.lengthIs(message.fields, 5)
assert.equal(message.fields[0], null)
assert.equal(message.fields[1], 'bang')
assert.equal(message.fields[2], 'zug zug')
assert.equal(message.fields[3], null)
assert.equal(message.fields[4], '!')
}
};
test('parses when split in the middle', function () {
testMessageRecievedAfterSpiltAt(6)
})
test('parses when split in the middle', function() {
testMessageRecievedAfterSpiltAt(6);
});
test('parses when split at end', function () {
testMessageRecievedAfterSpiltAt(2)
})
test('parses when split at end', function() {
testMessageRecievedAfterSpiltAt(2);
});
test('parses when split at beginning', function () {
testMessageRecievedAfterSpiltAt(fullBuffer.length - 2)
testMessageRecievedAfterSpiltAt(fullBuffer.length - 1)
testMessageRecievedAfterSpiltAt(fullBuffer.length - 5)
})
})
test('parses when split at beginning', function() {
testMessageRecievedAfterSpiltAt(fullBuffer.length - 2);
testMessageRecievedAfterSpiltAt(fullBuffer.length - 1);
testMessageRecievedAfterSpiltAt(fullBuffer.length - 5);
});
});
test('split buffer, multiple message parsing', function () {
var dataRowBuffer = buffers.dataRow(['!'])
var readyForQueryBuffer = buffers.readyForQuery()
var fullBuffer = Buffer.alloc(dataRowBuffer.length + readyForQueryBuffer.length)
dataRowBuffer.copy(fullBuffer, 0, 0)
readyForQueryBuffer.copy(fullBuffer, dataRowBuffer.length, 0)
test('split buffer, multiple message parsing', function() {
var dataRowBuffer = buffers.dataRow(['!']);
var readyForQueryBuffer = buffers.readyForQuery();
var fullBuffer = Buffer.alloc(dataRowBuffer.length + readyForQueryBuffer.length);
dataRowBuffer.copy(fullBuffer, 0, 0);
readyForQueryBuffer.copy(fullBuffer, dataRowBuffer.length, 0);
var messages = [];
var stream = new MemoryStream();
var messages = []
var stream = new MemoryStream()
var client = new Connection({
stream: stream
});
client.connect();
client.on('message', function(msg) {
messages.push(msg);
});
})
client.connect()
client.on('message', function (msg) {
messages.push(msg)
})
var verifyMessages = function() {
assert.lengthIs(messages, 2);
assert.same(messages[0],{
var verifyMessages = function () {
assert.lengthIs(messages, 2)
assert.same(messages[0], {
name: 'dataRow',
fieldCount: 1
});
assert.equal(messages[0].fields[0],'!');
assert.same(messages[1],{
})
assert.equal(messages[0].fields[0], '!')
assert.same(messages[1], {
name: 'readyForQuery'
});
messages = [];
};
//sanity check
test('recieves both messages when packet is not split', function() {
stream.emit('data', fullBuffer);
verifyMessages();
});
var splitAndVerifyTwoMessages = function(split) {
var firstBuffer = Buffer.alloc(fullBuffer.length-split);
var secondBuffer = Buffer.alloc(fullBuffer.length-firstBuffer.length);
fullBuffer.copy(firstBuffer, 0, 0);
fullBuffer.copy(secondBuffer, 0, firstBuffer.length);
stream.emit('data', firstBuffer);
stream.emit('data', secondBuffer);
};
})
messages = []
}
// sanity check
test('recieves both messages when packet is not split', function () {
stream.emit('data', fullBuffer)
verifyMessages()
})
var splitAndVerifyTwoMessages = function (split) {
var firstBuffer = Buffer.alloc(fullBuffer.length - split)
var secondBuffer = Buffer.alloc(fullBuffer.length - firstBuffer.length)
fullBuffer.copy(firstBuffer, 0, 0)
fullBuffer.copy(secondBuffer, 0, firstBuffer.length)
stream.emit('data', firstBuffer)
stream.emit('data', secondBuffer)
}
test('recieves both messages when packet is split', function() {
test('in the middle', function() {
splitAndVerifyTwoMessages(11);
});
test('at the front', function() {
splitAndVerifyTwoMessages(fullBuffer.length-1);
splitAndVerifyTwoMessages(fullBuffer.length-4);
splitAndVerifyTwoMessages(fullBuffer.length-6);
});
test('recieves both messages when packet is split', function () {
test('in the middle', function () {
splitAndVerifyTwoMessages(11)
})
test('at the front', function () {
splitAndVerifyTwoMessages(fullBuffer.length - 1)
splitAndVerifyTwoMessages(fullBuffer.length - 4)
splitAndVerifyTwoMessages(fullBuffer.length - 6)
})
test('at the end', function() {
splitAndVerifyTwoMessages(8);
splitAndVerifyTwoMessages(1);
});
});
});
test('at the end', function () {
splitAndVerifyTwoMessages(8)
splitAndVerifyTwoMessages(1)
})
})
})

View File

@ -1,22 +1,22 @@
"use strict";
require(__dirname + "/test-helper");
var Connection = require(__dirname + '/../../../lib/connection');
var stream = new MemoryStream();
'use strict'
require(__dirname + '/test-helper')
var Connection = require(__dirname + '/../../../lib/connection')
var stream = new MemoryStream()
var con = new Connection({
stream: stream
});
})
assert.received = function(stream, buffer) {
assert.lengthIs(stream.packets, 1);
var packet = stream.packets.pop();
assert.equalBuffers(packet, buffer);
};
assert.received = function (stream, buffer) {
assert.lengthIs(stream.packets, 1)
var packet = stream.packets.pop()
assert.equalBuffers(packet, buffer)
}
test("sends startup message", function() {
test('sends startup message', function () {
con.startup({
user: 'brian',
database: 'bang'
});
})
assert.received(stream, new BufferList()
.addInt16(3)
.addInt16(0)
@ -27,175 +27,174 @@ test("sends startup message", function() {
.addCString('client_encoding')
.addCString("'utf-8'")
.addCString('').join(true))
});
})
test('sends password message', function() {
con.password("!");
assert.received(stream, new BufferList().addCString("!").join(true,'p'));
});
test('sends password message', function () {
con.password('!')
assert.received(stream, new BufferList().addCString('!').join(true, 'p'))
})
test('sends query message', function() {
var txt = 'select * from boom';
con.query(txt);
assert.received(stream, new BufferList().addCString(txt).join(true,'Q'));
});
test('sends query message', function () {
var txt = 'select * from boom'
con.query(txt)
assert.received(stream, new BufferList().addCString(txt).join(true, 'Q'))
})
test('sends parse message', function() {
con.parse({text: '!'});
test('sends parse message', function () {
con.parse({text: '!'})
var expected = new BufferList()
.addCString("")
.addCString("!")
.addInt16(0).join(true, 'P');
assert.received(stream, expected);
});
.addCString('')
.addCString('!')
.addInt16(0).join(true, 'P')
assert.received(stream, expected)
})
test('sends parse message with named query', function() {
test('sends parse message with named query', function () {
con.parse({
name: 'boom',
text: 'select * from boom',
types: []
});
})
var expected = new BufferList()
.addCString("boom")
.addCString("select * from boom")
.addInt16(0).join(true,'P');
assert.received(stream, expected);
.addCString('boom')
.addCString('select * from boom')
.addInt16(0).join(true, 'P')
assert.received(stream, expected)
test('with multiple parameters', function() {
test('with multiple parameters', function () {
con.parse({
name: 'force',
text: 'select * from bang where name = $1',
types: [1, 2, 3 ,4]
});
types: [1, 2, 3, 4]
})
var expected = new BufferList()
.addCString("force")
.addCString("select * from bang where name = $1")
.addCString('force')
.addCString('select * from bang where name = $1')
.addInt16(4)
.addInt32(1)
.addInt32(2)
.addInt32(3)
.addInt32(4).join(true,'P');
assert.received(stream, expected);
});
});
.addInt32(4).join(true, 'P')
assert.received(stream, expected)
})
})
test('bind messages', function() {
test('with no values', function() {
con.bind();
test('bind messages', function () {
test('with no values', function () {
con.bind()
var expectedBuffer = new BufferList()
.addCString("")
.addCString("")
.addCString('')
.addCString('')
.addInt16(0)
.addInt16(0)
.addInt16(0)
.join(true,"B");
assert.received(stream, expectedBuffer);
});
.join(true, 'B')
assert.received(stream, expectedBuffer)
})
test('with named statement, portal, and values', function() {
test('with named statement, portal, and values', function () {
con.bind({
portal: 'bang',
statement: 'woo',
values: ['1', 'hi', null, 'zing']
});
})
var expectedBuffer = new BufferList()
.addCString('bang') //portal name
.addCString('woo') //statement name
.addCString('bang') // portal name
.addCString('woo') // statement name
.addInt16(0)
.addInt16(4)
.addInt32(1)
.add(Buffer.from("1"))
.add(Buffer.from('1'))
.addInt32(2)
.add(Buffer.from("hi"))
.add(Buffer.from('hi'))
.addInt32(-1)
.addInt32(4)
.add(Buffer.from('zing'))
.addInt16(0)
.join(true, 'B');
assert.received(stream, expectedBuffer);
});
});
.join(true, 'B')
assert.received(stream, expectedBuffer)
})
})
test('with named statement, portal, and buffer value', function() {
test('with named statement, portal, and buffer value', function () {
con.bind({
portal: 'bang',
statement: 'woo',
values: ['1', 'hi', null, Buffer.from('zing', 'utf8')]
});
})
var expectedBuffer = new BufferList()
.addCString('bang') //portal name
.addCString('woo') //statement name
.addInt16(4)//value count
.addInt16(0)//string
.addInt16(0)//string
.addInt16(0)//string
.addInt16(1)//binary
.addCString('bang') // portal name
.addCString('woo') // statement name
.addInt16(4)// value count
.addInt16(0)// string
.addInt16(0)// string
.addInt16(0)// string
.addInt16(1)// binary
.addInt16(4)
.addInt32(1)
.add(Buffer.from("1"))
.add(Buffer.from('1'))
.addInt32(2)
.add(Buffer.from("hi"))
.add(Buffer.from('hi'))
.addInt32(-1)
.addInt32(4)
.add(Buffer.from('zing', 'UTF-8'))
.addInt16(0)
.join(true, 'B');
assert.received(stream, expectedBuffer);
});
.join(true, 'B')
assert.received(stream, expectedBuffer)
})
test("sends execute message", function() {
test("for unamed portal with no row limit", function() {
con.execute();
test('sends execute message', function () {
test('for unamed portal with no row limit', function () {
con.execute()
var expectedBuffer = new BufferList()
.addCString('')
.addInt32(0)
.join(true,'E');
assert.received(stream, expectedBuffer);
});
.join(true, 'E')
assert.received(stream, expectedBuffer)
})
test("for named portal with row limit", function() {
test('for named portal with row limit', function () {
con.execute({
portal: 'my favorite portal',
rows: 100
});
})
var expectedBuffer = new BufferList()
.addCString("my favorite portal")
.addCString('my favorite portal')
.addInt32(100)
.join(true, 'E');
assert.received(stream, expectedBuffer);
});
});
.join(true, 'E')
assert.received(stream, expectedBuffer)
})
})
test('sends flush command', function() {
con.flush();
var expected = new BufferList().join(true, 'H');
assert.received(stream, expected);
});
test('sends flush command', function () {
con.flush()
var expected = new BufferList().join(true, 'H')
assert.received(stream, expected)
})
test('sends sync command', function() {
con.sync();
var expected = new BufferList().join(true,'S');
assert.received(stream, expected);
});
test('sends sync command', function () {
con.sync()
var expected = new BufferList().join(true, 'S')
assert.received(stream, expected)
})
test('sends end command', function() {
con.end();
var expected = Buffer.from([0x58, 0, 0, 0, 4]);
assert.received(stream, expected);
});
test('sends end command', function () {
con.end()
var expected = Buffer.from([0x58, 0, 0, 0, 4])
assert.received(stream, expected)
})
test('sends describe command',function() {
test('describe statement', function() {
con.describe({type: 'S', name: 'bang'});
test('sends describe command', function () {
test('describe statement', function () {
con.describe({type: 'S', name: 'bang'})
var expected = new BufferList().addChar('S').addCString('bang').join(true, 'D')
assert.received(stream, expected);
});
assert.received(stream, expected)
})
test("describe unnamed portal", function() {
con.describe({type: 'P'});
var expected = new BufferList().addChar('P').addCString("").join(true, "D");
assert.received(stream, expected);
});
});
test('describe unnamed portal', function () {
con.describe({type: 'P'})
var expected = new BufferList().addChar('P').addCString('').join(true, 'D')
assert.received(stream, expected)
})
})

Some files were not shown because too many files have changed in this diff Show More