@trenskow/pged 4.1.0 → 4.1.3

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 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, async (queryBuilder) => {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trenskow/pged",
3
- "version": "4.1.0",
3
+ "version": "4.1.3",
4
4
  "description": "Just a silly little db management and query builder for PostgreSQL.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,9 +22,9 @@
22
22
  },
23
23
  "homepage": "https://github.com/trenskow/pged#readme",
24
24
  "dependencies": {
25
- "@trenskow/caseit": "^1.1.0",
25
+ "@trenskow/caseit": "^1.1.4",
26
26
  "@trenskow/custom-promise": "^0.10.1",
27
- "pg": "^8.7.1",
28
- "puqeue": "^1.0.5"
27
+ "pg": "^8.7.3",
28
+ "puqeue": "^1.0.6"
29
29
  }
30
30
  }
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 = {}, executor) {
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._executor = executor;
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
- const rows = await this._executor(this);
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) {