Update to NPM version
This commit is contained in:
10
ProjectSourceCode/node_modules/pg-promise/lib/helpers/README.md
generated
vendored
Normal file
10
ProjectSourceCode/node_modules/pg-promise/lib/helpers/README.md
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
### `helpers` namespace
|
||||
|
||||
This folder contains everything that's available via the [helpers] namespace, after initializing the library:
|
||||
|
||||
```js
|
||||
const pgp = require('pg-promise')(/*initialization options*/);
|
||||
const helpers = pgp.helpers; // `helpers` namespace
|
||||
```
|
||||
|
||||
[helpers]:http://vitaly-t.github.io/pg-promise/helpers.html
|
||||
647
ProjectSourceCode/node_modules/pg-promise/lib/helpers/column-set.js
generated
vendored
Normal file
647
ProjectSourceCode/node_modules/pg-promise/lib/helpers/column-set.js
generated
vendored
Normal file
@@ -0,0 +1,647 @@
|
||||
/*
|
||||
* 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 {InnerState} = require(`../inner-state`);
|
||||
const {assert} = require(`../assert`);
|
||||
const {TableName} = require(`./table-name`);
|
||||
const {Column} = require(`./column`);
|
||||
|
||||
const npm = {
|
||||
os: require(`os`),
|
||||
utils: require(`../utils`),
|
||||
formatting: require(`../formatting`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @class helpers.ColumnSet
|
||||
* @description
|
||||
* Performance-optimized, read-only structure with query-formatting columns.
|
||||
*
|
||||
* In order to avail from performance optimization provided by this class, it should be created
|
||||
* only once, statically, and then reused.
|
||||
*
|
||||
* @param {object|helpers.Column|array} columns
|
||||
* Columns information object, depending on the type:
|
||||
*
|
||||
* - When it is a simple object, its properties are enumerated to represent both column names and property names
|
||||
* within the source objects. See also option `inherit` that's applicable in this case.
|
||||
*
|
||||
* - When it is a single {@link helpers.Column Column} object, property {@link helpers.ColumnSet#columns columns} is initialized with
|
||||
* just a single column. It is not a unique situation when only a single column is required for an update operation.
|
||||
*
|
||||
* - When it is an array, each element is assumed to represent details for a column. If the element is already of type {@link helpers.Column Column},
|
||||
* it is used directly; otherwise the element is passed into {@link helpers.Column Column} constructor for initialization.
|
||||
* On any duplicate column name (case-sensitive) it will throw {@link external:Error Error} = `Duplicate column name "name".`
|
||||
*
|
||||
* - When it is none of the above, it will throw {@link external:TypeError TypeError} = `Invalid parameter 'columns' specified.`
|
||||
*
|
||||
* @param {object} [options]
|
||||
*
|
||||
* @param {helpers.TableName|string|{table,schema}} [options.table]
|
||||
* Table details.
|
||||
*
|
||||
* When it is a non-null value, and not a {@link helpers.TableName TableName} object, a new {@link helpers.TableName TableName} is constructed from the value.
|
||||
*
|
||||
* It can be used as the default for methods {@link helpers.insert insert} and {@link helpers.update update} when their parameter
|
||||
* `table` is omitted, and for logging purposes.
|
||||
*
|
||||
* @param {boolean} [options.inherit = false]
|
||||
* Use inherited properties in addition to the object's own properties.
|
||||
*
|
||||
* By default, only the object's own properties are enumerated for column names.
|
||||
*
|
||||
* @returns {helpers.ColumnSet}
|
||||
*
|
||||
* @see
|
||||
*
|
||||
* {@link helpers.ColumnSet#columns columns},
|
||||
* {@link helpers.ColumnSet#names names},
|
||||
* {@link helpers.ColumnSet#table table},
|
||||
* {@link helpers.ColumnSet#variables variables} |
|
||||
* {@link helpers.ColumnSet#assign assign},
|
||||
* {@link helpers.ColumnSet#assignColumns assignColumns},
|
||||
* {@link helpers.ColumnSet#extend extend},
|
||||
* {@link helpers.ColumnSet#merge merge},
|
||||
* {@link helpers.ColumnSet#prepare prepare}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // A complex insert/update object scenario for table 'purchases' in schema 'fiscal'.
|
||||
* // For a good performance, you should declare such objects once and then reuse them.
|
||||
* //
|
||||
* // Column Requirements:
|
||||
* //
|
||||
* // 1. Property 'id' is only to be used for a WHERE condition in updates
|
||||
* // 2. Property 'list' needs to be formatted as a csv
|
||||
* // 3. Property 'code' is to be used as raw text, and to be defaulted to 0 when the
|
||||
* // property is missing in the source object
|
||||
* // 4. Property 'log' is a JSON object with 'log-entry' for the column name
|
||||
* // 5. Property 'data' requires SQL type casting '::int[]'
|
||||
* // 6. Property 'amount' needs to be set to 100, if it is 0
|
||||
* // 7. Property 'total' must be skipped during updates, if 'amount' was 0, plus its
|
||||
* // column name is 'total-val'
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet([
|
||||
* '?id', // ColumnConfig equivalent: {name: 'id', cnd: true}
|
||||
* 'list:csv', // ColumnConfig equivalent: {name: 'list', mod: ':csv'}
|
||||
* {
|
||||
* name: 'code',
|
||||
* mod: '^', // format as raw text
|
||||
* def: 0 // default to 0 when the property doesn't exist
|
||||
* },
|
||||
* {
|
||||
* name: 'log-entry',
|
||||
* prop: 'log',
|
||||
* mod: ':json' // format as JSON
|
||||
* },
|
||||
* {
|
||||
* name: 'data',
|
||||
* cast: 'int[]' // use SQL type casting '::int[]'
|
||||
* },
|
||||
* {
|
||||
* name: 'amount',
|
||||
* init(col) {
|
||||
* // set to 100, if the value is 0:
|
||||
* return col.value === 0 ? 100 : col.value;
|
||||
* }
|
||||
* },
|
||||
* {
|
||||
* name: 'total-val',
|
||||
* prop: 'total',
|
||||
* skip(col) {
|
||||
* // skip from updates, if 'amount' is 0:
|
||||
* return col.source.amount === 0;
|
||||
* }
|
||||
* }
|
||||
* ], {table: {table: 'purchases', schema: 'fiscal'}});
|
||||
*
|
||||
* // Alternatively, you could take the table declaration out:
|
||||
* // const table = new pgp.helpers.TableName('purchases', 'fiscal');
|
||||
*
|
||||
* console.log(cs); // console output for the object:
|
||||
* //=>
|
||||
* // ColumnSet {
|
||||
* // table: "fiscal"."purchases"
|
||||
* // columns: [
|
||||
* // Column {
|
||||
* // name: "id"
|
||||
* // cnd: true
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "list"
|
||||
* // mod: ":csv"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "code"
|
||||
* // mod: "^"
|
||||
* // def: 0
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "log-entry"
|
||||
* // prop: "log"
|
||||
* // mod: ":json"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "data"
|
||||
* // cast: "int[]"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "amount"
|
||||
* // init: [Function]
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "total-val"
|
||||
* // prop: "total"
|
||||
* // skip: [Function]
|
||||
* // }
|
||||
* // ]
|
||||
* // }
|
||||
*/
|
||||
class ColumnSet extends InnerState {
|
||||
|
||||
constructor(columns, opt) {
|
||||
super();
|
||||
|
||||
if (!columns || typeof columns !== `object`) {
|
||||
throw new TypeError(`Invalid parameter 'columns' specified.`);
|
||||
}
|
||||
|
||||
opt = assert(opt, [`table`, `inherit`]);
|
||||
|
||||
if (!npm.utils.isNull(opt.table)) {
|
||||
this.table = (opt.table instanceof TableName) ? opt.table : new TableName(opt.table);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.ColumnSet#table
|
||||
* @type {helpers.TableName}
|
||||
* @readonly
|
||||
* @description
|
||||
* Destination table. It can be specified for two purposes:
|
||||
*
|
||||
* - **primary:** to be used as the default table when it is omitted during a call into methods {@link helpers.insert insert} and {@link helpers.update update}
|
||||
* - **secondary:** to be automatically written into the console (for logging purposes).
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @name helpers.ColumnSet#columns
|
||||
* @type helpers.Column[]
|
||||
* @readonly
|
||||
* @description
|
||||
* Array of {@link helpers.Column Column} objects.
|
||||
*/
|
||||
if (Array.isArray(columns)) {
|
||||
const colNames = {};
|
||||
this.columns = columns.map(c => {
|
||||
const col = (c instanceof Column) ? c : new Column(c);
|
||||
if (col.name in colNames) {
|
||||
throw new Error(`Duplicate column name "${col.name}".`);
|
||||
}
|
||||
colNames[col.name] = true;
|
||||
return col;
|
||||
});
|
||||
} else {
|
||||
if (columns instanceof Column) {
|
||||
this.columns = [columns];
|
||||
} else {
|
||||
this.columns = [];
|
||||
for (const name in columns) {
|
||||
if (opt.inherit || Object.prototype.hasOwnProperty.call(columns, name)) {
|
||||
this.columns.push(new Column(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.freeze(this.columns);
|
||||
Object.freeze(this);
|
||||
|
||||
this.extendState({
|
||||
names: undefined,
|
||||
variables: undefined,
|
||||
updates: undefined,
|
||||
isSimple: true
|
||||
});
|
||||
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
const c = this.columns[i];
|
||||
// ColumnSet is simple when the source objects require no preparation,
|
||||
// and should be used directly:
|
||||
if (c.prop || c.init || `def` in c) {
|
||||
this._inner.isSimple = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.ColumnSet#names
|
||||
* @type string
|
||||
* @readonly
|
||||
* @description
|
||||
* Returns a string - comma-separated list of all column names, properly escaped.
|
||||
*
|
||||
* @example
|
||||
* const cs = new ColumnSet(['id^', {name: 'cells', cast: 'int[]'}, 'doc:json']);
|
||||
* console.log(cs.names);
|
||||
* //=> "id","cells","doc"
|
||||
*/
|
||||
get names() {
|
||||
const _i = this._inner;
|
||||
if (!_i.names) {
|
||||
_i.names = this.columns.map(c => c.escapedName).join();
|
||||
}
|
||||
return _i.names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.ColumnSet#variables
|
||||
* @type string
|
||||
* @readonly
|
||||
* @description
|
||||
* Returns a string - formatting template for all column values.
|
||||
*
|
||||
* @see {@link helpers.ColumnSet#assign assign}
|
||||
*
|
||||
* @example
|
||||
* const cs = new ColumnSet(['id^', {name: 'cells', cast: 'int[]'}, 'doc:json']);
|
||||
* console.log(cs.variables);
|
||||
* //=> ${id^},${cells}::int[],${doc:json}
|
||||
*/
|
||||
get variables() {
|
||||
const _i = this._inner;
|
||||
if (!_i.variables) {
|
||||
_i.variables = this.columns.map(c => c.variable + c.castText).join();
|
||||
}
|
||||
return _i.variables;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#assign
|
||||
* @description
|
||||
* Returns a formatting template of SET assignments, either generic or for a single object.
|
||||
*
|
||||
* The method is optimized to cache the output string when there are no columns that can be skipped dynamically.
|
||||
*
|
||||
* This method is primarily for internal use, that's why it does not validate the input.
|
||||
*
|
||||
* @param {object} [options]
|
||||
* Assignment/formatting options.
|
||||
*
|
||||
* @param {object} [options.source]
|
||||
* Source - a single object that contains values for columns.
|
||||
*
|
||||
* The object is only necessary to correctly apply the logic of skipping columns dynamically, based on the source data
|
||||
* and the rules defined in the {@link helpers.ColumnSet ColumnSet}. If, however, you do not care about that, then you do not need to specify any object.
|
||||
*
|
||||
* Note that even if you do not specify the object, the columns marked as conditional (`cnd: true`) will always be skipped.
|
||||
*
|
||||
* @param {string} [options.prefix]
|
||||
* In cases where needed, an alias prefix to be added before each column.
|
||||
*
|
||||
* @returns {string}
|
||||
* Comma-separated list of variable-to-column assignments.
|
||||
*
|
||||
* @see {@link helpers.ColumnSet#variables variables}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet([
|
||||
* '?first', // = {name: 'first', cnd: true}
|
||||
* 'second:json',
|
||||
* {name: 'third', mod: ':raw', cast: 'text'}
|
||||
* ]);
|
||||
*
|
||||
* cs.assign();
|
||||
* //=> "second"=${second:json},"third"=${third:raw}::text
|
||||
*
|
||||
* cs.assign({prefix: 'a b c'});
|
||||
* //=> "a b c"."second"=${second:json},"a b c"."third"=${third:raw}::text
|
||||
*/
|
||||
ColumnSet.prototype.assign = function (options) {
|
||||
const _i = this._inner;
|
||||
const hasPrefix = options && options.prefix && typeof options.prefix === `string`;
|
||||
if (_i.updates && !hasPrefix) {
|
||||
return _i.updates;
|
||||
}
|
||||
let dynamic = hasPrefix;
|
||||
const hasSource = options && options.source && typeof options.source === `object`;
|
||||
let list = this.columns.filter(c => {
|
||||
if (c.cnd) {
|
||||
return false;
|
||||
}
|
||||
if (c.skip) {
|
||||
dynamic = true;
|
||||
if (hasSource) {
|
||||
const a = colDesc(c, options.source);
|
||||
if (c.skip.call(options.source, a)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const prefix = hasPrefix ? npm.formatting.as.alias(options.prefix) + `.` : ``;
|
||||
list = list.map(c => prefix + c.escapedName + `=` + c.variable + c.castText).join();
|
||||
|
||||
if (!dynamic) {
|
||||
_i.updates = list;
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#assignColumns
|
||||
* @description
|
||||
* Generates assignments for all columns in the set, with support for aliases and column-skipping logic.
|
||||
* Aliases are set by using method {@link formatting.alias as.alias}.
|
||||
*
|
||||
* @param {{}} [options]
|
||||
* Optional Parameters.
|
||||
*
|
||||
* @param {string} [options.from]
|
||||
* Alias for the source columns.
|
||||
*
|
||||
* @param {string} [options.to]
|
||||
* Alias for the destination columns.
|
||||
*
|
||||
* @param {string | Array<string> | function} [options.skip]
|
||||
* Name(s) of the column(s) to be skipped (case-sensitive). It can be either a single string or an array of strings.
|
||||
*
|
||||
* It can also be a function - iterator, to be called for every column, passing in {@link helpers.Column Column} as
|
||||
* `this` context, and plus as a single parameter. The function would return a truthy value for every column that needs to be skipped.
|
||||
*
|
||||
* @returns {string}
|
||||
* A string of comma-separated column assignments.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['id', 'city', 'street']);
|
||||
*
|
||||
* cs.assignColumns({from: 'EXCLUDED', skip: 'id'})
|
||||
* //=> "city"=EXCLUDED."city","street"=EXCLUDED."street"
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['?id', 'city', 'street']);
|
||||
*
|
||||
* cs.assignColumns({from: 'source', to: 'target', skip: c => c.cnd})
|
||||
* //=> target."city"=source."city",target."street"=source."street"
|
||||
*
|
||||
*/
|
||||
ColumnSet.prototype.assignColumns = function (options) {
|
||||
options = assert(options, [`from`, `to`, `skip`]);
|
||||
const skip = (typeof options.skip === `string` && [options.skip]) || ((Array.isArray(options.skip) || typeof options.skip === `function`) && options.skip);
|
||||
const from = (typeof options.from === `string` && options.from && (npm.formatting.as.alias(options.from) + `.`)) || ``;
|
||||
const to = (typeof options.to === `string` && options.to && (npm.formatting.as.alias(options.to) + `.`)) || ``;
|
||||
const iterator = typeof skip === `function` ? c => !skip.call(c, c) : c => skip.indexOf(c.name) === -1;
|
||||
const cols = skip ? this.columns.filter(iterator) : this.columns;
|
||||
return cols.map(c => to + c.escapedName + `=` + from + c.escapedName).join();
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#extend
|
||||
* @description
|
||||
* Creates a new {@link helpers.ColumnSet ColumnSet}, by joining the two sets of columns.
|
||||
*
|
||||
* If the two sets contain a column with the same `name` (case-sensitive), an error is thrown.
|
||||
*
|
||||
* @param {helpers.Column|helpers.ColumnSet|array} columns
|
||||
* Columns to be appended, of the same type as parameter `columns` during {@link helpers.ColumnSet ColumnSet} construction, except:
|
||||
* - it can also be of type {@link helpers.ColumnSet ColumnSet}
|
||||
* - it cannot be a simple object (properties enumeration is not supported here)
|
||||
*
|
||||
* @returns {helpers.ColumnSet}
|
||||
* New {@link helpers.ColumnSet ColumnSet} object with the extended/concatenated list of columns.
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet#merge merge}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')();
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['one', 'two'], {table: 'my-table'});
|
||||
* console.log(cs);
|
||||
* //=>
|
||||
* // ColumnSet {
|
||||
* // table: "my-table"
|
||||
* // columns: [
|
||||
* // Column {
|
||||
* // name: "one"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "two"
|
||||
* // }
|
||||
* // ]
|
||||
* // }
|
||||
* const csExtended = cs.extend(['three']);
|
||||
* console.log(csExtended);
|
||||
* //=>
|
||||
* // ColumnSet {
|
||||
* // table: "my-table"
|
||||
* // columns: [
|
||||
* // Column {
|
||||
* // name: "one"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "two"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "three"
|
||||
* // }
|
||||
* // ]
|
||||
* // }
|
||||
*/
|
||||
ColumnSet.prototype.extend = function (columns) {
|
||||
let cs = columns;
|
||||
if (!(cs instanceof ColumnSet)) {
|
||||
cs = new ColumnSet(columns);
|
||||
}
|
||||
// Any duplicate column will throw Error = 'Duplicate column name "name".',
|
||||
return new ColumnSet(this.columns.concat(cs.columns), {table: this.table});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#merge
|
||||
* @description
|
||||
* Creates a new {@link helpers.ColumnSet ColumnSet}, by joining the two sets of columns.
|
||||
*
|
||||
* Items in `columns` with the same `name` (case-sensitive) override the original columns.
|
||||
*
|
||||
* @param {helpers.Column|helpers.ColumnSet|array} columns
|
||||
* Columns to be appended, of the same type as parameter `columns` during {@link helpers.ColumnSet ColumnSet} construction, except:
|
||||
* - it can also be of type {@link helpers.ColumnSet ColumnSet}
|
||||
* - it cannot be a simple object (properties enumeration is not supported here)
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet#extend extend}
|
||||
*
|
||||
* @returns {helpers.ColumnSet}
|
||||
* New {@link helpers.ColumnSet ColumnSet} object with the merged list of columns.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')();
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['?one', 'two:json'], {table: 'my-table'});
|
||||
* console.log(cs);
|
||||
* //=>
|
||||
* // ColumnSet {
|
||||
* // table: "my-table"
|
||||
* // columns: [
|
||||
* // Column {
|
||||
* // name: "one"
|
||||
* // cnd: true
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "two"
|
||||
* // mod: ":json"
|
||||
* // }
|
||||
* // ]
|
||||
* // }
|
||||
* const csMerged = cs.merge(['two', 'three^']);
|
||||
* console.log(csMerged);
|
||||
* //=>
|
||||
* // ColumnSet {
|
||||
* // table: "my-table"
|
||||
* // columns: [
|
||||
* // Column {
|
||||
* // name: "one"
|
||||
* // cnd: true
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "two"
|
||||
* // }
|
||||
* // Column {
|
||||
* // name: "three"
|
||||
* // mod: "^"
|
||||
* // }
|
||||
* // ]
|
||||
* // }
|
||||
*
|
||||
*/
|
||||
ColumnSet.prototype.merge = function (columns) {
|
||||
let cs = columns;
|
||||
if (!(cs instanceof ColumnSet)) {
|
||||
cs = new ColumnSet(columns);
|
||||
}
|
||||
const colNames = {}, cols = [];
|
||||
this.columns.forEach((c, idx) => {
|
||||
cols.push(c);
|
||||
colNames[c.name] = idx;
|
||||
});
|
||||
cs.columns.forEach(c => {
|
||||
if (c.name in colNames) {
|
||||
cols[colNames[c.name]] = c;
|
||||
} else {
|
||||
cols.push(c);
|
||||
}
|
||||
});
|
||||
return new ColumnSet(cols, {table: this.table});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#prepare
|
||||
* @description
|
||||
* Prepares a source object to be formatted, by cloning it and applying the rules as set by the
|
||||
* columns configuration.
|
||||
*
|
||||
* This method is primarily for internal use, that's why it does not validate the input parameters.
|
||||
*
|
||||
* @param {object} source
|
||||
* The source object to be prepared, if required.
|
||||
*
|
||||
* It must be a non-`null` object, which the method does not validate, as it is
|
||||
* intended primarily for internal use by the library.
|
||||
*
|
||||
* @returns {object}
|
||||
* When the object needs to be prepared, the method returns a clone of the source object,
|
||||
* with all properties and values set according to the columns configuration.
|
||||
*
|
||||
* When the object does not need to be prepared, the original object is returned.
|
||||
*/
|
||||
ColumnSet.prototype.prepare = function (source) {
|
||||
if (this._inner.isSimple) {
|
||||
return source; // a simple ColumnSet requires no object preparation;
|
||||
}
|
||||
const target = {};
|
||||
this.columns.forEach(c => {
|
||||
const a = colDesc(c, source);
|
||||
if (c.init) {
|
||||
target[a.name] = c.init.call(source, a);
|
||||
} else {
|
||||
if (a.exists || `def` in c) {
|
||||
target[a.name] = a.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
return target;
|
||||
};
|
||||
|
||||
function colDesc(column, source) {
|
||||
const a = {
|
||||
source,
|
||||
name: column.prop || column.name
|
||||
};
|
||||
a.exists = a.name in source;
|
||||
if (a.exists) {
|
||||
a.value = source[a.name];
|
||||
} else {
|
||||
a.value = `def` in column ? column.def : undefined;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @method helpers.ColumnSet#toString
|
||||
* @description
|
||||
* Creates a well-formatted multi-line string that represents the object.
|
||||
*
|
||||
* It is called automatically when writing the object into the console.
|
||||
*
|
||||
* @param {number} [level=0]
|
||||
* Nested output level, to provide visual offset.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
ColumnSet.prototype.toString = function (level) {
|
||||
level = level > 0 ? parseInt(level) : 0;
|
||||
const gap0 = npm.utils.messageGap(level),
|
||||
gap1 = npm.utils.messageGap(level + 1),
|
||||
lines = [
|
||||
`ColumnSet {`
|
||||
];
|
||||
if (this.table) {
|
||||
lines.push(gap1 + `table: ` + this.table);
|
||||
}
|
||||
if (this.columns.length) {
|
||||
lines.push(gap1 + `columns: [`);
|
||||
this.columns.forEach(c => {
|
||||
lines.push(c.toString(2));
|
||||
});
|
||||
lines.push(gap1 + `]`);
|
||||
} else {
|
||||
lines.push(gap1 + `columns: []`);
|
||||
}
|
||||
lines.push(gap0 + `}`);
|
||||
return lines.join(npm.os.EOL);
|
||||
};
|
||||
|
||||
npm.utils.addInspection(ColumnSet, function () {
|
||||
return this.toString();
|
||||
});
|
||||
|
||||
module.exports = {ColumnSet};
|
||||
455
ProjectSourceCode/node_modules/pg-promise/lib/helpers/column.js
generated
vendored
Normal file
455
ProjectSourceCode/node_modules/pg-promise/lib/helpers/column.js
generated
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* 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 {InnerState} = require(`../inner-state`);
|
||||
const {assert} = require(`../assert`);
|
||||
|
||||
const npm = {
|
||||
os: require(`os`),
|
||||
utils: require(`../utils`),
|
||||
formatting: require(`../formatting`),
|
||||
patterns: require(`../patterns`)
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @class helpers.Column
|
||||
* @description
|
||||
*
|
||||
* Read-only structure with details for a single column. Used primarily by {@link helpers.ColumnSet ColumnSet}.
|
||||
*
|
||||
* The class parses details into a template, to be used for query generation.
|
||||
*
|
||||
* @param {string|helpers.ColumnConfig} col
|
||||
* Column details, depending on the type.
|
||||
*
|
||||
* When it is a string, it is expected to contain a name for both the column and the source property, assuming that the two are the same.
|
||||
* The name must adhere to JavaScript syntax for variable names. The name can be appended with any format modifier as supported by
|
||||
* {@link formatting.format as.format} (`^`, `~`, `#`, `:csv`, `:list`, `:json`, `:alias`, `:name`, `:raw`, `:value`), which is then removed from the name and put
|
||||
* into property `mod`. If the name starts with `?`, it is removed, while setting flag `cnd` = `true`.
|
||||
*
|
||||
* If the string doesn't adhere to the above requirements, the method will throw {@link external:TypeError TypeError} = `Invalid column syntax`.
|
||||
*
|
||||
* When `col` is a simple {@link helpers.ColumnConfig ColumnConfig}-like object, it is used as an input configurator to set all the properties
|
||||
* of the class.
|
||||
*
|
||||
* @property {string} name
|
||||
* Destination column name + source property name (if `prop` is skipped). The name must adhere to JavaScript syntax for variables,
|
||||
* unless `prop` is specified, in which case `name` represents only the column name, and therefore can be any non-empty string.
|
||||
*
|
||||
* @property {string} [prop]
|
||||
* Source property name, if different from the column's name. It must adhere to JavaScript syntax for variables.
|
||||
*
|
||||
* It is ignored when it is the same as `name`.
|
||||
*
|
||||
* @property {string} [mod]
|
||||
* Formatting modifier, as supported by method {@link formatting.format as.format}: `^`, `~`, `#`, `:csv`, `:list`, `:json`, `:alias`, `:name`, `:raw`, `:value`.
|
||||
*
|
||||
* @property {string} [cast]
|
||||
* Server-side type casting, without `::` in front.
|
||||
*
|
||||
* @property {boolean} [cnd]
|
||||
* Conditional column flag.
|
||||
*
|
||||
* Used by methods {@link helpers.update update} and {@link helpers.sets sets}, ignored by methods {@link helpers.insert insert} and
|
||||
* {@link helpers.values values}. It indicates that the column is reserved for a `WHERE` condition, not to be set or updated.
|
||||
*
|
||||
* It can be set from a string initialization, by adding `?` in front of the name.
|
||||
*
|
||||
* @property {*} [def]
|
||||
* Default value for the property, to be used only when the source object doesn't have the property.
|
||||
* It is ignored when property `init` is set.
|
||||
*
|
||||
* @property {helpers.initCB} [init]
|
||||
* Override callback for the value.
|
||||
*
|
||||
* @property {helpers.skipCB} [skip]
|
||||
* An override for skipping columns dynamically.
|
||||
*
|
||||
* Used by methods {@link helpers.update update} (for a single object) and {@link helpers.sets sets}, ignored by methods
|
||||
* {@link helpers.insert insert} and {@link helpers.values values}.
|
||||
*
|
||||
* It is also ignored when conditional flag `cnd` is set.
|
||||
*
|
||||
* @returns {helpers.Column}
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.ColumnConfig ColumnConfig},
|
||||
* {@link helpers.Column#castText castText},
|
||||
* {@link helpers.Column#escapedName escapedName},
|
||||
* {@link helpers.Column#variable variable}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')({
|
||||
* capSQL: true // if you want all generated SQL capitalized
|
||||
* });
|
||||
*
|
||||
* const Column = pgp.helpers.Column;
|
||||
*
|
||||
* // creating a column from just a name:
|
||||
* const col1 = new Column('colName');
|
||||
* console.log(col1);
|
||||
* //=>
|
||||
* // Column {
|
||||
* // name: "colName"
|
||||
* // }
|
||||
*
|
||||
* // creating a column from a name + modifier:
|
||||
* const col2 = new Column('colName:csv');
|
||||
* console.log(col2);
|
||||
* //=>
|
||||
* // Column {
|
||||
* // name: "colName"
|
||||
* // mod: ":csv"
|
||||
* // }
|
||||
*
|
||||
* // creating a column from a configurator:
|
||||
* const col3 = new Column({
|
||||
* name: 'colName', // required
|
||||
* prop: 'propName', // optional
|
||||
* mod: '^', // optional
|
||||
* def: 123 // optional
|
||||
* });
|
||||
* console.log(col3);
|
||||
* //=>
|
||||
* // Column {
|
||||
* // name: "colName"
|
||||
* // prop: "propName"
|
||||
* // mod: "^"
|
||||
* // def: 123
|
||||
* // }
|
||||
*
|
||||
*/
|
||||
class Column extends InnerState {
|
||||
|
||||
constructor(col) {
|
||||
super();
|
||||
|
||||
if (typeof col === `string`) {
|
||||
const info = parseColumn(col);
|
||||
this.name = info.name;
|
||||
if (`mod` in info) {
|
||||
this.mod = info.mod;
|
||||
}
|
||||
if (`cnd` in info) {
|
||||
this.cnd = info.cnd;
|
||||
}
|
||||
} else {
|
||||
col = assert(col, [`name`, `prop`, `mod`, `cast`, `cnd`, `def`, `init`, `skip`]);
|
||||
if (`name` in col) {
|
||||
if (!npm.utils.isText(col.name)) {
|
||||
throw new TypeError(`Invalid 'name' value: ${npm.utils.toJson(col.name)}. A non-empty string was expected.`);
|
||||
}
|
||||
if (npm.utils.isNull(col.prop) && !isValidVariable(col.name)) {
|
||||
throw new TypeError(`Invalid 'name' syntax: ${npm.utils.toJson(col.name)}.`);
|
||||
}
|
||||
this.name = col.name; // column name + property name (if 'prop' isn't specified)
|
||||
|
||||
if (!npm.utils.isNull(col.prop)) {
|
||||
if (!npm.utils.isText(col.prop)) {
|
||||
throw new TypeError(`Invalid 'prop' value: ${npm.utils.toJson(col.prop)}. A non-empty string was expected.`);
|
||||
}
|
||||
if (!isValidVariable(col.prop)) {
|
||||
throw new TypeError(`Invalid 'prop' syntax: ${npm.utils.toJson(col.prop)}.`);
|
||||
}
|
||||
if (col.prop !== col.name) {
|
||||
// optional property name, if different from the column's name;
|
||||
this.prop = col.prop;
|
||||
}
|
||||
}
|
||||
if (!npm.utils.isNull(col.mod)) {
|
||||
if (typeof col.mod !== `string` || !isValidMod(col.mod)) {
|
||||
throw new TypeError(`Invalid 'mod' value: ${npm.utils.toJson(col.mod)}.`);
|
||||
}
|
||||
this.mod = col.mod; // optional format modifier;
|
||||
}
|
||||
if (!npm.utils.isNull(col.cast)) {
|
||||
this.cast = parseCast(col.cast); // optional SQL type casting
|
||||
}
|
||||
if (`cnd` in col) {
|
||||
this.cnd = !!col.cnd;
|
||||
}
|
||||
if (`def` in col) {
|
||||
this.def = col.def; // optional default
|
||||
}
|
||||
if (typeof col.init === `function`) {
|
||||
this.init = col.init; // optional value override (overrides 'def' also)
|
||||
}
|
||||
if (typeof col.skip === `function`) {
|
||||
this.skip = col.skip;
|
||||
}
|
||||
} else {
|
||||
throw new TypeError(`Invalid column details.`);
|
||||
}
|
||||
}
|
||||
|
||||
const variable = `\${` + (this.prop || this.name) + (this.mod || ``) + `}`;
|
||||
const castText = this.cast ? (`::` + this.cast) : ``;
|
||||
const escapedName = npm.formatting.as.name(this.name);
|
||||
|
||||
this.extendState({variable, castText, escapedName});
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.Column#variable
|
||||
* @type string
|
||||
* @readonly
|
||||
* @description
|
||||
* Full-syntax formatting variable, ready for direct use in query templates.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet([
|
||||
* 'id',
|
||||
* 'coordinate:json',
|
||||
* {
|
||||
* name: 'places',
|
||||
* mod: ':csv',
|
||||
* cast: 'int[]'
|
||||
* }
|
||||
* ]);
|
||||
*
|
||||
* // cs.columns[0].variable = ${id}
|
||||
* // cs.columns[1].variable = ${coordinate:json}
|
||||
* // cs.columns[2].variable = ${places:csv}::int[]
|
||||
*/
|
||||
get variable() {
|
||||
return this._inner.variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.Column#castText
|
||||
* @type string
|
||||
* @readonly
|
||||
* @description
|
||||
* Full-syntax sql type casting, if there is any, or else an empty string.
|
||||
*/
|
||||
get castText() {
|
||||
return this._inner.castText;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name helpers.Column#escapedName
|
||||
* @type string
|
||||
* @readonly
|
||||
* @description
|
||||
* Escaped name of the column, ready to be injected into queries directly.
|
||||
*
|
||||
*/
|
||||
get escapedName() {
|
||||
return this._inner.escapedName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function parseCast(name) {
|
||||
if (typeof name === `string`) {
|
||||
const s = name.replace(/^[:\s]*|\s*$/g, ``);
|
||||
if (s) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
throw new TypeError(`Invalid 'cast' value: ${npm.utils.toJson(name)}.`);
|
||||
}
|
||||
|
||||
function parseColumn(name) {
|
||||
const m = name.match(npm.patterns.validColumn);
|
||||
if (m && m[0] === name) {
|
||||
const res = {};
|
||||
if (name[0] === `?`) {
|
||||
res.cnd = true;
|
||||
name = name.substr(1);
|
||||
}
|
||||
const mod = name.match(npm.patterns.hasValidModifier);
|
||||
if (mod) {
|
||||
res.name = name.substr(0, mod.index);
|
||||
res.mod = mod[0];
|
||||
} else {
|
||||
res.name = name;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
throw new TypeError(`Invalid column syntax: ${npm.utils.toJson(name)}.`);
|
||||
}
|
||||
|
||||
function isValidMod(mod) {
|
||||
return npm.patterns.validModifiers.indexOf(mod) !== -1;
|
||||
}
|
||||
|
||||
function isValidVariable(name) {
|
||||
const m = name.match(npm.patterns.validVariable);
|
||||
return !!m && m[0] === name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @method helpers.Column#toString
|
||||
* @description
|
||||
* Creates a well-formatted multi-line string that represents the object.
|
||||
*
|
||||
* It is called automatically when writing the object into the console.
|
||||
*
|
||||
* @param {number} [level=0]
|
||||
* Nested output level, to provide visual offset.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
Column.prototype.toString = function (level) {
|
||||
level = level > 0 ? parseInt(level) : 0;
|
||||
const gap0 = npm.utils.messageGap(level),
|
||||
gap1 = npm.utils.messageGap(level + 1),
|
||||
lines = [
|
||||
gap0 + `Column {`,
|
||||
gap1 + `name: ` + npm.utils.toJson(this.name)
|
||||
];
|
||||
if (`prop` in this) {
|
||||
lines.push(gap1 + `prop: ` + npm.utils.toJson(this.prop));
|
||||
}
|
||||
if (`mod` in this) {
|
||||
lines.push(gap1 + `mod: ` + npm.utils.toJson(this.mod));
|
||||
}
|
||||
if (`cast` in this) {
|
||||
lines.push(gap1 + `cast: ` + npm.utils.toJson(this.cast));
|
||||
}
|
||||
if (`cnd` in this) {
|
||||
lines.push(gap1 + `cnd: ` + npm.utils.toJson(this.cnd));
|
||||
}
|
||||
if (`def` in this) {
|
||||
lines.push(gap1 + `def: ` + npm.utils.toJson(this.def));
|
||||
}
|
||||
if (`init` in this) {
|
||||
lines.push(gap1 + `init: [Function]`);
|
||||
}
|
||||
if (`skip` in this) {
|
||||
lines.push(gap1 + `skip: [Function]`);
|
||||
}
|
||||
lines.push(gap0 + `}`);
|
||||
return lines.join(npm.os.EOL);
|
||||
};
|
||||
|
||||
npm.utils.addInspection(Column, function () {
|
||||
return this.toString();
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef helpers.ColumnConfig
|
||||
* @description
|
||||
* A simple structure with column details, to be passed into the {@link helpers.Column Column} constructor for initialization.
|
||||
*
|
||||
* @property {string} name
|
||||
* Destination column name + source property name (if `prop` is skipped). The name must adhere to JavaScript syntax for variables,
|
||||
* unless `prop` is specified, in which case `name` represents only the column name, and therefore can be any non-empty string.
|
||||
*
|
||||
* @property {string} [prop]
|
||||
* Source property name, if different from the column's name. It must adhere to JavaScript syntax for variables.
|
||||
*
|
||||
* It is ignored when it is the same as `name`.
|
||||
*
|
||||
* @property {string} [mod]
|
||||
* Formatting modifier, as supported by method {@link formatting.format as.format}: `^`, `~`, `#`, `:csv`, `:list`, `:json`, `:alias`, `:name`, `:raw`, `:value`.
|
||||
*
|
||||
* @property {string} [cast]
|
||||
* Server-side type casting. Leading `::` is allowed, but not needed (automatically removed when specified).
|
||||
*
|
||||
* @property {boolean} [cnd]
|
||||
* Conditional column flag.
|
||||
*
|
||||
* Used by methods {@link helpers.update update} and {@link helpers.sets sets}, ignored by methods {@link helpers.insert insert} and
|
||||
* {@link helpers.values values}. It indicates that the column is reserved for a `WHERE` condition, not to be set or updated.
|
||||
*
|
||||
* It can be set from a string initialization, by adding `?` in front of the name.
|
||||
*
|
||||
* @property {*} [def]
|
||||
* Default value for the property, to be used only when the source object doesn't have the property.
|
||||
* It is ignored when property `init` is set.
|
||||
*
|
||||
* @property {helpers.initCB} [init]
|
||||
* Override callback for the value.
|
||||
*
|
||||
* @property {helpers.skipCB} [skip]
|
||||
* An override for skipping columns dynamically.
|
||||
*
|
||||
* Used by methods {@link helpers.update update} (for a single object) and {@link helpers.sets sets}, ignored by methods
|
||||
* {@link helpers.insert insert} and {@link helpers.values values}.
|
||||
*
|
||||
* It is also ignored when conditional flag `cnd` is set.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback helpers.initCB
|
||||
* @description
|
||||
* A callback function type used by parameter `init` within {@link helpers.ColumnConfig ColumnConfig}.
|
||||
*
|
||||
* It works as an override for the corresponding property value in the `source` object.
|
||||
*
|
||||
* The function is called with `this` set to the `source` object.
|
||||
*
|
||||
* @param {*} col
|
||||
* Column-to-property descriptor.
|
||||
*
|
||||
* @param {object} col.source
|
||||
* The source object, equals to `this` that's passed into the function.
|
||||
*
|
||||
* @param {string} col.name
|
||||
* Resolved name of the property within the `source` object, i.e. the value of `name` when `prop` is not used
|
||||
* for the column, or the value of `prop` when it is specified.
|
||||
*
|
||||
* @param {*} col.value
|
||||
*
|
||||
* Property value, set to one of the following:
|
||||
*
|
||||
* - Value of the property within the `source` object (`value` = `source[name]`), if the property exists
|
||||
* - If the property doesn't exist and `def` is set in the column, then `value` is set to the value of `def`
|
||||
* - If the property doesn't exist and `def` is not set in the column, then `value` is set to `undefined`
|
||||
*
|
||||
* @param {boolean} col.exists
|
||||
* Indicates whether the property exists in the `source` object (`exists = name in source`).
|
||||
*
|
||||
* @returns {*}
|
||||
* The new value to be used for the corresponding column.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback helpers.skipCB
|
||||
* @description
|
||||
* A callback function type used by parameter `skip` within {@link helpers.ColumnConfig ColumnConfig}.
|
||||
*
|
||||
* It is to dynamically determine when the property with specified `name` in the `source` object is to be skipped.
|
||||
*
|
||||
* The function is called with `this` set to the `source` object.
|
||||
*
|
||||
* @param {*} col
|
||||
* Column-to-property descriptor.
|
||||
*
|
||||
* @param {object} col.source
|
||||
* The source object, equals to `this` that's passed into the function.
|
||||
*
|
||||
* @param {string} col.name
|
||||
* Resolved name of the property within the `source` object, i.e. the value of `name` when `prop` is not used
|
||||
* for the column, or the value of `prop` when it is specified.
|
||||
*
|
||||
* @param {*} col.value
|
||||
*
|
||||
* Property value, set to one of the following:
|
||||
*
|
||||
* - Value of the property within the `source` object (`value` = `source[name]`), if the property exists
|
||||
* - If the property doesn't exist and `def` is set in the column, then `value` is set to the value of `def`
|
||||
* - If the property doesn't exist and `def` is not set in the column, then `value` is set to `undefined`
|
||||
*
|
||||
* @param {boolean} col.exists
|
||||
* Indicates whether the property exists in the `source` object (`exists = name in source`).
|
||||
*
|
||||
* @returns {boolean}
|
||||
* A truthy value that indicates whether the column is to be skipped.
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {Column};
|
||||
73
ProjectSourceCode/node_modules/pg-promise/lib/helpers/index.js
generated
vendored
Normal file
73
ProjectSourceCode/node_modules/pg-promise/lib/helpers/index.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 {Column} = require(`./column`);
|
||||
const {ColumnSet} = require(`./column-set`);
|
||||
const {TableName} = require(`./table-name`);
|
||||
const method = require(`./methods`);
|
||||
const utils = require(`../utils`);
|
||||
|
||||
/**
|
||||
* @namespace helpers
|
||||
* @description
|
||||
* Namespace for query-formatting generators, available as {@link module:pg-promise~helpers pgp.helpers}, after initializing the library.
|
||||
*
|
||||
* It unifies the approach to generating multi-row `INSERT` / `UPDATE` queries with the single-row ones.
|
||||
*
|
||||
* See also: $[Performance Boost].
|
||||
*
|
||||
* @property {function} TableName
|
||||
* {@link helpers.TableName TableName} class constructor.
|
||||
*
|
||||
* @property {function} ColumnSet
|
||||
* {@link helpers.ColumnSet ColumnSet} class constructor.
|
||||
*
|
||||
* @property {function} Column
|
||||
* {@link helpers.Column Column} class constructor.
|
||||
*
|
||||
* @property {function} insert
|
||||
* {@link helpers.insert insert} static method.
|
||||
*
|
||||
* @property {function} update
|
||||
* {@link helpers.update update} static method.
|
||||
*
|
||||
* @property {function} values
|
||||
* {@link helpers.values values} static method.
|
||||
*
|
||||
* @property {function} sets
|
||||
* {@link helpers.sets sets} static method.
|
||||
*
|
||||
* @property {function} concat
|
||||
* {@link helpers.concat concat} static method.
|
||||
*/
|
||||
module.exports = config => {
|
||||
const capSQL = () => config.options && config.options.capSQL;
|
||||
const res = {
|
||||
insert(data, columns, table) {
|
||||
return method.insert(data, columns, table, capSQL());
|
||||
},
|
||||
update(data, columns, table, options) {
|
||||
return method.update(data, columns, table, options, capSQL());
|
||||
},
|
||||
concat(queries) {
|
||||
return method.concat(queries, capSQL());
|
||||
},
|
||||
values(data, columns) {
|
||||
return method.values(data, columns, capSQL());
|
||||
},
|
||||
sets(data, columns) {
|
||||
return method.sets(data, columns, capSQL());
|
||||
},
|
||||
TableName,
|
||||
ColumnSet,
|
||||
Column
|
||||
};
|
||||
utils.lock(res, true, config.options);
|
||||
return res;
|
||||
};
|
||||
103
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/concat.js
generated
vendored
Normal file
103
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/concat.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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 {QueryFile} = require(`../../query-file`);
|
||||
|
||||
const npm = {
|
||||
formatting: require(`../../formatting`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.concat
|
||||
* @description
|
||||
* Formats and concatenates multiple queries into a single query string.
|
||||
*
|
||||
* Before joining the queries, the method does the following:
|
||||
* - Formats each query, if `values` are provided;
|
||||
* - Removes all leading and trailing spaces, tabs and semi-colons;
|
||||
* - Automatically skips all empty queries.
|
||||
*
|
||||
* @param {array<string|helpers.QueryFormat|QueryFile>} queries
|
||||
* Array of mixed-type elements:
|
||||
* - a simple query string, to be used as is
|
||||
* - a {@link helpers.QueryFormat QueryFormat}-like object = `{query, [values], [options]}`
|
||||
* - a {@link QueryFile} object
|
||||
*
|
||||
* @returns {string}
|
||||
* Concatenated string with all queries.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')();
|
||||
*
|
||||
* const qf1 = new pgp.QueryFile('./query1.sql', {minify: true});
|
||||
* const qf2 = new pgp.QueryFile('./query2.sql', {minify: true});
|
||||
*
|
||||
* const query = pgp.helpers.concat([
|
||||
* {query: 'INSERT INTO Users(name, age) VALUES($1, $2)', values: ['John', 23]}, // QueryFormat-like object
|
||||
* {query: qf1, values: [1, 'Name']}, // QueryFile with formatting parameters
|
||||
* 'SELECT count(*) FROM Users', // a simple-string query,
|
||||
* qf2 // direct QueryFile object
|
||||
* ]);
|
||||
*
|
||||
* // query = concatenated string with all the queries
|
||||
*/
|
||||
function concat(queries, capSQL) {
|
||||
if (!Array.isArray(queries)) {
|
||||
throw new TypeError(`Parameter 'queries' must be an array.`);
|
||||
}
|
||||
const fmOptions = {capSQL};
|
||||
const all = queries.map((q, index) => {
|
||||
if (typeof q === `string`) {
|
||||
// a simple query string without parameters:
|
||||
return clean(q);
|
||||
}
|
||||
if (q && typeof q === `object`) {
|
||||
if (q instanceof QueryFile) {
|
||||
// QueryFile object:
|
||||
return clean(q[npm.formatting.as.ctf.toPostgres]());
|
||||
}
|
||||
if (`query` in q) {
|
||||
// object {query, values, options}:
|
||||
let opt = q.options && typeof q.options === `object` ? q.options : {};
|
||||
opt = opt.capSQL === undefined ? Object.assign(opt, fmOptions) : opt;
|
||||
return clean(npm.formatting.as.format(q.query, q.values, opt));
|
||||
}
|
||||
}
|
||||
throw new Error(`Invalid query element at index ${index}.`);
|
||||
});
|
||||
|
||||
return all.filter(q => q).join(`;`);
|
||||
}
|
||||
|
||||
function clean(q) {
|
||||
// removes from the query all leading and trailing symbols ' ', '\t' and ';'
|
||||
return q.replace(/^[\s;]*|[\s;]*$/g, ``);
|
||||
}
|
||||
|
||||
module.exports = {concat};
|
||||
|
||||
/**
|
||||
* @typedef helpers.QueryFormat
|
||||
* @description
|
||||
* A simple structure of parameters to be passed into method {@link formatting.format as.format} exactly as they are,
|
||||
* used by {@link helpers.concat}.
|
||||
*
|
||||
* @property {string|value|object} query
|
||||
* A query string or a value/object that implements $[Custom Type Formatting], to be formatted according to `values`.
|
||||
*
|
||||
* @property {array|object|value} [values]
|
||||
* Query-formatting values.
|
||||
*
|
||||
* @property {object} [options]
|
||||
* Query-formatting options, as supported by method {@link formatting.format as.format}.
|
||||
*
|
||||
* @see
|
||||
* {@link formatting.format as.format}
|
||||
*/
|
||||
13
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/index.js
generated
vendored
Normal file
13
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/index.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
const {concat} = require(`./concat`);
|
||||
const {insert} = require(`./insert`);
|
||||
const {update} = require(`./update`);
|
||||
const {values} = require(`./values`);
|
||||
const {sets} = require(`./sets`);
|
||||
|
||||
module.exports = {
|
||||
concat,
|
||||
insert,
|
||||
update,
|
||||
values,
|
||||
sets
|
||||
};
|
||||
148
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/insert.js
generated
vendored
Normal file
148
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/insert.js
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 {TableName} = require(`../table-name`);
|
||||
const {ColumnSet} = require(`../column-set`);
|
||||
|
||||
const npm = {
|
||||
formatting: require(`../../formatting`),
|
||||
utils: require(`../../utils`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.insert
|
||||
* @description
|
||||
* Generates an `INSERT` query for either one object or an array of objects.
|
||||
*
|
||||
* @param {object|object[]} data
|
||||
* An insert object with properties for insert values, or an array of such objects.
|
||||
*
|
||||
* When `data` is not a non-null object and not an array, it will throw {@link external:TypeError TypeError} = `Invalid parameter 'data' specified.`
|
||||
*
|
||||
* When `data` is an empty array, it will throw {@link external:TypeError TypeError} = `Cannot generate an INSERT from an empty array.`
|
||||
*
|
||||
* When `data` is an array that contains a non-object value, the method will throw {@link external:Error Error} =
|
||||
* `Invalid insert object at index N.`
|
||||
*
|
||||
* @param {array|helpers.Column|helpers.ColumnSet} [columns]
|
||||
* Set of columns to be inserted.
|
||||
*
|
||||
* It is optional when `data` is a single object, and required when `data` is an array of objects. If not specified for an array
|
||||
* of objects, the method will throw {@link external:TypeError TypeError} = `Parameter 'columns' is required when inserting multiple records.`
|
||||
*
|
||||
* When `columns` is not a {@link helpers.ColumnSet ColumnSet} object, a temporary {@link helpers.ColumnSet ColumnSet}
|
||||
* is created - from the value of `columns` (if it was specified), or from the value of `data` (if it is not an array).
|
||||
*
|
||||
* When the final {@link helpers.ColumnSet ColumnSet} is empty (no columns in it), the method will throw
|
||||
* {@link external:Error Error} = `Cannot generate an INSERT without any columns.`
|
||||
*
|
||||
* @param {helpers.TableName|string|{table,schema}} [table]
|
||||
* Destination table.
|
||||
*
|
||||
* It is normally a required parameter. But when `columns` is passed in as a {@link helpers.ColumnSet ColumnSet} object
|
||||
* with `table` set in it, that will be used when this parameter isn't specified. When neither is available, the method
|
||||
* will throw {@link external:Error Error} = `Table name is unknown.`
|
||||
*
|
||||
* @returns {string}
|
||||
* An `INSERT` query string.
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet ColumnSet},
|
||||
* {@link helpers.TableName TableName}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')({
|
||||
* capSQL: true // if you want all generated SQL capitalized
|
||||
* });
|
||||
*
|
||||
* const dataSingle = {val: 123, msg: 'hello'};
|
||||
* const dataMulti = [{val: 123, msg: 'hello'}, {val: 456, msg: 'world!'}];
|
||||
*
|
||||
* // Column details can be taken from the data object:
|
||||
*
|
||||
* pgp.helpers.insert(dataSingle, null, 'my-table');
|
||||
* //=> INSERT INTO "my-table"("val","msg") VALUES(123,'hello')
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details are required for a multi-row `INSERT`:
|
||||
*
|
||||
* pgp.helpers.insert(dataMulti, ['val', 'msg'], 'my-table');
|
||||
* //=> INSERT INTO "my-table"("val","msg") VALUES(123,'hello'),(456,'world!')
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details from a reusable ColumnSet (recommended for performance):
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['val', 'msg'], {table: 'my-table'});
|
||||
*
|
||||
* pgp.helpers.insert(dataMulti, cs);
|
||||
* //=> INSERT INTO "my-table"("val","msg") VALUES(123,'hello'),(456,'world!')
|
||||
*
|
||||
*/
|
||||
function insert(data, columns, table, capSQL) {
|
||||
|
||||
if (!data || typeof data !== `object`) {
|
||||
throw new TypeError(`Invalid parameter 'data' specified.`);
|
||||
}
|
||||
|
||||
const isArray = Array.isArray(data);
|
||||
|
||||
if (isArray && !data.length) {
|
||||
throw new TypeError(`Cannot generate an INSERT from an empty array.`);
|
||||
}
|
||||
|
||||
if (columns instanceof ColumnSet) {
|
||||
if (npm.utils.isNull(table)) {
|
||||
table = columns.table;
|
||||
}
|
||||
} else {
|
||||
if (isArray && npm.utils.isNull(columns)) {
|
||||
throw new TypeError(`Parameter 'columns' is required when inserting multiple records.`);
|
||||
}
|
||||
columns = new ColumnSet(columns || data);
|
||||
}
|
||||
|
||||
if (!columns.columns.length) {
|
||||
throw new Error(`Cannot generate an INSERT without any columns.`);
|
||||
}
|
||||
|
||||
if (!table) {
|
||||
throw new Error(`Table name is unknown.`);
|
||||
}
|
||||
|
||||
if (!(table instanceof TableName)) {
|
||||
table = new TableName(table);
|
||||
}
|
||||
|
||||
let query = capSQL ? sql.capCase : sql.lowCase;
|
||||
const fmOptions = {capSQL};
|
||||
|
||||
const format = npm.formatting.as.format;
|
||||
query = format(query, [table.name, columns.names], fmOptions);
|
||||
|
||||
if (isArray) {
|
||||
return query + data.map((d, index) => {
|
||||
if (!d || typeof d !== `object`) {
|
||||
throw new Error(`Invalid insert object at index ${index}.`);
|
||||
}
|
||||
return `(` + format(columns.variables, columns.prepare(d), fmOptions) + `)`;
|
||||
}).join();
|
||||
}
|
||||
return query + `(` + format(columns.variables, columns.prepare(data), fmOptions) + `)`;
|
||||
}
|
||||
|
||||
const sql = {
|
||||
lowCase: `insert into $1^($2^) values`,
|
||||
capCase: `INSERT INTO $1^($2^) VALUES`
|
||||
};
|
||||
|
||||
module.exports = {insert};
|
||||
80
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/sets.js
generated
vendored
Normal file
80
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/sets.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 {ColumnSet} = require(`../column-set`);
|
||||
|
||||
const npm = {
|
||||
format: require(`../../formatting`).as.format,
|
||||
utils: require(`../../utils`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.sets
|
||||
* @description
|
||||
* Generates a string of comma-separated value-set statements from a single object: `col1=val1, col2=val2, ...`,
|
||||
* to be used as part of a query.
|
||||
*
|
||||
* Since it is to be used as part of `UPDATE` queries, {@link helpers.Column Column} properties `cnd` and `skip` apply.
|
||||
*
|
||||
* @param {object} data
|
||||
* A simple, non-null and non-array source object.
|
||||
*
|
||||
* If it is anything else, the method will throw {@link external:TypeError TypeError} = `Invalid parameter 'data' specified.`
|
||||
*
|
||||
* @param {array|helpers.Column|helpers.ColumnSet} [columns]
|
||||
* Columns for which to set values.
|
||||
*
|
||||
* When not specified, properties of the `data` object are used.
|
||||
*
|
||||
* When no effective columns are found, an empty string is returned.
|
||||
*
|
||||
* @returns {string}
|
||||
* - comma-separated value-set statements for the `data` object
|
||||
* - an empty string, if no effective columns found
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet ColumnSet}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')();
|
||||
*
|
||||
* const data = {id: 1, val: 123, msg: 'hello'};
|
||||
*
|
||||
* // Properties can be pulled automatically from the object:
|
||||
*
|
||||
* pgp.helpers.sets(data);
|
||||
* //=> "id"=1,"val"=123,"msg"='hello'
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details from a reusable ColumnSet (recommended for performance);
|
||||
* // NOTE: Conditional columns (start with '?') are skipped:
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['?id','val', 'msg']);
|
||||
*
|
||||
* pgp.helpers.sets(data, cs);
|
||||
* //=> "val"=123,"msg"='hello'
|
||||
*
|
||||
*/
|
||||
function sets(data, columns, capSQL) {
|
||||
|
||||
if (!data || typeof data !== `object` || Array.isArray(data)) {
|
||||
throw new TypeError(`Invalid parameter 'data' specified.`);
|
||||
}
|
||||
|
||||
if (!(columns instanceof ColumnSet)) {
|
||||
columns = new ColumnSet(columns || data);
|
||||
}
|
||||
|
||||
return npm.format(columns.assign({source: data}), columns.prepare(data), {capSQL});
|
||||
}
|
||||
|
||||
module.exports = {sets};
|
||||
245
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/update.js
generated
vendored
Normal file
245
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/update.js
generated
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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 {assert} = require(`../../assert`);
|
||||
const {TableName} = require(`../table-name`);
|
||||
const {ColumnSet} = require(`../column-set`);
|
||||
|
||||
const npm = {
|
||||
formatting: require(`../../formatting`),
|
||||
utils: require(`../../utils`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.update
|
||||
* @description
|
||||
* Generates a simplified `UPDATE` query for either one object or an array of objects.
|
||||
*
|
||||
* The resulting query needs a `WHERE` clause to be appended to it, to specify the update logic.
|
||||
* This is to allow for update conditions of any complexity that are easy to add.
|
||||
*
|
||||
* @param {object|object[]} data
|
||||
* An update object with properties for update values, or an array of such objects.
|
||||
*
|
||||
* When `data` is not a non-null object and not an array, it will throw {@link external:TypeError TypeError} = `Invalid parameter 'data' specified.`
|
||||
*
|
||||
* When `data` is an empty array, it will throw {@link external:TypeError TypeError} = `Cannot generate an UPDATE from an empty array.`
|
||||
*
|
||||
* When `data` is an array that contains a non-object value, the method will throw {@link external:Error Error} =
|
||||
* `Invalid update object at index N.`
|
||||
*
|
||||
* @param {array|helpers.Column|helpers.ColumnSet} [columns]
|
||||
* Set of columns to be updated.
|
||||
*
|
||||
* It is optional when `data` is a single object, and required when `data` is an array of objects. If not specified for an array
|
||||
* of objects, the method will throw {@link external:TypeError TypeError} = `Parameter 'columns' is required when updating multiple records.`
|
||||
*
|
||||
* When `columns` is not a {@link helpers.ColumnSet ColumnSet} object, a temporary {@link helpers.ColumnSet ColumnSet}
|
||||
* is created - from the value of `columns` (if it was specified), or from the value of `data` (if it is not an array).
|
||||
*
|
||||
* When the final {@link helpers.ColumnSet ColumnSet} is empty (no columns in it), the method will throw
|
||||
* {@link external:Error Error} = `Cannot generate an UPDATE without any columns.`, unless option `emptyUpdate` was specified.
|
||||
*
|
||||
* @param {helpers.TableName|string|{table,schema}} [table]
|
||||
* Table to be updated.
|
||||
*
|
||||
* It is normally a required parameter. But when `columns` is passed in as a {@link helpers.ColumnSet ColumnSet} object
|
||||
* with `table` set in it, that will be used when this parameter isn't specified. When neither is available, the method
|
||||
* will throw {@link external:Error Error} = `Table name is unknown.`
|
||||
*
|
||||
* @param {{}} [options]
|
||||
* An object with formatting options for multi-row `UPDATE` queries.
|
||||
*
|
||||
* @param {string} [options.tableAlias=t]
|
||||
* Name of the SQL variable that represents the destination table.
|
||||
*
|
||||
* @param {string} [options.valueAlias=v]
|
||||
* Name of the SQL variable that represents the values.
|
||||
*
|
||||
* @param {*} [options.emptyUpdate]
|
||||
* This is a convenience option, to avoid throwing an error when generating a conditional update results in no columns.
|
||||
*
|
||||
* When present, regardless of the value, this option overrides the method's behavior when applying `skip` logic results in no columns,
|
||||
* i.e. when every column is being skipped.
|
||||
*
|
||||
* By default, in that situation the method throws {@link external:Error Error} = `Cannot generate an UPDATE without any columns.`
|
||||
* But when this option is present, the method will instead return whatever value the option was passed.
|
||||
*
|
||||
* @returns {*}
|
||||
* An `UPDATE` query string that needs a `WHERE` condition appended.
|
||||
*
|
||||
* If it results in an empty update, and option `emptyUpdate` was passed in, then the method returns the value
|
||||
* to which the option was set.
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet ColumnSet},
|
||||
* {@link helpers.TableName TableName}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')({
|
||||
* capSQL: true // if you want all generated SQL capitalized
|
||||
* });
|
||||
*
|
||||
* const dataSingle = {id: 1, val: 123, msg: 'hello'};
|
||||
* const dataMulti = [{id: 1, val: 123, msg: 'hello'}, {id: 2, val: 456, msg: 'world!'}];
|
||||
*
|
||||
* // Although column details can be taken from the data object, it is not
|
||||
* // a likely scenario for an update, unless updating the whole table:
|
||||
*
|
||||
* pgp.helpers.update(dataSingle, null, 'my-table');
|
||||
* //=> UPDATE "my-table" SET "id"=1,"val"=123,"msg"='hello'
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // A typical single-object update:
|
||||
*
|
||||
* // Dynamic conditions must be escaped/formatted properly:
|
||||
* const condition = pgp.as.format(' WHERE id = ${id}', dataSingle);
|
||||
*
|
||||
* pgp.helpers.update(dataSingle, ['val', 'msg'], 'my-table') + condition;
|
||||
* //=> UPDATE "my-table" SET "val"=123,"msg"='hello' WHERE id = 1
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details are required for a multi-row `UPDATE`;
|
||||
* // Adding '?' in front of a column name means it is only for a WHERE condition:
|
||||
*
|
||||
* pgp.helpers.update(dataMulti, ['?id', 'val', 'msg'], 'my-table') + ' WHERE v.id = t.id';
|
||||
* //=> UPDATE "my-table" AS t SET "val"=v."val","msg"=v."msg" FROM (VALUES(1,123,'hello'),(2,456,'world!'))
|
||||
* // AS v("id","val","msg") WHERE v.id = t.id
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details from a reusable ColumnSet (recommended for performance):
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['?id', 'val', 'msg'], {table: 'my-table'});
|
||||
*
|
||||
* pgp.helpers.update(dataMulti, cs) + ' WHERE v.id = t.id';
|
||||
* //=> UPDATE "my-table" AS t SET "val"=v."val","msg"=v."msg" FROM (VALUES(1,123,'hello'),(2,456,'world!'))
|
||||
* // AS v("id","val","msg") WHERE v.id = t.id
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Using parameter `options` to change the default alias names:
|
||||
*
|
||||
* pgp.helpers.update(dataMulti, cs, null, {tableAlias: 'X', valueAlias: 'Y'}) + ' WHERE Y.id = X.id';
|
||||
* //=> UPDATE "my-table" AS X SET "val"=Y."val","msg"=Y."msg" FROM (VALUES(1,123,'hello'),(2,456,'world!'))
|
||||
* // AS Y("id","val","msg") WHERE Y.id = X.id
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Handling an empty update
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['?id', '?name'], {table: 'tt'}); // no actual update-able columns
|
||||
* const result = pgp.helpers.update(dataMulti, cs, null, {emptyUpdate: 123});
|
||||
* if(result === 123) {
|
||||
* // We know the update is empty, i.e. no columns that can be updated;
|
||||
* // And it didn't throw because we specified `emptyUpdate` option.
|
||||
* }
|
||||
*/
|
||||
function update(data, columns, table, options, capSQL) {
|
||||
|
||||
if (!data || typeof data !== `object`) {
|
||||
throw new TypeError(`Invalid parameter 'data' specified.`);
|
||||
}
|
||||
|
||||
const isArray = Array.isArray(data);
|
||||
|
||||
if (isArray && !data.length) {
|
||||
throw new TypeError(`Cannot generate an UPDATE from an empty array.`);
|
||||
}
|
||||
|
||||
if (columns instanceof ColumnSet) {
|
||||
if (npm.utils.isNull(table)) {
|
||||
table = columns.table;
|
||||
}
|
||||
} else {
|
||||
if (isArray && npm.utils.isNull(columns)) {
|
||||
throw new TypeError(`Parameter 'columns' is required when updating multiple records.`);
|
||||
}
|
||||
columns = new ColumnSet(columns || data);
|
||||
}
|
||||
|
||||
options = assert(options, [`tableAlias`, `valueAlias`, `emptyUpdate`]);
|
||||
|
||||
const format = npm.formatting.as.format,
|
||||
useEmptyUpdate = `emptyUpdate` in options,
|
||||
fmOptions = {capSQL};
|
||||
|
||||
if (isArray) {
|
||||
const tableAlias = npm.formatting.as.alias(npm.utils.isNull(options.tableAlias) ? `t` : options.tableAlias);
|
||||
const valueAlias = npm.formatting.as.alias(npm.utils.isNull(options.valueAlias) ? `v` : options.valueAlias);
|
||||
|
||||
const q = capSQL ? sql.multi.capCase : sql.multi.lowCase;
|
||||
|
||||
const actualColumns = columns.columns.filter(c => !c.cnd);
|
||||
|
||||
if (checkColumns(actualColumns)) {
|
||||
return options.emptyUpdate;
|
||||
}
|
||||
|
||||
checkTable();
|
||||
|
||||
const targetCols = actualColumns.map(c => c.escapedName + `=` + valueAlias + `.` + c.escapedName).join();
|
||||
|
||||
const values = data.map((d, index) => {
|
||||
if (!d || typeof d !== `object`) {
|
||||
throw new Error(`Invalid update object at index ${index}.`);
|
||||
}
|
||||
return `(` + format(columns.variables, columns.prepare(d), fmOptions) + `)`;
|
||||
}).join();
|
||||
|
||||
return format(q, [table.name, tableAlias, targetCols, values, valueAlias, columns.names], fmOptions);
|
||||
}
|
||||
|
||||
const updates = columns.assign({source: data});
|
||||
|
||||
if (checkColumns(updates)) {
|
||||
return options.emptyUpdate;
|
||||
}
|
||||
|
||||
checkTable();
|
||||
|
||||
const query = capSQL ? sql.single.capCase : sql.single.lowCase;
|
||||
|
||||
return format(query, table.name) + format(updates, columns.prepare(data), fmOptions);
|
||||
|
||||
function checkTable() {
|
||||
if (table && !(table instanceof TableName)) {
|
||||
table = new TableName(table);
|
||||
}
|
||||
if (!table) {
|
||||
throw new Error(`Table name is unknown.`);
|
||||
}
|
||||
}
|
||||
|
||||
function checkColumns(cols) {
|
||||
if (!cols.length) {
|
||||
if (useEmptyUpdate) {
|
||||
return true;
|
||||
}
|
||||
throw new Error(`Cannot generate an UPDATE without any columns.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sql = {
|
||||
single: {
|
||||
lowCase: `update $1^ set `,
|
||||
capCase: `UPDATE $1^ SET `
|
||||
},
|
||||
multi: {
|
||||
lowCase: `update $1^ as $2^ set $3^ from (values$4^) as $5^($6^)`,
|
||||
capCase: `UPDATE $1^ AS $2^ SET $3^ FROM (VALUES$4^) AS $5^($6^)`
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {update};
|
||||
115
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/values.js
generated
vendored
Normal file
115
ProjectSourceCode/node_modules/pg-promise/lib/helpers/methods/values.js
generated
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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 {ColumnSet} = require(`../column-set`);
|
||||
|
||||
const npm = {
|
||||
formatting: require(`../../formatting`),
|
||||
utils: require(`../../utils`)
|
||||
};
|
||||
|
||||
/**
|
||||
* @method helpers.values
|
||||
* @description
|
||||
* Generates a string of comma-separated value groups from either one object or an array of objects,
|
||||
* to be used as part of a query:
|
||||
*
|
||||
* - from a single object: `(val_1, val_2, ...)`
|
||||
* - from an array of objects: `(val_11, val_12, ...), (val_21, val_22, ...)`
|
||||
*
|
||||
* @param {object|object[]} data
|
||||
* A source object with properties as values, or an array of such objects.
|
||||
*
|
||||
* If it is anything else, the method will throw {@link external:TypeError TypeError} = `Invalid parameter 'data' specified.`
|
||||
*
|
||||
* When `data` is an array that contains a non-object value, the method will throw {@link external:Error Error} =
|
||||
* `Invalid object at index N.`
|
||||
*
|
||||
* When `data` is an empty array, an empty string is returned.
|
||||
*
|
||||
* @param {array|helpers.Column|helpers.ColumnSet} [columns]
|
||||
* Columns for which to return values.
|
||||
*
|
||||
* It is optional when `data` is a single object, and required when `data` is an array of objects. If not specified for an array
|
||||
* of objects, the method will throw {@link external:TypeError TypeError} = `Parameter 'columns' is required when generating multi-row values.`
|
||||
*
|
||||
* When the final {@link helpers.ColumnSet ColumnSet} is empty (no columns in it), the method will throw
|
||||
* {@link external:Error Error} = `Cannot generate values without any columns.`
|
||||
*
|
||||
* @returns {string}
|
||||
* - comma-separated value groups, according to `data`
|
||||
* - an empty string, if `data` is an empty array
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.Column Column},
|
||||
* {@link helpers.ColumnSet ColumnSet}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const pgp = require('pg-promise')();
|
||||
*
|
||||
* const dataSingle = {val: 123, msg: 'hello'};
|
||||
* const dataMulti = [{val: 123, msg: 'hello'}, {val: 456, msg: 'world!'}];
|
||||
*
|
||||
* // Properties can be pulled automatically from a single object:
|
||||
*
|
||||
* pgp.helpers.values(dataSingle);
|
||||
* //=> (123,'hello')
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details are required when using an array of objects:
|
||||
*
|
||||
* pgp.helpers.values(dataMulti, ['val', 'msg']);
|
||||
* //=> (123,'hello'),(456,'world!')
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* // Column details from a reusable ColumnSet (recommended for performance):
|
||||
*
|
||||
* const cs = new pgp.helpers.ColumnSet(['val', 'msg']);
|
||||
*
|
||||
* pgp.helpers.values(dataMulti, cs);
|
||||
* //=> (123,'hello'),(456,'world!')
|
||||
*
|
||||
*/
|
||||
function values(data, columns, capSQL) {
|
||||
|
||||
if (!data || typeof data !== `object`) {
|
||||
throw new TypeError(`Invalid parameter 'data' specified.`);
|
||||
}
|
||||
|
||||
const isArray = Array.isArray(data);
|
||||
|
||||
if (!(columns instanceof ColumnSet)) {
|
||||
if (isArray && npm.utils.isNull(columns)) {
|
||||
throw new TypeError(`Parameter 'columns' is required when generating multi-row values.`);
|
||||
}
|
||||
columns = new ColumnSet(columns || data);
|
||||
}
|
||||
|
||||
if (!columns.columns.length) {
|
||||
throw new Error(`Cannot generate values without any columns.`);
|
||||
}
|
||||
|
||||
const format = npm.formatting.as.format,
|
||||
fmOptions = {capSQL};
|
||||
|
||||
if (isArray) {
|
||||
return data.map((d, index) => {
|
||||
if (!d || typeof d !== `object`) {
|
||||
throw new Error(`Invalid object at index ${index}.`);
|
||||
}
|
||||
return `(` + format(columns.variables, columns.prepare(d), fmOptions) + `)`;
|
||||
}).join();
|
||||
}
|
||||
return `(` + format(columns.variables, columns.prepare(data), fmOptions) + `)`;
|
||||
}
|
||||
|
||||
module.exports = {values};
|
||||
128
ProjectSourceCode/node_modules/pg-promise/lib/helpers/table-name.js
generated
vendored
Normal file
128
ProjectSourceCode/node_modules/pg-promise/lib/helpers/table-name.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 {assert} = require(`../assert`);
|
||||
|
||||
const npm = {
|
||||
utils: require(`../utils`),
|
||||
format: require(`../formatting`).as // formatting namespace
|
||||
};
|
||||
|
||||
/**
|
||||
* @class helpers.TableName
|
||||
* @description
|
||||
* Represents a full table name that can be injected into queries directly.
|
||||
*
|
||||
* This is a read-only type that can be used wherever parameter `table` is supported.
|
||||
*
|
||||
* It supports $[Custom Type Formatting], which means you can use the type directly as a formatting
|
||||
* parameter, without specifying any escaping.
|
||||
*
|
||||
* Filter `:alias` is an alternative approach to splitting an SQL name into multiple ones.
|
||||
*
|
||||
* @param {string|object} table
|
||||
* Table name details, depending on the type:
|
||||
*
|
||||
* - table name, if `table` is a string
|
||||
* - object `{table, [schema]}`
|
||||
*
|
||||
* @property {string} name
|
||||
* Formatted/escaped full table name, combining `schema` + `table`.
|
||||
*
|
||||
* @property {string} table
|
||||
* Table name.
|
||||
*
|
||||
* @property {string} schema
|
||||
* Database schema name.
|
||||
*
|
||||
* It is `undefined` when no valid schema was specified.
|
||||
*
|
||||
* @returns {helpers.TableName}
|
||||
*
|
||||
* @see
|
||||
* {@link helpers.TableName#toPostgres toPostgres}
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* const table = new pgp.helpers.TableName({table: 'my-table', schema: 'my-schema'});
|
||||
* console.log(table);
|
||||
* //=> "my-schema"."my-table"
|
||||
*
|
||||
* // Formatting the type directly:
|
||||
* pgp.as.format('SELECT * FROM $1', table);
|
||||
* //=> SELECT * FROM "my-schema"."my-table"
|
||||
*
|
||||
*/
|
||||
class TableName {
|
||||
|
||||
constructor(table) {
|
||||
if (typeof table === `string`) {
|
||||
this.table = table;
|
||||
} else {
|
||||
const config = assert(table, [`table`, `schema`]);
|
||||
this.table = config.table;
|
||||
if (npm.utils.isText(config.schema)) {
|
||||
this.schema = config.schema;
|
||||
}
|
||||
}
|
||||
if (!npm.utils.isText(this.table)) {
|
||||
throw new TypeError(`Table name must be a non-empty text string.`);
|
||||
}
|
||||
this.name = npm.format.name(this.table);
|
||||
if (this.schema) {
|
||||
this.name = npm.format.name(this.schema) + `.` + this.name;
|
||||
}
|
||||
Object.freeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @method helpers.TableName#toPostgres
|
||||
* @description
|
||||
* $[Custom Type Formatting], based on $[Symbolic CTF], i.e. the actual method is available only via {@link external:Symbol Symbol}:
|
||||
*
|
||||
* ```js
|
||||
* const ctf = pgp.as.ctf; // Custom Type Formatting symbols namespace
|
||||
* const fullName = tn[ctf.toPostgres]; // tn = an object of type TableName
|
||||
* ```
|
||||
*
|
||||
* This is a raw formatting type (`rawType = true`), i.e. when used as a query-formatting parameter, type `TableName`
|
||||
* injects full table name as raw text.
|
||||
*
|
||||
* @param {helpers.TableName} [self]
|
||||
* Optional self-reference, for ES6 arrow functions.
|
||||
*
|
||||
* @returns {string}
|
||||
* Escaped full table name that includes optional schema name, if specified.
|
||||
*/
|
||||
TableName.prototype[npm.format.ctf.toPostgres] = function (self) {
|
||||
self = this instanceof TableName && this || self;
|
||||
return self.name;
|
||||
};
|
||||
|
||||
TableName.prototype[npm.format.ctf.rawType] = true; // use as pre-formatted
|
||||
|
||||
/**
|
||||
* @method helpers.TableName#toString
|
||||
* @description
|
||||
* Creates a well-formatted string that represents the object.
|
||||
*
|
||||
* It is called automatically when writing the object into the console.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
TableName.prototype.toString = function () {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
npm.utils.addInspection(TableName, function () {
|
||||
return this.toString();
|
||||
});
|
||||
|
||||
module.exports = {TableName};
|
||||
Reference in New Issue
Block a user