neoorm 0.8.0 → 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 +13 -6
- package/dist/bin/neoorm.d.ts +1 -1
- package/dist/bin/neoorm.d.ts.map +1 -1
- package/dist/bin/neoorm.js +148 -75
- 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 +5 -1
- package/dist/codegen/generate-summary.d.ts.map +1 -1
- package/dist/codegen/generate-summary.js +10 -1
- package/dist/codegen/generate-summary.js.map +1 -1
- package/dist/codegen/generate.d.ts +24 -4
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +150 -13
- package/dist/codegen/generate.js.map +1 -1
- package/dist/codegen/manifest-relations.d.ts +2 -0
- package/dist/codegen/manifest-relations.d.ts.map +1 -1
- package/dist/codegen/manifest-relations.js +2 -1
- package/dist/codegen/manifest-relations.js.map +1 -1
- package/dist/codegen/schema-to-manifest.d.ts +1 -1
- package/dist/codegen/schema-to-manifest.d.ts.map +1 -1
- package/dist/codegen/schema-to-manifest.js +349 -29
- 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/emit-typebox.d.ts +4 -0
- package/dist/codegen/validation/emit-typebox.d.ts.map +1 -0
- package/dist/codegen/validation/emit-typebox.js +360 -0
- package/dist/codegen/validation/emit-typebox.js.map +1 -0
- package/dist/codegen/validation/emit-zod.d.ts +4 -0
- package/dist/codegen/validation/emit-zod.d.ts.map +1 -0
- package/dist/codegen/validation/emit-zod.js +288 -0
- package/dist/codegen/validation/emit-zod.js.map +1 -0
- package/dist/codegen/validation/from-manifest.d.ts +5 -0
- package/dist/codegen/validation/from-manifest.d.ts.map +1 -0
- package/dist/codegen/validation/from-manifest.js +284 -0
- package/dist/codegen/validation/from-manifest.js.map +1 -0
- package/dist/codegen/validation/infer.d.ts +47 -0
- package/dist/codegen/validation/infer.d.ts.map +1 -0
- package/dist/codegen/validation/infer.js +2 -0
- package/dist/codegen/validation/infer.js.map +1 -0
- package/dist/codegen/validation/json-generic-types.d.ts +7 -0
- package/dist/codegen/validation/json-generic-types.d.ts.map +1 -0
- package/dist/codegen/validation/json-generic-types.js +295 -0
- package/dist/codegen/validation/json-generic-types.js.map +1 -0
- package/dist/codegen/validation/types.d.ts +84 -0
- package/dist/codegen/validation/types.d.ts.map +1 -0
- package/dist/codegen/validation/types.js +6 -0
- package/dist/codegen/validation/types.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -0
- 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 +6 -1
- package/dist/dialect/index.d.ts.map +1 -1
- package/dist/dialect/index.js +5 -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 +2 -1
- package/dist/dialect/postgres.d.ts.map +1 -1
- package/dist/dialect/postgres.js +93 -30
- 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 +60 -3
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/docs/pages.d.ts.map +1 -1
- package/dist/docs/pages.js +5 -0
- package/dist/docs/pages.js.map +1 -1
- package/dist/docs/render.js +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -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 -9
- 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 +186 -9
- package/dist/introspect/pull.js.map +1 -1
- package/dist/introspect/queries.d.ts +11 -1
- package/dist/introspect/queries.d.ts.map +1 -1
- package/dist/introspect/queries.js +43 -12
- 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 +154 -28
- 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 +62 -12
- package/dist/plugins/builtin.d.ts.map +1 -1
- package/dist/plugins/builtin.js +378 -30
- package/dist/plugins/builtin.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.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/columns.d.ts.map +1 -1
- package/dist/plugins/postgis/columns.js +52 -0
- package/dist/plugins/postgis/columns.js.map +1 -1
- package/dist/plugins/postgis/columns.test.js +13 -0
- package/dist/plugins/postgis/columns.test.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/plugins/types.d.ts +3 -0
- package/dist/plugins/types.d.ts.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 +131 -6
- 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/error-hints.d.ts.map +1 -1
- package/dist/runtime/error-hints.js +37 -10
- package/dist/runtime/error-hints.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/aggregate.d.ts.map +1 -1
- package/dist/runtime/query/aggregate.js +3 -3
- package/dist/runtime/query/aggregate.js.map +1 -1
- 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 +33 -28
- 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 +108 -76
- 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 +116 -68
- package/dist/runtime/query/find.js.map +1 -1
- package/dist/runtime/query/group-by.d.ts.map +1 -1
- package/dist/runtime/query/group-by.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/projection.d.ts.map +1 -1
- package/dist/runtime/query/projection.js +1 -1
- package/dist/runtime/query/projection.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 +72 -58
- 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 +272 -116
- package/dist/runtime/query/relation-writes.js.map +1 -1
- package/dist/runtime/query/table-index.d.ts +1 -1
- package/dist/runtime/query/table-index.d.ts.map +1 -1
- package/dist/runtime/query/table-index.js +17 -10
- 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/sqlite-open.js +1 -1
- package/dist/runtime/sqlite-open.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 +26 -0
- package/dist/schema/column-constraints.d.ts.map +1 -0
- package/dist/schema/column-constraints.js +143 -0
- package/dist/schema/column-constraints.js.map +1 -0
- package/dist/schema/column.d.ts +92 -3
- package/dist/schema/column.d.ts.map +1 -1
- package/dist/schema/column.js +17 -11
- package/dist/schema/column.js.map +1 -1
- package/dist/schema/index.d.ts +9 -6
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +8 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-column.d.ts +9 -0
- package/dist/schema/json-column.d.ts.map +1 -0
- package/dist/schema/json-column.js +11 -0
- package/dist/schema/json-column.js.map +1 -0
- package/dist/schema/many-to-many.d.ts +1 -1
- package/dist/schema/many-to-many.d.ts.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 +80 -19
- 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 +7 -6
- 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/dist/utils/load-ts.d.ts +2 -1
- package/dist/utils/load-ts.d.ts.map +1 -1
- package/dist/utils/load-ts.js +13 -1
- package/dist/utils/load-ts.js.map +1 -1
- package/docs/cli.md +4 -4
- package/docs/configuration.md +12 -5
- package/docs/elysia.md +131 -0
- package/docs/errors.md +1 -1
- package/docs/examples.md +4 -2
- package/docs/getting-started.md +28 -2
- package/docs/mariadb.md +149 -0
- package/docs/migrations.md +5 -3
- package/docs/mysql.md +134 -0
- package/docs/plugins.md +2 -0
- package/docs/queries.md +14 -11
- package/docs/relations.md +19 -4
- package/docs/schema.md +100 -9
- package/docs/sqlite.md +14 -2
- package/docs/typebox.md +139 -0
- package/docs/zod.md +128 -0
- package/package.json +33 -3
|
@@ -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,11 +286,11 @@ 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
|
}
|
|
174
|
-
async function
|
|
293
|
+
async function _insertJunctionRows(executor, runtime, throughAccessor, leftFkCol, _rightFkCol, leftId, rightIds) {
|
|
175
294
|
const { manifest } = runtime;
|
|
176
295
|
const m2m = manifest.manyToMany.find((m) => m.throughAccessor === throughAccessor);
|
|
177
296
|
if (!m2m) {
|
|
@@ -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,29 +415,59 @@ 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;
|
|
296
437
|
const tableIndex = getTableIndex(runtime.tableIndex, table.accessor);
|
|
297
438
|
const rel = findRelation(table, relationName, tableIndex);
|
|
298
|
-
if (
|
|
439
|
+
if (rel?.cardinality !== "one")
|
|
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);
|
|
299
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
|
-
data: value
|
|
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) {
|
|
@@ -336,7 +491,7 @@ export async function applyToOnePreWrites(executor, runtime, table, scalarData,
|
|
|
336
491
|
return;
|
|
337
492
|
for (const write of relationWrites) {
|
|
338
493
|
const rel = findRelation(table, write.relationName);
|
|
339
|
-
if (
|
|
494
|
+
if (rel?.cardinality !== "one" || !tableOwnsFkColumn(table, rel))
|
|
340
495
|
continue;
|
|
341
496
|
await executeToOneWrite(executor, runtime, table, scalarData, write.relationName, write.value, runCreate);
|
|
342
497
|
}
|
|
@@ -349,27 +504,27 @@ async function executeM2MWrite(executor, runtime, tableAccessor, parentId, relat
|
|
|
349
504
|
const isLeft = m2m.leftAccessor === tableAccessor;
|
|
350
505
|
const targetAccessor = isLeft ? m2m.rightAccessor : m2m.leftAccessor;
|
|
351
506
|
if ("delete" in value) {
|
|
352
|
-
const del = value
|
|
507
|
+
const del = value.delete;
|
|
353
508
|
if (del === true) {
|
|
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) {
|
|
362
|
-
const disconnect = value
|
|
517
|
+
const disconnect = value.disconnect;
|
|
363
518
|
if (disconnect === true) {
|
|
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,85 +532,88 @@ 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
|
-
const items = value
|
|
387
|
-
const
|
|
541
|
+
const items = value.connectOrCreate;
|
|
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
|
-
if (
|
|
397
|
-
rel.cardinality !== "many" ||
|
|
555
|
+
if (rel?.cardinality !== "many" ||
|
|
398
556
|
findM2M(manifest, table.accessor, relationName)) {
|
|
399
557
|
return;
|
|
400
558
|
}
|
|
401
559
|
if ("delete" in value) {
|
|
402
|
-
const del = value
|
|
560
|
+
const del = value.delete;
|
|
403
561
|
if (del === true) {
|
|
404
562
|
await deleteInverseManyChildren(executor, runtime, rel, parentId, undefined);
|
|
405
563
|
}
|
|
406
564
|
else {
|
|
407
|
-
const
|
|
408
|
-
await deleteInverseManyChildren(executor, runtime, rel, parentId,
|
|
565
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, del);
|
|
566
|
+
await deleteInverseManyChildren(executor, runtime, rel, parentId, pks);
|
|
409
567
|
}
|
|
410
568
|
}
|
|
411
569
|
if ("disconnect" in value) {
|
|
412
|
-
const disconnect = value
|
|
570
|
+
const disconnect = value.disconnect;
|
|
413
571
|
if (disconnect === true) {
|
|
414
572
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
415
573
|
}
|
|
416
574
|
else {
|
|
417
|
-
const
|
|
418
|
-
await disconnectInverseMany(executor, runtime, rel, parentId,
|
|
575
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, disconnect);
|
|
576
|
+
await disconnectInverseMany(executor, runtime, rel, parentId, pks);
|
|
419
577
|
}
|
|
420
578
|
}
|
|
421
579
|
if ("set" in value) {
|
|
422
|
-
const
|
|
423
|
-
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);
|
|
424
582
|
return;
|
|
425
583
|
}
|
|
426
584
|
if ("connect" in value) {
|
|
427
|
-
const
|
|
428
|
-
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);
|
|
429
587
|
}
|
|
430
588
|
if ("create" in value) {
|
|
431
|
-
const items = normalizeCreateList(value
|
|
589
|
+
const items = normalizeCreateList(value.create);
|
|
432
590
|
for (const item of items) {
|
|
433
591
|
await runCreate(executor, runtime, rel.targetAccessor, {
|
|
434
592
|
data: {
|
|
435
593
|
...item,
|
|
436
|
-
|
|
594
|
+
...childFkCreatePatch(rel, table, parentRow, parentId),
|
|
437
595
|
},
|
|
438
596
|
});
|
|
439
597
|
}
|
|
440
598
|
}
|
|
441
599
|
}
|
|
442
|
-
async function executeInverseOneWrite(executor, runtime, table, parentId, relationName, value, runCreate) {
|
|
600
|
+
async function executeInverseOneWrite(executor, runtime, table, parentId, relationName, value, runCreate, parentRow) {
|
|
443
601
|
const { manifest } = runtime;
|
|
444
602
|
const rel = findRelation(table, relationName);
|
|
445
|
-
if (
|
|
603
|
+
if (rel?.cardinality !== "one" || tableOwnsFkColumn(table, rel))
|
|
446
604
|
return;
|
|
447
605
|
const targetTable = manifest.tables[rel.targetAccessor];
|
|
448
606
|
if (!targetTable)
|
|
449
607
|
return;
|
|
450
608
|
const fkCol = childFkColumnMeta(targetTable, rel);
|
|
451
609
|
if ("delete" in value) {
|
|
452
|
-
const del = value
|
|
610
|
+
const del = value.delete;
|
|
453
611
|
if (del === true) {
|
|
454
612
|
await deleteInverseManyChildren(executor, runtime, rel, parentId, undefined);
|
|
455
613
|
}
|
|
456
614
|
else {
|
|
457
|
-
const
|
|
458
|
-
await deleteInverseManyChildren(executor, runtime, rel, parentId,
|
|
615
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, del);
|
|
616
|
+
await deleteInverseManyChildren(executor, runtime, rel, parentId, pks);
|
|
459
617
|
}
|
|
460
618
|
}
|
|
461
619
|
if ("disconnect" in value) {
|
|
@@ -465,26 +623,26 @@ async function executeInverseOneWrite(executor, runtime, table, parentId, relati
|
|
|
465
623
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
466
624
|
}
|
|
467
625
|
if ("set" in value) {
|
|
468
|
-
const
|
|
469
|
-
const
|
|
470
|
-
if (
|
|
626
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.set);
|
|
627
|
+
const pk = pks[0];
|
|
628
|
+
if (pk) {
|
|
471
629
|
await disconnectInverseMany(executor, runtime, rel, parentId, undefined);
|
|
472
|
-
await connectInverseMany(executor, runtime, rel, parentId, [
|
|
630
|
+
await connectInverseMany(executor, runtime, rel, parentId, [pk], table, parentRow);
|
|
473
631
|
}
|
|
474
632
|
return;
|
|
475
633
|
}
|
|
476
634
|
if ("connect" in value) {
|
|
477
|
-
const
|
|
478
|
-
const
|
|
479
|
-
if (!
|
|
635
|
+
const pks = normalizeConnectPks(runtime, rel.targetAccessor, value.connect);
|
|
636
|
+
const pk = pks[0];
|
|
637
|
+
if (!pk)
|
|
480
638
|
return;
|
|
481
|
-
if (
|
|
639
|
+
if (pks.length > 1) {
|
|
482
640
|
compileError(`Cannot connect more than one record to one-to-one relation ${relationName}`);
|
|
483
641
|
}
|
|
484
|
-
await connectInverseMany(executor, runtime, rel, parentId, [
|
|
642
|
+
await connectInverseMany(executor, runtime, rel, parentId, [pk], table, parentRow);
|
|
485
643
|
}
|
|
486
644
|
if ("create" in value) {
|
|
487
|
-
const items = normalizeCreateList(value
|
|
645
|
+
const items = normalizeCreateList(value.create);
|
|
488
646
|
if (items.length > 1) {
|
|
489
647
|
compileError(`Cannot create more than one record for one-to-one relation ${relationName}`);
|
|
490
648
|
}
|
|
@@ -493,13 +651,13 @@ async function executeInverseOneWrite(executor, runtime, table, parentId, relati
|
|
|
493
651
|
await runCreate(executor, runtime, rel.targetAccessor, {
|
|
494
652
|
data: {
|
|
495
653
|
...item,
|
|
496
|
-
|
|
654
|
+
...childFkCreatePatch(rel, table, parentRow, parentId),
|
|
497
655
|
},
|
|
498
656
|
});
|
|
499
657
|
}
|
|
500
658
|
}
|
|
501
659
|
}
|
|
502
|
-
export async function executeRelationWrites(executor, runtime, tableAccessor, parentId, relationWrites, runCreate) {
|
|
660
|
+
export async function executeRelationWrites(executor, runtime, tableAccessor, parentId, relationWrites, runCreate, parentRow) {
|
|
503
661
|
const { manifest } = runtime;
|
|
504
662
|
const table = requireTable(manifest, tableAccessor, "select");
|
|
505
663
|
for (const write of relationWrites) {
|
|
@@ -512,11 +670,11 @@ export async function executeRelationWrites(executor, runtime, tableAccessor, pa
|
|
|
512
670
|
continue;
|
|
513
671
|
if (rel.cardinality === "one") {
|
|
514
672
|
if (!tableOwnsFkColumn(table, rel)) {
|
|
515
|
-
await executeInverseOneWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate);
|
|
673
|
+
await executeInverseOneWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate, parentRow);
|
|
516
674
|
}
|
|
517
675
|
continue;
|
|
518
676
|
}
|
|
519
|
-
await executeInverseManyWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate);
|
|
677
|
+
await executeInverseManyWrite(executor, runtime, table, parentId, write.relationName, write.value, runCreate, parentRow);
|
|
520
678
|
}
|
|
521
679
|
}
|
|
522
680
|
export function hasPostRelationWrites(table, manifest, tableAccessor, relationWrites) {
|
|
@@ -539,9 +697,7 @@ export function relationWritesNeedTransaction(table, manifest, tableAccessor, re
|
|
|
539
697
|
}
|
|
540
698
|
for (const write of relationWrites) {
|
|
541
699
|
const rel = findRelation(table, write.relationName);
|
|
542
|
-
if (!rel
|
|
543
|
-
rel.cardinality !== "one" ||
|
|
544
|
-
!tableOwnsFkColumn(table, rel)) {
|
|
700
|
+
if (rel?.cardinality !== "one" || !tableOwnsFkColumn(table, rel)) {
|
|
545
701
|
continue;
|
|
546
702
|
}
|
|
547
703
|
if (typeof write.value === "object" &&
|