pqb 0.54.0 → 0.54.2

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.js CHANGED
@@ -432,7 +432,7 @@ class ColumnType extends orchidCore.ColumnTypeBase {
432
432
  return sql2;
433
433
  }
434
434
  });
435
- column.data.readonly = true;
435
+ column.data.readOnly = true;
436
436
  return column;
437
437
  }
438
438
  }
@@ -2158,7 +2158,7 @@ class TsVectorColumn extends ColumnType {
2158
2158
  toSQL,
2159
2159
  toCode
2160
2160
  });
2161
- column.data.readonly = true;
2161
+ column.data.readOnly = true;
2162
2162
  return column;
2163
2163
  }
2164
2164
  }
@@ -2458,8 +2458,7 @@ class VirtualColumn extends ColumnType {
2458
2458
  super(schema, inputSchema);
2459
2459
  this.dataType = "";
2460
2460
  this.operators = Operators.any;
2461
- this.data.explicitSelect = true;
2462
- this.data.insertable = this.data.updatable = false;
2461
+ this.data.explicitSelect = this.data.appReadOnly = this.data.virtual = true;
2463
2462
  }
2464
2463
  toCode() {
2465
2464
  throw new Error(`toCode is not implemented for virtual column`);
@@ -2470,8 +2469,7 @@ const _UnknownColumn = class _UnknownColumn extends VirtualColumn {
2470
2469
  constructor(schema) {
2471
2470
  super(schema, schema.unknown());
2472
2471
  this.selectable = true;
2473
- this.data.explicitSelect = void 0;
2474
- this.data.insertable = this.data.updatable = true;
2472
+ this.data.explicitSelect = this.data.appReadOnly = this.data.virtual = void 0;
2475
2473
  }
2476
2474
  };
2477
2475
  _UnknownColumn.instance = new _UnknownColumn(defaultSchemaConfig);
@@ -2730,8 +2728,9 @@ class NotFoundError extends OrchidOrmError {
2730
2728
  }
2731
2729
  _query = new WeakMap();
2732
2730
  class OrchidOrmInternalError extends Error {
2733
- constructor(query, message) {
2731
+ constructor(query, message, data) {
2734
2732
  super(message);
2733
+ this.data = data;
2735
2734
  // `#query` is private to prevent it from serializing to not cause problems to test runner reports
2736
2735
  __privateAdd(this, _query2);
2737
2736
  __privateSet(this, _query2, query);
@@ -3380,8 +3379,8 @@ const noneMethods = {
3380
3379
  const _queryNone = (q) => {
3381
3380
  if (isQueryNone(q)) return q;
3382
3381
  q = extendQuery(q, noneMethods);
3383
- pushQueryValueImmutable(q, "and", new RawSQL("false"));
3384
- pushQueryValueImmutable(
3382
+ orchidCore.pushQueryValueImmutable(q, "and", new RawSQL("false"));
3383
+ orchidCore.pushQueryValueImmutable(
3385
3384
  q,
3386
3385
  "transform",
3387
3386
  (_, queryData) => noneResult(q, queryData, queryData.returnType)
@@ -3405,11 +3404,7 @@ const resolveCallbacksInArgs = (q, args) => {
3405
3404
  };
3406
3405
  const _queryWhere = (q, args) => {
3407
3406
  resolveCallbacksInArgs(q, args);
3408
- return pushQueryArrayImmutable(
3409
- q,
3410
- "and",
3411
- args
3412
- );
3407
+ return pushQueryArrayImmutable(q, "and", args);
3413
3408
  };
3414
3409
  const _queryFindBy = (q, args) => {
3415
3410
  return _queryTake(_queryWhere(q, args));
@@ -3418,7 +3413,7 @@ const _queryFindByOptional = (q, args) => {
3418
3413
  return _queryTakeOptional(_queryWhere(q, args));
3419
3414
  };
3420
3415
  const _queryWhereSql = (q, args) => {
3421
- return pushQueryValueImmutable(
3416
+ return orchidCore.pushQueryValueImmutable(
3422
3417
  q,
3423
3418
  "and",
3424
3419
  sqlQueryArgsToExpression(args)
@@ -3426,24 +3421,24 @@ const _queryWhereSql = (q, args) => {
3426
3421
  };
3427
3422
  const _queryWhereNot = (q, args) => {
3428
3423
  resolveCallbacksInArgs(q, args);
3429
- return pushQueryValueImmutable(q, "and", {
3424
+ return orchidCore.pushQueryValueImmutable(q, "and", {
3430
3425
  NOT: args
3431
3426
  });
3432
3427
  };
3433
3428
  const _queryWhereNotSql = (q, args) => {
3434
- return pushQueryValueImmutable(q, "and", {
3429
+ return orchidCore.pushQueryValueImmutable(q, "and", {
3435
3430
  NOT: sqlQueryArgsToExpression(args)
3436
3431
  });
3437
3432
  };
3438
3433
  const _queryWhereOneOf = (q, args) => {
3439
3434
  resolveCallbacksInArgs(q, args);
3440
- return pushQueryValueImmutable(q, "and", {
3435
+ return orchidCore.pushQueryValueImmutable(q, "and", {
3441
3436
  OR: args
3442
3437
  });
3443
3438
  };
3444
3439
  const _queryWhereNotOneOf = (q, args) => {
3445
3440
  resolveCallbacksInArgs(q, args);
3446
- return pushQueryValueImmutable(q, "and", {
3441
+ return orchidCore.pushQueryValueImmutable(q, "and", {
3447
3442
  NOT: { OR: args }
3448
3443
  });
3449
3444
  };
@@ -3493,9 +3488,9 @@ const _queryWhereIn = (q, and, arg, values, not) => {
3493
3488
  }
3494
3489
  if (not) item = { NOT: item };
3495
3490
  if (and) {
3496
- pushQueryValueImmutable(q, "and", item);
3491
+ orchidCore.pushQueryValueImmutable(q, "and", item);
3497
3492
  } else {
3498
- pushQueryValueImmutable(q, "or", [item]);
3493
+ orchidCore.pushQueryValueImmutable(q, "or", [item]);
3499
3494
  }
3500
3495
  return q;
3501
3496
  };
@@ -4299,10 +4294,6 @@ const pushQueryArrayImmutable = (q, key, value) => {
4299
4294
  q.q[key] = arr ? [...arr, ...value] : value;
4300
4295
  return q;
4301
4296
  };
4302
- const pushQueryValueImmutable = (q, key, value) => {
4303
- orchidCore.pushOrNewArrayToObjectImmutable(q.q, key, value);
4304
- return q;
4305
- };
4306
4297
  const setQueryObjectValueImmutable = (q, object, key, value) => {
4307
4298
  q.q[object] = {
4308
4299
  ...q.q[object],
@@ -4518,7 +4509,7 @@ const _join = (query, require, type, first, args) => {
4518
4509
  computeds
4519
4510
  );
4520
4511
  }
4521
- pushQueryValueImmutable(query, "join", {
4512
+ orchidCore.pushQueryValueImmutable(query, "join", {
4522
4513
  type,
4523
4514
  args: joinArgs
4524
4515
  });
@@ -4595,7 +4586,7 @@ const _joinLateral = (self, type, arg, as, innerJoinLateral) => {
4595
4586
  }
4596
4587
  as || (as = getQueryAs(arg));
4597
4588
  orchidCore.setObjectValueImmutable(q.q, "joinedComputeds", as, arg.q.computeds);
4598
- pushQueryValueImmutable(q, "join", {
4589
+ orchidCore.pushQueryValueImmutable(q, "join", {
4599
4590
  type: `${type} LATERAL`,
4600
4591
  args: { l: arg, a: as, i: innerJoinLateral }
4601
4592
  });
@@ -4986,7 +4977,7 @@ const applyComputedColumns = (q, fn) => {
4986
4977
  const { data } = col;
4987
4978
  data.computed = item;
4988
4979
  data.explicitSelect = true;
4989
- data.readonly = true;
4980
+ data.readOnly = true;
4990
4981
  addColumnParserToQuery(
4991
4982
  q.q,
4992
4983
  key,
@@ -5800,7 +5791,7 @@ const addParserForSelectItem = (q, as, key, arg, columnAlias, joinQuery) => {
5800
5791
  );
5801
5792
  }
5802
5793
  if (query.hookSelect || query.parsers || query.transform) {
5803
- pushQueryValueImmutable(q, "batchParsers", {
5794
+ orchidCore.pushQueryValueImmutable(q, "batchParsers", {
5804
5795
  path: [key],
5805
5796
  fn: (path, queryResult) => {
5806
5797
  const { rows } = queryResult;
@@ -6240,6 +6231,8 @@ function _querySelect(q, args) {
6240
6231
  q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
6241
6232
  } else if (returnType === "value") {
6242
6233
  q.q.returnType = q.q.returningMany ? "all" : "one";
6234
+ } else if (returnType === "void") {
6235
+ q.q.returnType = q.q.returningMany ? "all" : "oneOrThrow";
6243
6236
  }
6244
6237
  const len = args.length;
6245
6238
  if (!len) {
@@ -6429,7 +6422,22 @@ const pushWithSql = (ctx, items) => {
6429
6422
  };
6430
6423
 
6431
6424
  const makeInsertSql = (ctx, q, query, quotedAs) => {
6432
- const { columns, shape, inCTE } = query;
6425
+ let { columns } = query;
6426
+ const { shape, inCTE, hookCreateSet } = query;
6427
+ const QueryClass = ctx.qb.constructor;
6428
+ let values = query.values;
6429
+ let hookSetSql;
6430
+ if (hookCreateSet) {
6431
+ ({ hookSetSql, columns, values } = processHookSet(
6432
+ ctx,
6433
+ q,
6434
+ values,
6435
+ hookCreateSet,
6436
+ columns,
6437
+ QueryClass,
6438
+ quotedAs
6439
+ ));
6440
+ }
6433
6441
  const quotedColumns = columns.map(
6434
6442
  (column) => `"${shape[column]?.data.name || column}"`
6435
6443
  );
@@ -6444,7 +6452,6 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6444
6452
  }
6445
6453
  }
6446
6454
  }
6447
- let values = query.values;
6448
6455
  if (quotedColumns.length === 0) {
6449
6456
  const key = Object.keys(q.shape)[0];
6450
6457
  if (key) {
@@ -6456,12 +6463,11 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6456
6463
  }
6457
6464
  }
6458
6465
  const insertSql = `INSERT INTO ${quotedAs}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`;
6459
- if (query.kind !== "object" && query.insertWith) {
6466
+ if ("from" in values && query.insertWith) {
6460
6467
  pushWithSql(ctx, Object.values(query.insertWith).flat());
6461
6468
  }
6462
6469
  const valuesPos = ctx.sql.length + 1;
6463
6470
  ctx.sql.push(insertSql, null);
6464
- const QueryClass = ctx.qb.constructor;
6465
6471
  if (query.onConflict) {
6466
6472
  ctx.sql.push("ON CONFLICT");
6467
6473
  const { target } = query.onConflict;
@@ -6525,7 +6531,28 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6525
6531
  returning = makeReturningSql(ctx, q, query, quotedAs, 2);
6526
6532
  }
6527
6533
  if (returning.select) ctx.sql.push("RETURNING", returning.select);
6528
- if (query.kind === "object") {
6534
+ if ("from" in values) {
6535
+ const { from, values: v } = values;
6536
+ const q2 = from.clone();
6537
+ if (v) {
6538
+ orchidCore.pushQueryValueImmutable(
6539
+ q2,
6540
+ "select",
6541
+ new RawSQL(
6542
+ encodeRow(
6543
+ ctx,
6544
+ ctx.values,
6545
+ q2,
6546
+ QueryClass,
6547
+ v,
6548
+ runtimeDefaults,
6549
+ quotedAs
6550
+ )
6551
+ )
6552
+ );
6553
+ }
6554
+ ctx.sql[valuesPos] = getSqlText(toSQL(q2, { values: ctx.values }));
6555
+ } else {
6529
6556
  const valuesSql = [];
6530
6557
  let ctxValues = ctx.values;
6531
6558
  const restValuesLen = ctxValues.length;
@@ -6546,7 +6573,8 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6546
6573
  QueryClass,
6547
6574
  values[i],
6548
6575
  runtimeDefaults,
6549
- quotedAs
6576
+ quotedAs,
6577
+ hookSetSql
6550
6578
  );
6551
6579
  if (!inCTE) encodedRow = "(" + encodedRow + ")";
6552
6580
  if (ctxValues.length > MAX_BINDING_PARAMS) {
@@ -6595,32 +6623,127 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
6595
6623
  if (inCTE) {
6596
6624
  ctx.sql[valuesPos] += ' WHERE NOT EXISTS (SELECT 1 FROM "f")';
6597
6625
  }
6598
- } else {
6599
- const { from, values: v } = values;
6600
- const q2 = from.clone();
6601
- if (v) {
6602
- pushQueryValueImmutable(
6603
- q2,
6604
- "select",
6605
- new RawSQL(
6606
- encodeRow(
6626
+ }
6627
+ return {
6628
+ hookSelect: returning.hookSelect,
6629
+ text: ctx.sql.join(" "),
6630
+ values: ctx.values
6631
+ };
6632
+ };
6633
+ const processHookSet = (ctx, q, values, hookCreateSet, columns, QueryClass, quotedAs) => {
6634
+ const hookSet = {};
6635
+ for (const item of hookCreateSet) {
6636
+ Object.assign(hookSet, item);
6637
+ }
6638
+ const addHookSetColumns = Object.keys(hookSet).filter(
6639
+ (key) => !columns.includes(key)
6640
+ );
6641
+ if ("from" in values) {
6642
+ const v = { ...values };
6643
+ const newColumns = [];
6644
+ const originalSelect = v.from.q.select;
6645
+ if (originalSelect) {
6646
+ v.from = _clone(v.from);
6647
+ const select = [];
6648
+ for (const s of originalSelect) {
6649
+ if (typeof s === "string" && !hookSet[s]) {
6650
+ select.push(s);
6651
+ newColumns.push(s);
6652
+ } else if (typeof s === "object" && "selectAs" in s) {
6653
+ const filtered = {};
6654
+ for (const key in s.selectAs) {
6655
+ if (!hookSet[key]) {
6656
+ filtered[key] = s.selectAs[key];
6657
+ newColumns.push(key);
6658
+ }
6659
+ }
6660
+ select.push({ selectAs: filtered });
6661
+ }
6662
+ }
6663
+ v.from.q.select = select;
6664
+ }
6665
+ let row;
6666
+ if (v.values) {
6667
+ const originalRow = v.values;
6668
+ const valuesColumns = columns.slice(-originalRow.length);
6669
+ row = [];
6670
+ valuesColumns.forEach((c, i) => {
6671
+ if (!hookSet[c]) {
6672
+ newColumns.push(c);
6673
+ row.push(originalRow[i]);
6674
+ }
6675
+ });
6676
+ } else {
6677
+ row = [];
6678
+ }
6679
+ v.values = row;
6680
+ columns.forEach((column) => {
6681
+ if (column in hookSet) {
6682
+ newColumns.push(column);
6683
+ const fromHook = {
6684
+ fromHook: encodeValue(
6607
6685
  ctx,
6608
6686
  ctx.values,
6609
- q2,
6687
+ q,
6610
6688
  QueryClass,
6611
- v[0],
6612
- runtimeDefaults,
6689
+ hookSet[column],
6613
6690
  quotedAs
6614
6691
  )
6615
- )
6616
- );
6692
+ };
6693
+ row.push(fromHook);
6694
+ }
6695
+ });
6696
+ if (addHookSetColumns) {
6697
+ for (const key of addHookSetColumns) {
6698
+ row.push({
6699
+ fromHook: encodeValue(
6700
+ ctx,
6701
+ ctx.values,
6702
+ q,
6703
+ QueryClass,
6704
+ hookSet[key],
6705
+ quotedAs
6706
+ )
6707
+ });
6708
+ }
6709
+ return {
6710
+ columns: [...newColumns, ...addHookSetColumns],
6711
+ values: v
6712
+ };
6617
6713
  }
6618
- ctx.sql[valuesPos] = getSqlText(toSQL(q2, { values: ctx.values }));
6714
+ return { columns: newColumns, values: v };
6619
6715
  }
6716
+ columns.forEach((column, i) => {
6717
+ if (column in hookSet) {
6718
+ const fromHook = {
6719
+ fromHook: encodeValue(
6720
+ ctx,
6721
+ ctx.values,
6722
+ q,
6723
+ QueryClass,
6724
+ hookSet[column],
6725
+ quotedAs
6726
+ )
6727
+ };
6728
+ for (const row of values) {
6729
+ row[i] = fromHook;
6730
+ }
6731
+ }
6732
+ });
6733
+ const hookSetSql = addHookSetColumns.map(
6734
+ (key) => encodeValue(
6735
+ ctx,
6736
+ ctx.values,
6737
+ q,
6738
+ QueryClass,
6739
+ hookSet[key],
6740
+ quotedAs
6741
+ )
6742
+ ).join(", ");
6620
6743
  return {
6621
- hookSelect: returning.hookSelect,
6622
- text: ctx.sql.join(" "),
6623
- values: ctx.values
6744
+ hookSetSql,
6745
+ columns: addHookSetColumns ? [...columns, ...addHookSetColumns] : columns,
6746
+ values
6624
6747
  };
6625
6748
  };
6626
6749
  const mergeColumnsSql = (columns, quotedColumns, target, except) => {
@@ -6644,24 +6767,30 @@ const mergeColumnsSql = (columns, quotedColumns, target, except) => {
6644
6767
  `DO UPDATE SET ${quotedColumns[0]} = excluded.${quotedColumns[0]}`
6645
6768
  );
6646
6769
  };
6647
- const encodeRow = (ctx, values, q, QueryClass, row, runtimeDefaults, quotedAs) => {
6648
- const arr = row.map((value) => {
6649
- if (value && typeof value === "object") {
6650
- if (value instanceof orchidCore.Expression) {
6651
- return value.toSQL(ctx, quotedAs);
6652
- } else if (value instanceof QueryClass) {
6653
- return `(${getSqlText(joinSubQuery(q, value).toSQL(ctx))})`;
6654
- }
6655
- }
6656
- return value === void 0 ? "DEFAULT" : orchidCore.addValue(values, value);
6657
- });
6770
+ const encodeRow = (ctx, values, q, QueryClass, row, runtimeDefaults, quotedAs, hookSetSql) => {
6771
+ const arr = row.map(
6772
+ (value) => encodeValue(ctx, values, q, QueryClass, value, quotedAs)
6773
+ );
6658
6774
  if (runtimeDefaults) {
6659
6775
  for (const fn of runtimeDefaults) {
6660
6776
  arr.push(orchidCore.addValue(values, fn()));
6661
6777
  }
6662
6778
  }
6779
+ if (hookSetSql) arr.push(hookSetSql);
6663
6780
  return arr.join(", ");
6664
6781
  };
6782
+ const encodeValue = (ctx, values, q, QueryClass, value, quotedAs) => {
6783
+ if (value && typeof value === "object") {
6784
+ if (value instanceof orchidCore.Expression) {
6785
+ return value.toSQL(ctx, quotedAs);
6786
+ } else if (value instanceof QueryClass) {
6787
+ return `(${getSqlText(joinSubQuery(q, value).toSQL(ctx))})`;
6788
+ } else if ("fromHook" in value) {
6789
+ return value.fromHook;
6790
+ }
6791
+ }
6792
+ return value === void 0 ? "DEFAULT" : orchidCore.addValue(values, value);
6793
+ };
6665
6794
  const hookSelectKeys = [
6666
6795
  null,
6667
6796
  "afterUpdateSelect",
@@ -7240,8 +7369,20 @@ const pushUpdateSql = (ctx, table, query, quotedAs) => {
7240
7369
  query.schema,
7241
7370
  table.table || query.from
7242
7371
  );
7372
+ let hookSet;
7373
+ if (query.hookUpdateSet) {
7374
+ hookSet = {};
7375
+ for (const item of query.hookUpdateSet) {
7376
+ Object.assign(hookSet, item);
7377
+ }
7378
+ } else {
7379
+ hookSet = orchidCore.emptyObject;
7380
+ }
7243
7381
  const set = [];
7244
- processData(ctx, table, set, query.updateData, quotedAs);
7382
+ processData(ctx, table, set, query.updateData, hookSet, quotedAs);
7383
+ if (query.hookUpdateSet) {
7384
+ applySet(ctx, table, set, hookSet, orchidCore.emptyObject, quotedAs);
7385
+ }
7245
7386
  if (!set.length) {
7246
7387
  if (!query.select) {
7247
7388
  query.select = countSelect;
@@ -7281,32 +7422,35 @@ const pushUpdateReturning = (ctx, table, query, quotedAs, keyword) => {
7281
7422
  if (s) ctx.sql.push(keyword, s);
7282
7423
  return hookSelect;
7283
7424
  };
7284
- const processData = (ctx, table, set, data, quotedAs) => {
7425
+ const processData = (ctx, table, set, data, hookSet, quotedAs) => {
7285
7426
  let append;
7286
- const QueryClass = ctx.qb.constructor;
7287
7427
  for (const item of data) {
7288
7428
  if (typeof item === "function") {
7289
7429
  const result = item(data);
7290
7430
  if (result) append = orchidCore.pushOrNewArray(append, result);
7291
7431
  } else {
7292
- const shape = table.q.shape;
7293
- for (const key in item) {
7294
- const value = item[key];
7295
- if (value === void 0) continue;
7296
- set.push(
7297
- `"${shape[key].data.name || key}" = ${processValue(
7298
- ctx,
7299
- table,
7300
- QueryClass,
7301
- key,
7302
- value,
7303
- quotedAs
7304
- )}`
7305
- );
7306
- }
7432
+ applySet(ctx, table, set, item, hookSet, quotedAs);
7307
7433
  }
7308
7434
  }
7309
- if (append) processData(ctx, table, set, append, quotedAs);
7435
+ if (append) processData(ctx, table, set, append, hookSet, quotedAs);
7436
+ };
7437
+ const applySet = (ctx, table, set, item, hookSet, quotedAs) => {
7438
+ const QueryClass = ctx.qb.constructor;
7439
+ const shape = table.q.shape;
7440
+ for (const key in item) {
7441
+ const value = item[key];
7442
+ if (value === void 0 || key in hookSet) continue;
7443
+ set.push(
7444
+ `"${shape[key].data.name || key}" = ${processValue(
7445
+ ctx,
7446
+ table,
7447
+ QueryClass,
7448
+ key,
7449
+ value,
7450
+ quotedAs
7451
+ )}`
7452
+ );
7453
+ }
7310
7454
  };
7311
7455
  const processValue = (ctx, table, QueryClass, key, value, quotedAs) => {
7312
7456
  if (value && typeof value === "object") {
@@ -8649,7 +8793,7 @@ class WithMethods {
8649
8793
  withSql(name, ...args) {
8650
8794
  const q = _clone(this);
8651
8795
  const [options, shape, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8652
- pushQueryValueImmutable(q, "with", {
8796
+ orchidCore.pushQueryValueImmutable(q, "with", {
8653
8797
  n: name,
8654
8798
  o: options,
8655
8799
  s: sql(q)
@@ -8672,36 +8816,48 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
8672
8816
  var _a;
8673
8817
  const { shape } = q.q;
8674
8818
  for (const key in item) {
8675
- if (shape[key]?.data.insertable !== false) {
8676
- let value = item[key];
8677
- if (typeof value === "function") {
8678
- value = item[key] = resolveSubQueryCallbackV2(
8679
- q,
8680
- value
8681
- );
8682
- if (value && typeof value === "object" && value instanceof Db) {
8683
- moveQueryValueToWith(
8684
- q,
8685
- (_a = q.q).insertWith ?? (_a.insertWith = {}),
8686
- value,
8687
- item,
8688
- key,
8689
- rowIndex
8690
- );
8691
- }
8692
- }
8693
- if (!ctx.columns.has(key) && (shape[key] && !shape[key].data.readonly || shape === anyShape) && value !== void 0) {
8694
- ctx.columns.set(key, ctx.columns.size);
8695
- encoders[key] = shape[key]?.data.encode;
8696
- }
8697
- } else if (shape[key] instanceof VirtualColumn) {
8698
- shape[key].create?.(
8819
+ const column = shape[key];
8820
+ if (!column) continue;
8821
+ if (column.data.virtual) {
8822
+ column.create?.(
8699
8823
  q,
8700
8824
  ctx,
8701
8825
  item,
8702
8826
  rowIndex
8703
8827
  );
8828
+ continue;
8704
8829
  }
8830
+ throwOnReadOnly$1(q, column, key);
8831
+ let value = item[key];
8832
+ if (typeof value === "function") {
8833
+ value = item[key] = resolveSubQueryCallbackV2(
8834
+ q,
8835
+ value
8836
+ );
8837
+ if (value && typeof value === "object" && value instanceof Db) {
8838
+ moveQueryValueToWith(
8839
+ q,
8840
+ (_a = q.q).insertWith ?? (_a.insertWith = {}),
8841
+ value,
8842
+ item,
8843
+ key,
8844
+ rowIndex
8845
+ );
8846
+ }
8847
+ }
8848
+ if (!ctx.columns.has(key) && (column && !column.data.readOnly || shape === anyShape) && value !== void 0) {
8849
+ ctx.columns.set(key, ctx.columns.size);
8850
+ encoders[key] = column?.data.encode;
8851
+ }
8852
+ }
8853
+ };
8854
+ const throwOnReadOnly$1 = (q, column, key) => {
8855
+ if (column.data.appReadOnly || column.data.readOnly) {
8856
+ throw new OrchidOrmInternalError(
8857
+ q,
8858
+ "Trying to insert a readonly column",
8859
+ { column: key }
8860
+ );
8705
8861
  }
8706
8862
  };
8707
8863
  const createCtx = () => ({
@@ -8747,7 +8903,7 @@ const handleManyData = (q, data, ctx) => {
8747
8903
  const insert = (self, {
8748
8904
  columns,
8749
8905
  values
8750
- }, kind, many) => {
8906
+ }, many) => {
8751
8907
  const { q } = self;
8752
8908
  if (!q.select?.length) {
8753
8909
  q.returning = true;
@@ -8758,7 +8914,6 @@ const insert = (self, {
8758
8914
  q.type = "insert";
8759
8915
  q.columns = columns;
8760
8916
  q.values = values;
8761
- if (!q.kind) q.kind = kind;
8762
8917
  const { select, returnType } = q;
8763
8918
  if (!select) {
8764
8919
  if (returnType !== "void") {
@@ -8778,7 +8933,7 @@ const insert = (self, {
8778
8933
  }
8779
8934
  return self;
8780
8935
  };
8781
- const getFromSelectColumns = (from, obj, many) => {
8936
+ const getFromSelectColumns = (q, from, obj, many) => {
8782
8937
  if (!many && !queryTypeWithLimitOne[from.q.returnType]) {
8783
8938
  throw new Error(
8784
8939
  "Cannot create based on a query which returns multiple records"
@@ -8796,19 +8951,22 @@ const getFromSelectColumns = (from, obj, many) => {
8796
8951
  if (obj?.columns) {
8797
8952
  queryColumns.push(...obj.columns);
8798
8953
  }
8954
+ for (const key of queryColumns) {
8955
+ const column = q.shape[key];
8956
+ if (column) throwOnReadOnly$1(from, column, key);
8957
+ }
8799
8958
  return queryColumns;
8800
8959
  };
8801
8960
  const insertFromQuery = (q, from, many, data) => {
8802
8961
  const ctx = createCtx();
8803
8962
  const obj = data && handleOneData(q, data, ctx);
8804
- const columns = getFromSelectColumns(from, obj, many);
8963
+ const columns = getFromSelectColumns(q, from, obj, many);
8805
8964
  return insert(
8806
8965
  q,
8807
8966
  {
8808
8967
  columns,
8809
- values: { from, values: obj?.values }
8968
+ values: { from, values: obj?.values[0] }
8810
8969
  },
8811
- "from",
8812
8970
  many
8813
8971
  );
8814
8972
  };
@@ -8821,11 +8979,11 @@ const _queryInsert = (q, data) => {
8821
8979
  const obj = handleOneData(q, data, ctx);
8822
8980
  const values = q.q.values;
8823
8981
  if (values && "from" in values) {
8824
- obj.columns = getFromSelectColumns(values.from, obj);
8825
- values.values = obj.values;
8982
+ obj.columns = getFromSelectColumns(q, values.from, obj);
8983
+ values.values = obj.values[0];
8826
8984
  obj.values = values;
8827
8985
  }
8828
- return insert(q, obj, "object");
8986
+ return insert(q, obj);
8829
8987
  };
8830
8988
  const _queryCreateMany = (q, data) => {
8831
8989
  createSelect(q);
@@ -8833,7 +8991,7 @@ const _queryCreateMany = (q, data) => {
8833
8991
  };
8834
8992
  const _queryInsertMany = (q, data) => {
8835
8993
  const ctx = createCtx();
8836
- let result = insert(q, handleManyData(q, data, ctx), "object", true);
8994
+ let result = insert(q, handleManyData(q, data, ctx), true);
8837
8995
  if (!data.length) result = result.none();
8838
8996
  return result;
8839
8997
  };
@@ -8855,7 +9013,7 @@ const _queryDefaults = (q, data) => {
8855
9013
  q.q.defaults = data;
8856
9014
  return q;
8857
9015
  };
8858
- class Create {
9016
+ class QueryCreate {
8859
9017
  /**
8860
9018
  * `create` and `insert` create a single record.
8861
9019
  *
@@ -9259,6 +9417,8 @@ class OnConflictQueryBuilder {
9259
9417
  set(set) {
9260
9418
  let resolved;
9261
9419
  for (const key in set) {
9420
+ const column = this.query.shape[key];
9421
+ if (column) throwOnReadOnly$1(this.query, column, key);
9262
9422
  if (typeof set[key] === "function") {
9263
9423
  if (!resolved) resolved = { ...set };
9264
9424
  resolved[key] = set[key]();
@@ -9528,7 +9688,7 @@ class Having {
9528
9688
  */
9529
9689
  having(...args) {
9530
9690
  const q = _clone(this);
9531
- return pushQueryValueImmutable(
9691
+ return orchidCore.pushQueryValueImmutable(
9532
9692
  q,
9533
9693
  "having",
9534
9694
  args.map((arg) => arg(q).q.expr)
@@ -9544,14 +9704,18 @@ class Having {
9544
9704
  * @param args - SQL expression
9545
9705
  */
9546
9706
  havingSql(...args) {
9547
- return pushQueryValueImmutable(_clone(this), "having", args);
9707
+ return orchidCore.pushQueryValueImmutable(_clone(this), "having", args);
9548
9708
  }
9549
9709
  }
9550
9710
 
9551
- const before = (q, key, cb) => pushQueryValueImmutable(q, `before${key}`, cb);
9711
+ const before = (q, key, cb) => orchidCore.pushQueryValueImmutable(q, `before${key}`, cb);
9552
9712
  const after = (query, key, select, cb, commit) => {
9553
9713
  const q = query;
9554
- pushQueryValueImmutable(q, `after${key}${commit ? "Commit" : ""}`, cb);
9714
+ orchidCore.pushQueryValueImmutable(
9715
+ q,
9716
+ `after${key}${commit ? "Commit" : ""}`,
9717
+ cb
9718
+ );
9555
9719
  const prop = `after${key}Select`;
9556
9720
  const set = q.q[prop] = new Set(q.q[prop]);
9557
9721
  for (const column of select) {
@@ -9560,13 +9724,19 @@ const after = (query, key, select, cb, commit) => {
9560
9724
  return query;
9561
9725
  };
9562
9726
  const _queryHookBeforeQuery = (q, cb) => {
9563
- return pushQueryValueImmutable(q, "before", cb);
9727
+ return orchidCore.pushQueryValueImmutable(q, "before", cb);
9564
9728
  };
9565
9729
  const _queryHookAfterQuery = (q, cb) => {
9566
- return pushQueryValueImmutable(q, "after", cb);
9730
+ return orchidCore.pushQueryValueImmutable(q, "after", cb);
9567
9731
  };
9568
9732
  const _queryHookBeforeCreate = (q, cb) => {
9569
- return before(q, "Create", cb);
9733
+ return before(
9734
+ q,
9735
+ "Create",
9736
+ (q2) => cb(
9737
+ new orchidCore.QueryHookUtils(q2, q2.q.columns, "hookCreateSet")
9738
+ )
9739
+ );
9570
9740
  };
9571
9741
  const _queryHookAfterCreate = (q, select, cb) => {
9572
9742
  return after(q, "Create", select, cb);
@@ -9575,7 +9745,15 @@ const _queryHookAfterCreateCommit = (q, select, cb) => {
9575
9745
  return after(q, "Create", select, cb, true);
9576
9746
  };
9577
9747
  const _queryHookBeforeUpdate = (q, cb) => {
9578
- return before(q, "Update", cb);
9748
+ return before(q, "Update", (q2) => {
9749
+ const columns = [];
9750
+ for (const item of q2.q.updateData) {
9751
+ if (typeof item === "object") {
9752
+ columns.push(...Object.keys(item));
9753
+ }
9754
+ }
9755
+ return cb(new orchidCore.QueryHookUtils(q2, columns, "hookUpdateSet"));
9756
+ });
9579
9757
  };
9580
9758
  const _queryHookAfterUpdate = (q, select, cb) => {
9581
9759
  return after(q, "Update", select, cb);
@@ -9584,7 +9762,7 @@ const _queryHookAfterUpdateCommit = (q, select, cb) => {
9584
9762
  return after(q, "Update", select, cb, true);
9585
9763
  };
9586
9764
  const _queryHookBeforeSave = (q, cb) => {
9587
- return before(before(q, "Create", cb), "Update", cb);
9765
+ return _queryHookBeforeUpdate(_queryHookBeforeCreate(q, cb), cb);
9588
9766
  };
9589
9767
  const _queryHookAfterSave = (q, select, cb) => {
9590
9768
  return after(after(q, "Create", select, cb), "Update", select, cb);
@@ -9789,7 +9967,7 @@ class QueryHooks {
9789
9967
  */
9790
9968
  catchAfterCommitError(fn) {
9791
9969
  const q = _clone(this);
9792
- pushQueryValueImmutable(q, "catchAfterCommitErrors", fn);
9970
+ orchidCore.pushQueryValueImmutable(q, "catchAfterCommitErrors", fn);
9793
9971
  return q;
9794
9972
  }
9795
9973
  }
@@ -10471,7 +10649,7 @@ const makeOnItem = (joinTo, joinFrom, args) => ({
10471
10649
  }
10472
10650
  });
10473
10651
  const pushQueryOnForOuter = (q, joinFrom, joinTo, leftColumn, rightColumn) => {
10474
- return pushQueryValueImmutable(q, "and", {
10652
+ return orchidCore.pushQueryValueImmutable(q, "and", {
10475
10653
  ON: {
10476
10654
  joinFrom: joinTo,
10477
10655
  from: leftColumn,
@@ -10482,14 +10660,14 @@ const pushQueryOnForOuter = (q, joinFrom, joinTo, leftColumn, rightColumn) => {
10482
10660
  });
10483
10661
  };
10484
10662
  const pushQueryOn = (q, joinFrom, joinTo, ...on) => {
10485
- return pushQueryValueImmutable(
10663
+ return orchidCore.pushQueryValueImmutable(
10486
10664
  q,
10487
10665
  "and",
10488
10666
  makeOnItem(joinFrom, joinTo, on)
10489
10667
  );
10490
10668
  };
10491
10669
  const pushQueryOrOn = (q, joinFrom, joinTo, ...on) => {
10492
- return pushQueryValueImmutable(q, "or", [
10670
+ return orchidCore.pushQueryValueImmutable(q, "or", [
10493
10671
  makeOnItem(joinFrom, joinTo, on)
10494
10672
  ]);
10495
10673
  };
@@ -10521,7 +10699,7 @@ const _queryJoinOrOn = (q, args) => {
10521
10699
  );
10522
10700
  };
10523
10701
  const _queryJoinOnJsonPathEquals = (q, args) => {
10524
- return pushQueryValueImmutable(q, "and", {
10702
+ return orchidCore.pushQueryValueImmutable(q, "and", {
10525
10703
  ON: args
10526
10704
  });
10527
10705
  };
@@ -10637,6 +10815,15 @@ class MergeQueryMethods {
10637
10815
  }
10638
10816
  }
10639
10817
 
10818
+ const throwOnReadOnly = (q, column, key) => {
10819
+ if (column.data.appReadOnly || column.data.readOnly) {
10820
+ throw new OrchidOrmInternalError(
10821
+ q,
10822
+ "Trying to update a readonly column",
10823
+ { column: key }
10824
+ );
10825
+ }
10826
+ };
10640
10827
  const _queryChangeCounter = (self, op, data) => {
10641
10828
  const q = self.q;
10642
10829
  q.type = "update";
@@ -10653,11 +10840,19 @@ const _queryChangeCounter = (self, op, data) => {
10653
10840
  map = {};
10654
10841
  for (const key in data) {
10655
10842
  map[key] = { op, arg: data[key] };
10843
+ const column = self.shape[key];
10844
+ if (column) {
10845
+ throwOnReadOnly(self, column, key);
10846
+ }
10656
10847
  }
10657
10848
  } else {
10658
10849
  map = { [data]: { op, arg: 1 } };
10850
+ const column = self.shape[data];
10851
+ if (column) {
10852
+ throwOnReadOnly(self, column, data);
10853
+ }
10659
10854
  }
10660
- pushQueryValueImmutable(self, "updateData", map);
10855
+ orchidCore.pushQueryValueImmutable(self, "updateData", map);
10661
10856
  return self;
10662
10857
  };
10663
10858
  const update = (self) => {
@@ -10674,17 +10869,18 @@ const update = (self) => {
10674
10869
  const _queryUpdate = (query, arg) => {
10675
10870
  const { q } = query;
10676
10871
  const set = { ...arg };
10677
- pushQueryValueImmutable(query, "updateData", set);
10872
+ orchidCore.pushQueryValueImmutable(query, "updateData", set);
10678
10873
  const { shape } = q;
10679
10874
  const ctx = {};
10680
10875
  for (const key in arg) {
10681
10876
  const item = shape[key];
10682
- if (item instanceof VirtualColumn && item.update) {
10683
- item.update(query, ctx, set);
10877
+ if (!item && shape !== anyShape) {
10684
10878
  delete set[key];
10685
- } else if ((!shape[key] || shape[key].data.readonly) && shape !== anyShape) {
10879
+ } else if (item.data.virtual) {
10880
+ item.update?.(query, ctx, set);
10686
10881
  delete set[key];
10687
10882
  } else {
10883
+ if (item) throwOnReadOnly(query, item, key);
10688
10884
  let value = set[key];
10689
10885
  if (typeof value === "function") {
10690
10886
  value = resolveSubQueryCallbackV2(
@@ -10710,7 +10906,7 @@ const _queryUpdate = (query, arg) => {
10710
10906
  "with"
10711
10907
  );
10712
10908
  } else {
10713
- const encode = shape[key].data.encode;
10909
+ const encode = item?.data.encode;
10714
10910
  if (encode) set[key] = encode(value);
10715
10911
  }
10716
10912
  }
@@ -11288,9 +11484,9 @@ class SearchMethods {
11288
11484
  }
11289
11485
  setQueryObjectValueImmutable(q, "sources", arg.as, arg);
11290
11486
  if (arg.order) {
11291
- pushQueryValueImmutable(q, "order", arg.as);
11487
+ orchidCore.pushQueryValueImmutable(q, "order", arg.as);
11292
11488
  }
11293
- return pushQueryValueImmutable(q, "and", { SEARCH: arg });
11489
+ return orchidCore.pushQueryValueImmutable(q, "and", { SEARCH: arg });
11294
11490
  }
11295
11491
  }
11296
11492
 
@@ -11358,7 +11554,7 @@ function orCreate(query, data, updateData, mergeData) {
11358
11554
  q22.q.log = q2.q.log;
11359
11555
  q22.q.logger = q2.q.logger;
11360
11556
  q22.q.type = "upsert";
11361
- q22.q.beforeCreate = q2.q.beforeCreate;
11557
+ q22.q.beforeCreate = q2.q.beforeCreate?.map((cb) => () => cb(c));
11362
11558
  if (hasAfterCallback) {
11363
11559
  ((_a = q22.q).afterCreate ?? (_a.afterCreate = [])).push(
11364
11560
  (data2, query2) => afterHooks && Promise.all([...afterHooks].map((fn) => fn(data2, query2)))
@@ -11380,109 +11576,13 @@ function orCreate(query, data, updateData, mergeData) {
11380
11576
  };
11381
11577
  return query;
11382
11578
  }
11383
- class QueryUpsertOrCreate {
11384
- /**
11385
- * `upsert` tries to update a single record, and then it creates the record if it doesn't yet exist.
11386
- *
11387
- * `find` or `findBy` must precede `upsert` because it does not work with multiple updates.
11388
- *
11389
- * In case more than one row was updated, it will throw `MoreThanOneRowError` and the transaction will be rolled back.
11390
- *
11391
- * It can take `update` and `create` objects, then they are used separately for update and create queries.
11392
- * Or, it can take `data` and `create` objects, `data` will be used for update and be mixed to `create` object.
11393
- *
11394
- * `data` and `update` objects are of the same type that's expected by `update` method, `create` object is of type of `create` method argument.
11395
- *
11396
- * No values are returned by default, place `select` or `selectAll` before `upsert` to specify returning columns.
11397
- *
11398
- * ```ts
11399
- * await User.selectAll()
11400
- * .findBy({ email: 'some@email.com' })
11401
- * .upsert({
11402
- * data: {
11403
- * // update record's name
11404
- * name: 'new name',
11405
- * // supports sql and nested queries
11406
- * fromSQL: () => sql`*SQL expression*`,
11407
- * fromQuery: () => db.someTable.create(data).get('column'),
11408
- * },
11409
- * create: {
11410
- * // create a new record with this email and a name 'new name'
11411
- * email: 'some@email.com',
11412
- * // supports sql and nested queries as well
11413
- * },
11414
- * create: {
11415
- * // create a new record with this email and a name 'new name'
11416
- * email: 'some@email.com',
11417
- * },
11418
- * });
11419
- *
11420
- * // the same as above but using `update` and `create`
11421
- * await User.selectAll()
11422
- * .findBy({ email: 'some@email.com' })
11423
- * .upsert({
11424
- * update: {
11425
- * name: 'updated user',
11426
- * },
11427
- * create: {
11428
- * email: 'some@email.com',
11429
- * // here we use a different name when creating a record
11430
- * name: 'created user',
11431
- * },
11432
- * });
11433
- * ```
11434
- *
11435
- * The data for `create` may be returned from a function, it won't be called if a record was updated:
11436
- *
11437
- * ```ts
11438
- * await User.selectAll()
11439
- * .findBy({ email: 'some@email.com' })
11440
- * .upsert({
11441
- * update: {
11442
- * name: 'updated user',
11443
- * },
11444
- * create: () => ({
11445
- * email: 'some@email.com',
11446
- * name: 'created user',
11447
- * }),
11448
- * });
11449
- *
11450
- * // the same as above using `data`
11451
- * await User.selectAll()
11452
- * .findBy({ email: 'some@email.com' })
11453
- * .upsert({
11454
- * data: {
11455
- * name: 'updated user',
11456
- * },
11457
- * create: () => ({
11458
- * email: 'some@email.com',
11459
- * // name in `create` is overriding the name from `data`
11460
- * name: 'created user',
11461
- * }),
11462
- * });
11463
- * ```
11464
- *
11465
- * Data from `data` or `update` is passed to the `create` function and can be used:
11466
- *
11467
- * ```ts
11468
- * const user = await User.selectAll()
11469
- * .findBy({ email: 'some@email.com' })
11470
- * .upsert({
11471
- * data: {
11472
- * name: 'updated user',
11473
- * },
11474
- * // `updateData` has the exact type of what is passed to `data`
11475
- * create: (updateData) => ({
11476
- * email: `${updateData.name}@email.com`,
11477
- * }),
11478
- * });
11479
- * ```
11480
- *
11481
- * `upsert` works in the exact same way as [orCreate](#orCreate), but with `UPDATE` statement instead of `SELECT`.
11482
- * it also performs a single query if the record exists, and two queries if there is no record yet.
11483
- *
11484
- * @param data - `update` property for the data to update, `create` property for the data to create
11485
- */
11579
+ const QueryOrCreate = {
11580
+ orCreate(data) {
11581
+ return orCreate(_clone(this), data);
11582
+ }
11583
+ };
11584
+
11585
+ const QueryUpsert = {
11486
11586
  upsert(data) {
11487
11587
  const q = _clone(this);
11488
11588
  let updateData;
@@ -11497,75 +11597,7 @@ class QueryUpsertOrCreate {
11497
11597
  }
11498
11598
  return orCreate(q, data.create, updateData, mergeData);
11499
11599
  }
11500
- /**
11501
- * `orCreate` creates a record only if it was not found by conditions.
11502
- *
11503
- * `find` or `findBy` must precede `orCreate`.
11504
- *
11505
- * It is accepting the same argument as `create` commands.
11506
- *
11507
- * No result is returned by default, place `get`, `select`, or `selectAll` before `orCreate` to specify returning columns.
11508
- *
11509
- * ```ts
11510
- * const user = await db.user
11511
- * .selectAll()
11512
- * .findBy({ email: 'some@email.com' })
11513
- * .orCreate({
11514
- * email: 'some@email.com',
11515
- * name: 'created user',
11516
- * // supports sql and nested queries
11517
- * fromSQL: () => sql`*SQL expression*`,
11518
- * fromQuery: () => db.someTable.create(data).get('column'),
11519
- * fromRelated: (q) => q.relatedTable.update(data).get('column'),
11520
- * });
11521
- * ```
11522
- *
11523
- * The data can be returned from a function, it won't be called if the record was found:
11524
- *
11525
- * ```ts
11526
- * const user = await User.selectAll()
11527
- * .findBy({ email: 'some@email.com' })
11528
- * .orCreate(() => ({
11529
- * email: 'some@email.com',
11530
- * name: 'created user',
11531
- * }));
11532
- * ```
11533
- *
11534
- * `orCreate` works by performing just a single query in the case if the record exists, and one additional query when the record does not exist.
11535
- *
11536
- * At first, it performs a "find" query, the query cost is exact same as if you didn't use `orCreate`.
11537
- *
11538
- * Then, if the record wasn't found, it performs a single query with CTE expressions to try finding it again, for the case it was already created just a moment before,
11539
- * and then it creates the record if it's still not found. Using such CTE allows to skip using transactions, while still conforming to atomicity.
11540
- *
11541
- * ```sql
11542
- * -- first query
11543
- * SELECT * FROM "table" WHERE "key" = 'value'
11544
- *
11545
- * -- the record could have been created in between these two queries
11546
- *
11547
- * -- second query
11548
- * WITH find_row AS (
11549
- * SELECT * FROM "table" WHERE "key" = 'value'
11550
- * )
11551
- * WITH insert_row AS (
11552
- * INSERT INTO "table" ("key")
11553
- * SELECT 'value'
11554
- * -- skip the insert if the row already exists
11555
- * WHERE NOT EXISTS (SELECT 1 FROM find_row)
11556
- * RETURNING *
11557
- * )
11558
- * SELECT * FROM find_row
11559
- * UNION ALL
11560
- * SELECT * FROM insert_row
11561
- * ```
11562
- *
11563
- * @param data - the same data as for `create`, it may be returned from a callback
11564
- */
11565
- orCreate(data) {
11566
- return orCreate(_clone(this), data);
11567
- }
11568
- }
11600
+ };
11569
11601
 
11570
11602
  class SqlMethod {
11571
11603
  sql(...args) {
@@ -11630,7 +11662,7 @@ class TransformMethods {
11630
11662
  * @param fn - function to transform query result with
11631
11663
  */
11632
11664
  transform(fn) {
11633
- return pushQueryValueImmutable(_clone(this), "transform", fn);
11665
+ return orchidCore.pushQueryValueImmutable(_clone(this), "transform", fn);
11634
11666
  }
11635
11667
  }
11636
11668
 
@@ -11676,7 +11708,7 @@ class QueryMap {
11676
11708
  * @param fn - function to transform an individual record
11677
11709
  */
11678
11710
  map(fn) {
11679
- return pushQueryValueImmutable(_clone(this), "transform", {
11711
+ return orchidCore.pushQueryValueImmutable(_clone(this), "transform", {
11680
11712
  map: fn
11681
11713
  });
11682
11714
  }
@@ -12305,7 +12337,7 @@ class QueryMethods {
12305
12337
  * @param arg - window config
12306
12338
  */
12307
12339
  window(arg) {
12308
- return pushQueryValueImmutable(_clone(this), "window", arg);
12340
+ return orchidCore.pushQueryValueImmutable(_clone(this), "window", arg);
12309
12341
  }
12310
12342
  wrap(query, as) {
12311
12343
  return queryWrap(this, _clone(query), as);
@@ -12360,7 +12392,7 @@ class QueryMethods {
12360
12392
  * @param args - SQL expression
12361
12393
  */
12362
12394
  orderSql(...args) {
12363
- return pushQueryValueImmutable(
12395
+ return orchidCore.pushQueryValueImmutable(
12364
12396
  _clone(this),
12365
12397
  "order",
12366
12398
  sqlQueryArgsToExpression(args)
@@ -12649,6 +12681,8 @@ class QueryMethods {
12649
12681
  return _chain(this, _clone(rel.query), rel);
12650
12682
  }
12651
12683
  }
12684
+ Object.assign(QueryMethods.prototype, QueryUpsert);
12685
+ Object.assign(QueryMethods.prototype, QueryOrCreate);
12652
12686
  orchidCore.applyMixins(QueryMethods, [
12653
12687
  AsMethods,
12654
12688
  AggregateMethods,
@@ -12659,7 +12693,7 @@ orchidCore.applyMixins(QueryMethods, [
12659
12693
  WithMethods,
12660
12694
  Union,
12661
12695
  JsonMethods,
12662
- Create,
12696
+ QueryCreate,
12663
12697
  Update,
12664
12698
  Delete,
12665
12699
  Transaction,
@@ -12671,7 +12705,6 @@ orchidCore.applyMixins(QueryMethods, [
12671
12705
  Then,
12672
12706
  QueryLog,
12673
12707
  QueryHooks,
12674
- QueryUpsertOrCreate,
12675
12708
  QueryGet,
12676
12709
  MergeQueryMethods,
12677
12710
  SqlMethod,
@@ -12847,6 +12880,7 @@ class Db extends QueryMethods {
12847
12880
  let hasParsers = false;
12848
12881
  let modifyQuery = void 0;
12849
12882
  let prepareSelectAll = false;
12883
+ let hasHookSetters;
12850
12884
  const { snakeCase } = options;
12851
12885
  for (const key in shape) {
12852
12886
  const column = shape[key];
@@ -12882,6 +12916,9 @@ class Db extends QueryMethods {
12882
12916
  column.data.runtimeDefault = encode ? () => encode(def()) : def;
12883
12917
  }
12884
12918
  }
12919
+ if (column.data.setOnCreate || column.data.setOnUpdate || column.data.setOnSave) {
12920
+ hasHookSetters = true;
12921
+ }
12885
12922
  }
12886
12923
  this.q = {
12887
12924
  adapter,
@@ -12956,6 +12993,27 @@ class Db extends QueryMethods {
12956
12993
  if (softDelete) {
12957
12994
  enableSoftDelete(this, table, shape, softDelete, scopes);
12958
12995
  }
12996
+ if (hasHookSetters) {
12997
+ const hooks = {
12998
+ setOnCreate: _queryHookBeforeCreate,
12999
+ setOnUpdate: _queryHookBeforeUpdate,
13000
+ setOnSave: _queryHookBeforeSave
13001
+ };
13002
+ for (const key in shape) {
13003
+ const { data } = shape[key];
13004
+ for (const hookKey in hooks) {
13005
+ const fn = data[hookKey];
13006
+ if (fn) {
13007
+ hooks[hookKey](this, (arg) => {
13008
+ const value = fn(arg);
13009
+ if (value !== void 0) {
13010
+ arg.set({ [key]: value });
13011
+ }
13012
+ });
13013
+ }
13014
+ }
13015
+ }
13016
+ }
12959
13017
  }
12960
13018
  [node_util.inspect.custom]() {
12961
13019
  return `Query<${this.table}>`;
@@ -13308,7 +13366,6 @@ exports.Clear = Clear;
13308
13366
  exports.ColumnRefExpression = ColumnRefExpression;
13309
13367
  exports.ColumnType = ColumnType;
13310
13368
  exports.ComputedColumn = ComputedColumn;
13311
- exports.Create = Create;
13312
13369
  exports.CustomTypeColumn = CustomTypeColumn;
13313
13370
  exports.DateBaseColumn = DateBaseColumn;
13314
13371
  exports.DateColumn = DateColumn;
@@ -13355,12 +13412,13 @@ exports.PathColumn = PathColumn;
13355
13412
  exports.PointColumn = PointColumn;
13356
13413
  exports.PolygonColumn = PolygonColumn;
13357
13414
  exports.PostgisGeographyPointColumn = PostgisGeographyPointColumn;
13415
+ exports.QueryCreate = QueryCreate;
13358
13416
  exports.QueryError = QueryError;
13359
13417
  exports.QueryGet = QueryGet;
13360
13418
  exports.QueryHooks = QueryHooks;
13361
13419
  exports.QueryLog = QueryLog;
13362
13420
  exports.QueryMethods = QueryMethods;
13363
- exports.QueryUpsertOrCreate = QueryUpsertOrCreate;
13421
+ exports.QueryUpsert = QueryUpsert;
13364
13422
  exports.RawSQL = RawSQL;
13365
13423
  exports.RealColumn = RealColumn;
13366
13424
  exports.RefExpression = RefExpression;
@@ -13515,7 +13573,6 @@ exports.pushQueryArrayImmutable = pushQueryArrayImmutable;
13515
13573
  exports.pushQueryOn = pushQueryOn;
13516
13574
  exports.pushQueryOnForOuter = pushQueryOnForOuter;
13517
13575
  exports.pushQueryOrOn = pushQueryOrOn;
13518
- exports.pushQueryValueImmutable = pushQueryValueImmutable;
13519
13576
  exports.pushTableDataCode = pushTableDataCode;
13520
13577
  exports.queryFrom = queryFrom;
13521
13578
  exports.queryFromSql = queryFromSql;