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.d.ts +335 -356
- package/dist/index.js +190 -181
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +186 -182
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +8038 -8072
- package/dist/internal.js +6254 -0
- package/dist/internal.js.map +1 -1
- package/dist/internal.mjs +6232 -7
- package/dist/internal.mjs.map +1 -1
- package/package.json +1 -1
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,
|
|
458
|
+
const rawSqlToCode = (rawSql, ctx) => {
|
|
459
459
|
const { _sql: sql, _values: values } = rawSql;
|
|
460
|
-
let code
|
|
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
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
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
|
-
*
|
|
675
|
-
*
|
|
686
|
+
* // raw SQL default:
|
|
687
|
+
* timestamp: t.timestamp().default(t.sql`now()`),
|
|
676
688
|
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
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
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
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
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
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
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
*
|
|
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
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
*
|
|
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
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
896
|
-
*
|
|
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
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
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 = (
|
|
1311
|
-
if (typeof value === "object" && value && isRawSQL(value)) return rawSqlToCode(value,
|
|
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 } =
|
|
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 } =
|
|
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
|
|
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
|
|
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
|
-
*
|
|
3746
|
-
*
|
|
3747
|
-
*
|
|
3748
|
-
*
|
|
3749
|
-
*
|
|
3750
|
-
*
|
|
3751
|
-
*
|
|
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
|
-
*
|
|
3758
|
-
*
|
|
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 {
|
|
4518
|
+
* import { defineTable } from './table-factory';
|
|
4516
4519
|
*
|
|
4517
|
-
* export
|
|
4518
|
-
*
|
|
4519
|
-
*
|
|
4520
|
-
*
|
|
4521
|
-
*
|
|
4522
|
-
*
|
|
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 './
|
|
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
|
|
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
|
|
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
|
|
9176
|
-
*
|
|
9177
|
-
*
|
|
9178
|
-
*
|
|
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
|
|
9187
|
-
*
|
|
9188
|
-
*
|
|
9189
|
-
*
|
|
9190
|
-
*
|
|
9191
|
-
*
|
|
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
|
|
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
|
|
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
|
|
10158
|
-
*
|
|
10159
|
-
*
|
|
10160
|
-
*
|
|
10161
|
-
*
|
|
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
|
-
*
|
|
10181
|
-
*
|
|
10182
|
-
*
|
|
10183
|
-
*
|
|
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
|
|
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
|
|
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
|
|
11111
|
-
const column =
|
|
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 =
|
|
11104
|
+
} else result = selectShape;
|
|
11115
11105
|
else {
|
|
11116
11106
|
result = {};
|
|
11117
|
-
for (const item of select) if (typeof item === "string") addColumnToShapeFromSelect(q, item,
|
|
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,
|
|
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 `
|
|
12692
|
+
* You can set a different default language in the `createTableFactory` config:
|
|
12692
12693
|
*
|
|
12693
12694
|
* ```ts
|
|
12694
|
-
* import {
|
|
12695
|
+
* import { createTableFactory } from 'orchid-orm';
|
|
12695
12696
|
*
|
|
12696
|
-
* export const
|
|
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 {
|
|
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
|
-
*
|
|
13093
|
-
*
|
|
13094
|
-
*
|
|
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 ? `(${
|
|
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 === "*" ? "*" : `(${
|
|
14410
|
-
if (copy.forceNotNull) options.push(`FORCE_NOT_NULL (${
|
|
14411
|
-
if (copy.forceNull) options.push(`FORCE_NULL (${
|
|
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;
|