mirror of
https://github.com/brianc/node-postgres.git
synced 2025-12-08 20:16:25 +00:00
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:
parent
f7de9ce820
commit
8798e50ad3
6
.eslintrc
Normal file
6
.eslintrc
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "standard",
|
||||
"rules": {
|
||||
"no-new-func": "off"
|
||||
}
|
||||
}
|
||||
9
Makefile
9
Makefile
@ -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
|
||||
|
||||
416
lib/client.js
416
lib/client.js
@ -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
|
||||
|
||||
@ -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
@ -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)
|
||||
})
|
||||
|
||||
73
lib/index.js
73
lib/index.js
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
"use strict";
|
||||
'use strict'
|
||||
module.exports = require('./client')
|
||||
|
||||
@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -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.
|
||||
};
|
||||
}
|
||||
|
||||
268
lib/query.js
268
lib/query.js
@ -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
|
||||
|
||||
166
lib/result.js
166
lib/result.js
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
178
lib/utils.js
178
lib/utils.js
@ -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
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@ -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": {
|
||||
|
||||
@ -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()
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}))
|
||||
|
||||
@ -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
|
||||
|
||||
38
test/cli.js
38
test/cli.js
@ -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
|
||||
|
||||
@ -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()
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
@ -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()
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -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
@ -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]
|
||||
}
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}));
|
||||
}))
|
||||
|
||||
@ -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()
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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))
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
var helper = require('./../test-helper');
|
||||
'use strict'
|
||||
var helper = require('./../test-helper')
|
||||
|
||||
module.exports = helper;
|
||||
module.exports = helper
|
||||
|
||||
@ -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
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}));
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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)
|
||||
});
|
||||
}));
|
||||
});
|
||||
})
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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())
|
||||
})
|
||||
}))
|
||||
}))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
}))
|
||||
}))
|
||||
})
|
||||
}));
|
||||
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 })
|
||||
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@ -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'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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')
|
||||
})
|
||||
|
||||
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"use strict";
|
||||
'use strict'
|
||||
var async = require('async')
|
||||
|
||||
var helper = require('./test-helper')
|
||||
|
||||
@ -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
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}))
|
||||
|
||||
@ -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()
|
||||
})
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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()
|
||||
}));
|
||||
}));
|
||||
});
|
||||
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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])
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
|
||||
@ -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)
|
||||
}))
|
||||
})
|
||||
|
||||
@ -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"')
|
||||
|
||||
@ -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')
|
||||
})
|
||||
|
||||
@ -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!!')
|
||||
})
|
||||
|
||||
|
||||
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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'))
|
||||
|
||||
@ -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")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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()
|
||||
})
|
||||
})
|
||||
|
||||
@ -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')
|
||||
})
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
@ -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]
|
||||
}
|
||||
|
||||
@ -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)
|
||||
})
|
||||
|
||||
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user