pqb 0.71.3 → 0.72.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.js CHANGED
@@ -455,9 +455,14 @@ var RawSql = class extends Expression {
455
455
  };
456
456
  const isRawSQL = (arg) => arg instanceof RawSql;
457
457
  RawSql.prototype.type = ExpressionTypeMethod.prototype.type;
458
- const rawSqlToCode = (rawSql, t) => {
458
+ const rawSqlToCode = (rawSql, ctx) => {
459
459
  const { _sql: sql, _values: values } = rawSql;
460
- let code = `${t}.sql`;
460
+ let code;
461
+ if (typeof ctx === "string") code = `${ctx}.sql`;
462
+ else {
463
+ ctx.isSqlUsed = true;
464
+ code = ctx.sql ?? `${ctx.t}.sql`;
465
+ }
461
466
  code += typeof sql === "string" ? values ? `({ raw: '${sql.replace(/'/g, "\\'")}' })` : `\`${sql.replace(/`/g, "\\`")}\`` : templateLiteralSQLToCode(sql);
462
467
  if (values) code += `.values(${JSON.stringify(values)})`;
463
468
  return code;
@@ -593,6 +598,15 @@ const parseIndexOrExclude = (item) => {
593
598
  for (let i = item.columns.length - 1; i >= 0; i--) if (typeof item.columns[i] === "string") item.columns[i] = { column: item.columns[i] };
594
599
  return item;
595
600
  };
