@trenskow/pged 4.1.0 → 4.1.1
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/index.js +4 -21
- package/package.json +1 -1
- package/query-builder.js +59 -9
package/index.js
CHANGED
|
@@ -89,7 +89,8 @@ module.exports = exports = class PGed {
|
|
|
89
89
|
return result;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
_convertResult(result) {
|
|
92
|
+
_convertResult(result, options) {
|
|
93
|
+
if ((options || {}).format === 'raw') return (result || {}).rows;
|
|
93
94
|
return ((result || {}).rows || []).map((row) => {
|
|
94
95
|
let newRow = {};
|
|
95
96
|
Object.keys(row).forEach((key) => {
|
|
@@ -209,7 +210,7 @@ module.exports = exports = class PGed {
|
|
|
209
210
|
|
|
210
211
|
let result;
|
|
211
212
|
|
|
212
|
-
const todo = async () => result = this._convertResult(await this._query(query, parameters));
|
|
213
|
+
const todo = async () => result = this._convertResult(await this._query(query, parameters), options);
|
|
213
214
|
|
|
214
215
|
if (this._transactions.always || options.transaction) await this.transaction(todo);
|
|
215
216
|
else await this.retained(todo);
|
|
@@ -225,25 +226,7 @@ module.exports = exports = class PGed {
|
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
_queryBuild(table) {
|
|
228
|
-
return new QueryBuilder(table, this._options,
|
|
229
|
-
|
|
230
|
-
const [query, parameters] = queryBuilder._build();
|
|
231
|
-
|
|
232
|
-
let result = await this.exec(
|
|
233
|
-
query,
|
|
234
|
-
parameters,
|
|
235
|
-
{
|
|
236
|
-
first: queryBuilder._first,
|
|
237
|
-
transaction: queryBuilder._transaction
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
if (['null', 'undefined'].includes(typeof result)) {
|
|
241
|
-
result = queryBuilder._defaultResult;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return result;
|
|
245
|
-
|
|
246
|
-
});
|
|
229
|
+
return new QueryBuilder(table, this._options, this);
|
|
247
230
|
}
|
|
248
231
|
|
|
249
232
|
from(table) {
|
package/package.json
CHANGED
package/query-builder.js
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
const
|
|
4
4
|
caseit = require('@trenskow/caseit'),
|
|
5
|
-
CustomPromise = require('@trenskow/custom-promise')
|
|
5
|
+
CustomPromise = require('@trenskow/custom-promise'),
|
|
6
|
+
Puqeue = require('puqeue');
|
|
7
|
+
|
|
8
|
+
const tableInformationQueue = new Puqeue();
|
|
9
|
+
const tableInformation = {};
|
|
6
10
|
|
|
7
11
|
module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
8
12
|
|
|
9
|
-
constructor(table, options = {},
|
|
13
|
+
constructor(table, options = {}, connection) {
|
|
10
14
|
|
|
11
15
|
super();
|
|
12
16
|
|
|
@@ -36,7 +40,7 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
36
40
|
|
|
37
41
|
this._offset = 0;
|
|
38
42
|
|
|
39
|
-
this.
|
|
43
|
+
this._connection = connection;
|
|
40
44
|
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -285,6 +289,17 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
285
289
|
}).concat(this._paginated ? `count(${this._table}.*) over() as total` : []).join(', ');
|
|
286
290
|
}
|
|
287
291
|
|
|
292
|
+
_formatParameter(keyPath, value) {
|
|
293
|
+
let [table, key] = keyPath.split('.');
|
|
294
|
+
if (typeof key === 'undefined') [table, key] = [this._table, table];
|
|
295
|
+
switch ((tableInformation[caseit(table, this._options.casing.db)] || {})[caseit(key, this._options.casing.db)]) {
|
|
296
|
+
case 'jsonb':
|
|
297
|
+
return typeof value === 'string' ? value : JSON.stringify(value);
|
|
298
|
+
default:
|
|
299
|
+
return value;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
288
303
|
get _operatorMap() {
|
|
289
304
|
return {
|
|
290
305
|
'$or': 'or',
|
|
@@ -381,11 +396,11 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
381
396
|
}
|
|
382
397
|
|
|
383
398
|
if (!Array.isArray(condition[key])) {
|
|
384
|
-
this._queryParameters.push(condition[key]);
|
|
399
|
+
this._queryParameters.push(this._formatParameter(key, condition[key]));
|
|
385
400
|
return this._buildCondition(dbKey, comparer, `$${this._queryParameters.length}`);
|
|
386
401
|
} else {
|
|
387
402
|
const values = condition[key].map((value) => {
|
|
388
|
-
this._queryParameters.push(value);
|
|
403
|
+
this._queryParameters.push(this._formatParameter(key, value));
|
|
389
404
|
return `$${this._queryParameters.length}`;
|
|
390
405
|
});
|
|
391
406
|
return this._buildCondition(dbKey, comparer, `any(array[${values.join(',')}])`);
|
|
@@ -465,7 +480,7 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
465
480
|
} else if (/^:/.test(value)) {
|
|
466
481
|
value = value.substring(1);
|
|
467
482
|
} else {
|
|
468
|
-
this._queryParameters.push(value);
|
|
483
|
+
this._queryParameters.push(this._formatParameter(key, value));
|
|
469
484
|
value = `$${this._queryParameters.length}`;
|
|
470
485
|
}
|
|
471
486
|
return `${this._dbCase(key, true)} = ${value}`;
|
|
@@ -477,8 +492,8 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
477
492
|
}
|
|
478
493
|
|
|
479
494
|
_buildInsertValues() {
|
|
480
|
-
return this._insertValues.map((value) => {
|
|
481
|
-
this._queryParameters.push(value);
|
|
495
|
+
return this._insertValues.map((value, idx) => {
|
|
496
|
+
this._queryParameters.push(this._formatParameter(this._insertKeys[idx], value));
|
|
482
497
|
return `$${this._queryParameters.length}`;
|
|
483
498
|
}).join(', ');
|
|
484
499
|
}
|
|
@@ -564,8 +579,41 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
564
579
|
|
|
565
580
|
}
|
|
566
581
|
|
|
582
|
+
async _resolveTableInformation() {
|
|
583
|
+
await tableInformationQueue.add(async () => {
|
|
584
|
+
|
|
585
|
+
const tables = [this._table]
|
|
586
|
+
.concat(this._joins.map((join) => join.table))
|
|
587
|
+
.filter((table) => !Object.keys(tableInformation).includes(table));
|
|
588
|
+
|
|
589
|
+
await Promise.all(tables.map(async (table) => {
|
|
590
|
+
const rows = await this._connection.exec(`SELECT column_name, data_type FROM information_schema.columns WHERE table_name = '${table}';`, [], { format: 'raw' });
|
|
591
|
+
Object.assign(tableInformation, Object.fromEntries([[table, Object.fromEntries(rows.map((row) => {
|
|
592
|
+
return [row.column_name, row.data_type];
|
|
593
|
+
}))]]));
|
|
594
|
+
}));
|
|
595
|
+
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
|
|
567
599
|
async _exec() {
|
|
568
|
-
|
|
600
|
+
|
|
601
|
+
await this._resolveTableInformation();
|
|
602
|
+
|
|
603
|
+
const [query, parameters] = this._build();
|
|
604
|
+
|
|
605
|
+
let rows = await this._connection.exec(
|
|
606
|
+
query,
|
|
607
|
+
parameters,
|
|
608
|
+
{
|
|
609
|
+
first: this._first,
|
|
610
|
+
transaction: this._transaction
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
if (['null', 'undefined'].includes(typeof rows)) {
|
|
614
|
+
rows = this._defaultResult;
|
|
615
|
+
}
|
|
616
|
+
|
|
569
617
|
if (this._paginated && !this._first) {
|
|
570
618
|
let total;
|
|
571
619
|
if (rows.length == 0) {
|
|
@@ -580,7 +628,9 @@ module.exports = exports = class QueryBuilder extends CustomPromise {
|
|
|
580
628
|
rows.forEach((item) => delete item.total);
|
|
581
629
|
return { total, items: rows };
|
|
582
630
|
}
|
|
631
|
+
|
|
583
632
|
return rows;
|
|
633
|
+
|
|
584
634
|
}
|
|
585
635
|
|
|
586
636
|
then(resolve, reject) {
|