neoorm 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/bin/neoorm.d.ts +1 -1
- package/dist/bin/neoorm.d.ts.map +1 -1
- package/dist/bin/neoorm.js +131 -57
- package/dist/bin/neoorm.js.map +1 -1
- package/dist/codegen/diff-manifest.d.ts.map +1 -1
- package/dist/codegen/diff-manifest.js +106 -4
- package/dist/codegen/diff-manifest.js.map +1 -1
- package/dist/codegen/generate-summary.d.ts +1 -0
- package/dist/codegen/generate-summary.d.ts.map +1 -1
- package/dist/codegen/generate-summary.js +3 -0
- package/dist/codegen/generate-summary.js.map +1 -1
- package/dist/codegen/generate.d.ts +7 -1
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +53 -20
- package/dist/codegen/generate.js.map +1 -1
- package/dist/codegen/schema-to-manifest.d.ts.map +1 -1
- package/dist/codegen/schema-to-manifest.js +302 -22
- package/dist/codegen/schema-to-manifest.js.map +1 -1
- package/dist/codegen/validation/emit-elysia.d.ts +4 -0
- package/dist/codegen/validation/emit-elysia.d.ts.map +1 -0
- package/dist/codegen/validation/emit-elysia.js +304 -0
- package/dist/codegen/validation/emit-elysia.js.map +1 -0
- package/dist/codegen/validation/types.d.ts +1 -1
- package/dist/codegen/validation/types.js +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/datasource-provider.d.ts +5 -1
- package/dist/datasource-provider.d.ts.map +1 -1
- package/dist/datasource-provider.js +21 -2
- package/dist/datasource-provider.js.map +1 -1
- package/dist/dialect/column-kind-support.d.ts +9 -0
- package/dist/dialect/column-kind-support.d.ts.map +1 -0
- package/dist/dialect/column-kind-support.js +25 -0
- package/dist/dialect/column-kind-support.js.map +1 -0
- package/dist/dialect/fk.d.ts +30 -1
- package/dist/dialect/fk.d.ts.map +1 -1
- package/dist/dialect/fk.js +113 -0
- package/dist/dialect/fk.js.map +1 -1
- package/dist/dialect/index.d.ts +5 -1
- package/dist/dialect/index.d.ts.map +1 -1
- package/dist/dialect/index.js +4 -0
- package/dist/dialect/index.js.map +1 -1
- package/dist/dialect/mariadb.d.ts +4 -0
- package/dist/dialect/mariadb.d.ts.map +1 -0
- package/dist/dialect/mariadb.js +15 -0
- package/dist/dialect/mariadb.js.map +1 -0
- package/dist/dialect/mariadb.test.d.ts +2 -0
- package/dist/dialect/mariadb.test.d.ts.map +1 -0
- package/dist/dialect/mariadb.test.js +151 -0
- package/dist/dialect/mariadb.test.js.map +1 -0
- package/dist/dialect/mysql-family.d.ts +14 -0
- package/dist/dialect/mysql-family.d.ts.map +1 -0
- package/dist/dialect/mysql-family.js +453 -0
- package/dist/dialect/mysql-family.js.map +1 -0
- package/dist/dialect/mysql.d.ts +6 -0
- package/dist/dialect/mysql.d.ts.map +1 -0
- package/dist/dialect/mysql.js +16 -0
- package/dist/dialect/mysql.js.map +1 -0
- package/dist/dialect/mysql.test.d.ts +2 -0
- package/dist/dialect/mysql.test.d.ts.map +1 -0
- package/dist/dialect/mysql.test.js +211 -0
- package/dist/dialect/mysql.test.js.map +1 -0
- package/dist/dialect/placeholders.d.ts +7 -0
- package/dist/dialect/placeholders.d.ts.map +1 -0
- package/dist/dialect/placeholders.js +18 -0
- package/dist/dialect/placeholders.js.map +1 -0
- package/dist/dialect/postgres.d.ts.map +1 -1
- package/dist/dialect/postgres.js +55 -27
- package/dist/dialect/postgres.js.map +1 -1
- package/dist/dialect/resolve.d.ts +13 -0
- package/dist/dialect/resolve.d.ts.map +1 -0
- package/dist/dialect/resolve.js +66 -0
- package/dist/dialect/resolve.js.map +1 -0
- package/dist/dialect/shared.d.ts +8 -1
- package/dist/dialect/shared.d.ts.map +1 -1
- package/dist/dialect/shared.js +37 -0
- package/dist/dialect/shared.js.map +1 -1
- package/dist/dialect/sqlite.d.ts.map +1 -1
- package/dist/dialect/sqlite.js +50 -18
- package/dist/dialect/sqlite.js.map +1 -1
- package/dist/dialect/sqlite.test.js +43 -1
- package/dist/dialect/sqlite.test.js.map +1 -1
- package/dist/dialect/types.d.ts +46 -3
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/docs/pages.d.ts.map +1 -1
- package/dist/docs/pages.js +3 -0
- package/dist/docs/pages.js.map +1 -1
- package/dist/docs/render.js +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/init/scaffold.d.ts +2 -1
- package/dist/init/scaffold.d.ts.map +1 -1
- package/dist/init/scaffold.js.map +1 -1
- package/dist/init/templates.d.ts +3 -2
- package/dist/init/templates.d.ts.map +1 -1
- package/dist/init/templates.js +19 -10
- package/dist/init/templates.js.map +1 -1
- package/dist/introspect/group-fks.d.ts +24 -0
- package/dist/introspect/group-fks.d.ts.map +1 -0
- package/dist/introspect/group-fks.js +48 -0
- package/dist/introspect/group-fks.js.map +1 -0
- package/dist/introspect/mysql/to-manifest.d.ts +4 -0
- package/dist/introspect/mysql/to-manifest.d.ts.map +1 -0
- package/dist/introspect/mysql/to-manifest.js +317 -0
- package/dist/introspect/mysql/to-manifest.js.map +1 -0
- package/dist/introspect/pull.d.ts +1 -0
- package/dist/introspect/pull.d.ts.map +1 -1
- package/dist/introspect/pull.js +179 -6
- package/dist/introspect/pull.js.map +1 -1
- package/dist/introspect/queries.d.ts +10 -1
- package/dist/introspect/queries.d.ts.map +1 -1
- package/dist/introspect/queries.js +41 -11
- package/dist/introspect/queries.js.map +1 -1
- package/dist/introspect/sqlite/to-manifest.d.ts.map +1 -1
- package/dist/introspect/sqlite/to-manifest.js +99 -26
- package/dist/introspect/sqlite/to-manifest.js.map +1 -1
- package/dist/introspect/to-manifest.d.ts.map +1 -1
- package/dist/introspect/to-manifest.js +145 -26
- package/dist/introspect/to-manifest.js.map +1 -1
- package/dist/migrate/dev-lock.d.ts +15 -0
- package/dist/migrate/dev-lock.d.ts.map +1 -0
- package/dist/migrate/dev-lock.js +101 -0
- package/dist/migrate/dev-lock.js.map +1 -0
- package/dist/migrate/runner.d.ts.map +1 -1
- package/dist/migrate/runner.js +143 -51
- package/dist/migrate/runner.js.map +1 -1
- package/dist/plugins/builtin.d.ts +42 -0
- package/dist/plugins/builtin.d.ts.map +1 -1
- package/dist/plugins/builtin.js +276 -8
- package/dist/plugins/builtin.js.map +1 -1
- package/dist/plugins/json/operators.d.ts.map +1 -1
- package/dist/plugins/json/operators.js +69 -3
- package/dist/plugins/json/operators.js.map +1 -1
- package/dist/plugins/postgis/operators.d.ts.map +1 -1
- package/dist/plugins/postgis/operators.js +15 -3
- package/dist/plugins/postgis/operators.js.map +1 -1
- package/dist/runtime/client.d.ts +31 -4
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +129 -4
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/driver.d.ts +2 -0
- package/dist/runtime/driver.d.ts.map +1 -1
- package/dist/runtime/driver.js +12 -0
- package/dist/runtime/driver.js.map +1 -1
- package/dist/runtime/executor.d.ts +1 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +7 -1
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/mariadb-driver.d.ts +25 -0
- package/dist/runtime/mariadb-driver.d.ts.map +1 -0
- package/dist/runtime/mariadb-driver.js +103 -0
- package/dist/runtime/mariadb-driver.js.map +1 -0
- package/dist/runtime/mysql-driver.d.ts +25 -0
- package/dist/runtime/mysql-driver.d.ts.map +1 -0
- package/dist/runtime/mysql-driver.js +101 -0
- package/dist/runtime/mysql-driver.js.map +1 -0
- package/dist/runtime/mysql-error.d.ts +15 -0
- package/dist/runtime/mysql-error.d.ts.map +1 -0
- package/dist/runtime/mysql-error.js +119 -0
- package/dist/runtime/mysql-error.js.map +1 -0
- package/dist/runtime/mysql-family-pool.d.ts +50 -0
- package/dist/runtime/mysql-family-pool.d.ts.map +1 -0
- package/dist/runtime/mysql-family-pool.js +52 -0
- package/dist/runtime/mysql-family-pool.js.map +1 -0
- package/dist/runtime/mysql-family-pool.test.d.ts +2 -0
- package/dist/runtime/mysql-family-pool.test.d.ts.map +1 -0
- package/dist/runtime/mysql-family-pool.test.js +169 -0
- package/dist/runtime/mysql-family-pool.test.js.map +1 -0
- package/dist/runtime/mysql-placeholders.d.ts +18 -0
- package/dist/runtime/mysql-placeholders.d.ts.map +1 -0
- package/dist/runtime/mysql-placeholders.js +133 -0
- package/dist/runtime/mysql-placeholders.js.map +1 -0
- package/dist/runtime/mysql-placeholders.test.d.ts +2 -0
- package/dist/runtime/mysql-placeholders.test.d.ts.map +1 -0
- package/dist/runtime/mysql-placeholders.test.js +33 -0
- package/dist/runtime/mysql-placeholders.test.js.map +1 -0
- package/dist/runtime/query/compile-aggregate.d.ts +1 -1
- package/dist/runtime/query/compile-aggregate.d.ts.map +1 -1
- package/dist/runtime/query/compile-aggregate.js +25 -22
- package/dist/runtime/query/compile-aggregate.js.map +1 -1
- package/dist/runtime/query/compile-where.d.ts +9 -9
- package/dist/runtime/query/compile-where.d.ts.map +1 -1
- package/dist/runtime/query/compile-where.js +87 -66
- package/dist/runtime/query/compile-where.js.map +1 -1
- package/dist/runtime/query/compile-write.d.ts +9 -9
- package/dist/runtime/query/compile-write.d.ts.map +1 -1
- package/dist/runtime/query/compile-write.js +77 -63
- package/dist/runtime/query/compile-write.js.map +1 -1
- package/dist/runtime/query/count.d.ts.map +1 -1
- package/dist/runtime/query/count.js +4 -1
- package/dist/runtime/query/count.js.map +1 -1
- package/dist/runtime/query/create.d.ts.map +1 -1
- package/dist/runtime/query/create.js +38 -12
- package/dist/runtime/query/create.js.map +1 -1
- package/dist/runtime/query/cursor.d.ts +1 -1
- package/dist/runtime/query/cursor.d.ts.map +1 -1
- package/dist/runtime/query/cursor.js +6 -7
- package/dist/runtime/query/cursor.js.map +1 -1
- package/dist/runtime/query/delete.d.ts.map +1 -1
- package/dist/runtime/query/delete.js +41 -15
- package/dist/runtime/query/delete.js.map +1 -1
- package/dist/runtime/query/execute.d.ts +1 -0
- package/dist/runtime/query/execute.d.ts.map +1 -1
- package/dist/runtime/query/execute.js +23 -8
- package/dist/runtime/query/execute.js.map +1 -1
- package/dist/runtime/query/find-or-create.d.ts +1 -1
- package/dist/runtime/query/find-or-create.d.ts.map +1 -1
- package/dist/runtime/query/find-or-create.js +16 -8
- package/dist/runtime/query/find-or-create.js.map +1 -1
- package/dist/runtime/query/find.d.ts +2 -0
- package/dist/runtime/query/find.d.ts.map +1 -1
- package/dist/runtime/query/find.js +108 -62
- package/dist/runtime/query/find.js.map +1 -1
- package/dist/runtime/query/mutation-returning.d.ts +10 -0
- package/dist/runtime/query/mutation-returning.d.ts.map +1 -0
- package/dist/runtime/query/mutation-returning.js +85 -0
- package/dist/runtime/query/mutation-returning.js.map +1 -0
- package/dist/runtime/query/paginate.d.ts.map +1 -1
- package/dist/runtime/query/paginate.js +3 -3
- package/dist/runtime/query/paginate.js.map +1 -1
- package/dist/runtime/query/relation-join.d.ts +5 -0
- package/dist/runtime/query/relation-join.d.ts.map +1 -0
- package/dist/runtime/query/relation-join.js +26 -0
- package/dist/runtime/query/relation-join.js.map +1 -0
- package/dist/runtime/query/relation-planner.d.ts +1 -1
- package/dist/runtime/query/relation-planner.d.ts.map +1 -1
- package/dist/runtime/query/relation-planner.js +69 -55
- package/dist/runtime/query/relation-planner.js.map +1 -1
- package/dist/runtime/query/relation-writes.d.ts +2 -2
- package/dist/runtime/query/relation-writes.d.ts.map +1 -1
- package/dist/runtime/query/relation-writes.js +257 -98
- package/dist/runtime/query/relation-writes.js.map +1 -1
- package/dist/runtime/query/table-index.d.ts.map +1 -1
- package/dist/runtime/query/table-index.js +16 -9
- package/dist/runtime/query/table-index.js.map +1 -1
- package/dist/runtime/query/unique.d.ts +3 -0
- package/dist/runtime/query/unique.d.ts.map +1 -1
- package/dist/runtime/query/unique.js +26 -6
- package/dist/runtime/query/unique.js.map +1 -1
- package/dist/runtime/query/unique.test.js +110 -7
- package/dist/runtime/query/unique.test.js.map +1 -1
- package/dist/runtime/query/update.d.ts.map +1 -1
- package/dist/runtime/query/update.js +89 -23
- package/dist/runtime/query/update.js.map +1 -1
- package/dist/runtime/query/updated-at.js +2 -2
- package/dist/runtime/query/updated-at.js.map +1 -1
- package/dist/runtime/query/upsert.d.ts.map +1 -1
- package/dist/runtime/query/upsert.js +29 -5
- package/dist/runtime/query/upsert.js.map +1 -1
- package/dist/runtime/transaction.d.ts +1 -0
- package/dist/runtime/transaction.d.ts.map +1 -1
- package/dist/runtime/transaction.js +8 -0
- package/dist/runtime/transaction.js.map +1 -1
- package/dist/runtime/types.d.ts +10 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/schema/column-constraints.d.ts +1 -1
- package/dist/schema/column-constraints.d.ts.map +1 -1
- package/dist/schema/column-constraints.js +6 -3
- package/dist/schema/column-constraints.js.map +1 -1
- package/dist/schema/column.d.ts +2 -2
- package/dist/schema/column.d.ts.map +1 -1
- package/dist/schema/column.js +1 -1
- package/dist/schema/column.js.map +1 -1
- package/dist/schema/index.d.ts +4 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/nested-relation-types.d.ts +10 -9
- package/dist/schema/nested-relation-types.d.ts.map +1 -1
- package/dist/schema/relation-types.d.ts +73 -12
- package/dist/schema/relation-types.d.ts.map +1 -1
- package/dist/schema/relation.d.ts +11 -1
- package/dist/schema/relation.d.ts.map +1 -1
- package/dist/schema/relation.js +6 -0
- package/dist/schema/relation.js.map +1 -1
- package/dist/schema/table.d.ts +74 -11
- package/dist/schema/table.d.ts.map +1 -1
- package/dist/schema/table.js +93 -7
- package/dist/schema/table.js.map +1 -1
- package/dist/schema/types.d.ts +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/sql/builder.d.ts +13 -3
- package/dist/sql/builder.d.ts.map +1 -1
- package/dist/sql/builder.js +155 -5
- package/dist/sql/builder.js.map +1 -1
- package/dist/sql/index.d.ts +1 -0
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/qualify-tables.d.ts +15 -0
- package/dist/sql/qualify-tables.d.ts.map +1 -0
- package/dist/sql/qualify-tables.js +206 -0
- package/dist/sql/qualify-tables.js.map +1 -0
- package/dist/sql/template.d.ts +5 -0
- package/dist/sql/template.d.ts.map +1 -1
- package/dist/sql/template.js +23 -3
- package/dist/sql/template.js.map +1 -1
- package/docs/cli.md +4 -4
- package/docs/configuration.md +7 -6
- package/docs/elysia.md +131 -0
- package/docs/errors.md +1 -1
- package/docs/examples.md +4 -2
- package/docs/getting-started.md +6 -4
- package/docs/mariadb.md +149 -0
- package/docs/migrations.md +5 -3
- package/docs/mysql.md +134 -0
- package/docs/plugins.md +1 -1
- package/docs/queries.md +14 -11
- package/docs/relations.md +19 -4
- package/docs/schema.md +73 -10
- package/docs/sqlite.md +6 -2
- package/docs/typebox.md +4 -4
- package/docs/zod.md +2 -2
- package/package.json +18 -2
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseFkTarget, relationFkPairs } from "../../dialect/fk.js";
|
|
2
|
+
import { joinPlaceholders } from "../../dialect/placeholders.js";
|
|
3
|
+
import { postgresDialect } from "../../dialect/postgres.js";
|
|
2
4
|
import { compileError } from "../compile-error.js";
|
|
3
5
|
import { QueryErrorCode } from "../error-codes.js";
|
|
4
6
|
import { buildInsertManyQuery, buildInsertManyValueRows, dataToSqlValues, } from "./compile.js";
|
|
5
7
|
import { runQuery } from "./execute.js";
|
|
6
|
-
import { findOrCreatePk } from "./find-or-create.js";
|
|
8
|
+
import { findOrCreatePk, findOrCreateRecord } from "./find-or-create.js";
|
|
7
9
|
import { findM2M, findRelation, tableOwnsFkColumn } from "./manifest-lookup.js";
|
|
8
|
-
import { fillMissingPrimaryKeys, primaryKeySqlName,
|
|
10
|
+
import { fillMissingPrimaryKeys, primaryKeySqlName, primaryKeyTsNames, resolvePkWhere, targetRelationPkSql, } from "./primary-key.js";
|
|
9
11
|
import { columnBySqlName, columnByTsName, getTableIndex, requireTable, requireTsColumn, } from "./table-index.js";
|
|
10
12
|
const RELATION_WRITE_KEYS = [
|
|
11
13
|
"delete",
|
|
@@ -56,31 +58,148 @@ function connectPkError(table, pkTsName, detail) {
|
|
|
56
58
|
code: QueryErrorCode.missing_primary_key,
|
|
57
59
|
tableAccessor: table.accessor,
|
|
58
60
|
tableSqlName: table.sqlName,
|
|
59
|
-
columnTsName: pkTsName,
|
|
61
|
+
...(pkTsName !== undefined ? { columnTsName: pkTsName } : {}),
|
|
60
62
|
});
|
|
61
63
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
function normalizeConnectPks(runtime, targetAccessor, value) {
|
|
65
|
+
const table = requireTable(runtime.manifest, targetAccessor, "select");
|
|
66
|
+
const tableIndex = getTableIndex(runtime.tableIndex, targetAccessor);
|
|
67
|
+
if (value == null || value === false)
|
|
68
|
+
return [];
|
|
69
|
+
const items = Array.isArray(value) ? value : [value];
|
|
70
|
+
return items.map((item) => {
|
|
71
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
72
|
+
const pkNames = primaryKeyTsNames(table, tableIndex);
|
|
73
|
+
connectPkError(table, pkNames[0], `Relation connect requires { ${pkNames.join(", ")} } for table "${table.accessor}"`);
|
|
74
|
+
}
|
|
75
|
+
return resolvePkWhere(table, item, tableIndex);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function pkField(table, pk, tsName) {
|
|
79
|
+
const value = pk[tsName];
|
|
80
|
+
if (value == null) {
|
|
81
|
+
connectPkError(table, tsName, `Relation connect requires primary key "${tsName}" for table "${table.accessor}"`);
|
|
65
82
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
function assignOutgoingFkScalars(scalarData, rel, targetTable, targetIndex, record, nulls = false) {
|
|
86
|
+
for (const pair of relationFkPairs(rel)) {
|
|
87
|
+
if (nulls) {
|
|
88
|
+
scalarData[pair.fkColumn] = null;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const targetTs = columnBySqlName(targetIndex, targetTable, pair.targetColumn)
|
|
92
|
+
?.tsName ??
|
|
93
|
+
columnByTsName(targetIndex, targetTable, pair.targetColumn)
|
|
94
|
+
?.tsName ??
|
|
95
|
+
pair.targetColumn;
|
|
96
|
+
scalarData[pair.fkColumn] = pkField(targetTable, record, targetTs);
|
|
69
97
|
}
|
|
70
|
-
return String(id);
|
|
71
98
|
}
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
99
|
+
function childFkCreatePatch(rel, parentTable, parentRow, parentId) {
|
|
100
|
+
const assignment = inverseFkAssignments(rel, parentTable, parentRow, parentId);
|
|
101
|
+
const pairs = relationFkPairs(rel);
|
|
102
|
+
const patch = {};
|
|
103
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
104
|
+
const pair = pairs[i];
|
|
105
|
+
if (!pair)
|
|
106
|
+
continue;
|
|
107
|
+
patch[pair.fkColumn] = assignment.values[i] ?? parentId;
|
|
77
108
|
}
|
|
78
|
-
return
|
|
109
|
+
return patch;
|
|
79
110
|
}
|
|
80
|
-
function
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
111
|
+
function inverseFkAssignments(rel, parentTable, parentRow, parentId) {
|
|
112
|
+
const pairs = relationFkPairs(rel);
|
|
113
|
+
const refs = rel.referencedSqlColumns && rel.referencedSqlColumns.length > 0
|
|
114
|
+
? rel.referencedSqlColumns
|
|
115
|
+
: pairs.map((pair) => pair.targetColumn);
|
|
116
|
+
if (pairs.length <= 1) {
|
|
117
|
+
return {
|
|
118
|
+
sqlNames: [rel.fkSqlColumn],
|
|
119
|
+
values: [parentId],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const values = pairs.map((pair, i) => {
|
|
123
|
+
const ref = refs[i] ?? pair.targetColumn;
|
|
124
|
+
const col = parentTable.columns.find((item) => item.sqlName === ref || item.tsName === ref);
|
|
125
|
+
const value = parentRow?.[col?.tsName ?? ref];
|
|
126
|
+
return value ?? parentId;
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
sqlNames: pairs.map((pair) => pair.fkSqlColumn),
|
|
130
|
+
values,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function fkTargetTsName(table, tableIndex, relation, throughFk) {
|
|
134
|
+
if (throughFk?.fkTarget) {
|
|
135
|
+
const { columnSql } = parseFkTarget(throughFk.fkTarget);
|
|
136
|
+
const col = columnBySqlName(tableIndex, table, columnSql) ??
|
|
137
|
+
columnByTsName(tableIndex, table, columnSql);
|
|
138
|
+
if (col)
|
|
139
|
+
return col.tsName;
|
|
140
|
+
}
|
|
141
|
+
const sql = targetRelationPkSql(table, relation);
|
|
142
|
+
const col = columnBySqlName(tableIndex, table, sql) ??
|
|
143
|
+
columnByTsName(tableIndex, table, sql);
|
|
144
|
+
if (col)
|
|
145
|
+
return col.tsName;
|
|
146
|
+
const names = primaryKeyTsNames(table, tableIndex);
|
|
147
|
+
const first = names[0];
|
|
148
|
+
if (!first) {
|
|
149
|
+
connectPkError(table, undefined, `No primary key defined for table "${table.accessor}"`);
|
|
150
|
+
}
|
|
151
|
+
return first;
|
|
152
|
+
}
|
|
153
|
+
function m2mOtherThroughColumn(runtime, m2m, parentAccessor) {
|
|
154
|
+
const throughTable = runtime.manifest.tables[m2m.throughAccessor];
|
|
155
|
+
if (!throughTable)
|
|
156
|
+
return undefined;
|
|
157
|
+
const throughIndex = getTableIndex(runtime.tableIndex, throughTable.accessor);
|
|
158
|
+
const isLeft = m2m.leftAccessor === parentAccessor;
|
|
159
|
+
const otherFkCol = isLeft ? m2m.rightFkColumn : m2m.leftFkColumn;
|
|
160
|
+
return columnBySqlName(throughIndex, throughTable, otherFkCol);
|
|
161
|
+
}
|
|
162
|
+
function m2mConnectFkValues(runtime, m2m, parentAccessor, targetAccessor, value) {
|
|
163
|
+
const pks = normalizeConnectPks(runtime, targetAccessor, value);
|
|
164
|
+
const targetTable = requireTable(runtime.manifest, targetAccessor, "select");
|
|
165
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetAccessor);
|
|
166
|
+
const throughFk = m2mOtherThroughColumn(runtime, m2m, parentAccessor);
|
|
167
|
+
const fkTs = fkTargetTsName(targetTable, targetIndex, undefined, throughFk);
|
|
168
|
+
return { pks, ids: extractFkValues(targetTable, pks, fkTs) };
|
|
169
|
+
}
|
|
170
|
+
function extractFkValues(table, pks, fkTsName) {
|
|
171
|
+
return pks.map((pk) => pkField(table, pk, fkTsName));
|
|
172
|
+
}
|
|
173
|
+
function sqlPkPredicate(dialect, table, tableIndex, pks, startParam) {
|
|
174
|
+
const tsNames = primaryKeyTsNames(table, tableIndex);
|
|
175
|
+
if (tsNames.length === 0 || pks.length === 0) {
|
|
176
|
+
connectPkError(table, undefined, `No primary key defined for table "${table.accessor}"`);
|
|
177
|
+
}
|
|
178
|
+
const quoted = tsNames.map((tsName) => {
|
|
179
|
+
const col = columnByTsName(tableIndex, table, tsName);
|
|
180
|
+
return dialect.quoteIdentifier(col?.sqlName ?? tsName);
|
|
181
|
+
});
|
|
182
|
+
if (tsNames.length === 1) {
|
|
183
|
+
const tsName = tsNames[0];
|
|
184
|
+
if (!tsName || !quoted[0]) {
|
|
185
|
+
connectPkError(table, tsName, `No primary key defined for table "${table.accessor}"`);
|
|
186
|
+
}
|
|
187
|
+
const placeholders = joinPlaceholders(dialect, pks.length, startParam);
|
|
188
|
+
return {
|
|
189
|
+
sql: `${quoted[0]} IN (${placeholders})`,
|
|
190
|
+
params: pks.map((pk) => pkField(table, pk, tsName)),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
const params = [];
|
|
194
|
+
let index = startParam;
|
|
195
|
+
const groups = pks.map((pk) => {
|
|
196
|
+
const parts = tsNames.map((tsName, i) => {
|
|
197
|
+
params.push(pkField(table, pk, tsName));
|
|
198
|
+
return `${quoted[i]} = ${dialect.placeholder(index++)}`;
|
|
199
|
+
});
|
|
200
|
+
return `(${parts.join(" AND ")})`;
|
|
201
|
+
});
|
|
202
|
+
return { sql: `(${groups.join(" OR ")})`, params };
|
|
84
203
|
}
|
|
85
204
|
function normalizeCreateList(value) {
|
|
86
205
|
if (!value)
|
|
@@ -109,10 +228,10 @@ export function splitScalarsAndRelationWrites(manifest, tableAccessor, table, da
|
|
|
109
228
|
}
|
|
110
229
|
return { scalarData, relationWrites };
|
|
111
230
|
}
|
|
112
|
-
export async function resolveConnectOrCreate(executor, runtime, targetAccessor, items) {
|
|
231
|
+
export async function resolveConnectOrCreate(executor, runtime, targetAccessor, items, fkTsName) {
|
|
113
232
|
const ids = [];
|
|
114
233
|
for (const item of items) {
|
|
115
|
-
const id = await findOrCreatePk(executor, runtime, targetAccessor, item);
|
|
234
|
+
const id = await findOrCreatePk(executor, runtime, targetAccessor, item, fkTsName);
|
|
116
235
|
ids.push(id);
|
|
117
236
|
}
|
|
118
237
|
return ids;
|
|
@@ -167,7 +286,7 @@ async function insertM2MLinks(executor, runtime, m2m, parentAccessor, parentId,
|
|
|
167
286
|
const valueByKey = new Map(keys.map((key, i) => [key, values[i]]));
|
|
168
287
|
return dataKeys.map((key) => valueByKey.get(key));
|
|
169
288
|
});
|
|
170
|
-
const { valueRows, values } = buildInsertManyValueRows(throughTable, dataKeys, rowValues, runtime.tableIndex);
|
|
289
|
+
const { valueRows, values } = buildInsertManyValueRows(throughTable, dataKeys, rowValues, runtime.tableIndex, dialect);
|
|
171
290
|
const sql = buildInsertManyQuery(throughTable, dataKeys, valueRows, runtime.tableIndex, true, dialect);
|
|
172
291
|
await runQuery(executor, runtime, { operation: "insert", tableAccessor: throughTable.accessor }, sql, values);
|
|
173
292
|
}
|
|
@@ -181,6 +300,7 @@ async function _insertJunctionRows(executor, runtime, throughAccessor, leftFkCol
|
|
|
181
300
|
await insertM2MLinks(executor, runtime, m2m, parentAccessor, leftId, rightIds);
|
|
182
301
|
}
|
|
183
302
|
async function deleteJunctionRows(executor, runtime, m2m, parentAccessor, parentId, rightIds) {
|
|
303
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
184
304
|
const { manifest } = runtime;
|
|
185
305
|
const throughTable = manifest.tables[m2m.throughAccessor];
|
|
186
306
|
if (!throughTable)
|
|
@@ -194,10 +314,10 @@ async function deleteJunctionRows(executor, runtime, m2m, parentAccessor, parent
|
|
|
194
314
|
if (!parentCol || !otherCol)
|
|
195
315
|
return;
|
|
196
316
|
const params = [parentId];
|
|
197
|
-
let sql = `DELETE FROM ${tableRef(throughTable)} WHERE ${quoteIdentifier(parentCol.sqlName)} = $1`;
|
|
317
|
+
let sql = `DELETE FROM ${dialect.tableRef(throughTable)} WHERE ${dialect.quoteIdentifier(parentCol.sqlName)} = ${dialect.placeholder(1)}`;
|
|
198
318
|
if (rightIds && rightIds.length > 0) {
|
|
199
|
-
const placeholders =
|
|
200
|
-
sql += ` AND ${quoteIdentifier(otherCol.sqlName)} IN (${placeholders})`;
|
|
319
|
+
const placeholders = joinPlaceholders(dialect, rightIds.length, 2);
|
|
320
|
+
sql += ` AND ${dialect.quoteIdentifier(otherCol.sqlName)} IN (${placeholders})`;
|
|
201
321
|
params.push(...rightIds);
|
|
202
322
|
}
|
|
203
323
|
await runQuery(executor, runtime, { operation: "delete", tableAccessor: throughTable.accessor }, sql, params);
|
|
@@ -210,56 +330,63 @@ function childFkColumnMeta(targetTable, relation, tableIndex) {
|
|
|
210
330
|
}
|
|
211
331
|
return col;
|
|
212
332
|
}
|
|
213
|
-
async function connectInverseMany(executor, runtime, relation, parentId,
|
|
333
|
+
async function connectInverseMany(executor, runtime, relation, parentId, childPks, parentTable, parentRow) {
|
|
334
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
214
335
|
const { manifest } = runtime;
|
|
215
336
|
const targetTable = manifest.tables[relation.targetAccessor];
|
|
216
|
-
if (!targetTable ||
|
|
337
|
+
if (!targetTable || childPks.length === 0)
|
|
217
338
|
return;
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
339
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetTable.accessor);
|
|
340
|
+
const assignment = inverseFkAssignments(relation, parentTable ?? targetTable, parentRow, parentId);
|
|
341
|
+
const predicate = sqlPkPredicate(dialect, targetTable, targetIndex, childPks, assignment.values.length + 1);
|
|
342
|
+
const setSql = assignment.sqlNames
|
|
343
|
+
.map((sqlName, i) => `${dialect.quoteIdentifier(sqlName)} = ${dialect.placeholder(i + 1)}`)
|
|
344
|
+
.join(", ");
|
|
345
|
+
await runQuery(executor, runtime, { operation: "update", tableAccessor: relation.targetAccessor }, `UPDATE ${dialect.tableRef(targetTable)} SET ${setSql} WHERE ${predicate.sql}`, [...assignment.values, ...predicate.params]);
|
|
222
346
|
}
|
|
223
|
-
async function disconnectInverseMany(executor, runtime, relation, parentId,
|
|
347
|
+
async function disconnectInverseMany(executor, runtime, relation, parentId, childPks) {
|
|
348
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
224
349
|
const { manifest } = runtime;
|
|
225
350
|
const targetTable = manifest.tables[relation.targetAccessor];
|
|
226
351
|
if (!targetTable)
|
|
227
352
|
return;
|
|
228
|
-
const
|
|
353
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetTable.accessor);
|
|
354
|
+
const fkCol = childFkColumnMeta(targetTable, relation, targetIndex);
|
|
229
355
|
if (!fkCol.nullable) {
|
|
230
356
|
compileError(`Cannot disconnect relation ${relation.name}: FK column is not nullable`);
|
|
231
357
|
}
|
|
232
358
|
const params = [parentId];
|
|
233
|
-
let sql = `UPDATE ${tableRef(targetTable)} SET ${quoteIdentifier(fkCol.sqlName)} = NULL WHERE ${quoteIdentifier(fkCol.sqlName)} = $1`;
|
|
234
|
-
if (
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
params.push(...childIds);
|
|
359
|
+
let sql = `UPDATE ${dialect.tableRef(targetTable)} SET ${dialect.quoteIdentifier(fkCol.sqlName)} = NULL WHERE ${dialect.quoteIdentifier(fkCol.sqlName)} = ${dialect.placeholder(1)}`;
|
|
360
|
+
if (childPks && childPks.length > 0) {
|
|
361
|
+
const predicate = sqlPkPredicate(dialect, targetTable, targetIndex, childPks, 2);
|
|
362
|
+
sql += ` AND ${predicate.sql}`;
|
|
363
|
+
params.push(...predicate.params);
|
|
239
364
|
}
|
|
240
365
|
await runQuery(executor, runtime, { operation: "update", tableAccessor: relation.targetAccessor }, sql, params);
|
|
241
366
|
}
|
|
242
|
-
async function setInverseMany(executor, runtime, relation, parentId,
|
|
367
|
+
async function setInverseMany(executor, runtime, relation, parentId, childPks, parentTable, parentRow) {
|
|
243
368
|
await disconnectInverseMany(executor, runtime, relation, parentId, undefined);
|
|
244
|
-
await connectInverseMany(executor, runtime, relation, parentId,
|
|
369
|
+
await connectInverseMany(executor, runtime, relation, parentId, childPks, parentTable, parentRow);
|
|
245
370
|
}
|
|
246
|
-
async function deleteInverseManyChildren(executor, runtime, relation, parentId,
|
|
371
|
+
async function deleteInverseManyChildren(executor, runtime, relation, parentId, childPks) {
|
|
372
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
247
373
|
const { manifest } = runtime;
|
|
248
374
|
const targetTable = manifest.tables[relation.targetAccessor];
|
|
249
375
|
if (!targetTable)
|
|
250
376
|
return;
|
|
251
|
-
const
|
|
252
|
-
const
|
|
377
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetTable.accessor);
|
|
378
|
+
const fkCol = childFkColumnMeta(targetTable, relation, targetIndex);
|
|
253
379
|
const params = [parentId];
|
|
254
|
-
let sql = `DELETE FROM ${tableRef(targetTable)} WHERE ${quoteIdentifier(fkCol.sqlName)} = $1`;
|
|
255
|
-
if (
|
|
256
|
-
const
|
|
257
|
-
sql += ` AND ${
|
|
258
|
-
params.push(...
|
|
380
|
+
let sql = `DELETE FROM ${dialect.tableRef(targetTable)} WHERE ${dialect.quoteIdentifier(fkCol.sqlName)} = ${dialect.placeholder(1)}`;
|
|
381
|
+
if (childPks && childPks.length > 0) {
|
|
382
|
+
const predicate = sqlPkPredicate(dialect, targetTable, targetIndex, childPks, 2);
|
|
383
|
+
sql += ` AND ${predicate.sql}`;
|
|
384
|
+
params.push(...predicate.params);
|
|
259
385
|
}
|
|
260
386
|
await runQuery(executor, runtime, { operation: "delete", tableAccessor: relation.targetAccessor }, sql, params);
|
|
261
387
|
}
|
|
262
388
|
async function listM2MLinkedIds(executor, runtime, m2m, parentAccessor, parentId) {
|
|
389
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
263
390
|
const { manifest } = runtime;
|
|
264
391
|
const throughTable = manifest.tables[m2m.throughAccessor];
|
|
265
392
|
if (!throughTable)
|
|
@@ -272,10 +399,11 @@ async function listM2MLinkedIds(executor, runtime, m2m, parentAccessor, parentId
|
|
|
272
399
|
const otherCol = columnBySqlName(throughIndex, throughTable, otherFkCol);
|
|
273
400
|
if (!parentCol || !otherCol)
|
|
274
401
|
return [];
|
|
275
|
-
const rows = await runQuery(executor, runtime, { operation: "select", tableAccessor: throughTable.accessor }, `SELECT ${quoteIdentifier(otherCol.sqlName)} FROM ${tableRef(throughTable)} WHERE ${quoteIdentifier(parentCol.sqlName)} = $1`, [parentId]);
|
|
402
|
+
const rows = await runQuery(executor, runtime, { operation: "select", tableAccessor: throughTable.accessor }, `SELECT ${dialect.quoteIdentifier(otherCol.sqlName)} FROM ${dialect.tableRef(throughTable)} WHERE ${dialect.quoteIdentifier(parentCol.sqlName)} = ${dialect.placeholder(1)}`, [parentId]);
|
|
276
403
|
return rows.map((row) => String(row[otherCol.sqlName] ?? row[otherCol.tsName]));
|
|
277
404
|
}
|
|
278
|
-
async function deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId, relatedIds) {
|
|
405
|
+
async function deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId, relatedIds, targetPks) {
|
|
406
|
+
const dialect = runtime.dialect ?? postgresDialect;
|
|
279
407
|
const { manifest } = runtime;
|
|
280
408
|
const isLeft = m2m.leftAccessor === tableAccessor;
|
|
281
409
|
const targetAccessor = isLeft ? m2m.rightAccessor : m2m.leftAccessor;
|
|
@@ -287,9 +415,22 @@ async function deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId,
|
|
|
287
415
|
if (ids.length === 0)
|
|
288
416
|
return;
|
|
289
417
|
await deleteJunctionRows(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
418
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetAccessor);
|
|
419
|
+
if (targetPks && targetPks.length > 0) {
|
|
420
|
+
const predicate = sqlPkPredicate(dialect, targetTable, targetIndex, targetPks, 1);
|
|
421
|
+
await runQuery(executor, runtime, { operation: "delete", tableAccessor: targetAccessor }, `DELETE FROM ${dialect.tableRef(targetTable)} WHERE ${predicate.sql}`, predicate.params);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const targetPkCol = dialect.quoteIdentifier(primaryKeySqlName(targetTable));
|
|
425
|
+
const placeholders = joinPlaceholders(dialect, ids.length);
|
|
426
|
+
await runQuery(executor, runtime, { operation: "delete", tableAccessor: targetAccessor }, `DELETE FROM ${dialect.tableRef(targetTable)} WHERE ${targetPkCol} IN (${placeholders})`, ids);
|
|
427
|
+
}
|
|
428
|
+
function assertExclusiveConnectOrCreate(value, relationName) {
|
|
429
|
+
if (!("connectOrCreate" in value))
|
|
430
|
+
return;
|
|
431
|
+
if ("connect" in value || "create" in value) {
|
|
432
|
+
compileError(`Relation "${relationName}" cannot mix connectOrCreate with connect or create`, { code: QueryErrorCode.invalid_nested_write });
|
|
433
|
+
}
|
|
293
434
|
}
|
|
294
435
|
async function executeToOneWrite(executor, runtime, table, scalarData, relationName, value, runCreate) {
|
|
295
436
|
const { manifest } = runtime;
|
|
@@ -297,19 +438,36 @@ async function executeToOneWrite(executor, runtime, table, scalarData, relationN
|
|
|
297
438
|
const rel = findRelation(table, relationName, tableIndex);
|
|
298
439
|
if (rel?.cardinality !== "one")
|
|
299
440
|
return;
|
|
441
|
+
const targetTable = manifest.tables[rel.targetAccessor];
|
|
442
|
+
if (!targetTable)
|
|
443
|
+
compileError(`Unknown table: ${rel.targetAccessor}`);
|
|
444
|
+
const targetIndex = getTableIndex(runtime.tableIndex, rel.targetAccessor);
|
|
445
|
+
assertExclusiveConnectOrCreate(value, relationName);
|
|
446
|
+
if ("connectOrCreate" in value) {
|
|
447
|
+
const item = value.connectOrCreate;
|
|
448
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
449
|
+
compileError(`Relation "${relationName}" connectOrCreate requires { where, create }`, { code: QueryErrorCode.invalid_nested_write });
|
|
450
|
+
}
|
|
451
|
+
const { record } = await findOrCreateRecord(executor, runtime, rel.targetAccessor, {
|
|
452
|
+
where: item.where,
|
|
453
|
+
create: item.create,
|
|
454
|
+
});
|
|
455
|
+
assignOutgoingFkScalars(scalarData, rel, targetTable, targetIndex, record);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
300
458
|
if ("connect" in value) {
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
if (
|
|
459
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.connect);
|
|
460
|
+
const pk = pks[0];
|
|
461
|
+
if (pk === undefined) {
|
|
304
462
|
compileError(`Relation connect requires a primary key for table "${rel.targetAccessor}"`, {
|
|
305
463
|
code: QueryErrorCode.missing_primary_key,
|
|
306
464
|
tableAccessor: rel.targetAccessor,
|
|
307
465
|
});
|
|
308
466
|
}
|
|
309
|
-
if (
|
|
467
|
+
if (pks.length > 1) {
|
|
310
468
|
compileError(`Cannot connect more than one record to to-one relation ${relationName}`);
|
|
311
469
|
}
|
|
312
|
-
scalarData
|
|
470
|
+
assignOutgoingFkScalars(scalarData, rel, targetTable, targetIndex, pk);
|
|
313
471
|
return;
|
|
314
472
|
}
|
|
315
473
|
if ("disconnect" in value) {
|
|
@@ -318,17 +476,14 @@ async function executeToOneWrite(executor, runtime, table, scalarData, relationN
|
|
|
318
476
|
if (fkCol && !fkCol.nullable) {
|
|
319
477
|
compileError(`Cannot disconnect relation ${relationName}: FK column is not nullable`);
|
|
320
478
|
}
|
|
321
|
-
scalarData
|
|
479
|
+
assignOutgoingFkScalars(scalarData, rel, targetTable, targetIndex, {}, true);
|
|
322
480
|
return;
|
|
323
481
|
}
|
|
324
482
|
if ("create" in value) {
|
|
325
483
|
const created = await runCreate(executor, runtime, rel.targetAccessor, {
|
|
326
484
|
data: value.create,
|
|
327
485
|
});
|
|
328
|
-
|
|
329
|
-
if (!targetTable)
|
|
330
|
-
compileError(`Unknown table: ${rel.targetAccessor}`);
|
|
331
|
-
scalarData[rel.fkColumn] = rowScalarPkValue(created, targetTable);
|
|
486
|
+
assignOutgoingFkScalars(scalarData, rel, targetTable, targetIndex, created);
|
|
332
487
|
}
|
|
333
488
|
}
|
|
334
489
|
export async function applyToOnePreWrites(executor, runtime, table, scalarData, relationWrites, runCreate) {
|
|
@@ -354,8 +509,8 @@ async function executeM2MWrite(executor, runtime, tableAccessor, parentId, relat
|
|
|
354
509
|
await deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId, undefined);
|
|
355
510
|
}
|
|
356
511
|
else {
|
|
357
|
-
const ids =
|
|
358
|
-
await deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
512
|
+
const { pks, ids } = m2mConnectFkValues(runtime, m2m, tableAccessor, targetAccessor, del);
|
|
513
|
+
await deleteM2MRelated(executor, runtime, m2m, tableAccessor, parentId, ids, pks);
|
|
359
514
|
}
|
|
360
515
|
}
|
|
361
516
|
if ("disconnect" in value) {
|
|
@@ -364,12 +519,12 @@ async function executeM2MWrite(executor, runtime, tableAccessor, parentId, relat
|
|
|
364
519
|
await deleteJunctionRows(executor, runtime, m2m, tableAccessor, parentId);
|
|
365
520
|
}
|
|
366
521
|
else {
|
|
367
|
-
const ids =
|
|
522
|
+
const { ids } = m2mConnectFkValues(runtime, m2m, tableAccessor, targetAccessor, disconnect);
|
|
368
523
|
await deleteJunctionRows(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
369
524
|
}
|
|
370
525
|
}
|
|
371
526
|
if ("set" in value) {
|
|
372
|
-
const ids =
|
|
527
|
+
const { ids } = m2mConnectFkValues(runtime, m2m, tableAccessor, targetAccessor, value.set);
|
|
373
528
|
await deleteJunctionRows(executor, runtime, m2m, tableAccessor, parentId);
|
|
374
529
|
if (ids.length > 0) {
|
|
375
530
|
await insertM2MLinks(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
@@ -377,20 +532,24 @@ async function executeM2MWrite(executor, runtime, tableAccessor, parentId, relat
|
|
|
377
532
|
return;
|
|
378
533
|
}
|
|
379
534
|
if ("connect" in value) {
|
|
380
|
-
const ids =
|
|
535
|
+
const { ids } = m2mConnectFkValues(runtime, m2m, tableAccessor, targetAccessor, value.connect);
|
|
381
536
|
if (ids.length > 0) {
|
|
382
537
|
await insertM2MLinks(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
383
538
|
}
|
|
384
539
|
}
|
|
385
540
|
if ("connectOrCreate" in value) {
|
|
386
541
|
const items = value.connectOrCreate;
|
|
387
|
-
const
|
|
542
|
+
const targetTable = requireTable(runtime.manifest, targetAccessor, "select");
|
|
543
|
+
const targetIndex = getTableIndex(runtime.tableIndex, targetAccessor);
|
|
544
|
+
const throughFk = m2mOtherThroughColumn(runtime, m2m, tableAccessor);
|
|
545
|
+
const fkTs = fkTargetTsName(targetTable, targetIndex, undefined, throughFk);
|
|
546
|
+
const ids = await resolveConnectOrCreate(executor, runtime, targetAccessor, items, fkTs);
|
|
388
547
|
if (ids.length > 0) {
|
|
389
548
|
await insertM2MLinks(executor, runtime, m2m, tableAccessor, parentId, ids);
|
|
390
549
|
}
|
|
391
550
|
}
|
|
392
551
|
}
|
|
393
|
-
async function executeInverseManyWrite(executor, runtime, table, parentId, relationName, value, runCreate) {
|
|
552
|
+
async function executeInverseManyWrite(executor, runtime, table, parentId, relationName, value, runCreate, parentRow) {
|
|
394
553
|
const { manifest } = runtime;
|
|
395
554
|
const rel = findRelation(table, relationName);
|
|
396
555
|
if (rel?.cardinality !== "many" ||
|
|
@@ -403,8 +562,8 @@ async function executeInverseManyWrite(executor, runtime, table, parentId, relat
|
|
|
403
562
|
await deleteInverseManyChildren(executor, runtime, rel, parentId, undefined);
|
|
404
563
|
}
|
|
405
564
|
else {
|
|
406
|
-
const
|
|
407
|
-
await deleteInverseManyChildren(executor, runtime, rel, parentId,
|
|
565
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, del);
|
|
566
|
+
await deleteInverseManyChildren(executor, runtime, rel, parentId, pks);
|
|
408
567
|
}
|
|
409
568
|
}
|
|
410
569
|
if ("disconnect" in value) {
|
|
@@ -413,18 +572,18 @@ async function executeInverseManyWrite(executor, runtime, table, parentId, relat
|
|
|
413
572
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
414
573
|
}
|
|
415
574
|
else {
|
|
416
|
-
const
|
|
417
|
-
await disconnectInverseMany(executor, runtime, rel, parentId,
|
|
575
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, disconnect);
|
|
576
|
+
await disconnectInverseMany(executor, runtime, rel, parentId, pks);
|
|
418
577
|
}
|
|
419
578
|
}
|
|
420
579
|
if ("set" in value) {
|
|
421
|
-
const
|
|
422
|
-
await setInverseMany(executor, runtime, rel, parentId,
|
|
580
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.set);
|
|
581
|
+
await setInverseMany(executor, runtime, rel, parentId, pks, table, parentRow);
|
|
423
582
|
return;
|
|
424
583
|
}
|
|
425
584
|
if ("connect" in value) {
|
|
426
|
-
const
|
|
427
|
-
await connectInverseMany(executor, runtime, rel, parentId,
|
|
585
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.connect);
|
|
586
|
+
await connectInverseMany(executor, runtime, rel, parentId, pks, table, parentRow);
|
|
428
587
|
}
|
|
429
588
|
if ("create" in value) {
|
|
430
589
|
const items = normalizeCreateList(value.create);
|
|
@@ -432,13 +591,13 @@ async function executeInverseManyWrite(executor, runtime, table, parentId, relat
|
|
|
432
591
|
await runCreate(executor, runtime, rel.targetAccessor, {
|
|
433
592
|
data: {
|
|
434
593
|
...item,
|
|
435
|
-
|
|
594
|
+
...childFkCreatePatch(rel, table, parentRow, parentId),
|
|
436
595
|
},
|
|
437
596
|
});
|
|
438
597
|
}
|
|
439
598
|
}
|
|
440
599
|
}
|
|
441
|
-
async function executeInverseOneWrite(executor, runtime, table, parentId, relationName, value, runCreate) {
|
|
600
|
+
async function executeInverseOneWrite(executor, runtime, table, parentId, relationName, value, runCreate, parentRow) {
|
|
442
601
|
const { manifest } = runtime;
|
|
443
602
|
const rel = findRelation(table, relationName);
|
|
444
603
|
if (rel?.cardinality !== "one" || tableOwnsFkColumn(table, rel))
|
|
@@ -453,8 +612,8 @@ async function executeInverseOneWrite(executor, runtime, table, parentId, relati
|
|
|
453
612
|
await deleteInverseManyChildren(executor, runtime, rel, parentId, undefined);
|
|
454
613
|
}
|
|
455
614
|
else {
|
|
456
|
-
const
|
|
457
|
-
await deleteInverseManyChildren(executor, runtime, rel, parentId,
|
|
615
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, del);
|
|
616
|
+
await deleteInverseManyChildren(executor, runtime, rel, parentId, pks);
|
|
458
617
|
}
|
|
459
618
|
}
|
|
460
619
|
if ("disconnect" in value) {
|
|
@@ -464,23 +623,23 @@ async function executeInverseOneWrite(executor, runtime, table, parentId, relati
|
|
|
464
623
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
465
624
|
}
|
|
466
625
|
if ("set" in value) {
|
|
467
|
-
const
|
|
468
|
-
const
|
|
469
|
-
if (
|
|
626
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.set);
|
|
627
|
+
const pk = pks[0];
|
|
628
|
+
if (pk) {
|
|
470
629
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
471
|
-
await connectInverseMany(executor, runtime, rel, parentId, [
|
|
630
|
+
await connectInverseMany(executor, runtime, rel, parentId, [pk], table, parentRow);
|
|
472
631
|
}
|
|
473
632
|
return;
|
|
474
633
|
}
|
|
475
634
|
if ("connect" in value) {
|
|
476
|
-
const
|
|
477
|
-
const
|
|
478
|
-
if (!
|
|
635
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.connect);
|
|
636
|
+
const pk = pks[0];
|
|
637
|
+
if (!pk)
|
|
479
638
|
return;
|
|
480
|
-
if (
|
|
639
|
+
if (pks.length > 1) {
|
|
481
640
|
compileError(`Cannot connect more than one record to one-to-one relation ${relationName}`);
|
|
482
641
|
}
|
|
483
|
-
await connectInverseMany(executor, runtime, rel, parentId, [
|
|
642
|
+
await connectInverseMany(executor, runtime, rel, parentId, [pk], table, parentRow);
|
|
484
643
|
}
|
|
485
644
|
if ("create" in value) {
|
|
486
645
|
const items = normalizeCreateList(value.create);
|
|
@@ -492,13 +651,13 @@ async function executeInverseOneWrite(executor, runtime, table, parentId, relati
|
|
|
492
651
|
await runCreate(executor, runtime, rel.targetAccessor, {
|
|
493
652
|
data: {
|
|
494
653
|
...item,
|
|
495
|
-
|
|
654
|
+
...childFkCreatePatch(rel, table, parentRow, parentId),
|
|
496
655
|
},
|
|
497
656
|
});
|
|
498
657
|
}
|
|
499
658
|
}
|
|
500
659
|
}
|
|
501
|
-
export async function executeRelationWrites(executor, runtime, tableAccessor, parentId, relationWrites, runCreate) {
|
|
660
|
+
export async function executeRelationWrites(executor, runtime, tableAccessor, parentId, relationWrites, runCreate, parentRow) {
|
|
502
661
|
const { manifest } = runtime;
|
|
503
662
|
const table = requireTable(manifest, tableAccessor, "select");
|
|
504
663
|
for (const write of relationWrites) {
|
|
@@ -511,11 +670,11 @@ export async function executeRelationWrites(executor, runtime, tableAccessor, pa
|
|
|
511
670
|
continue;
|
|
512
671
|
if (rel.cardinality === "one") {
|
|
513
672
|
if (!tableOwnsFkColumn(table, rel)) {
|
|
514
|
-
await executeInverseOneWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate);
|
|
673
|
+
await executeInverseOneWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate, parentRow);
|
|
515
674
|
}
|
|
516
675
|
continue;
|
|
517
676
|
}
|
|
518
|
-
await executeInverseManyWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate);
|
|
677
|
+
await executeInverseManyWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate, parentRow);
|
|
519
678
|
}
|
|
520
679
|
}
|
|
521
680
|
export function hasPostRelationWrites(table, manifest, tableAccessor, relationWrites) {
|