601
+ const getForeignKeyTableInstance = (table) => {
602
+ const item = "instance" in table ? table.instance() : new table();
603
+ if (!item.table) throw new Error("Referenced table is missing table property");
604
+ return {
605
+ ...item,
606
+ schema: typeof item.schema === "function" ? item.schema() : item.schema,
607
+ table: item.table
608
+ };
609
+ };
596
610
  function makeColumnNullable(column, inputSchema, outputSchema, querySchema) {
597
611
  const c = setColumnData(column, "isNullable", true);
598
612
  c.inputSchema = inputSchema;
@@ -664,20 +678,17 @@ var Column = class {
664
678
  * Or you can specify a callback that returns a value. This function will be called for each creating record. Such a default won't be applied to a database.
665
679
  *
666
680
  * ```ts
667
- * export class Table extends BaseTable {
668
- * readonly table = 'table';
669
- * columns = this.setColumns((t) => ({
670
- * // values as defaults:
671
- * int: t.integer().default(123),
672
- * text: t.text().default('text'),
681
+ * export const Table = defineTable('table', (t) => ({
682
+ * // values as defaults:
683
+ * int: t.integer().default(123),
684
+ * text: t.text().default('text'),
673
685
  *
674
- * // raw SQL default:
675
- * timestamp: t.timestamp().default(t.sql`now()`),
686
+ * // raw SQL default:
687
+ * timestamp: t.timestamp().default(t.sql`now()`),
676
688
  *
677
- * // runtime default, each new records gets a new random value:
678
- * random: t.numeric().default(() => Math.random()),
679
- * }));
680
- * }
689
+ * // runtime default, each new records gets a new random value:
690
+ * random: t.numeric().default(() => Math.random()),
691
+ * }));
681
692
  * ```
682
693
  *
683
694
  * @param value - default value or a function returning a value
@@ -772,14 +783,11 @@ var Column = class {
772
783
  * It won't be selected with `selectAll` or `select('*')` as well.
773
784
  *
774
785
  * ```ts
775
- * export class UserTable extends BaseTable {
776
- * readonly table = 'user';
777
- * columns = this.setColumns((t) => ({
778
- * id: t.identity().primaryKey(),
779
- * name: t.string(),
780
- * password: t.string().select(false),
781
- * }));
782
- * }
786
+ * export const UserTable = defineTable('user', (t) => ({
787
+ * id: t.identity().primaryKey(),
788
+ * name: t.string(),
789
+ * password: t.string().select(false),
790
+ * }));
783
791
  *
784
792
  * // only id and name are selected, without password
785
793
  * const user = await db.user.find(123);
@@ -822,20 +830,17 @@ var Column = class {
822
830
  * `readOnly` column can be used together with a `default`.
823
831
  *
824
832
  * ```ts
825
- * export class Table extends BaseTable {
826
- * readonly table = 'table';
827
- * columns = this.setColumns((t) => ({
828
- * id: t.identity().primaryKey(),
829
- * column: t.string().default(() => 'default value'),
830
- * another: t.string().readOnly(),
831
- * }));
832
- *
833
- * init(orm: typeof db) {
834
- * this.beforeSave(({ set }) => {
833
+ * export const Table = defineTable('table', (t) => ({
834
+ * id: t.identity().primaryKey(),
835
+ * column: t.string().default(() => 'default value'),
836
+ * another: t.string().nullable().readOnly(),
837
+ * })).init((orm: typeof db, hooks) => {
838
+ * hooks.beforeSave(({ columns, set }) => {
839
+ * if (columns.include('column')) {
835
840
  * set({ another: 'value' });
836
- * });
837
- * }
838
- * }
841
+ * }
842
+ * });
843
+ * });
839
844
  *
840
845
  * // later in the code
841
846
  * db.table.create({ column: 'value' }); // TS error, runtime error
@@ -851,13 +856,15 @@ var Column = class {
851
856
  * If no value or undefined is returned, the hook won't have any effect.
852
857
  *
853
858
  * ```ts
854
- * export class Table extends BaseTable {
855
- * readonly table = 'table';
856
- * columns = this.setColumns((t) => ({
857
- * id: t.identity().primaryKey(),
858
- * column: t.string().setOnCreate(() => 'value'),
859
- * }));
860
- * }
859
+ * export const Table = defineTable('table', (t) => ({
860
+ * id: t.identity().primaryKey(),
861
+ * some: t.number(),
862
+ * column: t
863
+ * .string()
864
+ * .setOnCreate(({ columns }) =>
865
+ * columns.include('some') ? 'value' : undefined,
866
+ * ),
867
+ * }));
861
868
  * ```
862
869
  */
863
870
  setOnCreate(fn) {
@@ -870,13 +877,15 @@ var Column = class {
870
877
  * If no value or undefined is returned, the hook won't have any effect.
871
878
  *
872
879
  * ```ts
873
- * export class Table extends BaseTable {
874
- * readonly table = 'table';
875
- * columns = this.setColumns((t) => ({
876
- * id: t.identity().primaryKey(),
877
- * column: t.string().setOnUpdate(() => 'value'),
878
- * }));
879
- * }
880
+ * export const Table = defineTable('table', (t) => ({
881
+ * id: t.identity().primaryKey(),
882
+ * some: t.number(),
883
+ * column: t
884
+ * .string()
885
+ * .setOnUpdate(({ columns }) =>
886
+ * columns.include('some') ? 'value' : undefined,
887
+ * ),
888
+ * }));
880
889
  * ```
881
890
  */
882
891
  setOnUpdate(fn) {
@@ -889,13 +898,15 @@ var Column = class {
889
898
  * If no value or undefined is returned, the hook won't have any effect.
890
899
  *
891
900
  * ```ts
892
- * export class Table extends BaseTable {
893
- * readonly table = 'table';
894
- * columns = this.setColumns((t) => ({
895
- * id: t.identity().primaryKey(),
896
- * column: t.string().setOnSave(() => 'value'),
897
- * }));
898
- * }
901
+ * export const Table = defineTable('table', (t) => ({
902
+ * id: t.identity().primaryKey(),
903
+ * some: t.number(),
904
+ * column: t
905
+ * .string()
906
+ * .setOnSave(({ columns }) =>
907
+ * columns.include('some') ? 'value' : undefined,
908
+ * ),
909
+ * }));
899
910
  * ```
900
911
  */
901
912
  setOnSave(fn) {
@@ -910,14 +921,11 @@ var Column = class {
910
921
  * Using `primaryKey` on a `uuid` column will automatically add a [gen_random_uuid](https://www.postgresql.org/docs/current/functions-uuid.html) default.
911
922
  *
912
923
  * ```ts
913
- * export class Table extends BaseTable {
914
- * readonly table = 'table';
915
- * columns = this.setColumns((t) => ({
916
- * id: t.uuid().primaryKey(),
917
- * // database-level name can be passed:
918
- * id: t.uuid().primaryKey('primary_key_name'),
919
- * }));
920
- * }
924
+ * export const Table = defineTable('table', (t) => ({
925
+ * id: t.uuid().primaryKey(),
926
+ * // optionally, specify a database-level constraint name:
927
+ * id: t.uuid().primaryKey('primary_key_name'),
928
+ * }));
921
929
  *
922
930
  * // primary key can be used by `find` later:
923
931
  * db.table.find('97ba9e78-7510-415a-9c03-23d440aec443');
@@ -1307,8 +1315,8 @@ const codeToString = (code, tabs, shift) => {
1307
1315
  * @param t - column types variable name
1308
1316
  * @param value - column default
1309
1317
  */
1310
- const columnDefaultArgumentToCode = (t, value) => {
1311
- if (typeof value === "object" && value && isRawSQL(value)) return rawSqlToCode(value, t);
1318
+ const columnDefaultArgumentToCode = (ctx, value) => {
1319
+ if (typeof value === "object" && value && isRawSQL(value)) return rawSqlToCode(value, ctx);
1312
1320
  else if (typeof value === "function") return value.toString();
1313
1321
  else if (typeof value === "string") return singleQuote(value);
1314
1322
  else return JSON.stringify(value);
@@ -1552,26 +1560,26 @@ const excludeInnerToCode = (item, t) => {
1552
1560
  return code;
1553
1561
  };
1554
1562
  const excludeToCode = indexOrExcludeToCode(excludeInnerToCode);
1555
- const constraintToCode = (item, t, m, prefix) => {
1556
- const code = constraintInnerToCode(item, t, m);
1563
+ const constraintToCode = (item, t, m, prefix, ctx) => {
1564
+ const code = constraintInnerToCode(item, t, m, ctx);
1557
1565
  if (prefix) code[0] = prefix + code[0];
1558
1566
  const last = code[code.length - 1];
1559
1567
  if (typeof last === "string" && !last.endsWith(",")) code[code.length - 1] += ",";
1560
1568
  return code;
1561
1569
  };
1562
- const constraintInnerToCode = (item, t, m) => {
1570
+ const constraintInnerToCode = (item, t, m, ctx) => {
1563
1571
  if (item.references) return [
1564
1572
  `${t}.foreignKey(`,
1565
1573
  referencesArgsToCode(item.references, item.name, m),
1566
1574
  "),"
1567
1575
  ];
1568
- return [`${t}.check(${rawSqlToCode(item.check, t)}${item.name ? `, ${singleQuote(item.name)}` : ""})`];
1576
+ return [`${t}.check(${rawSqlToCode(item.check, ctx ?? t)}${item.name ? `, ${singleQuote(item.name)}` : ""})`];
1569
1577
  };
1570
1578
  const referencesArgsToCode = ({ columns, fnOrTable, foreignColumns, options }, name = options?.name || false, m) => {
1571
1579
  const args = [];
1572
1580
  args.push(`${singleQuoteArray(columns)},`);
1573
1581
  if (m && typeof fnOrTable !== "string") {
1574
- const { schema, table } = new (fnOrTable())();
1582
+ const { schema, table } = getForeignKeyTableInstance(fnOrTable());
1575
1583
  fnOrTable = schema ? `${schema}.${table}` : table;
1576
1584
  }
1577
1585
  args.push(`${typeof fnOrTable === "string" ? singleQuote(fnOrTable) : fnOrTable.toString()},`);
@@ -1600,7 +1608,7 @@ const columnForeignKeysToCode = (foreignKeys, migration) => {
1600
1608
  const foreignKeyArgumentToCode = ({ fnOrTable, foreignColumns, options = emptyObject }, migration) => {
1601
1609
  const code = [];
1602
1610
  if (migration && typeof fnOrTable !== "string") {
1603
- const { schema, table } = new (fnOrTable())();
1611
+ const { schema, table } = getForeignKeyTableInstance(fnOrTable());
1604
1612
  fnOrTable = schema ? `${schema}.${table}` : table;
1605
1613
  }
1606
1614
  code.push(typeof fnOrTable === "string" ? singleQuote(fnOrTable) : fnOrTable.toString());
@@ -1668,7 +1676,7 @@ const columnExcludesToCode = (items) => {
1668
1676
  return code;
1669
1677
  };
1670
1678
  const columnCheckToCode = (ctx, checks) => {
1671
- return checks.map(({ sql, name }) => `.check(${rawSqlToCode(sql, ctx.t)}${name ? `, '${name}'` : ""})`).join("");
1679
+ return checks.map(({ sql, name }) => `.check(${rawSqlToCode(sql, ctx)}${name ? `, '${name}'` : ""})`).join("");
1672
1680
  };
1673
1681
  const identityToCode = (identity, dataType) => {
1674
1682
  const code = [];
@@ -1704,7 +1712,7 @@ const columnCode = (type, ctx, key, code) => {
1704
1712
  if (data.explicitSelect) addCode(code, ".select(false)");
1705
1713
  if (data.isNullable) addCode(code, ".nullable()");
1706
1714
  if (data.as && !ctx.migration) addCode(code, `.as(${data.as.toCode(ctx, key)})`);
1707
- if (data.default !== void 0 && data.default !== data.defaultDefault && (!ctx.migration || typeof data.default !== "function")) addCode(code, `.default(${columnDefaultArgumentToCode(ctx.t, data.default)})`);
1715
+ if (data.default !== void 0 && data.default !== data.defaultDefault && (!ctx.migration || typeof data.default !== "function")) addCode(code, `.default(${columnDefaultArgumentToCode(ctx, data.default)})`);
1708
1716
  if (data.indexes) for (const part of columnIndexesToCode(data.indexes)) addCode(code, part);
1709
1717
  if (data.excludes) for (const part of columnExcludesToCode(data.excludes)) addCode(code, part);
1710
1718
  if (data.comment) addCode(code, `.comment(${singleQuote(data.comment)})`);
@@ -3742,24 +3750,19 @@ var QueryStorage = class {
3742
3750
  * so later they can be identified when handling after commit errors.
3743
3751
  *
3744
3752
  * ```ts
3745
- * class SomeTable extends BaseTable {
3746
- * readonly table = 'someTable';
3747
- * columns = this.setColumns((t) => ({
3748
- * ...someColumns,
3749
- * }));
3750
- *
3751
- * init(orm: typeof db) {
3752
- * // anonymous funciton - has no name
3753
- * this.afterCreateCommit([], async () => {
3754
- * // ...
3755
- * });
3753
+ * export const SomeTable = defineTable('someTable', (t) => ({
3754
+ * ...someColumns,
3755
+ * })).init((orm: typeof db, hooks) => {
3756
+ * // anonymous funciton - has no name
3757
+ * hooks.afterCreateCommit([], async () => {
3758
+ * // ...
3759
+ * });
3756
3760
  *
3757
- * // named function
3758
- * this.afterCreateCommit([], function myHook() => {
3759
- * // ...
3760
- * });
3761
- * }
3762
- * }
3761
+ * // named function
3762
+ * hooks.afterCreateCommit([], function myHook() {
3763
+ * // ...
3764
+ * });
3765
+ * });
3763
3766
  * ```
3764
3767
  */
3765
3768
  var AfterCommitError = class extends OrchidOrmError {
@@ -4512,21 +4515,16 @@ const _unscope = (q, scope) => {
4512
4515
  * If you define a scope with name `default`, it will be applied for all table queries by default.
4513
4516
  *
4514
4517
  * ```ts
4515
- * import { BaseTable } from './baseTable';
4518
+ * import { defineTable } from './table-factory';
4516
4519
  *
4517
- * export class SomeTable extends BaseTable {
4518
- * readonly table = 'some';
4519
- * columns = this.setColumns((t) => ({
4520
- * id: t.identity().primaryKey(),
4521
- * hidden: t.boolean(),
4522
- * active: t.boolean(),
4523
- * }));
4524
- *
4525
- * scopes = this.setScopes({
4526
- * default: (q) => q.where({ hidden: false }),
4527
- * active: (q) => q.where({ active: true }),
4528
- * });
4529
- * }
4520
+ * export const SomeTable = defineTable('some', (t) => ({
4521
+ * id: t.identity().primaryKey(),
4522
+ * hidden: t.boolean(),
4523
+ * active: t.boolean(),
4524
+ * })).scopes({
4525
+ * default: (q) => q.where({ hidden: false }),
4526
+ * active: (q) => q.where({ active: true }),
4527
+ * });
4530
4528
  *
4531
4529
  * const db = orchidORM(
4532
4530
  * { databaseURL: '...' },
@@ -5834,7 +5832,7 @@ var Where = class {
5834
5832
  * Constructing `WHERE` conditions:
5835
5833
  *
5836
5834
  * ```ts
5837
- * import { sql } from './baseTable'
5835
+ * import { sql } from './table-factory';
5838
5836
  *
5839
5837
  * db.table.where({
5840
5838
  * // column of the current table
@@ -5850,7 +5848,7 @@ var Where = class {
5850
5848
  * },
5851
5849
  *
5852
5850
  * // where column equals to raw SQL
5853
- * // import `sql` from your `BaseTable`
5851
+ * // import `sql` from your table factory
5854
5852
  * column: sql`sql expression`,
5855
5853
  * // or use `(q) => sql` for the same
5856
5854
  * column2: (q) => sql`sql expression`,
@@ -6589,7 +6587,8 @@ const tableColumnToSql = (ctx, queryData, shape, table, key, quotedAs, select, a
6589
6587
  } else {
6590
6588
  const tableName = _getQueryAliasOrName(queryData, table);
6591
6589
  const quoted = `"${table}"`;
6592
- const col = quoted === quotedAs ? shape[key] : queryData.joinedShapes?.[tableName]?.[key];
6590
+ const joined = queryData.joinedShapes?.[tableName];
6591
+ const col = joined ? joined[key] : quoted === quotedAs ? shape[key] : void 0;
6593
6592
  if (jsonList && as) jsonList[as] = col && getSelectedColumnData(col);
6594
6593
  if (col?.data.selectSql) sql = `(${col.data.selectSql.toSQL(ctx, quoted)})`;
6595
6594
  else if (col?.data.name) sql = `"${tableName}"."${col.data.name}"`;
@@ -9172,31 +9171,26 @@ var QueryCreate = class {
9172
9171
  * A primary key or a unique index for a **single** column can be fined on a column:
9173
9172
  *
9174
9173
  * ```ts
9175
- * export class MyTable extends BaseTable {
9176
- * columns = this.setColumns((t) => ({
9177
- * pkey: t.uuid().primaryKey(),
9178
- * unique: t.string().unique(),
9179
- * }));
9180
- * }
9174
+ * export const MyTable = defineTable('myTable', (t) => ({
9175
+ * pkey: t.uuid().primaryKey(),
9176
+ * unique: t.string().unique(),
9177
+ * }));
9181
9178
  * ```
9182
9179
  *
9183
9180
  * But for composite primary keys or indexes (having multiple columns), define it in a separate function:
9184
9181
  *
9185
9182
  * ```ts
9186
- * export class MyTable extends BaseTable {
9187
- * columns = this.setColumns(
9188
- * (t) => ({
9189
- * one: t.integer(),
9190
- * two: t.string(),
9191
- * three: t.boolean(),
9192
- * }),
9193
- * (t) => [t.primaryKey(['one', 'two']), t.unique(['two', 'three'])],
9194
- * );
9195
- * }
9183
+ * export const MyTable = defineTable('myTable', (t) => ({
9184
+ * one: t.integer(),
9185
+ * two: t.string(),
9186
+ * three: t.boolean(),
9187
+ * }))
9188
+ * .primaryKey(['one', 'two'])
9189
+ * .unique(['two', 'three']);
9196
9190
  * ```
9197
9191
  * :::
9198
9192
  *
9199
- * You can use the `sql` function exported from your `BaseTable` file in onConflict.
9193
+ * You can use the `sql` function exported from your table factory file in onConflict.
9200
9194
  * It can be useful to specify a condition when you have a partial index:
9201
9195
  *
9202
9196
  * ```ts
@@ -9586,12 +9580,14 @@ const toSql = (table, type, topCtx, isSubSql, cteName, calledByThen, dontAddTabl
9586
9580
  if (upsertOrCreate.q.returnType === "oneOrThrow") upsertOrCreate.q.returnType = "one";
9587
9581
  else if (upsertOrCreate.q.returnType === "valueOrThrow") upsertOrCreate.q.returnType = "value";
9588
9582
  const { as, makeSql: makeFirstSql } = moveMutativeQueryToCteBase(toSql, ctx, upsertOrCreate, upsertUpdate ? "update" : null);
9583
+ query.upsertUpdateAsFns?.forEach((fn) => fn(as));
9589
9584
  upsertOrCreate.q.or = upsertOrCreate.q.scopes = void 0;
9590
9585
  upsertOrCreate.q.and = [new RawSql(`NOT EXISTS (SELECT 1 FROM "${as}")`)];
9591
9586
  if (query.upsertInsert) {
9592
9587
  _queryInsert(upsertOrCreate, query.upsertInsert());
9593
9588
  upsertOrCreate.q.type = "upsert";
9594
9589
  }
9590
+ upsertOrCreate.q.with = query.upsertCreateWith;
9595
9591
  upsertOrCreate.q.appendQueries = query.upsertCreateAppendQueries;
9596
9592
  upsertOrCreate.q.asFns = query.upsertCreateAsFns;
9597
9593
  const { makeSql: makeSecondSql } = moveMutativeQueryToCteBase(toSql, ctx, upsertOrCreate, "insert");
@@ -10069,7 +10065,16 @@ const _joinLateral = (self, type, joinQuery, as, innerJoinLateral) => {
10069
10065
  const joinedAs = getQueryAs(query);
10070
10066
  setObjectValueImmutable(joinQuery.q, "joinedShapes", joinedAs, query.q.selectShape);
10071
10067
  }
10072
- const shape = joinQuery.table && joinQuery.q.joinedShapes?.[joinQuery.table] || joinQuery.q.joinedShapes?.[joinAs] || getShapeFromSelect(joinQuery, true);
10068
+ const joinedShapeMayHaveNames = joinQuery.table && joinQuery.q.joinedShapes?.[joinQuery.table] || joinQuery.q.joinedShapes?.[joinAs];
10069
+ let joinedShape;
10070
+ if (joinedShapeMayHaveNames) {
10071
+ joinedShape = {};
10072
+ for (const key in joinedShapeMayHaveNames) {
10073
+ const column = joinedShapeMayHaveNames[key];
10074
+ joinedShape[key] = column.data.name ? setColumnData(column, "name", void 0) : column;
10075
+ }
10076
+ }
10077
+ const shape = joinedShape || getShapeFromSelect(joinQuery, true);
10073
10078
  setObjectValueImmutable(query.q, "joinedShapes", joinAs, shape);
10074
10079
  if (joinValue) setObjectValueImmutable(query.q, "valuesJoinedAs", joinAs, joinValueAs);
10075
10080
  setObjectValueImmutable(query.q, "joinedParsers", joinValueAs || joinAs, getQueryParsers(joinQuery));
@@ -10154,36 +10159,21 @@ var QueryJoin = class {
10154
10159
  * For the following examples, imagine you have a `User` table with `id` and `name`, and `Message` table with `id`, `text`, messages belongs to user via `userId` column:
10155
10160
  *
10156
10161
  * ```ts
10157
- * export class UserTable extends BaseTable {
10158
- * readonly table = 'user';
10159
- * columns = this.setColumns((t) => ({
10160
- * id: t.identity().primaryKey(),
10161
- * name: t.text(),
10162
- * }));
10163
- *
10164
- * relations = {
10165
- * messages: this.hasMany(() => MessageTable, {
10166
- * primaryKey: 'id',
10167
- * foreignKey: 'userId',
10168
- * }),
10169
- * };
10170
- * }
10171
- *
10172
- * export class MessageTable extends BaseTable {
10173
- * readonly table = 'message';
10174
- * columns = this.setColumns((t) => ({
10175
- * id: t.identity().primaryKey(),
10176
- * text: t.text(),
10177
- * ...t.timestamps(),
10178
- * }));
10162
+ * export const UserTable = defineTable('user', (t) => ({
10163
+ * id: t.identity().primaryKey(),
10164
+ * name: t.text(),
10165
+ * })).relations((user) => ({
10166
+ * messages: user('id').hasMany(() => MessageTable('userId')),
10167
+ * }));
10179
10168
  *
10180
- * relations = {
10181
- * user: this.belongsTo(() => UserTable, {
10182
- * primaryKey: 'id',
10183
- * foreignKey: 'userId',
10184
- * }),
10185
- * };
10186
- * }
10169
+ * export const MessageTable = defineTable('message', (t) => ({
10170
+ * id: t.identity().primaryKey(),
10171
+ * userId: t.integer(),
10172
+ * text: t.text(),
10173
+ * ...t.timestamps(),
10174
+ * })).relations((message) => ({
10175
+ * user: message('userId').belongsTo(() => UserTable('id')),
10176
+ * }));
10187
10177
  * ```
10188
10178
  *
10189
10179
  * `join` is a method for SQL `JOIN`, which is equivalent to `INNER JOIN`, `LEFT INNERT JOIN`.
@@ -10380,7 +10370,7 @@ var QueryJoin = class {
10380
10370
  * ```ts
10381
10371
  * db.user.join(
10382
10372
  * db.message,
10383
- * // `sql` can be imported from your `BaseTable` file
10373
+ * // `sql` can be imported from your table factory file
10384
10374
  * sql`lower("message"."text") = lower("user"."name")`,
10385
10375
  * );
10386
10376
  * ```
@@ -11097,7 +11087,7 @@ const selectColumn = (query, q, key, columnAs, columnAlias) => {
11097
11087
  };
11098
11088
  const getShapeFromSelect = (q, isSubQuery) => {
11099
11089
  const query = q.q;
11100
- const { selectShape: shape } = query;
11090
+ const { selectShape } = query;
11101
11091
  let select;
11102
11092
  if (query.selectedComputeds) {
11103
11093
  select = query.select ? [...query.select] : [];
@@ -11107,18 +11097,18 @@ const getShapeFromSelect = (q, isSubQuery) => {
11107
11097
  if (!select) if (query.type) result = {};
11108
11098
  else if (isSubQuery) {
11109
11099
  result = {};
11110
- for (const key in shape) {
11111
- const column = shape[key];
11100
+ for (const key in selectShape) {
11101
+ const column = selectShape[key];
11112
11102
  if (!column.data.explicitSelect) result[key] = column.data.name ? setColumnData(column, "name", void 0) : column;
11113
11103
  }
11114
- } else result = shape;
11104
+ } else result = selectShape;
11115
11105
  else {
11116
11106
  result = {};
11117
- for (const item of select) if (typeof item === "string") addColumnToShapeFromSelect(q, item, shape, query, result, isSubQuery);
11107
+ for (const item of select) if (typeof item === "string") addColumnToShapeFromSelect(q, item, selectShape, query, result, isSubQuery);
11118
11108
  else if (isExpression(item)) result.value = item.result.value;
11119
11109
  else if (item && "selectAs" in item) for (const key in item.selectAs) {
11120
11110
  const it = item.selectAs[key];
11121
- if (typeof it === "string") addColumnToShapeFromSelect(q, it, shape, query, result, isSubQuery, key);
11111
+ if (typeof it === "string") addColumnToShapeFromSelect(q, it, selectShape, query, result, isSubQuery, key);
11122
11112
  else if (isExpression(it)) result[key] = it.result.value || UnknownColumn.instance;
11123
11113
  else if (it) {
11124
11114
  const { returnType } = it.q;
@@ -11476,6 +11466,7 @@ function _orCreate(query, data, updateData, mergeData) {
11476
11466
  const { q } = query;
11477
11467
  q.returnsOne = true;
11478
11468
  if (!q.select) q.returnType = "void";
11469
+ q.type = "upsert";
11479
11470
  if (typeof data === "function") q.upsertInsert = () => mergeData ? {
11480
11471
  ...mergeData,
11481
11472
  ...data(updateData)
@@ -12465,6 +12456,16 @@ const _appendQuery = (main, append, asFn) => {
12465
12456
  const _appendQueryOnUpsertCreate = (main, append, asFn) => {
12466
12457
  return pushQueryValueImmutable(pushQueryValueImmutable(main, "upsertCreateAppendQueries", prepareSubQueryForSql(main, append)), "upsertCreateAsFns", asFn);
12467
12458
  };
12459
+ const _onUpsertUpdate = (q, asFn) => {
12460
+ return pushQueryValueImmutable(q, "upsertUpdateAsFns", asFn);
12461
+ };
12462
+ const _prependWithOnUpsertCreate = (q, name, query) => {
12463
+ const prev = q.q.with;
12464
+ q.q.with = q.q.upsertCreateWith;
12465
+ _prependWith(q, name, query);
12466
+ q.q.upsertCreateWith = q.q.with;
12467
+ q.q.with = prev;
12468
+ };
12468
12469
  const mergableObjects = new Set([
12469
12470
  "selectShape",
12470
12471
  "withShapes",
@@ -12688,12 +12689,12 @@ var SearchMethods = class {
12688
12689
  *
12689
12690
  * By default, the search language is English.
12690
12691
  *
12691
- * You can set a different default language in the `createBaseTable` config:
12692
+ * You can set a different default language in the `createTableFactory` config:
12692
12693
  *
12693
12694
  * ```ts
12694
- * import { createBaseTable } from 'orchid-orm';
12695
+ * import { createTableFactory } from 'orchid-orm';
12695
12696
  *
12696
- * export const BaseTable = createBaseTable({
12697
+ * export const { defineTable, defineView, sql } = createTableFactory({
12697
12698
  * language: 'swedish',
12698
12699
  * });
12699
12700
  * ```
@@ -13079,20 +13080,20 @@ const _softDelete = (column, customNowSQL) => {
13079
13080
  * All queries on such table will filter out deleted records by default.
13080
13081
  *
13081
13082
  * ```ts
13082
- * import { BaseTable } from './baseTable';
13083
- *
13084
- * export class SomeTable extends BaseTable {
13085
- * readonly table = 'some';
13086
- * columns = this.setColumns((t) => ({
13087
- * id: t.identity().primaryKey(),
13088
- * deletedAt: t.timestamp().nullable(),
13089
- * }));
13083
+ * import { defineTable } from './table-factory';
13090
13084
  *
13085
+ * export const SomeTable = defineTable('some', (t) => ({
13086
+ * id: t.identity().primaryKey(),
13087
+ * deletedAt: t.timestamp().nullable(),
13088
+ * }))
13091
13089
  * // true is for using `deletedAt` column
13092
- * readonly softDelete = true;
13093
- * // or provide a different column name
13094
- * readonly softDelete = 'myDeletedAt';
13095
- * }
13090
+ * .softDelete();
13091
+ *
13092
+ * // or provide a different column name
13093
+ * export const OtherTable = defineTable('other', (t) => ({
13094
+ * id: t.identity().primaryKey(),
13095
+ * myDeletedAt: t.timestamp().nullable(),
13096
+ * })).softDelete('myDeletedAt');
13096
13097
  *
13097
13098
  * const db = orchidORM(
13098
13099
  * { databaseURL: '...' },
@@ -14389,11 +14390,14 @@ function getColumnInfo(query, column) {
14389
14390
  };
14390
14391
  return q;
14391
14392
  }
14393
+ const columnsSql = (shape, columns) => {
14394
+ return columns.map((item) => `"${shape[item]?.data.name || item}"`).join(", ");
14395
+ };
14392
14396
  const makeCopySql = (table, copy) => {
14393
14397
  const ctx = newToSqlCtx(table);
14394
14398
  const { q } = table;
14395
14399
  const quotedAs = `"${q.as || table.table}"`;
14396
- const columns = copy.columns ? `(${copy.columns.map((item) => `"${table.shape[item]?.data.name || item}"`).join(", ")})` : "";
14400
+ const columns = copy.columns ? `(${columnsSql(table.shape, copy.columns)})` : "";
14397
14401
  const target = "from" in copy ? copy.from : copy.to;
14398
14402
  const quotedTable = quoteTableWithSchema(table);
14399
14403
  ctx.sql.push(`COPY ${quotedTable}${columns} ${"from" in copy ? "FROM" : "TO"} ${typeof target === "string" ? escapeString(target) : `PROGRAM ${escapeString(target.program)}`}`);
@@ -14406,9 +14410,9 @@ const makeCopySql = (table, copy) => {
14406
14410
  if (copy.header) options.push(`HEADER ${copy.header}`);
14407
14411
  if (copy.quote) options.push(`QUOTE ${escapeString(copy.quote)}`);
14408
14412
  if (copy.escape) options.push(`ESCAPE ${escapeString(copy.escape)}`);
14409
- if (copy.forceQuote) options.push(`FORCE_QUOTE ${copy.forceQuote === "*" ? "*" : `(${copy.forceQuote.map((x) => `"${x}"`).join(", ")})`}`);
14410
- if (copy.forceNotNull) options.push(`FORCE_NOT_NULL (${copy.forceNotNull.map((x) => `"${x}"`).join(", ")})`);
14411
- if (copy.forceNull) options.push(`FORCE_NULL (${copy.forceNull.map((x) => `"${x}"`).join(", ")})`);
14413
+ if (copy.forceQuote) options.push(`FORCE_QUOTE ${copy.forceQuote === "*" ? "*" : `(${columnsSql(table.shape, copy.forceQuote)})`}`);
14414
+ if (copy.forceNotNull) options.push(`FORCE_NOT_NULL (${columnsSql(table.shape, copy.forceNotNull)})`);
14415
+ if (copy.forceNull) options.push(`FORCE_NULL (${columnsSql(table.shape, copy.forceNull)})`);
14412
14416
  if (copy.encoding) options.push(`ENCODING ${escapeString(copy.encoding)}`);
14413
14417
  ctx.sql.push(`WITH (${options.join(", ")})`);
14414
14418
  }
@@ -14599,8 +14603,10 @@ exports._clone = _clone;
14599
14603
  exports._createDbSqlMethod = _createDbSqlMethod;
14600
14604
  exports._hookSelectColumns = _hookSelectColumns;
14601
14605
  exports._initQueryBuilder = _initQueryBuilder;
14606
+ exports._onUpsertUpdate = _onUpsertUpdate;
14602
14607
  exports._orCreate = _orCreate;
14603
14608
  exports._prependWith = _prependWith;
14609
+ exports._prependWithOnUpsertCreate = _prependWithOnUpsertCreate;
14604
14610
  exports._queryCreate = _queryCreate;
14605
14611
  exports._queryCreateMany = _queryCreateMany;
14606
14612
  exports._queryCreateManyFrom = _queryCreateManyFrom;
@@ -14634,6 +14640,7 @@ exports.codeToString = codeToString;
14634
14640
  exports.colors = colors;
14635
14641
  exports.columnsShapeToCode = columnsShapeToCode;
14636
14642
  exports.constraintInnerToCode = constraintInnerToCode;
14643
+ exports.constraintToCode = constraintToCode;
14637
14644
  exports.consumeColumnName = consumeColumnName;
14638
14645
  exports.copyTableData = copyTableData;
14639
14646
  exports.createDbWithAdapter = createDbWithAdapter;
@@ -14644,6 +14651,7 @@ exports.emptyObject = emptyObject;
14644
14651
  exports.escapeForMigration = escapeForMigration;
14645
14652
  exports.escapeString = escapeString;
14646
14653
  exports.excludeInnerToCode = excludeInnerToCode;
14654
+ exports.excludeToCode = excludeToCode;
14647
14655
  exports.exhaustive = exhaustive;
14648
14656
  exports.getCallerFilePath = getCallerFilePath;
14649
14657
  exports.getClonedQueryData = getClonedQueryData;
@@ -14664,6 +14672,7 @@ exports.getSqlText = getSqlText;
14664
14672
  exports.getStackTrace = getStackTrace;
14665
14673
  exports.getSupportedDefaultPrivileges = getSupportedDefaultPrivileges;
14666
14674
  exports.indexInnerToCode = indexInnerToCode;
14675
+ exports.indexToCode = indexToCode;
14667
14676
  exports.internalSchemaConfig = internalSchemaConfig;
14668
14677
  exports.isExpression = isExpression;
14669
14678
  exports.isQueryReturnsAll = isQueryReturnsAll;