123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- /*
- * Copyright (c) 2015-present, Vitaly Tomilov
- *
- * See the LICENSE file at the top-level directory of this distribution
- * for licensing information.
- *
- * Removal or modification of this copyright notice is prohibited.
- */
- const {PromiseAdapter} = require('./promise-adapter');
- const {DatabasePool} = require('./database-pool');
- const {PreparedStatement, ParameterizedQuery} = require('./types');
- const {QueryFile} = require('./query-file');
- const {queryResult} = require('./query-result');
- const {parsePromise} = require('./promise-parser');
- const {assert} = require('./assert');
- const npm = {
- path: require('path'),
- pg: require('pg'),
- minify: require('pg-minify'),
- formatting: require('./formatting'),
- helpers: require('./helpers'),
- errors: require('./errors'),
- utils: require('./utils'),
- pubUtils: require('./utils/public'),
- mode: require('./tx-mode'),
- package: require('../package.json'),
- text: require('./text')
- };
- let originalClientConnect;
- /**
- * @author Vitaly Tomilov
- * @module pg-promise
- *
- * @description
- * ## pg-promise v11.4
- * All documentation here is for the latest official release only.
- *
- * ### Initialization Options
- *
- * Below is the complete list of _Initialization Options_ for the library that can be passed in during
- * the library's initialization:
- *
- * ```js
- * const initOptions = {/* options as documented below */};
- *
- * const pgp = require('pg-promise')(initOptions);
- * ```
- *
- * @property {{}} [options]
- * Library Initialization Options.
- *
- * @property {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 set this option to a truthy value, query formatting will be done entirely by the
- * $[pg] driver, which means you won't be able to use any of the feature-rich query formatting
- * that this library implements, restricting yourself to the very basic `$1, $2,...` syntax.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {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).
- *
- * @property {object|function} [options.promiseLib=Promise]
- * Overrides the default (ES6 Promise) promise library for its internal use.
- *
- * Example below sets to use $[Bluebird] - the best and recommended promise library. It is the fastest one,
- * and supports $[Long Stack Traces], essential for debugging promises.
- *
- * ```js
- * const Promise = require('bluebird');
- * const initOptions = {
- * promiseLib: Promise
- * };
- * const pgp = require('pg-promise')(initOptions);
- * ```
- *
- * All existing promise libraries are supported. The ones with recognizable signature are used automatically,
- * while the rest can be configured via the $[Promise Adapter].
- *
- * This is a static option (can only be set prior to initialization).
- *
- * @property {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).
- *
- * @property {string|Array<string>|null|undefined|function} [options.schema]
- * Forces change of the default database schema(s) for every fresh connection, i.e.
- * the library will execute `SET search_path TO schema_1, schema_2, ...` in the background
- * whenever a fresh physical connection is allocated.
- *
- * Normally, one changes the default schema(s) by $[changing the database or the role], but sometimes you
- * may want to switch the default schema(s) without persisting the change, and then use this option.
- *
- * It can be a string, an array of strings, or a callback function that takes `dc` (database context)
- * as the only parameter (and as `this`), and returns schema(s) according to the database context. A callback function
- * can also return nothing (`undefined` or `null`), if no schema change needed for the specified database context.
- *
- * The order of schema names matters, so if a table name exists in more than one schema, its default access resolves
- * to the table from the first such schema on the list.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {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).
- *
- * @property {function} [options.connect]
- * Global event {@link event:connect connect} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.disconnect]
- * Global event {@link event:disconnect disconnect} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.query]
- * Global event {@link event:query query} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.receive]
- * Global event {@link event:receive receive} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.task]
- * Global event {@link event:task task} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.transact]
- * Global event {@link event:transact transact} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {function} [options.error]
- * Global event {@link event:error error} handler.
- *
- * This option is dynamic (can be set before or after initialization).
- *
- * @property {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) {
- options = assert(options, ['pgFormatting', 'pgNative', 'promiseLib', 'capSQL', 'noWarnings',
- 'connect', 'disconnect', 'query', 'receive', 'task', 'transact', 'error', 'extend', 'schema']);
- let pg = npm.pg;
- const p = parsePromise(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(npm.text.nativeError);
- }
- } else {
- if (!originalClientConnect) {
- originalClientConnect = pg.Client.prototype.connect;
- pg.Client.prototype.connect = function () {
- const handler = msg => {
- if (msg.parameterName === 'server_version') {
- this.serverVersion = msg.parameterValue;
- this.connection.removeListener('parameterStatus', handler);
- }
- };
- this.connection.on('parameterStatus', handler);
- return originalClientConnect.call(this, ...arguments);
- };
- }
- }
- 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: ' + npm.utils.toJson(cn));
- };
- npm.utils.addReadProperties(inst, rootNameSpace);
- /**
- * @member {external:PG} pg
- * @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.
- */
- inst.pg = pg; // keep it modifiable, so the protocol can be mocked
- /**
- * @member {function} end
- * @readonly
- * @description
- * Shuts down all connection pools created in the process, so it 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, and their query methods will be rejecting
- * with {@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}).
- *
- * For more details see $[Library de-initialization].
- */
- npm.utils.addReadProp(inst, 'end', () => {
- DatabasePool.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;
- 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,
- /**
- * @member {PromiseAdapter} PromiseAdapter
- * @readonly
- * @description
- * {@link PromiseAdapter} class.
- *
- * Available as `pgp.PromiseAdapter`, before and after initializing the library.
- */
- PromiseAdapter,
- /**
- * @member {ParameterizedQuery} ParameterizedQuery
- * @readonly
- * @description
- * {@link ParameterizedQuery} class.
- *
- * Available as `pgp.ParameterizedQuery`, before and after initializing the library.
- */
- ParameterizedQuery,
- /**
- * @member {PreparedStatement} PreparedStatement
- * @readonly
- * @description
- * {@link PreparedStatement} class.
- *
- * Available as `pgp.PreparedStatement`, before and after initializing the library.
- */
- PreparedStatement,
- /**
- * @member {QueryFile} QueryFile
- * @readonly
- * @description
- * {@link QueryFile} class.
- *
- * Available as `pgp.QueryFile`, before and after initializing the library.
- */
- 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://node-postgres.com
- */
- /**
- * @external Client
- * @see https://node-postgres.com/api/client
- */
- /**
- * @external pg-minify
- * @see https://github.com/vitaly-t/pg-minify
- */
- /**
- * @external spex
- * @see https://github.com/vitaly-t/spex
- */
|