'use strict';
const npm = {
con: require('manakin').local,
path: require('path'),
pg: require('pg'),
minify: require('pg-minify'),
adapter: require('./adapter'),
result: require('./result'),
promise: require('./promise'),
formatting: require('./formatting'),
helpers: require('./helpers'),
queryFile: require('./queryFile'),
errors: require('./errors'),
utils: require('./utils'),
pubUtils: require('./utils/public'),
mode: require('./txMode'),
types: require('./types'),
dbPool: require('./dbPool'),
package: require('../package.json')
};
/**
* @author Vitaly Tomilov
* @module pg-promise
*
* @description
* ### Initialization Options
*
* Below is the complete list of _Initialization Options_ for the library that can be passed during
* the library's initialization:
*
* ```js
* const initOptions = {/* options as documented below */};
*
* const pgp = require('pg-promise')(initOptions);
* ```
*
* @param {object} [options]
* Library Initialization Options.
*
* @param {boolean} [options.pgFormatting=false]
* Redirects all query formatting to the $[pg] driver.
*
* By default (`false`), the library uses its own advanced query-formatting engine.
* If you pass in this option as `true`, query formatting will be done entirely by the
* $[pg] driver, and you won't be able to use any of the feature-rich query formatting
* that this library implements.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {boolean} [options.pgNative=false]
* Use $[Native Bindings]. Library $[pg-native] must be included and installed independently, or else there will
* be an error thrown: {@link external:Error Error} = `Failed to initialize Native Bindings.`
*
* This is a static option (can only be set prior to initialization).
*
* @param {object|function} [options.promiseLib=Promise]
* Overrides the default promise library (ES6 Promise).
*
* **example:**
* ```js
* const Promise = require('bluebird');
* const initOptions = {
* promiseLib: Promise
* };
* const pgp = require('pg-promise')(initOptions);
* ```
*
* This is a static option (can only be set prior to initialization).
*
* @param {boolean} [options.noLocking=false]
* Prevents protocol locking.
*
* By default, the library locks much of its protocol to read-only access, as a fool-proof mechanism.
* Specifically for the {@link event:extend extend} event this serves as a protection against overriding existing
* properties or trying to set them at the wrong time.
*
* If this provision gets in the way of using a mock-up framework for your tests, you can force
* the library to deactivate most of the locks by setting `noLocking` = `true` within the options.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {boolean} [options.capSQL=false]
* Capitalizes any SQL generated by the library.
*
* By default, all internal SQL within the library is generated using the low case.
* If, however, you want all SQL to be capitalized instead, set `capSQL` = `true`.
*
* It is purely a cosmetic feature.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {boolean} [options.noWarnings=false]
* Disables all diagnostic warnings in the library (it is ill-advised).
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.connect]
* Global event {@link event:connect connect} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.disconnect]
* Global event {@link event:disconnect disconnect} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.query]
* Global event {@link event:query query} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.receive]
* Global event {@link event:receive receive} handler.
*
* @param {function} [options.task]
* Global event {@link event:task task} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.transact]
* Global event {@link event:transact transact} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.error]
* Global event {@link event:error error} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @param {function} [options.extend]
* Global event {@link event:extend extend} handler.
*
* This option is dynamic (can be set before or after initialization).
*
* @see
* {@link module:pg-promise~end end},
* {@link module:pg-promise~as as},
* {@link module:pg-promise~errors errors},
* {@link module:pg-promise~helpers helpers},
* {@link module:pg-promise~minify minify},
* {@link module:pg-promise~ParameterizedQuery ParameterizedQuery},
* {@link module:pg-promise~PreparedStatement PreparedStatement},
* {@link module:pg-promise~pg pg},
* {@link module:pg-promise~QueryFile QueryFile},
* {@link module:pg-promise~queryResult queryResult},
* {@link module:pg-promise~spex spex},
* {@link module:pg-promise~txMode txMode},
* {@link module:pg-promise~utils utils}
*
*/
function $main(options) {
if (npm.utils.isNull(options)) {
options = {};
} else {
if (typeof options !== 'object') {
throw new TypeError('Invalid initialization options: ' + JSON.stringify(options));
}
// list of supported initialization options:
const validOptions = ['pgFormatting', 'pgNative', 'promiseLib', 'noLocking', 'capSQL', 'noWarnings',
'connect', 'disconnect', 'query', 'receive', 'task', 'transact', 'error', 'extend'];
if (!options.noWarnings) {
for (let prop in options) {
if (validOptions.indexOf(prop) === -1) {
npm.con.warn('WARNING: Invalid property \'%s\' in initialization options.\n%s\n', prop, npm.utils.getLocalStack(3));
break;
}
}
}
}
let pg = npm.pg;
const p = npm.promise(options.promiseLib);
const config = {
version: npm.package.version,
promiseLib: p.promiseLib,
promise: p.promise
};
npm.utils.addReadProp(config, '$npm', {}, true);
// Locking properties that cannot be changed later:
npm.utils.addReadProp(options, 'promiseLib', options.promiseLib);
npm.utils.addReadProp(options, 'pgNative', !!options.pgNative);
config.options = options;
// istanbul ignore next:
// we do not cover code specific to Native Bindings
if (options.pgNative) {
pg = npm.pg.native;
if (npm.utils.isNull(pg)) {
throw new Error('Failed to initialize Native Bindings.');
}
}
const Database = require('./database')(config);
const inst = (cn, dc) => {
if (npm.utils.isText(cn) || (cn && typeof cn === 'object')) {
return new Database(cn, dc, config);
}
throw new TypeError('Invalid connection details: ' + JSON.stringify(cn));
};
npm.utils.addReadProperties(inst, rootNameSpace);
/**
* @member {external:PG} pg
* @readonly
* @description
* Instance of the $[pg] library that's being used, depending on initialization option `pgNative`:
* - regular `pg` module instance, without option `pgNative`, or equal to `false` (default)
* - `pg` module instance with $[Native Bindings], if option `pgNative` was set.
*
* Available as `pgp.pg`, after initializing the library.
*/
npm.utils.addReadProp(inst, 'pg', pg);
/**
* @member {function} end
* @readonly
* @description
* Shuts down all connection pools currently allocated, so the process can terminate without delay.
* It is available as `pgp.end`, after initializing the library.
*
* All {@link Database} objects created previously can no longer be used, throwing
* {@link external:Error Error} = `Connection pool of the database object has been destroyed.`
*
* And if you want to shut down only a specific connection pool, you do so via the {@link Database}
* object that owns the pool: `db.$pool.end()` (see {@link Database#$pool Database.$pool}).
*
*/
npm.utils.addReadProp(inst, 'end', () => {
npm.dbPool.shutDown();
});
/**
* @member {helpers} helpers
* @readonly
* @description
* Namespace for {@link helpers all query-formatting helper functions}.
*
* Available as `pgp.helpers`, after initializing the library.
*
* @see {@link helpers}.
*/
npm.utils.addReadProp(inst, 'helpers', npm.helpers(config));
/**
* @member {external:spex} spex
* @readonly
* @description
* Initialized instance of the $[spex] module, used by the library within tasks and transactions.
*
* Available as `pgp.spex`, after initializing the library.
*
* @see
* {@link Task#batch},
* {@link Task#page},
* {@link Task#sequence}
*/
npm.utils.addReadProp(inst, 'spex', config.$npm.spex);
config.pgp = inst;
Object.freeze(config);
return inst;
}
const rootNameSpace = {
/**
* @member {formatting} as
* @readonly
* @description
* Namespace for {@link formatting all query-formatting functions}.
*
* Available as `pgp.as`, before and after initializing the library.
*
* @see {@link formatting}.
*/
as: npm.formatting.as,
/**
* @member {external:pg-minify} minify
* @readonly
* @description
* Instance of the $[pg-minify] library used internally to minify SQL scripts.
*
* Available as `pgp.minify`, before and after initializing the library.
*/
minify: npm.minify,
/**
* @member {queryResult} queryResult
* @readonly
* @description
* Query Result Mask enumerator.
*
* Available as `pgp.queryResult`, before and after initializing the library.
*/
queryResult: npm.result,
/**
* @member {PromiseAdapter} PromiseAdapter
* @readonly
* @description
* {@link PromiseAdapter} class.
*
* Available as `pgp.PromiseAdapter`, before and after initializing the library.
*/
PromiseAdapter: npm.adapter,
/**
* @member {ParameterizedQuery} ParameterizedQuery
* @readonly
* @description
* {@link ParameterizedQuery} class.
*
* Available as `pgp.ParameterizedQuery`, before and after initializing the library.
*/
ParameterizedQuery: npm.types.ParameterizedQuery,
/**
* @member {PreparedStatement} PreparedStatement
* @readonly
* @description
* {@link PreparedStatement} class.
*
* Available as `pgp.PreparedStatement`, before and after initializing the library.
*/
PreparedStatement: npm.types.PreparedStatement,
/**
* @member {QueryFile} QueryFile
* @readonly
* @description
* {@link QueryFile} class.
*
* Available as `pgp.QueryFile`, before and after initializing the library.
*/
QueryFile: npm.queryFile,
/**
* @member {errors} errors
* @readonly
* @description
* {@link errors} - namespace for all error types.
*
* Available as `pgp.errors`, before and after initializing the library.
*/
errors: npm.errors,
/**
* @member {utils} utils
* @readonly
* @description
* {@link utils} - namespace for utility functions.
*
* Available as `pgp.utils`, before and after initializing the library.
*/
utils: npm.pubUtils,
/**
* @member {txMode} txMode
* @readonly
* @description
* {@link txMode Transaction Mode} namespace.
*
* Available as `pgp.txMode`, before and after initializing the library.
*/
txMode: npm.mode
};
npm.utils.addReadProperties($main, rootNameSpace);
module.exports = $main;
/**
* @external Promise
* @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
*/
/**
* @external PG
* @see https://github.com/brianc/node-postgres/blob/master/lib/index.js#L17
*/
/**
* @external Client
* @see https://github.com/brianc/node-postgres/blob/master/lib/client.js#L21
*/
/**
* @external pg-minify
* @see https://github.com/vitaly-t/pg-minify
*/
/**
* @external spex
* @see https://github.com/vitaly-t/spex
*/