pqb 0.30.7 → 0.31.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/dist/index.js CHANGED
@@ -3676,15 +3676,16 @@ class AsMethods {
3676
3676
  }
3677
3677
 
3678
3678
  function queryFrom(self, arg) {
3679
- var _a;
3679
+ var _a, _b;
3680
3680
  const data = self.q;
3681
3681
  if (typeof arg === "string") {
3682
3682
  data.as || (data.as = arg);
3683
+ data.shape = (_a = data.withShapes) == null ? void 0 : _a[arg];
3683
3684
  } else if (orchidCore.isExpression(arg)) {
3684
3685
  data.as || (data.as = "t");
3685
3686
  } else if (Array.isArray(arg)) {
3686
3687
  const { shape } = data;
3687
- const parsers = (_a = data.parsers) != null ? _a : data.parsers = {};
3688
+ const parsers = (_b = data.parsers) != null ? _b : data.parsers = {};
3688
3689
  for (const item of arg) {
3689
3690
  if (typeof item === "string") {
3690
3691
  const withShape = data.withShapes[item];
@@ -3714,7 +3715,7 @@ function queryFromSql(self, args) {
3714
3715
  data.from = sqlQueryArgsToExpression(args);
3715
3716
  return self;
3716
3717
  }
3717
- class From {
3718
+ class FromMethods {
3718
3719
  /**
3719
3720
  * Set the `FROM` value, by default the table name is used.
3720
3721
  *
@@ -4071,20 +4072,21 @@ const havingToSql = (ctx, query, quotedAs) => {
4071
4072
  ).join(" AND ");
4072
4073
  };
4073
4074
 
4074
- const pushWithSql = (ctx, withData) => {
4075
- if (!withData.length)
4075
+ const pushWithSql = (ctx, items) => {
4076
+ if (!items.length)
4076
4077
  return;
4077
4078
  ctx.sql.push(
4078
4079
  "WITH",
4079
- withData.map((withItem) => {
4080
- const [name, options, query] = withItem;
4080
+ items.map((item) => {
4081
+ var _a;
4081
4082
  let inner;
4082
- if (orchidCore.isExpression(query)) {
4083
- inner = query.toSQL(ctx, `"${name}"`);
4083
+ if (item.q) {
4084
+ inner = makeSQL(item.q, ctx).text;
4084
4085
  } else {
4085
- inner = makeSQL(query, ctx).text;
4086
+ inner = item.s.toSQL(ctx, `"${item.n}"`);
4086
4087
  }
4087
- return `${options.recursive ? "RECURSIVE " : ""}"${name}"${options.columns ? `(${options.columns.map((x) => `"${x}"`).join(", ")})` : ""} AS ${options.materialized ? "MATERIALIZED " : options.notMaterialized ? "NOT MATERIALIZED " : ""}(${inner})`;
4088
+ const o = (_a = item.o) != null ? _a : orchidCore.emptyObject;
4089
+ return `${o.recursive ? "RECURSIVE " : ""}"${item.n}"${o.columns ? `(${o.columns.map((x) => `"${x}"`).join(", ")})` : ""} AS ${o.materialized ? "MATERIALIZED " : o.notMaterialized ? "NOT MATERIALIZED " : ""}(${inner})`;
4088
4090
  }).join(", ")
4089
4091
  );
4090
4092
  };
@@ -4403,12 +4405,6 @@ const mergeColumnsSql = (quotedColumns2) => {
4403
4405
  };
4404
4406
  const encodeRow = (ctx, q, QueryClass, row, runtimeDefaults, quotedAs) => {
4405
4407
  const arr = row.map((value) => {
4406
- if (typeof value === "function") {
4407
- value = resolveSubQueryCallback(
4408
- q,
4409
- value
4410
- );
4411
- }
4412
4408
  if (value && typeof value === "object") {
4413
4409
  if (value instanceof orchidCore.Expression) {
4414
4410
  return value.toSQL(ctx, quotedAs);
@@ -4711,6 +4707,7 @@ const toSQL = (table, options) => {
4711
4707
  return !(options == null ? void 0 : options.clearCache) && table.q[toSQLCacheKey] || (table.q[toSQLCacheKey] = makeSQL(table, options));
4712
4708
  };
4713
4709
  const makeSQL = (table, options) => {
4710
+ var _a;
4714
4711
  const query = table.q;
4715
4712
  const sql = [];
4716
4713
  const values = (options == null ? void 0 : options.values) || [];
@@ -4724,24 +4721,21 @@ const makeSQL = (table, options) => {
4724
4721
  pushWithSql(ctx, query.with);
4725
4722
  }
4726
4723
  if (query.type) {
4724
+ const tableName = (_a = table.table) != null ? _a : query.as;
4725
+ if (!tableName)
4726
+ throw new Error(`Table is missing for ${query.type}`);
4727
4727
  if (query.type === "truncate") {
4728
- if (!table.table)
4729
- throw new Error("Table is missing for truncate");
4730
- pushTruncateSql(ctx, table.table, query);
4728
+ pushTruncateSql(ctx, tableName, query);
4731
4729
  return { text: sql.join(" "), values };
4732
4730
  }
4733
4731
  if (query.type === "columnInfo") {
4734
- if (!table.table)
4735
- throw new Error("Table is missing for truncate");
4736
4732
  pushColumnInfoSql(ctx, table, query);
4737
4733
  return { text: sql.join(" "), values };
4738
4734
  }
4739
- if (!table.table)
4740
- throw new Error(`Table is missing for ${query.type}`);
4741
- const quotedAs2 = `"${query.as || table.table}"`;
4735
+ const quotedAs2 = `"${query.as || tableName}"`;
4742
4736
  if (query.type === "insert") {
4743
4737
  return {
4744
- hookSelect: pushInsertSql(ctx, table, query, `"${table.table}"`),
4738
+ hookSelect: pushInsertSql(ctx, table, query, `"${tableName}"`),
4745
4739
  text: sql.join(" "),
4746
4740
  values
4747
4741
  };
@@ -4766,54 +4760,50 @@ const makeSQL = (table, options) => {
4766
4760
  }
4767
4761
  }
4768
4762
  const quotedAs = (query.as || table.table) && `"${query.as || table.table}"`;
4769
- sql.push("SELECT");
4770
- if (query.distinct) {
4771
- pushDistinctSql(ctx, table, query.distinct, quotedAs);
4772
- }
4773
- pushSelectSql(ctx, table, query, quotedAs);
4774
- if (table.table || query.from) {
4775
- pushFromAndAs(ctx, table, query, quotedAs);
4776
- }
4777
- if (query.join) {
4778
- pushJoinSql(
4779
- ctx,
4780
- table,
4781
- query,
4782
- quotedAs
4783
- );
4784
- }
4785
- if (query.and || query.or) {
4786
- pushWhereStatementSql(ctx, table, query, quotedAs);
4787
- }
4788
- if (query.group) {
4789
- const group = query.group.map(
4790
- (item) => orchidCore.isExpression(item) ? item.toSQL(ctx, quotedAs) : columnToSql(ctx, table.q, table.q.shape, item, quotedAs)
4791
- );
4792
- sql.push(`GROUP BY ${group.join(", ")}`);
4793
- }
4794
- if (query.having)
4795
- pushHavingSql(ctx, query, quotedAs);
4796
- if (query.window) {
4797
- const window = [];
4798
- query.window.forEach((item) => {
4799
- for (const key in item) {
4800
- window.push(
4801
- `"${key}" AS ${windowToSql(ctx, query, item[key], quotedAs)}`
4802
- );
4803
- }
4804
- });
4805
- sql.push(`WINDOW ${window.join(", ")}`);
4806
- }
4807
4763
  if (query.union) {
4808
- for (const item of query.union) {
4809
- let itemSql;
4810
- if (orchidCore.isExpression(item.arg)) {
4811
- itemSql = item.arg.toSQL(ctx, quotedAs);
4812
- } else {
4813
- const argSql = makeSQL(item.arg, { values });
4814
- itemSql = argSql.text;
4815
- }
4816
- sql.push(`${item.kind} ${item.wrap ? `(${itemSql})` : itemSql}`);
4764
+ sql.push(`(${makeSQL(query.union.b, { values }).text})`);
4765
+ for (const u of query.union.u) {
4766
+ const itemSql = orchidCore.isExpression(u.a) ? u.a.toSQL(ctx, quotedAs) : makeSQL(u.a, { values }).text;
4767
+ sql.push(`${u.k} (${itemSql})`);
4768
+ }
4769
+ } else {
4770
+ sql.push("SELECT");
4771
+ if (query.distinct) {
4772
+ pushDistinctSql(ctx, table, query.distinct, quotedAs);
4773
+ }
4774
+ pushSelectSql(ctx, table, query, quotedAs);
4775
+ if (table.table || query.from) {
4776
+ pushFromAndAs(ctx, table, query, quotedAs);
4777
+ }
4778
+ if (query.join) {
4779
+ pushJoinSql(
4780
+ ctx,
4781
+ table,
4782
+ query,
4783
+ quotedAs
4784
+ );
4785
+ }
4786
+ if (query.and || query.or) {
4787
+ pushWhereStatementSql(ctx, table, query, quotedAs);
4788
+ }
4789
+ if (query.group) {
4790
+ const group = query.group.map(
4791
+ (item) => orchidCore.isExpression(item) ? item.toSQL(ctx, quotedAs) : columnToSql(ctx, table.q, table.q.shape, item, quotedAs)
4792
+ );
4793
+ sql.push(`GROUP BY ${group.join(", ")}`);
4794
+ }
4795
+ if (query.having)
4796
+ pushHavingSql(ctx, query, quotedAs);
4797
+ if (query.window) {
4798
+ const window = [];
4799
+ query.window.forEach((item) => {
4800
+ for (const key in item) {
4801
+ window.push(
4802
+ `"${key}" AS ${windowToSql(ctx, query, item[key], quotedAs)}`
4803
+ );
4804
+ }
4805
+ });
4806
+ sql.push(`WINDOW ${window.join(", ")}`);
4817
4807
  }
4818
4808
  }
4819
4809
  if (query.order) {
@@ -4897,7 +4887,7 @@ const cloneQuery = (q) => {
4897
4887
  if (q.window)
4898
4888
  q.window = q.window.slice(0);
4899
4889
  if (q.union)
4900
- q.union = q.union.slice(0);
4890
+ q.union = { b: q.union.b, u: q.union.u.slice(0) };
4901
4891
  if (q.order)
4902
4892
  q.order = q.order.slice(0);
4903
4893
  } else if (q.type === "insert") {
@@ -6157,9 +6147,17 @@ const processCreateItem = (q, item, rowIndex, ctx, encoders) => {
6157
6147
  item,
6158
6148
  rowIndex
6159
6149
  );
6160
- } else if (!ctx.columns.has(key) && (shape[key] && !shape[key].data.computed || shape === anyShape)) {
6161
- ctx.columns.set(key, ctx.columns.size);
6162
- encoders[key] = (_c = shape[key]) == null ? void 0 : _c.encodeFn;
6150
+ } else {
6151
+ if (typeof item[key] === "function") {
6152
+ item[key] = resolveSubQueryCallback(
6153
+ q,
6154
+ item[key]
6155
+ );
6156
+ }
6157
+ if (!ctx.columns.has(key) && (shape[key] && !shape[key].data.computed || shape === anyShape)) {
6158
+ ctx.columns.set(key, ctx.columns.size);
6159
+ encoders[key] = (_c = shape[key]) == null ? void 0 : _c.encodeFn;
6160
+ }
6163
6161
  }
6164
6162
  }
6165
6163
  };
@@ -6365,6 +6363,22 @@ class Create {
6365
6363
  * });
6366
6364
  * ```
6367
6365
  *
6366
+ * `create` and `insert` can be used in {@link WithMethods.with} expressions:
6367
+ *
6368
+ * ```ts
6369
+ * db.$queryBuilder
6370
+ * // create a record in one table
6371
+ * .with('a', db.table.select('id').create(data))
6372
+ * // create a record in other table using the first table record id
6373
+ * .with('b', (q) =>
6374
+ * db.otherTable.select('id').create({
6375
+ * ...otherData,
6376
+ * aId: () => q.from('a').get('id'),
6377
+ * }),
6378
+ * )
6379
+ * .from('b');
6380
+ * ```
6381
+ *
6368
6382
  * @param data - data for the record, may have values, raw SQL, queries, relation operations.
6369
6383
  */
6370
6384
  create(data) {
@@ -6873,6 +6887,19 @@ class Delete {
6873
6887
  * // delete all users who have corresponding profile records:
6874
6888
  * db.table.join(Profile, 'profile.userId', 'user.id').all().delete();
6875
6889
  * ```
6890
+ *
6891
+ * `delete` can be used in {@link WithMethods.with} expressions:
6892
+ *
6893
+ * ```ts
6894
+ * db.$queryBuilder
6895
+ * // delete a record in one table
6896
+ * .with('a', db.table.find(1).select('id').delete())
6897
+ * // delete a record in other table using the first table record id
6898
+ * .with('b', (q) =>
6899
+ * db.otherTable.select('id').whereIn('aId', q.from('a').pluck('id')).delete(),
6900
+ * )
6901
+ * .from('b');
6902
+ * ```
6876
6903
  */
6877
6904
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6878
6905
  delete(..._args) {
@@ -8295,6 +8322,11 @@ class MergeQueryMethods {
8295
8322
  a[key] = a[key] ? [...a[key], ...value] : value;
8296
8323
  } else if (mergableObjects[key]) {
8297
8324
  a[key] = a[key] ? __spreadValues$5(__spreadValues$5({}, a[key]), value) : value;
8325
+ } else if (key === "union") {
8326
+ a[key] = a[key] ? {
8327
+ b: a[key].b,
8328
+ u: [...a[key].u, ...value.u]
8329
+ } : value;
8298
8330
  } else {
8299
8331
  a[key] = value;
8300
8332
  }
@@ -8308,196 +8340,225 @@ class MergeQueryMethods {
8308
8340
  }
8309
8341
  }
8310
8342
 
8311
- var __defProp$4 = Object.defineProperty;
8312
- var __defProps$1 = Object.defineProperties;
8313
- var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
8314
- var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
8315
- var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
8316
- var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
8317
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8318
- var __spreadValues$4 = (a, b) => {
8319
- for (var prop in b || (b = {}))
8320
- if (__hasOwnProp$4.call(b, prop))
8321
- __defNormalProp$4(a, prop, b[prop]);
8322
- if (__getOwnPropSymbols$4)
8323
- for (var prop of __getOwnPropSymbols$4(b)) {
8324
- if (__propIsEnum$4.call(b, prop))
8325
- __defNormalProp$4(a, prop, b[prop]);
8326
- }
8327
- return a;
8343
+ const _queryUnion = (base, args, k) => {
8344
+ const q = base.baseQuery.clone();
8345
+ const u = args.map(
8346
+ (a) => ({
8347
+ a: typeof a === "function" ? a(q) : a,
8348
+ k
8349
+ })
8350
+ );
8351
+ const union = q.q.union = base.q.union;
8352
+ if (union) {
8353
+ union.u.push(...u);
8354
+ } else {
8355
+ q.q.union = {
8356
+ b: base,
8357
+ u
8358
+ };
8359
+ }
8360
+ return q;
8328
8361
  };
8329
- var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
8330
- class With {
8362
+ class Union {
8331
8363
  /**
8332
- * Add Common Table Expression (CTE) to the query.
8364
+ * Creates a union query, takes one or more queries or SQL expressions.
8333
8365
  *
8334
8366
  * ```ts
8335
- * import { columnTypes } from 'orchid-orm';
8336
- * import { NumberColumn } from './number';
8337
- *
8338
- * // .with optionally accepts such options:
8339
- * type WithOptions = {
8340
- * // list of columns returned by this WITH statement
8341
- * // by default all columns from provided column shape will be included
8342
- * // true is for default behavior
8343
- * columns?: string[] | boolean;
8344
- *
8345
- * // Adds RECURSIVE keyword:
8346
- * recursive?: true;
8347
- *
8348
- * // Adds MATERIALIZED keyword:
8349
- * materialized?: true;
8350
- *
8351
- * // Adds NOT MATERIALIZED keyword:
8352
- * notMaterialized?: true;
8353
- * };
8354
- *
8355
- * // accepts columns shape and a raw expression:
8356
- * db.table.with(
8357
- * 'alias',
8358
- * {
8359
- * id: columnTypes.integer(),
8360
- * name: columnTypes.text(3, 100),
8361
- * },
8362
- * sql`SELECT id, name FROM "someTable"`,
8363
- * );
8364
- *
8365
- * // accepts query:
8366
- * db.table.with('alias', db.table.all());
8367
- *
8368
- * // accepts a callback for a query builder:
8369
- * db.table.with('alias', (qb) =>
8370
- * qb.select({ one: sql`1`.type((t) => t.integer()) }),
8371
- * );
8372
- *
8373
- * // All mentioned forms can accept options as a second argument:
8374
- * db.table.with(
8375
- * 'alias',
8376
- * {
8377
- * recursive: true,
8378
- * materialized: true,
8379
- * },
8380
- * rawOrQueryOrCallback,
8381
- * );
8367
+ * // The first query of the union
8368
+ * db.one
8369
+ * .select('id', 'name')
8370
+ * // add two more queries to the union
8371
+ * .union(
8372
+ * db.two.select('id', 'name'),
8373
+ * (q = q.sql`SELECT id, name FROM "thirdTable"`),
8374
+ * )
8375
+ * // sub-sequent `union` is equivalent to passing multiple queries into a single `union`
8376
+ * .union(db.three.select('id', 'name'));
8382
8377
  * ```
8383
8378
  *
8384
- * Defined `WITH` table can be used in `.from` or `.join` with all the type safeness:
8379
+ * `order`, `limit`, `offset` are special, it matters if you place them **before** or **after** the `union`, it also have a meaning to place them before and after.
8385
8380
  *
8386
8381
  * ```ts
8387
- * db.table.with('alias', db.table.all()).from('alias').select('alias.id');
8388
- *
8389
- * db.table
8390
- * .with('alias', db.table.all())
8391
- * .join('alias', 'alias.id', 'user.id')
8392
- * .select('alias.id');
8382
+ * // order, limit, offset are applied ONLY to 'one'
8383
+ * db.one
8384
+ * .order('x')
8385
+ * .limit(1)
8386
+ * .offset(1)
8387
+ * // 'two' also has order, limit, and offset
8388
+ * .unionAll(db.two.order('y').limit(2).offset(2))
8389
+ * // sets order, limit, offset for all records
8390
+ * .order('z')
8391
+ * .limit(3)
8392
+ * .offset(3);
8393
8393
  * ```
8394
8394
  *
8395
- * @param args - first argument is an alias for this CTE, other arguments can be column shape, query object, or raw SQL.
8396
- */
8397
- with(...args) {
8398
- const q = this.clone();
8399
- let options = args.length === 3 && !orchidCore.isExpression(args[2]) || args.length === 4 ? args[1] : void 0;
8400
- const last = args[args.length - 1];
8401
- const query = typeof last === "function" ? last(q.queryBuilder) : last;
8402
- const shape = args.length === 4 ? args[2] : orchidCore.isExpression(query) ? args[1] : query.q.shape;
8403
- if ((options == null ? void 0 : options.columns) === true) {
8404
- options = __spreadProps$1(__spreadValues$4({}, options), {
8405
- columns: Object.keys(shape)
8406
- });
8407
- }
8408
- pushQueryValue(q, "with", [args[0], options || orchidCore.emptyObject, query]);
8409
- return setQueryObjectValue(q, "withShapes", args[0], shape);
8410
- }
8411
- }
8412
-
8413
- class Union {
8414
- /**
8415
- * Creates a union query, taking an array or a list of callbacks, builders, or raw statements to build the union statement, with optional boolean `wrap`.
8416
- * If the `wrap` parameter is true, the queries will be individually wrapped in parentheses.
8395
+ * Equivalent SQL:
8417
8396
  *
8418
- * ```ts
8419
- * SomeTable.select('id', 'name').union(
8420
- * [
8421
- * OtherTable.select('id', 'name'),
8422
- * sql`SELECT id, name FROM "thirdTable"`,
8423
- * ],
8424
- * true, // optional wrap parameter
8425
- * );
8397
+ * ```sql
8398
+ * -- both union parts have their own order, limit, offset
8399
+ * ( SELECT * FROM one ORDER x ASC LIMIT 1 OFFSET 1 )
8400
+ * UNION ALL
8401
+ * ( SELECT * FROM two ORDER y ASC LIMIT 2 OFFSET 2 )
8402
+ * -- order, limit, offset of the whole query
8403
+ * ORDER BY z ASC LIMIT 3 OFFSET 3
8426
8404
  * ```
8427
8405
  *
8428
- * @param args - array of queries or raw SQLs
8429
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8406
+ * All the listed methods have the same signature, they are only different by SQL keyword:
8407
+ *
8408
+ * - `union` - union of all queries, performs deduplication
8409
+ * - `unionAll` - `union` that allows duplicated rows
8410
+ * - `intersect` - get only rows that are present in all queries
8411
+ * - `intersectAll` - `intersect` that allows duplicated rows
8412
+ * - `except` - get only rows that are in the first query but not in the second
8413
+ * - `exceptAll` - `except` that allows duplicated rows
8414
+ *
8415
+ * @param args - array of queries or SQL expressions
8430
8416
  */
8431
- union(args, wrap) {
8432
- return pushQueryArray(
8417
+ union(...args) {
8418
+ return _queryUnion(
8433
8419
  this.clone(),
8434
- "union",
8435
- args.map((arg) => ({ arg, kind: "UNION", wrap }))
8420
+ args,
8421
+ "UNION"
8436
8422
  );
8437
8423
  }
8438
8424
  /**
8439
- * Same as `union`, but allows duplicated rows.
8425
+ * Same as {@link union}, but allows duplicated rows.
8440
8426
  *
8441
- * @param args - array of queries or raw SQLs
8442
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8427
+ * @param args - array of queries or SQL expressions
8443
8428
  */
8444
- unionAll(args, wrap) {
8445
- return pushQueryArray(
8429
+ unionAll(...args) {
8430
+ return _queryUnion(
8446
8431
  this.clone(),
8447
- "union",
8448
- args.map((arg) => ({ arg, kind: "UNION ALL", wrap }))
8432
+ args,
8433
+ "UNION ALL"
8449
8434
  );
8450
8435
  }
8451
8436
  /**
8452
- * Same as `union`, but uses a `INTERSECT` SQL keyword instead
8437
+ * Same as {@link union}, but uses a `INTERSECT` SQL keyword instead
8453
8438
  *
8454
- * @param args - array of queries or raw SQLs
8455
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8439
+ * @param args - array of queries or SQL expressions
8456
8440
  */
8457
- intersect(args, wrap) {
8458
- return pushQueryArray(
8441
+ intersect(...args) {
8442
+ return _queryUnion(
8459
8443
  this.clone(),
8460
- "union",
8461
- args.map((arg) => ({ arg, kind: "INTERSECT", wrap }))
8444
+ args,
8445
+ "INTERSECT"
8462
8446
  );
8463
8447
  }
8464
8448
  /**
8465
- * Same as `intersect`, but allows duplicated rows.
8449
+ * Same as {@link intersect}, but allows duplicated rows.
8466
8450
  *
8467
- * @param args - array of queries or raw SQLs
8468
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8451
+ * @param args - array of queries or SQL expressions
8469
8452
  */
8470
- intersectAll(args, wrap) {
8471
- return pushQueryArray(
8453
+ intersectAll(...args) {
8454
+ return _queryUnion(
8472
8455
  this.clone(),
8473
- "union",
8474
- args.map((arg) => ({ arg, kind: "INTERSECT ALL", wrap }))
8456
+ args,
8457
+ "INTERSECT ALL"
8475
8458
  );
8476
8459
  }
8477
8460
  /**
8478
- * Same as `union`, but uses an `EXCEPT` SQL keyword instead
8461
+ * Same as {@link union}, but uses an `EXCEPT` SQL keyword instead
8479
8462
  *
8480
- * @param args - array of queries or raw SQLs
8481
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8463
+ * @param args - array of queries or SQL expressions
8482
8464
  */
8483
- except(args, wrap) {
8484
- return pushQueryArray(
8465
+ except(...args) {
8466
+ return _queryUnion(
8485
8467
  this.clone(),
8486
- "union",
8487
- args.map((arg) => ({ arg, kind: "EXCEPT", wrap }))
8468
+ args,
8469
+ "EXCEPT"
8488
8470
  );
8489
8471
  }
8490
8472
  /**
8491
- * Same as `except`, but allows duplicated rows.
8473
+ * Same as {@link except}, but allows duplicated rows.
8492
8474
  *
8493
- * @param args - array of queries or raw SQLs
8494
- * @param wrap - provide `true` if you want the queries to be wrapped into parentheses
8475
+ * @param args - array of queries or SQL expressions
8495
8476
  */
8496
- exceptAll(args, wrap) {
8497
- return pushQueryArray(
8477
+ exceptAll(...args) {
8478
+ return _queryUnion(
8498
8479
  this.clone(),
8499
- "union",
8500
- args.map((arg) => ({ arg, kind: "EXCEPT ALL", wrap }))
8480
+ args,
8481
+ "EXCEPT ALL"
8482
+ );
8483
+ }
8484
+ }
8485
+
8486
+ var __defProp$4 = Object.defineProperty;
8487
+ var __defProps$1 = Object.defineProperties;
8488
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
8489
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
8490
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
8491
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
8492
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8493
+ var __spreadValues$4 = (a, b) => {
8494
+ for (var prop in b || (b = {}))
8495
+ if (__hasOwnProp$4.call(b, prop))
8496
+ __defNormalProp$4(a, prop, b[prop]);
8497
+ if (__getOwnPropSymbols$4)
8498
+ for (var prop of __getOwnPropSymbols$4(b)) {
8499
+ if (__propIsEnum$4.call(b, prop))
8500
+ __defNormalProp$4(a, prop, b[prop]);
8501
+ }
8502
+ return a;
8503
+ };
8504
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
8505
+ class WithMethods {
8506
+ with(name, second, third) {
8507
+ const q = this.clone();
8508
+ let [options, queryArg] = third ? [second, third] : [void 0, second];
8509
+ let query;
8510
+ if (typeof queryArg === "function") {
8511
+ const arg = q.queryBuilder.clone();
8512
+ arg.q.withShapes = q.q.withShapes;
8513
+ query = queryArg(arg);
8514
+ } else {
8515
+ query = queryArg;
8516
+ }
8517
+ if ((options == null ? void 0 : options.columns) === true) {
8518
+ options = __spreadProps$1(__spreadValues$4({}, options), {
8519
+ columns: Object.keys(query.shape)
8520
+ });
8521
+ }
8522
+ pushQueryValue(q, "with", { n: name, o: options, q: query });
8523
+ const shape = getShapeFromSelect(query, true);
8524
+ return setQueryObjectValue(q, "withShapes", name, shape);
8525
+ }
8526
+ withRecursive(name, ...args) {
8527
+ var _a, _b, _c;
8528
+ const q = this.clone();
8529
+ let [options, baseFn, recursiveFn] = args.length === 2 ? [{}, args[0], args[1]] : args;
8530
+ const arg = q.queryBuilder.clone();
8531
+ arg.q.withShapes = q.q.withShapes;
8532
+ let query = typeof baseFn === "function" ? baseFn(arg) : baseFn;
8533
+ const shape = ((_b = (_a = arg.q).withShapes) != null ? _b : _a.withShapes = {})[name] = getShapeFromSelect(
8534
+ query,
8535
+ true
8536
+ );
8537
+ const recursive = recursiveFn(arg);
8538
+ query = _queryUnion(query, [recursive], (_c = options.union) != null ? _c : "UNION ALL");
8539
+ options.recursive = true;
8540
+ if (options.columns === true) {
8541
+ options = __spreadProps$1(__spreadValues$4({}, options), {
8542
+ columns: Object.keys(shape)
8543
+ });
8544
+ }
8545
+ pushQueryValue(q, "with", { n: name, o: options, q: query });
8546
+ return setQueryObjectValue(q, "withShapes", name, shape);
8547
+ }
8548
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8549
+ withSql(name, ...args) {
8550
+ const q = this.clone();
8551
+ const [options, shape, sql] = args.length === 2 ? [void 0, args[0], args[1]] : args;
8552
+ pushQueryValue(q, "with", {
8553
+ n: name,
8554
+ o: options,
8555
+ s: sql(q)
8556
+ });
8557
+ return setQueryObjectValue(
8558
+ q,
8559
+ "withShapes",
8560
+ name,
8561
+ shape(this.columnTypes)
8501
8562
  );
8502
8563
  }
8503
8564
  }
@@ -9331,11 +9392,10 @@ const _queryUpdate = (query, arg) => {
9331
9392
  "q",
9332
9393
  "withShapes"
9333
9394
  );
9334
- pushQueryValue(query, "with", [
9335
- as,
9336
- orchidCore.emptyObject,
9337
- value
9338
- ]);
9395
+ pushQueryValue(query, "with", {
9396
+ n: as,
9397
+ q: value
9398
+ });
9339
9399
  set[key] = new RawSQL(`(SELECT * FROM "${as}")`);
9340
9400
  }
9341
9401
  } else {
@@ -9502,7 +9562,24 @@ class Update {
9502
9562
  * })
9503
9563
  * ```
9504
9564
  *
9505
- * It is not supported because query inside `WITH` cannot reference the table in `UPDATE`.
9565
+ * `update` can be used in {@link WithMethods.with} expressions:
9566
+ *
9567
+ * ```ts
9568
+ * db.$queryBuilder
9569
+ * // update record in one table
9570
+ * .with('a', db.table.find(1).select('id').update(data))
9571
+ * // update record in other table using the first table record id
9572
+ * .with('b', (q) =>
9573
+ * db.otherTable
9574
+ * .find(1)
9575
+ * .select('id')
9576
+ * .update({
9577
+ * ...otherData,
9578
+ * aId: () => q.from('a').get('id'),
9579
+ * }),
9580
+ * )
9581
+ * .from('b');
9582
+ * ```
9506
9583
  *
9507
9584
  * ### null, undefined, unknown columns
9508
9585
  *
@@ -11296,10 +11373,10 @@ orchidCore.applyMixins(QueryMethods, [
11296
11373
  AsMethods,
11297
11374
  AggregateMethods,
11298
11375
  Select,
11299
- From,
11376
+ FromMethods,
11300
11377
  Join,
11301
11378
  OnMethods,
11302
- With,
11379
+ WithMethods,
11303
11380
  Union,
11304
11381
  JsonModifiers,
11305
11382
  JsonMethods,
@@ -11933,7 +12010,7 @@ exports.EnumColumn = EnumColumn;
11933
12010
  exports.ExpressionMethods = ExpressionMethods;
11934
12011
  exports.FnExpression = FnExpression;
11935
12012
  exports.For = For;
11936
- exports.From = From;
12013
+ exports.FromMethods = FromMethods;
11937
12014
  exports.Having = Having;
11938
12015
  exports.InetColumn = InetColumn;
11939
12016
  exports.IntegerBaseColumn = IntegerBaseColumn;
@@ -12000,7 +12077,7 @@ exports.Update = Update;
12000
12077
  exports.VarCharColumn = VarCharColumn;
12001
12078
  exports.VirtualColumn = VirtualColumn;
12002
12079
  exports.Where = Where;
12003
- exports.With = With;
12080
+ exports.WithMethods = WithMethods;
12004
12081
  exports.XMLColumn = XMLColumn;
12005
12082
  exports._initQueryBuilder = _initQueryBuilder;
12006
12083
  exports._queryAfterSaveCommit = _queryAfterSaveCommit;
@@ -12048,6 +12125,7 @@ exports._queryRows = _queryRows;
12048
12125
  exports._querySelect = _querySelect;
12049
12126
  exports._queryTake = _queryTake;
12050
12127
  exports._queryTakeOptional = _queryTakeOptional;
12128
+ exports._queryUnion = _queryUnion;
12051
12129
  exports._queryUpdate = _queryUpdate;
12052
12130
  exports._queryUpdateOrThrow = _queryUpdateOrThrow;
12053
12131
  exports._queryUpdateRaw = _queryUpdateRaw;