Skip to content

Commit

Permalink
improving option fresh
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaly-t committed Jun 5, 2016
1 parent 361bab1 commit 8b3e504
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 50 deletions.
20 changes: 19 additions & 1 deletion lib/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,29 @@ function countIf(arr, cb, obj) {
return count;
}

// Conditionally removes elements;
function removeIf(arr, cb, obj) {
if (obj) {
for (var i = arr.length; i--;) {
if (cb.call(obj, arr[i], i, arr)) {
arr.splice(i, 1);
}
}
} else {
for (var i = arr.length; i--;) {
if (cb(arr[i], i, arr)) {
arr.splice(i, 1);
}
}
}
}

module.exports = {
map: map,
filter: filter,
forEach: forEach,
countIf: countIf
countIf: countIf,
removeIf: removeIf
};

Object.freeze(module.exports);
93 changes: 50 additions & 43 deletions lib/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,50 @@ var $npm = {

var $arr = require('../lib/array');

var poolConnections = {};
var liveClientKeys = {};
var liveNativeClients = [];

function getFreshStatus(config, client) {
// we do not test code specific to Native Bindings;
// istanbul ignore next
if (config.native) {
for (var i = 0; i < liveNativeClients.length; i++) {
var c = liveNativeClients[i];
if (c.client === client) {
c.tick = Date.now();
return false;
}
}
liveNativeClients.push({
client: client,
tick: Date.now()
});
return true;
}
var isFreshClient = !(client.secretKey in liveClientKeys);
liveClientKeys[client.secretKey] = Date.now();
return isFreshClient;
}

function clearFreshStatus(config) {
var now = Date.now(), delay = $npm.pg.defaults.poolIdleTimeout + 1000;
// we do not test code specific to Native Bindings;
// istanbul ignore if
if (config.native) {
$arr.removeIf(liveNativeClients, function (c) {
return now - c.tick > delay;
});
} else {
$arr.map(Object.keys(liveClientKeys), function (key) {
// It is impossible to test expired connections automatically,
// therefore we are excluding it from the text coverage:
// istanbul ignore next;
if (now - liveClientKeys[key] > delay) {
delete liveClientKeys[key];
}
});
}
}

function poolConnect(ctx, config) {
return config.promise(function (resolve, reject) {
Expand All @@ -20,15 +63,7 @@ function poolConnect(ctx, config) {
});
reject(err);
} else {
var fresh;

// we do not test code specific to Native Bindings;
// istanbul ignore else
if (!config.native) {
fresh = !(client.secretKey in poolConnections);
poolConnections[client.secretKey] = Date.now();
}

var isFreshClient = getFreshStatus(config, client);
var end = client.end;
client.end = function () {
throw new Error("Cannot invoke client.end() directly.");
Expand All @@ -39,14 +74,10 @@ function poolConnect(ctx, config) {
client.end = end;
done();
$npm.events.disconnect(ctx, client);
// we do not test code specific to Native Bindings;
// istanbul ignore else
if (!config.native) {
clearConnections(config);
}
clearFreshStatus(config);
}
});
$npm.events.connect(ctx, client, fresh);
$npm.events.connect(ctx, client, isFreshClient);
}
});
});
Expand All @@ -63,15 +94,7 @@ function directConnect(ctx, config) {
});
reject(err);
} else {
var fresh;

// we do not test code specific to Native Bindings;
// istanbul ignore else
if (!config.native) {
fresh = !(client.secretKey in poolConnections);
poolConnections[client.secretKey] = Date.now();
}

var isFreshClient = getFreshStatus(config, client);
var end = client.end;
client.end = function () {
throw new Error("Cannot invoke client.end() directly.");
Expand All @@ -81,31 +104,15 @@ function directConnect(ctx, config) {
done: function () {
end.call(client);
$npm.events.disconnect(ctx, client);
// we do not test code specific to Native Bindings;
// istanbul ignore else
if (!config.native) {
clearConnections(config);
}
clearFreshStatus(config);
}
});
$npm.events.connect(ctx, client, fresh);
$npm.events.connect(ctx, client, isFreshClient);
}
});
});
}

