pqb 0.52.3 → 0.53.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/dist/index.mjs CHANGED
@@ -2,6 +2,7 @@ import { ExpressionTypeMethod, Expression, RawSQLBase, emptyObject, isTemplateLi
2
2
  import pg from 'pg';
3
3
  import { inspect } from 'node:util';
4
4
  import { AsyncLocalStorage } from 'node:async_hooks';
5
+ import { templateLiteralToSQL as templateLiteralToSQL$1 } from 'pqb';
5
6
 
6
7
  const used = [];
7
8
  const literalValues = [];
@@ -2750,7 +2751,7 @@ const _joinLateralProcessArg = (q, arg, cb) => {
2750
2751
  } else {
2751
2752
  const w = q.q.withShapes?.[arg];
2752
2753
  if (w) {
2753
- const t = Object.create(q.queryBuilder);
2754
+ const t = Object.create(q.qb);
2754
2755
  t.table = arg;
2755
2756
  t.shape = w.shape;
2756
2757
  t.computeds = w.computeds;
@@ -3879,7 +3880,7 @@ function queryFrom(self, arg) {
3879
3880
  if (typeof arg === "string") {
3880
3881
  data.as || (data.as = arg);
3881
3882
  const w = data.withShapes?.[arg];
3882
- data.shape = w?.shape ?? emptyObject;
3883
+ data.shape = w?.shape ?? anyShape;
3883
3884
  data.computeds = w?.computeds;
3884
3885
  } else if (isExpression(arg)) {
3885
3886
  data.as || (data.as = "t");
@@ -4662,17 +4663,19 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
4662
4663
  let values = query.values;
4663
4664
  if (quotedColumns.length === 0) {
4664
4665
  const key = Object.keys(q.shape)[0];
4665
- const column = q.shape[key];
4666
- quotedColumns[0] = `"${column?.data.name || key}"`;
4667
- if (Array.isArray(values) && Array.isArray(values[0])) {
4668
- values = values.map(() => [void 0]);
4666
+ if (key) {
4667
+ const column = q.shape[key];
4668
+ quotedColumns[0] = `"${column?.data.name || key}"`;
4669
+ if (Array.isArray(values) && Array.isArray(values[0])) {
4670
+ values = values.map(() => [void 0]);
4671
+ }
4669
4672
  }
4670
4673
  }
4671
4674
  ctx.sql.push(
4672
- `INSERT INTO ${quotedAs}(${quotedColumns.join(", ")})`,
4675
+ `INSERT INTO ${quotedAs}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`,
4673
4676
  null
4674
4677
  );
4675
- const QueryClass = ctx.queryBuilder.constructor;
4678
+ const QueryClass = ctx.qb.constructor;
4676
4679
  if (query.onConflict) {
4677
4680
  ctx.sql.push("ON CONFLICT");
4678
4681
  const { target } = query.onConflict;
@@ -5478,7 +5481,10 @@ const getTsVector = (ctx, data, lang, source, quotedAs) => {
5478
5481
  };
5479
5482
 
5480
5483
  const pushUpdateSql = (ctx, table, query, quotedAs) => {
5481
- const quotedTable = quoteSchemaAndTable(query.schema, table.table);
5484
+ const quotedTable = quoteSchemaAndTable(
5485
+ query.schema,
5486
+ table.table || query.from
5487
+ );
5482
5488
  const set = [];
5483
5489
  processData(ctx, table, set, query.updateData, quotedAs);
5484
5490
  if (!set.length) {
@@ -5522,7 +5528,7 @@ const pushUpdateReturning = (ctx, table, query, quotedAs, keyword) => {
5522
5528
  };
5523
5529
  const processData = (ctx, table, set, data, quotedAs) => {
5524
5530
  let append;
5525
- const QueryClass = ctx.queryBuilder.constructor;
5531
+ const QueryClass = ctx.qb.constructor;
5526
5532
  for (const item of data) {
5527
5533
  if (typeof item === "function") {
5528
5534
  const result = item(data);
@@ -5568,7 +5574,7 @@ const processValue = (ctx, table, QueryClass, key, value, quotedAs) => {
5568
5574
  };
5569
5575
 
5570
5576
  const pushDeleteSql = (ctx, table, query, quotedAs) => {
5571
- const from = `"${table.table}"`;
5577
+ const from = `"${table.table || query.from}"`;
5572
5578
  ctx.sql.push(`DELETE FROM ${from}`);
5573
5579
  if (from !== quotedAs) {
5574
5580
  ctx.sql.push(quotedAs);
@@ -5676,7 +5682,7 @@ const toSQL = (table, options) => {
5676
5682
  const sql = [];
5677
5683
  const values = options?.values || [];
5678
5684
  const ctx = {
5679
- queryBuilder: table.queryBuilder,
5685
+ qb: table.qb,
5680
5686
  q: query,
5681
5687
  sql,
5682
5688
  values,
@@ -5996,7 +6002,7 @@ const processWhere = (ands, ctx, table, query, data, quotedAs) => {
5996
6002
  throw new Error(`Unknown column ${key} provided to condition`);
5997
6003
  }
5998
6004
  }
5999
- if (value instanceof ctx.queryBuilder.constructor) {
6005
+ if (value instanceof ctx.qb.constructor) {
6000
6006
  ands.push(
6001
6007
  `${quotedColumn} = (${getSqlText(value.toSQL(ctx))})`
6002
6008
  );
@@ -6297,7 +6303,7 @@ const processJoinArgs = (joinTo, first, args, joinSubQuery, whereExists) => {
6297
6303
  if (!w) {
6298
6304
  throw new Error("Cannot find a `with` statement");
6299
6305
  }
6300
- const j = joinTo.queryBuilder.baseQuery.clone();
6306
+ const j = joinTo.qb.baseQuery.clone();
6301
6307
  j.table = first;
6302
6308
  j.q = {
6303
6309
  shape: w.shape,
@@ -7486,6 +7492,7 @@ class VirtualColumn extends ColumnType {
7486
7492
  this.dataType = "";
7487
7493
  this.operators = Operators.any;
7488
7494
  this.data.explicitSelect = true;
7495
+ this.data.insertable = this.data.updatable = false;
7489
7496
  }
7490
7497
  toCode() {
7491
7498
  throw new Error(`toCode is not implemented for virtual column`);
@@ -7497,6 +7504,7 @@ const _UnknownColumn = class _UnknownColumn extends VirtualColumn {
7497
7504
  super(schema, schema.unknown());
7498
7505
  this.selectable = true;
7499
7506
  this.data.explicitSelect = void 0;
7507
+ this.data.insertable = this.data.updatable = true;
7500
7508
  }
7501
7509
  };
7502
7510
  _UnknownColumn.instance = new _UnknownColumn(defaultSchemaConfig);
@@ -7564,6 +7572,12 @@ const makeColumnsByType = (schema) => {
7564
7572
  };
7565
7573
  };
7566
7574
 
7575
+ const anyShape = new Proxy(emptyObject, {
7576
+ get() {
7577
+ return UnknownColumn.instance;
7578
+ }
7579
+ });
7580
+
7567
7581
  const { types } = pg;
7568
7582
  const defaultTypeParsers = {};
7569
7583
  for (const key in types.builtins) {
@@ -8424,14 +8438,7 @@ const createSelect = (q) => {
8424
8438
  const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
8425
8439
  const { shape } = q.q;
8426
8440
  for (const key in item) {
8427
- if (shape[key] instanceof VirtualColumn) {
8428
- shape[key].create?.(
8429
- q,
8430
- ctx,
8431
- item,
8432
- rowIndex
8433
- );
8434
- } else {
8441
+ if (shape[key]?.data.insertable !== false) {
8435
8442
  if (typeof item[key] === "function") {
8436
8443
  item[key] = resolveSubQueryCallbackV2(
8437
8444
  q,
@@ -8442,6 +8449,13 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
8442
8449
  ctx.columns.set(key, ctx.columns.size);
8443
8450
  encoders[key] = shape[key]?.data.encode;
8444
8451
  }
8452
+ } else if (shape[key] instanceof VirtualColumn) {
8453
+ shape[key].create?.(
8454
+ q,
8455
+ ctx,
8456
+ item,
8457
+ rowIndex
8458
+ );
8445
8459
  }
8446
8460
  }
8447
8461
  };
@@ -8654,7 +8668,7 @@ class Create {
8654
8668
  * `create` and `insert` can be used in {@link WithMethods.with} expressions:
8655
8669
  *
8656
8670
  * ```ts
8657
- * db.$queryBuilder
8671
+ * db.$qb
8658
8672
  * // create a record in one table
8659
8673
  * .with('a', db.table.select('id').create(data))
8660
8674
  * // create a record in other table using the first table record id
@@ -9193,7 +9207,7 @@ class Delete {
9193
9207
  * `delete` can be used in {@link WithMethods.with} expressions:
9194
9208
  *
9195
9209
  * ```ts
9196
- * db.$queryBuilder
9210
+ * db.$qb
9197
9211
  * // delete a record in one table
9198
9212
  * .with('a', db.table.find(1).select('id').delete())
9199
9213
  * // delete a record in other table using the first table record id
@@ -10601,7 +10615,7 @@ class WithMethods {
10601
10615
  let [options, queryArg] = third ? [second, third] : [void 0, second];
10602
10616
  let query;
10603
10617
  if (typeof queryArg === "function") {
10604
- const arg = q.queryBuilder.clone();
10618
+ const arg = q.qb.clone();
10605
10619
  arg.q.withShapes = q.q.withShapes;
10606
10620
  query = queryArg(arg);
10607
10621
  } else {
@@ -10628,7 +10642,7 @@ class WithMethods {
10628
10642
  var _a;
10629
10643
  const q = _clone(this);
10630
10644
  let [options, baseFn, recursiveFn] = args.length === 2 ? [{}, args[0], args[1]] : args;
10631
- const arg = q.queryBuilder.clone();
10645
+ const arg = q.qb.clone();
10632
10646
  arg.q.withShapes = q.q.withShapes;
10633
10647
  let query = typeof baseFn === "function" ? baseFn(arg) : baseFn;
10634
10648
  const shape = getShapeFromSelect(query, true);
@@ -10909,7 +10923,7 @@ class Update {
10909
10923
  * `update` can be used in {@link WithMethods.with} expressions:
10910
10924
  *
10911
10925
  * ```ts
10912
- * db.$queryBuilder
10926
+ * db.$qb
10913
10927
  * // update record in one table
10914
10928
  * .with('a', db.table.find(1).select('id').update(data))
10915
10929
  * // update record in other table using the first table record id
@@ -11371,12 +11385,12 @@ function orCreate(query, data, updateData, mergeData) {
11371
11385
  q2.q.inCTE = inCTE;
11372
11386
  const c = q2.create(data);
11373
11387
  c.q.select = q2.q.select;
11374
- let q22 = q2.queryBuilder.with("f", q2).with("c", c);
11388
+ let q22 = q2.qb.with("f", q2).with("c", c);
11375
11389
  q22.q.returnsOne = true;
11376
11390
  queryFrom(q22, "f");
11377
11391
  q22 = _queryUnion(
11378
11392
  q22,
11379
- [q2.queryBuilder.from("c")],
11393
+ [q2.qb.from("c")],
11380
11394
  "UNION ALL",
11381
11395
  true,
11382
11396
  true
@@ -12811,12 +12825,49 @@ const parseIndexOrExclude = (item) => {
12811
12825
  return item;
12812
12826
  };
12813
12827
 
12814
- const anyShape = {};
12828
+ const performQuery = async (q, args, method) => {
12829
+ const trx = q.internal.transactionStorage.getStore();
12830
+ let sql;
12831
+ if (isRawSQL(args[0])) {
12832
+ const values = [];
12833
+ sql = {
12834
+ text: args[0].toSQL({ values }),
12835
+ values
12836
+ };
12837
+ } else {
12838
+ const values = [];
12839
+ sql = {
12840
+ text: templateLiteralToSQL$1(args, {
12841
+ qb: q.qb,
12842
+ q: q.q,
12843
+ sql: [],
12844
+ values
12845
+ }),
12846
+ values
12847
+ };
12848
+ }
12849
+ const log = trx?.log ?? q.q.log;
12850
+ let logData;
12851
+ if (log) logData = log.beforeQuery(sql);
12852
+ try {
12853
+ const result = await (trx?.adapter || q.adapter)[method](
12854
+ sql
12855
+ );
12856
+ if (log) log.afterQuery(sql, logData);
12857
+ return result;
12858
+ } catch (err) {
12859
+ if (log) {
12860
+ log.onError(err, sql, logData);
12861
+ }
12862
+ throw err;
12863
+ }
12864
+ };
12865
+
12815
12866
  class Db extends QueryMethods {
12816
- constructor(adapter, queryBuilder, table = void 0, shape = anyShape, columnTypes, transactionStorage, options, tableData = {}) {
12867
+ constructor(adapter, qb, table = void 0, shape = anyShape, columnTypes, transactionStorage, options, tableData = {}) {
12817
12868
  super();
12818
12869
  this.adapter = adapter;
12819
- this.queryBuilder = queryBuilder;
12870
+ this.qb = qb;
12820
12871
  this.table = table;
12821
12872
  this.shape = shape;
12822
12873
  this.columnTypes = columnTypes;
@@ -12993,11 +13044,54 @@ class Db extends QueryMethods {
12993
13044
  *
12994
13045
  * @param args - SQL template literal, or an object { raw: string, values?: unknown[] }
12995
13046
  */
12996
- query(...args) {
12997
- return performQuery(this, args, "query");
13047
+ get query() {
13048
+ const q = this;
13049
+ let query = q._query;
13050
+ if (!query) {
13051
+ q._query = query = Object.assign(
13052
+ (...args) => performQuery(q, args, "query"),
13053
+ {
13054
+ async records(...args) {
13055
+ const { rows } = await performQuery(q, args, "query");
13056
+ return rows;
13057
+ },
13058
+ async take(...args) {
13059
+ const {
13060
+ rows: [row]
13061
+ } = await performQuery(q, args, "query");
13062
+ if (!row) throw new NotFoundError(q);
13063
+ return row;
13064
+ },
13065
+ async takeOptional(...args) {
13066
+ const { rows } = await performQuery(q, args, "query");
13067
+ return rows[0];
13068
+ },
13069
+ async rows(...args) {
13070
+ const { rows } = await performQuery(q, args, "arrays");
13071
+ return rows;
13072
+ },
13073
+ async pluck(...args) {
13074
+ const { rows } = await performQuery(q, args, "arrays");
13075
+ return rows.map((row) => row[0]);
13076
+ },
13077
+ async get(...args) {
13078
+ const {
13079
+ rows: [row]
13080
+ } = await performQuery(q, args, "arrays");
13081
+ if (!row) throw new NotFoundError(q);
13082
+ return row[0];
13083
+ },
13084
+ async getOptional(...args) {
13085
+ const { rows } = await performQuery(q, args, "arrays");
13086
+ return rows[0]?.[0];
13087
+ }
13088
+ }
13089
+ );
13090
+ }
13091
+ return query;
12998
13092
  }
12999
13093
  /**
13000
- * The same as the {@link query}, but returns an array of arrays instead of objects:
13094
+ * Performs a SQL query, returns a db result with array of arrays instead of objects:
13001
13095
  *
13002
13096
  * ```ts
13003
13097
  * const value = 1;
@@ -13032,43 +13126,6 @@ class Db extends QueryMethods {
13032
13126
  return map.get(name);
13033
13127
  }
13034
13128
  }
13035
- const performQuery = async (q, args, method) => {
13036
- const trx = q.internal.transactionStorage.getStore();
13037
- let sql;
13038
- if (isRawSQL(args[0])) {
13039
- const values = [];
13040
- sql = {
13041
- text: args[0].toSQL({ values }),
13042
- values
13043
- };
13044
- } else {
13045
- const values = [];
13046
- sql = {
13047
- text: templateLiteralToSQL(args, {
13048
- queryBuilder: q.queryBuilder,
13049
- q: q.q,
13050
- sql: [],
13051
- values
13052
- }),
13053
- values
13054
- };
13055
- }
13056
- const log = trx?.log ?? q.q.log;
13057
- let logData;
13058
- if (log) logData = log.beforeQuery(sql);
13059
- try {
13060
- const result = await (trx?.adapter || q.adapter)[method](
13061
- sql
13062
- );
13063
- if (log) log.afterQuery(sql, logData);
13064
- return result;
13065
- } catch (err) {
13066
- if (log) {
13067
- log.onError(err, sql, logData);
13068
- }
13069
- throw err;
13070
- }
13071
- };
13072
13129
  applyMixins(Db, [QueryMethods]);
13073
13130
  Db.prototype.constructor = Db;
13074
13131
  const createDb = ({
@@ -13117,9 +13174,7 @@ const createDb = ({
13117
13174
  adapter,
13118
13175
  close: () => adapter.close()
13119
13176
  });
13120
- for (const name of Object.getOwnPropertyNames(Db.prototype)) {
13121
- db[name] = Db.prototype[name];
13122
- }
13177
+ Object.setPrototypeOf(db, Db.prototype);
13123
13178
  db.sql = (...args) => {
13124
13179
  const sql = raw(...args);
13125
13180
  sql.columnTypes = ct;
@@ -13152,13 +13207,13 @@ const _initQueryBuilder = (adapter, columnTypes, transactionStorage, commonOptio
13152
13207
  }
13153
13208
  qb.internal.domains = options.domains;
13154
13209
  qb.internal.generatorIgnore = options.generatorIgnore;
13155
- return qb.queryBuilder = qb;
13210
+ return qb.qb = qb;
13156
13211
  };
13157
13212
 
13158
13213
  class Rollback extends Error {
13159
13214
  }
13160
13215
  const trxForTest = Symbol("trxForTest");
13161
- const argToDb = (arg) => "$queryBuilder" in arg ? arg.$queryBuilder : arg;
13216
+ const argToDb = (arg) => "$qb" in arg ? arg.$qb : arg;
13162
13217
  const testTransaction = {
13163
13218
  /**
13164
13219
  * Start a test transaction.