@depup/pg-promise 12.6.2-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/lib/assert.js +10 -0
- package/lib/connect.js +178 -0
- package/lib/context.js +93 -0
- package/lib/database-pool.js +115 -0
- package/lib/database.js +1643 -0
- package/lib/errors/README.md +13 -0
- package/lib/errors/index.js +51 -0
- package/lib/errors/parameterized-query-error.js +71 -0
- package/lib/errors/prepared-statement-error.js +71 -0
- package/lib/errors/query-file-error.js +75 -0
- package/lib/errors/query-result-error.js +157 -0
- package/lib/events.js +543 -0
- package/lib/formatting.js +932 -0
- package/lib/helpers/README.md +10 -0
- package/lib/helpers/column-set.js +614 -0
- package/lib/helpers/column.js +406 -0
- package/lib/helpers/index.js +75 -0
- package/lib/helpers/methods/concat.js +103 -0
- package/lib/helpers/methods/index.js +13 -0
- package/lib/helpers/methods/insert.js +151 -0
- package/lib/helpers/methods/sets.js +81 -0
- package/lib/helpers/methods/update.js +248 -0
- package/lib/helpers/methods/values.js +116 -0
- package/lib/helpers/table-name.js +175 -0
- package/lib/index.js +29 -0
- package/lib/inner-state.js +39 -0
- package/lib/main.js +394 -0
- package/lib/patterns.js +43 -0
- package/lib/query-file.js +379 -0
- package/lib/query-result.js +39 -0
- package/lib/query.js +273 -0
- package/lib/special-query.js +30 -0
- package/lib/stream.js +125 -0
- package/lib/task.js +404 -0
- package/lib/text.js +40 -0
- package/lib/tx-mode.js +194 -0
- package/lib/types/index.js +18 -0
- package/lib/types/parameterized-query.js +247 -0
- package/lib/types/prepared-statement.js +298 -0
- package/lib/types/server-formatting.js +92 -0
- package/lib/utils/README.md +13 -0
- package/lib/utils/color.js +68 -0
- package/lib/utils/index.js +199 -0
- package/lib/utils/public.js +312 -0
- package/package.json +77 -0
- package/typescript/README.md +63 -0
- package/typescript/pg-promise.d.ts +728 -0
- package/typescript/pg-subset.d.ts +359 -0
- package/typescript/tslint.json +21 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2015-present, Vitaly Tomilov
|
|
3
|
+
*
|
|
4
|
+
* See the LICENSE file at the top-level directory of this distribution
|
|
5
|
+
* for licensing information.
|
|
6
|
+
*
|
|
7
|
+
* Removal or modification of this copyright notice is prohibited.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const {assert} = require('../assert');
|
|
11
|
+
|
|
12
|
+
const npm = {
|
|
13
|
+
fs: require('fs'),
|
|
14
|
+
path: require('path'),
|
|
15
|
+
utils: require('./'),
|
|
16
|
+
package: require('../../package.json')
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @method utils.camelize
|
|
21
|
+
* @description
|
|
22
|
+
* Camelizes a text string.
|
|
23
|
+
*
|
|
24
|
+
* Case-changing characters include:
|
|
25
|
+
* - _hyphen_
|
|
26
|
+
* - _underscore_
|
|
27
|
+
* - _period_
|
|
28
|
+
* - _space_
|
|
29
|
+
*
|
|
30
|
+
* @param {string} text
|
|
31
|
+
* Input text string.
|
|
32
|
+
*
|
|
33
|
+
* @returns {string}
|
|
34
|
+
* Camelized text string.
|
|
35
|
+
*
|
|
36
|
+
* @see
|
|
37
|
+
* {@link utils.camelizeVar camelizeVar}
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
function camelize(text) {
|
|
41
|
+
text = text.replace(/[-_\s.]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
|
|
42
|
+
return text.substring(0, 1).toLowerCase() + text.substring(1);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @method utils.camelizeVar
|
|
47
|
+
* @description
|
|
48
|
+
* Camelizes a text string, while making it compliant with JavaScript variable names:
|
|
49
|
+
* - contains symbols `a-z`, `A-Z`, `0-9`, `_` and `$`
|
|
50
|
+
* - cannot have leading digits
|
|
51
|
+
*
|
|
52
|
+
* First, it removes all symbols that do not meet the above criteria, except for _hyphen_, _period_ and _space_,
|
|
53
|
+
* and then it forwards into {@link utils.camelize camelize}.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} text
|
|
56
|
+
* Input text string.
|
|
57
|
+
*
|
|
58
|
+
* If it doesn't contain any symbols to make up a valid variable name, the result will be an empty string.
|
|
59
|
+
*
|
|
60
|
+
* @returns {string}
|
|
61
|
+
* Camelized text string that can be used as an open property name.
|
|
62
|
+
*
|
|
63
|
+
* @see
|
|
64
|
+
* {@link utils.camelize camelize}
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
function camelizeVar(text) {
|
|
68
|
+
text = text.replace(/[^a-zA-Z0-9$_\-\s.]/g, '').replace(/^[0-9_\-\s.]+/, '');
|
|
69
|
+
return camelize(text);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function _enumSql(dir, options, cb, namePath) {
|
|
73
|
+
const tree = {};
|
|
74
|
+
npm.fs.readdirSync(dir).forEach(file => {
|
|
75
|
+
let stat;
|
|
76
|
+
const fullPath = npm.path.join(dir, file);
|
|
77
|
+
try {
|
|
78
|
+
stat = npm.fs.statSync(fullPath);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// while it is very easy to test manually, it is very difficult to test for
|
|
81
|
+
// access-denied errors automatically; therefore excluding from the coverage:
|
|
82
|
+
// istanbul ignore next
|
|
83
|
+
if (options.ignoreErrors) {
|
|
84
|
+
return; // on to the next file/folder;
|
|
85
|
+
}
|
|
86
|
+
// istanbul ignore next
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
if (stat.isDirectory()) {
|
|
90
|
+
if (options.recursive) {
|
|
91
|
+
const dirName = camelizeVar(file);
|
|
92
|
+
const np = namePath ? (namePath + '.' + dirName) : dirName;
|
|
93
|
+
const t = _enumSql(fullPath, options, cb, np);
|
|
94
|
+
if (Object.keys(t).length) {
|
|
95
|
+
if (!dirName.length || dirName in tree) {
|
|
96
|
+
if (!options.ignoreErrors) {
|
|
97
|
+
throw new Error('Empty or duplicate camelized folder name: ' + fullPath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
tree[dirName] = t;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
if (npm.path.extname(file).toLowerCase() === '.sql') {
|
|
105
|
+
const name = camelizeVar(file.replace(/\.[^/.]+$/, ''));
|
|
106
|
+
if (!name.length || name in tree) {
|
|
107
|
+
if (!options.ignoreErrors) {
|
|
108
|
+
throw new Error('Empty or duplicate camelized file name: ' + fullPath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
tree[name] = fullPath;
|
|
112
|
+
if (cb) {
|
|
113
|
+
const result = cb(fullPath, name, namePath ? (namePath + '.' + name) : name);
|
|
114
|
+
if (result !== undefined) {
|
|
115
|
+
tree[name] = result;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return tree;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @method utils.enumSql
|
|
126
|
+
* @description
|
|
127
|
+
* Synchronously enumerates all SQL files (within a given directory) into a camelized SQL tree.
|
|
128
|
+
*
|
|
129
|
+
* All property names within the tree are camelized via {@link utils.camelizeVar camelizeVar},
|
|
130
|
+
* so they can be used in the code directly, as open property names.
|
|
131
|
+
*
|
|
132
|
+
* @param {string} dir
|
|
133
|
+
* Directory path where SQL files are located, either absolute or relative to the current directory.
|
|
134
|
+
*
|
|
135
|
+
* SQL files are identified by using `.sql` extension (case-insensitive).
|
|
136
|
+
*
|
|
137
|
+
* @param {{}} [options]
|
|
138
|
+
* Search options.
|
|
139
|
+
*
|
|
140
|
+
* @param {boolean} [options.recursive=false]
|
|
141
|
+
* Include sub-directories into the search.
|
|
142
|
+
*
|
|
143
|
+
* Sub-directories without SQL files will be skipped from the result.
|
|
144
|
+
*
|
|
145
|
+
* @param {boolean} [options.ignoreErrors=false]
|
|
146
|
+
* Ignore the following types of errors:
|
|
147
|
+
* - access errors, when there is no read access to a file or folder
|
|
148
|
+
* - empty or duplicate camelized property names
|
|
149
|
+
*
|
|
150
|
+
* This flag does not affect errors related to invalid input parameters, or if you pass in a
|
|
151
|
+
* non-existing directory.
|
|
152
|
+
*
|
|
153
|
+
* @param {function} [cb]
|
|
154
|
+
* A callback function that takes three arguments:
|
|
155
|
+
* - `file` - SQL file path, relative or absolute, according to how you specified the search directory
|
|
156
|
+
* - `name` - name of the property that represents the SQL file
|
|
157
|
+
* - `path` - property resolution path (full property name)
|
|
158
|
+
*
|
|
159
|
+
* If the function returns anything other than `undefined`, it overrides the corresponding property value in the tree.
|
|
160
|
+
*
|
|
161
|
+
* @returns {object}
|
|
162
|
+
* Camelized SQL tree object, with each value being an SQL file path (unless changed via the callback).
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
*
|
|
166
|
+
* // simple SQL tree generation for further processing:
|
|
167
|
+
* const tree = pgp.utils.enumSql('../sql', {recursive: true});
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
*
|
|
171
|
+
* // generating an SQL tree for dynamic use of names:
|
|
172
|
+
* const sql = pgp.utils.enumSql(__dirname, {recursive: true}, file => {
|
|
173
|
+
* return new pgp.QueryFile(file, {minify: true});
|
|
174
|
+
* });
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
*
|
|
178
|
+
* const {join: joinPath} = require('path');
|
|
179
|
+
*
|
|
180
|
+
* // replacing each relative path in the tree with a full one:
|
|
181
|
+
* const tree = pgp.utils.enumSql('../sql', {recursive: true}, file => {
|
|
182
|
+
* return joinPath(__dirname, file);
|
|
183
|
+
* });
|
|
184
|
+
*
|
|
185
|
+
*/
|
|
186
|
+
function enumSql(dir, options, cb) {
|
|
187
|
+
if (!npm.utils.isText(dir)) {
|
|
188
|
+
throw new TypeError('Parameter \'dir\' must be a non-empty text string.');
|
|
189
|
+
}
|
|
190
|
+
options = assert(options, ['recursive', 'ignoreErrors']);
|
|
191
|
+
cb = (typeof cb === 'function') ? cb : null;
|
|
192
|
+
return _enumSql(dir, options, cb, '');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @method utils.taskArgs
|
|
197
|
+
* @description
|
|
198
|
+
* Normalizes/prepares arguments for tasks and transactions.
|
|
199
|
+
*
|
|
200
|
+
* Its main purpose is to simplify adding custom methods {@link Database#task task}, {@link Database#taskIf taskIf},
|
|
201
|
+
* {@link Database#tx tx} and {@link Database#txIf txIf} within event {@link event:extend extend}, as the those methods use fairly
|
|
202
|
+
* complex logic for parsing inputs.
|
|
203
|
+
*
|
|
204
|
+
* @param args {Object}
|
|
205
|
+
* Array-like object of `arguments` that was passed into the method. It is expected that the `arguments`
|
|
206
|
+
* are always made of two parameters - `(options, cb)`, same as all the default task/transaction methods.
|
|
207
|
+
*
|
|
208
|
+
* And if your custom method needs additional parameters, they should be passed in as extra properties within `options`.
|
|
209
|
+
*
|
|
210
|
+
* @returns {Array}
|
|
211
|
+
* Array of arguments that can be passed into a task or transaction.
|
|
212
|
+
*
|
|
213
|
+
* It is extended with properties `options` and `cb` to access the corresponding array elements `[0]` and `[1]` by name.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
*
|
|
217
|
+
* // Registering a custom transaction method that assigns a default Transaction Mode:
|
|
218
|
+
*
|
|
219
|
+
* const initOptions = {
|
|
220
|
+
* extend: obj => {
|
|
221
|
+
* obj.myTx = function(options, cb) {
|
|
222
|
+
* const args = pgp.utils.taskArgs(arguments); // prepare arguments
|
|
223
|
+
*
|
|
224
|
+
* if (!('mode' in args.options)) {
|
|
225
|
+
* // if no 'mode' was specified, set default for transaction mode:
|
|
226
|
+
* args.options.mode = myTxModeObject; // of type pgp.txMode.TransactionMode
|
|
227
|
+
* }
|
|
228
|
+
*
|
|
229
|
+
* return obj.tx.apply(this, args);
|
|
230
|
+
* // or explicitly, if needed:
|
|
231
|
+
* // return obj.tx.call(this, args.options, args.cb);
|
|
232
|
+
* }
|
|
233
|
+
* }
|
|
234
|
+
* };
|
|
235
|
+
*
|
|
236
|
+
*/
|
|
237
|
+
function taskArgs(args) {
|
|
238
|
+
|
|
239
|
+
if (!args || typeof args.length !== 'number') {
|
|
240
|
+
throw new TypeError('Parameter \'args\' must be an array-like object of arguments.');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
let options = args[0], cb;
|
|
244
|
+
if (typeof options === 'function') {
|
|
245
|
+
cb = options;
|
|
246
|
+
options = {};
|
|
247
|
+
if (cb.name) {
|
|
248
|
+
options.tag = cb.name;
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
if (typeof args[1] === 'function') {
|
|
252
|
+
cb = args[1];
|
|
253
|
+
}
|
|
254
|
+
if (typeof options === 'string' || typeof options === 'number') {
|
|
255
|
+
options = {tag: options};
|
|
256
|
+
} else {
|
|
257
|
+
options = (typeof options === 'object' && options) || {};
|
|
258
|
+
if (!('tag' in options) && cb && cb.name) {
|
|
259
|
+
options.tag = cb.name;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const res = [options, cb];
|
|
265
|
+
|
|
266
|
+
Object.defineProperty(res, 'options', {
|
|
267
|
+
get: function () {
|
|
268
|
+
return this[0];
|
|
269
|
+
},
|
|
270
|
+
set: function (newValue) {
|
|
271
|
+
this[0] = newValue;
|
|
272
|
+
},
|
|
273
|
+
enumerable: true
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
Object.defineProperty(res, 'cb', {
|
|
277
|
+
get: function () {
|
|
278
|
+
return this[1];
|
|
279
|
+
},
|
|
280
|
+
set: function (newValue) {
|
|
281
|
+
this[1] = newValue;
|
|
282
|
+
},
|
|
283
|
+
enumerable: true
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
return res;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* @namespace utils
|
|
291
|
+
*
|
|
292
|
+
* @description
|
|
293
|
+
* Namespace for general-purpose static functions, available as `pgp.utils`, before and after initializing the library.
|
|
294
|
+
*
|
|
295
|
+
* @property {function} camelize
|
|
296
|
+
* {@link utils.camelize camelize} - camelizes a text string
|
|
297
|
+
*
|
|
298
|
+
* @property {function} camelizeVar
|
|
299
|
+
* {@link utils.camelizeVar camelizeVar} - camelizes a text string as a variable
|
|
300
|
+
*
|
|
301
|
+
* @property {function} enumSql
|
|
302
|
+
* {@link utils.enumSql enumSql} - enumerates SQL files in a directory
|
|
303
|
+
*
|
|
304
|
+
* @property {function} taskArgs
|
|
305
|
+
* {@link utils.taskArgs taskArgs} - prepares arguments for tasks and transactions
|
|
306
|
+
*/
|
|
307
|
+
module.exports = {
|
|
308
|
+
camelize,
|
|
309
|
+
camelizeVar,
|
|
310
|
+
enumSql,
|
|
311
|
+
taskArgs
|
|
312
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@depup/pg-promise",
|
|
3
|
+
"version": "12.6.2-depup.0",
|
|
4
|
+
"description": "[DepUp] PostgreSQL interface for Node.js",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "typescript/pg-promise.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"spelling": "cspell --config=.cspell.json \"**/*.{md,ts,js}\" --no-progress",
|
|
9
|
+
"coverage": "nyc --reporter=html --reporter=text ./node_modules/jasmine-node/bin/jasmine-node --captureExceptions test",
|
|
10
|
+
"doc": "jsdoc -c ./jsdoc/jsdoc.js ./jsdoc/README.md -t ./jsdoc/templates/custom",
|
|
11
|
+
"lint": "eslint ./lib ./test/*.js ./test/db",
|
|
12
|
+
"lint:fix": "npm run lint -- --fix",
|
|
13
|
+
"test": "jasmine-node --captureExceptions test",
|
|
14
|
+
"test:init": "node test/db/init.js",
|
|
15
|
+
"test:native": "jasmine-node test --config PG_NATIVE true"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"lib",
|
|
19
|
+
"typescript"
|
|
20
|
+
],
|
|
21
|
+
"homepage": "https://github.com/vitaly-t/pg-promise",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/vitaly-t/pg-promise.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/vitaly-t/pg-promise/issues",
|
|
28
|
+
"email": "vitaly.tomilov@gmail.com"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"depup",
|
|
32
|
+
"dependency-bumped",
|
|
33
|
+
"updated-deps",
|
|
34
|
+
"pg-promise",
|
|
35
|
+
"pg",
|
|
36
|
+
"promise",
|
|
37
|
+
"postgres"
|
|
38
|
+
],
|
|
39
|
+
"author": {
|
|
40
|
+
"name": "Vitaly Tomilov",
|
|
41
|
+
"email": "vitaly.tomilov@gmail.com"
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=16.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"assert-options": "0.8.3",
|
|
49
|
+
"pg": "8.20.0",
|
|
50
|
+
"pg-minify": "1.8.0",
|
|
51
|
+
"spex": "4.1.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"pg-query-stream": "4.14.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@eslint/js": "10.0.1",
|
|
58
|
+
"@types/node": "25.3.4",
|
|
59
|
+
"coveralls": "3.1.1",
|
|
60
|
+
"cspell": "9.7.0",
|
|
61
|
+
"eslint": "10.0.2",
|
|
62
|
+
"globals": "17.4.0",
|
|
63
|
+
"jasmine-node": "3.0.0",
|
|
64
|
+
"jsdoc": "4.0.5",
|
|
65
|
+
"JSONStream": "1.3.5",
|
|
66
|
+
"nyc": "18.0.0",
|
|
67
|
+
"typescript": "5.9.3"
|
|
68
|
+
},
|
|
69
|
+
"depup": {
|
|
70
|
+
"changes": {},
|
|
71
|
+
"depsUpdated": 0,
|
|
72
|
+
"originalPackage": "pg-promise",
|
|
73
|
+
"originalVersion": "12.6.2",
|
|
74
|
+
"processedAt": "2026-03-09T05:03:50.245Z",
|
|
75
|
+
"smokeTest": "passed"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
## TypeScript for pg-promise
|
|
2
|
+
|
|
3
|
+
Complete TypeScript declarations for [pg-promise].
|
|
4
|
+
|
|
5
|
+
### Inclusion
|
|
6
|
+
|
|
7
|
+
Typescript should be able to pick up the definitions without any manual configuration.
|
|
8
|
+
|
|
9
|
+
### Simple Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import pgPromise from 'pg-promise';
|
|
13
|
+
|
|
14
|
+
const pgp = pgPromise({/* Initialization Options */});
|
|
15
|
+
|
|
16
|
+
const db = pgp('postgres://username:password@host:port/database');
|
|
17
|
+
|
|
18
|
+
const {value} = await db.one('SELECT 123 as value');
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
#### With Extensions
|
|
22
|
+
|
|
23
|
+
The library supports dynamic protocol extensions, via event [extend], which requires
|
|
24
|
+
an explicit extension interface to be declared and parameterized, as shown below.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import * as pgPromise from 'pg-promise';
|
|
28
|
+
|
|
29
|
+
// your protocol extensions:
|
|
30
|
+
interface IExtensions {
|
|
31
|
+
findUser(userId: number): Promise<any>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// pg-promise initialization options:
|
|
35
|
+
const options: pgPromise.IInitOptions<IExtensions> = {
|
|
36
|
+
extend(obj) {
|
|
37
|
+
obj.findUser = userId => {
|
|
38
|
+
return obj.one('SELECT * FROM Users WHERE id = $1', [userId]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// initializing the library:
|
|
44
|
+
const pgp = pgPromise(options);
|
|
45
|
+
|
|
46
|
+
// database object:
|
|
47
|
+
const db = pgp('postgres://username:password@host:port/database');
|
|
48
|
+
|
|
49
|
+
// protocol is extended on each level:
|
|
50
|
+
const user = await db.findUser(123);
|
|
51
|
+
|
|
52
|
+
// ...including inside tasks and transactions:
|
|
53
|
+
await db.task(async t => {
|
|
54
|
+
const user = await t.findUser(123);
|
|
55
|
+
// ...etc
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For a comprehensive example, check out [pg-promise-demo].
|
|
60
|
+
|
|
61
|
+
[pg-promise-demo]:https://github.com/vitaly-t/pg-promise-demo
|
|
62
|
+
[extend]:https://vitaly-t.github.io/pg-promise/global.html#event:extend
|
|
63
|
+
[pg-promise]:https://github.com/vitaly-t/pg-promise
|