function clearConnections() {
var now = Date.now(), delay = $npm.pg.defaults.poolIdleTimeout + 1000;
$arr.map(Object.keys(poolConnections), function (k) {
// It is impossible to test expired connections automatically,
// therefore we are excluding it from the text coverage:
// istanbul ignore next;
if (now - poolConnections[k] > delay) {
delete poolConnections[k];
}
});
}

module.exports = function (config) {
return {
pool: function (ctx) {
Expand Down
3 changes: 1 addition & 2 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ var $events = {
* Database Context that was used when creating the database object (see {@link Database}).
*
* @param {boolean} fresh
* **Added in v.4.4.3**
* **Added in v.4.4.4**
*
* It indicates when the connection has been freshly allocated:
* - `true` - the connection has been freshly allocated
* - `false` - the connection has been used previously
* - `undefined` - unsupported with the Native Bindings
*
* @example
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pg-promise",
"version": "4.4.3",
"version": "4.4.4",
"description": "PostgreSQL via promises",
"main": "lib/index.js",
"scripts": {
Expand Down
36 changes: 36 additions & 0 deletions test/arraySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,39 @@ describe("countIf", function () {
});

});

describe("removeIf", function () {

describe("with context", function () {
var ctx, arr, indexes = [], values = [1, 2, 3, 4, 5];
$arr.removeIf(values, function (d, idx, a) {
arr = a;
ctx = this;
indexes.push(idx);
return d === 2 || d === 4;
}, values);
it("must remove correctly", function () {
expect(ctx).toBe(values);
expect(arr).toBe(values);
expect(values).toEqual([1, 3, 5]);
expect(indexes).toEqual([4, 3, 2, 1, 0]);
});
});

describe("without context", function () {
var ctx, arr, indexes = [], values = [1, 2, 3, 4, 5];
$arr.removeIf(values, function (d, idx, a) {
arr = a;
ctx = this;
indexes.push(idx);
return d === 2 || d === 4;
});
it("must remove correctly", function () {
expect(ctx).toBeUndefined();
expect(arr).toBe(values);
expect(values).toEqual([1, 3, 5]);
expect(indexes).toEqual([4, 3, 2, 1, 0]);
});
});

});
2 changes: 2 additions & 0 deletions test/typescript/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import * as pgPromise from 'pg-promise';

var pgp = pgPromise({
connect: (bla1:any, dc:any, fresh:boolean)=> {
},
receive: (data:any, result:any, e:any)=> {
var dc = e.dc;
var d = data[0].prop;
Expand Down
2 changes: 1 addition & 1 deletion typescript/README.MD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### TypeScript for pg-promise

Complete TypeScript ambient declarations for [pg-promise] version 4.4.0 or later.
Complete TypeScript ambient declarations for [pg-promise] version 4.4.4 or later.

| File | Description |
|------------------|----------------------------------|
Expand Down
4 changes: 2 additions & 2 deletions typescript/pg-promise.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
////////////////////////////////////////
// Requires pg-promise v4.4.0 or later.
// Requires pg-promise v4.4.4 or later.
////////////////////////////////////////

/// <reference path='./pg-subset' />
Expand Down Expand Up @@ -597,7 +597,7 @@ declare module 'pg-promise' {
pgFormatting?:boolean;
pgNative?:boolean,
promiseLib?:any;
connect?:(client:pg.Client, dc:any) => void;
connect?:(client:pg.Client, dc:any, fresh:boolean) => void;
disconnect?:(client:pg.Client, dc:any) => void;
query?:(e:IEventContext) => void;
receive?:(data:Array<any>, result:pg.IResult, e:IEventContext) => void;
Expand Down

0 comments on commit 8b3e504

Please sign in to comment.