Skip to content

Commit

Permalink
adding support for db warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaly-t committed Jun 18, 2016
1 parent 27ac188 commit 9f7782e
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 8 deletions.
48 changes: 48 additions & 0 deletions lib/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ var $arr = require('./array');
* Represents the database protocol, extensible via event {@link event:extend extend}.
* This type is not available directly, it can only be created via the library's base call.
*
* **IMPORTANT:**
*
* For any given connection, you should only create a single database object in a separate module,
* to be shared in your application. If instead you keep creating the database object dynamically,
* your application will suffer from loss in performance and memory leaks because of event handlers
* that each database object needs to set up.
*
* Starting with version 4.7.0, if you create more than one database object for the same connection,
* you will see the following warning in a development environment (`NODE_ENV` = `development`):
* `WARNING: Creating a duplicate database object for the same connection.`
*
* See also property `noWarnings` in {@link module:pg-promise Initialization Options}.
*
* @param {String|Object} cn
* Database connection details, which can be:
*
Expand Down Expand Up @@ -60,19 +73,27 @@ var $arr = require('./array');
* {@link event:extend extend}
*
* @example
* 'use strict';
*
* // Loading and initializing the library:
* var pgp = require('pg-promise')({
* // Initialization Options
* });
*
* // Preparing the connection details:
* var cn = "postgres://username:password@host:port/database";
*
* // Creating a new database instance from the connection details:
* var db = pgp(cn);
*
* // Exporting the database object:
* module.exports = db;
*/
function Database(cn, dc, config) {

checkForDuplicates(cn, config);
setErrorHandler(cn, dc, config);

var $p = config.promise;

/**
Expand Down Expand Up @@ -1174,6 +1195,33 @@ function Database(cn, dc, config) {

}

var dbObjects = {};

function checkForDuplicates(cn, config) {
var cnKey = JSON.stringify(cn);
if (cnKey in dbObjects) {
if (!config.options.noWarnings) {
var msg = "WARNING: Creating a duplicate database object for the same connection.\n" +
new Error().stack.split('\n').slice(4, 9).join('\n') + '\n';
$npm.utils.printWarning(msg);
}
} else {
dbObjects[cnKey] = true;
}
}

function setErrorHandler(cn, dc, config) {
// this event only happens when the connection is lost physically,
// which cannot be tested automatically; removing from coverage:
// istanbul ignore next
config.pgp.pg.on('error', function (err) {
$npm.events.error(config.options, err, {
cn: $npm.utils.getSafeConnection(cn),
dc: dc
});
});
}

module.exports = function (config) {
var npm = config.$npm;
npm.connect = npm.connect || $npm.connect(config);
Expand Down
4 changes: 2 additions & 2 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,9 +491,9 @@ var $events = {

/* istanbul ignore if */
if (!$npm.main.suppressErrors) {
console.error("Unexpected error in '" + event + "' event handler.");
$npm.utils.printError("Unexpected error in '" + event + "' event handler.");
if (!$npm.utils.isNull(err)) {
console.error(err.stack || err.message || err);
$npm.utils.printError(err.stack || err.message || err);
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ var $npm = {
*
* This property can be set dynamically (before or after initialization).
*
* @param {boolean} [options.noWarnings]
* **Added in v.4.7.0**
*
* Disables all diagnostic warnings in the library.
*
* If it is not set (missing or `undefined`), it will default to the following:
* - `true`, if `NODE_ENV` != `development`
* - `false`, if `NODE_ENV` = `development`
*
* This property can be set dynamically (before or after initialization).
*
* @param {function} [options.connect]
* Global event {@link event:connect connect} handler.
*
Expand Down Expand Up @@ -178,6 +189,10 @@ function $main(options) {
}
}

if (!('noWarnings' in options) || options.noWarnings === undefined) {
options.noWarnings = process.env.NODE_ENV !== 'development';
}

var Database = require('./database')(config);

var inst = function (cn, dc) {
Expand Down
13 changes: 12 additions & 1 deletion lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,19 @@ function isPathAbsolute(path) {
return path.charAt(0) === '/';
}

function printWarning(message) {
console.log("\u001b[33m" + message + "\u001b[0m");
}

// errors are disabled on Travis CI, so excluding from coverage:
// istanbul ignore next
function printError(message) {
console.log("\u001b[31m" + message + "\u001b[0m");
}

var exp = {
printError: printError,
printWarning: printWarning,
isPathAbsolute: isPathAbsolute,
lock: lock,
isText: isText,
Expand All @@ -146,4 +158,3 @@ exp.startDir = mainFile ? $path.dirname(mainFile) : process.cwd();
Object.freeze(exp);

module.exports = exp;

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.6.5",
"version": "4.7.0",
"description": "Promises interface for PostgreSQL",
"main": "lib/index.js",
"scripts": {
Expand Down
6 changes: 6 additions & 0 deletions test/db/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ function main(options, dc) {
}
}
}

if (options && typeof options === 'object') {
options.noWarnings = true;
}

var result = {
pgpLib: pgpLib,
pgp: pgpLib(options),
cn: cn
};
result.pgp.pg.setMaxListeners(100);
result.db = result.pgp(cn, dc);
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion test/entrySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe("Library entry function", function () {
describe("without any options", function () {
var result;
beforeEach(function (done) {
var db = header().db;
var db = header({noWarnings: true}).db;
db.query("select * from users")
.then(function (data) {
result = data;
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.6.5 or later.
Complete TypeScript ambient declarations for [pg-promise] version 4.7.0 or later.

#### Inclusion

Expand Down
5 changes: 3 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.6.5 or later.
// Requires pg-promise v4.7.0 or later.
////////////////////////////////////////

/// <reference path='./pg-subset' />
Expand Down Expand Up @@ -605,10 +605,11 @@ declare module 'pg-promise' {
}

}

// Library's Initialization Options
// API: http://vitaly-t.github.io/pg-promise/module-pg-promise.html
interface IOptions<Ext> {
noWarnings?:boolean;
pgFormatting?:boolean;
pgNative?:boolean,
promiseLib?:any;
Expand Down

0 comments on commit 9f7782e

Please sign in to comment.