Comparing version 0.5.5 to 0.5.6
@@ -132,3 +132,3 @@ var sys = require('sys'); | ||
this.activeQuery = null; | ||
this.emit('drain') | ||
this._drainPaused > 0 ? this._drainPaused++ : this.emit('drain') | ||
} | ||
@@ -158,2 +158,15 @@ } | ||
//prevents client from otherwise emitting 'drain' event until 'resumeDrain' is called | ||
p.pauseDrain = function() { | ||
this._drainPaused = 1; | ||
}; | ||
//resume raising 'drain' event | ||
p.resumeDrain = function() { | ||
if(this._drainPaused > 1) { | ||
this.emit('drain'); | ||
} | ||
this._drainPaused = 0; | ||
}; | ||
p.end = function() { | ||
@@ -160,0 +173,0 @@ this.connection.end(); |
133
lib/index.js
var EventEmitter = require('events').EventEmitter; | ||
var sys = require('sys'); | ||
var Client = require(__dirname+'/client'); | ||
var defaults = require(__dirname + '/defaults'); | ||
//external genericPool module | ||
var genericPool = require('generic-pool'); | ||
@@ -9,46 +13,12 @@ | ||
//returns connect function using supplied client constructor | ||
var makeConnectFunction = function(ClientConstructor) { | ||
return function(config, callback) { | ||
var c = config; | ||
var cb = callback; | ||
//allow for no config to be passed | ||
if(typeof c === 'function') { | ||
cb = c; | ||
c = defaults; | ||
} | ||
//get unique pool name if using a config object instead of config string | ||
var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database; | ||
var pool = pools[poolName]; | ||
if(pool) return pool.acquire(cb); | ||
var pool = pools[poolName] = genericPool.Pool({ | ||
name: poolName, | ||
create: function(callback) { | ||
var client = new ClientConstructor(c); | ||
client.connect(); | ||
var connectError = function(err) { | ||
client.removeListener('connect', connectSuccess); | ||
callback(err, null); | ||
}; | ||
var connectSuccess = function() { | ||
client.removeListener('error', connectError); | ||
callback(null, client); | ||
}; | ||
client.once('connect', connectSuccess); | ||
client.once('error', connectError); | ||
client.on('drain', function() { | ||
pool.release(client); | ||
}); | ||
}, | ||
destroy: function(client) { | ||
client.end(); | ||
}, | ||
max: defaults.poolSize, | ||
idleTimeoutMillis: defaults.poolIdleTimeout | ||
}); | ||
return pool.acquire(cb); | ||
} | ||
} | ||
var PG = function(clientConstructor) { | ||
EventEmitter.call(this); | ||
this.Client = clientConstructor; | ||
this.Connection = require(__dirname + '/connection'); | ||
this.defaults = defaults; | ||
}; | ||
var end = function() { | ||
sys.inherits(PG, EventEmitter); | ||
PG.prototype.end = function() { | ||
Object.keys(pools).forEach(function(name) { | ||
@@ -60,25 +30,64 @@ var pool = pools[name]; | ||
}) | ||
}; | ||
} | ||
module.exports = { | ||
Client: Client, | ||
Connection: require(__dirname + '/connection'), | ||
connect: makeConnectFunction(Client), | ||
end: end, | ||
defaults: defaults | ||
PG.prototype.connect = function(config, callback) { | ||
var self = this; | ||
var c = config; | ||
var cb = callback; | ||
//allow for no config to be passed | ||
if(typeof c === 'function') { | ||
cb = c; | ||
c = defaults; | ||
} | ||
//get unique pool name even if object was used as config | ||
var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database; | ||
var pool = pools[poolName]; | ||
if(pool) return pool.acquire(cb); | ||
var pool = pools[poolName] = genericPool.Pool({ | ||
name: poolName, | ||
create: function(callback) { | ||
var client = new self.Client(c); | ||
client.connect(); | ||
var connectError = function(err) { | ||
client.removeListener('connect', connectSuccess); | ||
callback(err, null); | ||
}; | ||
var connectSuccess = function() { | ||
client.removeListener('error', connectError); | ||
//handle connected client background errors by emitting event | ||
//via the pg object and then removing errored client from the pool | ||
client.on('error', function(e) { | ||
self.emit('error', e, client); | ||
pool.destroy(client); | ||
}); | ||
callback(null, client); | ||
}; | ||
client.once('connect', connectSuccess); | ||
client.once('error', connectError); | ||
client.on('drain', function() { | ||
pool.release(client); | ||
}); | ||
}, | ||
destroy: function(client) { | ||
client.end(); | ||
}, | ||
max: defaults.poolSize, | ||
idleTimeoutMillis: defaults.poolIdleTimeout | ||
}); | ||
return pool.acquire(cb); | ||
} | ||
var nativeExport = null; | ||
//lazy require native module...the c++ may not have been compiled | ||
module.exports = new PG(Client); | ||
//lazy require native module...the native module may not have installed | ||
module.exports.__defineGetter__("native", function() { | ||
if(nativeExport === null) { | ||
var NativeClient = require(__dirname + '/native'); | ||
nativeExport = { | ||
Client: NativeClient, | ||
connect: makeConnectFunction(NativeClient), | ||
end: end, | ||
defaults: defaults | ||
} | ||
} | ||
return nativeExport; | ||
delete module.exports.native; | ||
return (module.exports.native = new PG(require(__dirname + '/native'))); | ||
}) |
//maps types from javascript to postgres and vise-versa | ||
var typeParsers = {}; | ||
//registers a method used to parse a string representing a particular | ||
//oid type into a javascript type | ||
var registerStringTypeParser = function(oid, converter) { | ||
typeParsers[oid] = converter; | ||
}; | ||
//the empty parse function | ||
@@ -15,9 +8,2 @@ var noParse = function(val) { | ||
//returns a function used to convert a specific type (specified by | ||
//oid) into a result javascript type | ||
var getStringTypeParser = function(oid) { | ||
return typeParsers[oid] || noParse; | ||
}; | ||
//parses PostgreSQL server formatted date strings into javascript date objects | ||
@@ -132,2 +118,15 @@ var parseDate = function(isoDate) { | ||
var typeParsers = {}; | ||
//registers a method used to parse a string representing a particular | ||
//oid type into a javascript type | ||
var registerStringTypeParser = function(oid, converter) { | ||
typeParsers[oid] = converter; | ||
}; | ||
//returns a function used to convert a specific type (specified by | ||
//oid) into a result javascript type | ||
var getStringTypeParser = function(oid) { | ||
return typeParsers[oid] || noParse; | ||
}; | ||
//default string type parser registrations | ||
@@ -134,0 +133,0 @@ registerStringTypeParser(20, parseInt); |
{ "name": "pg", | ||
"version": "0.5.5", | ||
"version": "0.5.6", | ||
"description": "PostgreSQL client - pure javascript & libpq with the same API", | ||
@@ -4,0 +4,0 @@ "keywords" : ["postgres", "pg", "libpq", "postgre", "database", "rdbms"], |
@@ -8,5 +8,2 @@ var helper = require(__dirname + '/../test-helper'); | ||
if(helper.args.libpq) { | ||
pg = require(__dirname + "/../../../lib/binding"); | ||
} | ||
var connectionString = helper.connectionString(__filename); | ||
@@ -13,0 +10,0 @@ |
var helper = require(__dirname + '/test-helper'); | ||
var pg = require("index"); | ||
var pg = helper.pg; | ||
@@ -4,0 +4,0 @@ test('default values', function() { |
var net = require('net'); | ||
var helper = require(__dirname+'/../test-helper'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
var connect = function(callback) { | ||
@@ -5,0 +5,0 @@ var username = helper.args.user; |
@@ -1,2 +0,1 @@ | ||
require.paths.unshift(__dirname + '/../lib/'); | ||
//make assert a global... | ||
@@ -9,3 +8,3 @@ assert = require('assert'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../lib/connection'); | ||
var args = require(__dirname + '/cli'); | ||
@@ -98,2 +97,5 @@ | ||
return assert.calls(function(err, arg) { | ||
if(err) { | ||
console.log(err); | ||
} | ||
assert.isNull(err); | ||
@@ -219,3 +221,3 @@ callback(arg); | ||
Sink: Sink, | ||
pg: require('index'), | ||
pg: require(__dirname + '/../lib/'), | ||
connectionString: function() { | ||
@@ -222,0 +224,0 @@ return "pg"+(count++)+"://"+args.user+":"+args.password+"@"+args.host+":"+args.port+"/"+args.database; |
var helper = require(__dirname + '/test-helper'); | ||
var Connection = require('connection'); | ||
var con = new Connection({stream: "NO"}); | ||
var client = new Client({connection:con}); | ||
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(); | ||
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); | ||
}) | ||
test('with drain paused', function() { | ||
//mock out a fake connection | ||
var con = new Connection({stream: "NO"}); | ||
con.connect = function() { | ||
con.emit('connect'); | ||
}; | ||
con.query = function() { | ||
}; | ||
var client = new Client({connection:con}); | ||
client.connect(); | ||
var drainCount = 0; | ||
client.on('drain', function() { | ||
drainCount++; | ||
}); | ||
test('normally unpaused', function() { | ||
con.emit('readyForQuery'); | ||
client.query('boom'); | ||
assert.emits(client, 'drain', function() { | ||
assert.equal(drainCount, 1); | ||
}); | ||
con.emit('readyForQuery'); | ||
}); | ||
test('pausing', function() { | ||
test('unpaused with no queries in between', function() { | ||
client.pauseDrain(); | ||
client.resumeDrain(); | ||
assert.equal(drainCount, 1); | ||
}); | ||
test('paused', function() { | ||
test('resumeDrain after empty', function() { | ||
client.pauseDrain(); | ||
client.query('asdf'); | ||
con.emit('readyForQuery'); | ||
assert.equal(drainCount, 1); | ||
client.resumeDrain(); | ||
assert.equal(drainCount, 2); | ||
}); | ||
test('resumDrain while still pending', function() { | ||
client.pauseDrain(); | ||
client.query('asdf'); | ||
client.query('asdf1'); | ||
con.emit('readyForQuery'); | ||
client.resumeDrain(); | ||
assert.equal(drainCount, 2); | ||
con.emit('readyForQuery'); | ||
assert.equal(drainCount, 3); | ||
}); | ||
}); | ||
}); | ||
}); | ||
var helper = require(__dirname+'/../test-helper'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
var makeClient = function() { | ||
@@ -4,0 +4,0 @@ var connection = new Connection({stream: "no"}); |
var helper = require(__dirname + '/test-helper'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
var con = new Connection({stream: new MemoryStream()}); | ||
@@ -4,0 +4,0 @@ test("connection emits stream errors", function() { |
require(__dirname+'/test-helper'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
var buffers = require(__dirname + '/../../test-buffers'); | ||
@@ -4,0 +4,0 @@ var PARSE = function(buffer) { |
require(__dirname + "/test-helper"); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
var stream = new MemoryStream(); | ||
@@ -4,0 +4,0 @@ var con = new Connection({ |
require(__dirname+'/test-helper'); | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../../lib/connection'); | ||
test('connection can take existing stream', function() { | ||
@@ -4,0 +4,0 @@ var stream = new MemoryStream(); |
var helper = require(__dirname+'/../test-helper'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var Connection = require('connection'); | ||
var Connection = require(__dirname + '/../../lib/connection'); | ||
MemoryStream = function() { | ||
@@ -5,0 +5,0 @@ EventEmitter.call(this); |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
5137
3
192783
84
132