@fragno-dev/db 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +202 -140
- package/CHANGELOG.md +35 -0
- package/README.md +30 -9
- package/dist/adapters/adapters.d.ts +23 -21
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
- package/dist/adapters/generic-sql/driver-config.js +23 -1
- package/dist/adapters/generic-sql/driver-config.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
- package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/select-builder.js +5 -3
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/where-builder.js +39 -29
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
- package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
- package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
- package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
- package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +7 -3
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
- package/dist/adapters/generic-sql/uow-encoder.js +28 -8
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
- package/dist/adapters/in-memory/condition-evaluator.js +131 -0
- package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
- package/dist/adapters/in-memory/errors.d.ts +13 -0
- package/dist/adapters/in-memory/errors.d.ts.map +1 -0
- package/dist/adapters/in-memory/errors.js +23 -0
- package/dist/adapters/in-memory/errors.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
- package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-uow.js +648 -0
- package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
- package/dist/adapters/in-memory/index.d.ts +4 -0
- package/dist/adapters/in-memory/index.js +4 -0
- package/dist/adapters/in-memory/options.d.ts +28 -0
- package/dist/adapters/in-memory/options.d.ts.map +1 -0
- package/dist/adapters/in-memory/options.js +61 -0
- package/dist/adapters/in-memory/options.js.map +1 -0
- package/dist/adapters/in-memory/reference-resolution.js +26 -0
- package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
- package/dist/adapters/in-memory/sorted-array-index.js +129 -0
- package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
- package/dist/adapters/in-memory/store.js +71 -0
- package/dist/adapters/in-memory/store.js.map +1 -0
- package/dist/adapters/in-memory/value-comparison.js +28 -0
- package/dist/adapters/in-memory/value-comparison.js.map +1 -0
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
- package/dist/adapters/shared/uow-operation-compiler.js +11 -11
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
- package/dist/adapters/sql/index.d.ts +5 -0
- package/dist/adapters/sql/index.js +4 -0
- package/dist/db-fragment-definition-builder.d.ts +18 -7
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +116 -54
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.js +63 -0
- package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
- package/dist/dispatchers/node/index.d.ts +17 -0
- package/dist/dispatchers/node/index.d.ts.map +1 -0
- package/dist/dispatchers/node/index.js +59 -0
- package/dist/dispatchers/node/index.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +79 -2
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +150 -32
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/fragments/internal-fragment.routes.js +29 -0
- package/dist/fragments/internal-fragment.routes.js.map +1 -0
- package/dist/fragments/internal-fragment.schema.d.ts +9 -0
- package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.schema.js +22 -0
- package/dist/fragments/internal-fragment.schema.js.map +1 -0
- package/dist/hooks/durable-hooks-processor.d.ts +14 -0
- package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
- package/dist/hooks/durable-hooks-processor.js +32 -0
- package/dist/hooks/durable-hooks-processor.js.map +1 -0
- package/dist/hooks/hooks.d.ts +42 -1
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +72 -6
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/migration-engine/auto-from-schema.js +14 -11
- package/dist/migration-engine/auto-from-schema.js.map +1 -1
- package/dist/migration-engine/generation-engine.d.ts +16 -10
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +72 -33
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/migration-engine/shared.js.map +1 -1
- package/dist/mod.d.ts +15 -8
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +14 -8
- package/dist/mod.js.map +1 -1
- package/dist/naming/sql-naming.d.ts +19 -0
- package/dist/naming/sql-naming.d.ts.map +1 -0
- package/dist/naming/sql-naming.js +116 -0
- package/dist/naming/sql-naming.js.map +1 -0
- package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
- package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/outbox/outbox-builder.js +156 -0
- package/dist/outbox/outbox-builder.js.map +1 -0
- package/dist/outbox/outbox.d.ts +52 -0
- package/dist/outbox/outbox.d.ts.map +1 -0
- package/dist/outbox/outbox.js +37 -0
- package/dist/outbox/outbox.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
- package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
- package/dist/packages/fragno/dist/api/route.js +14 -1
- package/dist/packages/fragno/dist/api/route.js.map +1 -1
- package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
- package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
- package/dist/query/column-defaults.js +20 -4
- package/dist/query/column-defaults.js.map +1 -1
- package/dist/query/cursor.d.ts +3 -1
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +45 -14
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/db-now.d.ts +8 -0
- package/dist/query/db-now.d.ts.map +1 -0
- package/dist/query/db-now.js +7 -0
- package/dist/query/db-now.js.map +1 -0
- package/dist/query/serialize/create-sql-serializer.js +3 -2
- package/dist/query/serialize/create-sql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
- package/dist/query/serialize/sql-serializer.js +2 -2
- package/dist/query/serialize/sql-serializer.js.map +1 -1
- package/dist/query/simple-query-interface.d.ts +6 -1
- package/dist/query/simple-query-interface.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +86 -5
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +9 -6
- package/dist/query/value-decoding.js.map +1 -1
- package/dist/query/value-encoding.js +29 -9
- package/dist/query/value-encoding.js.map +1 -1
- package/dist/schema/create.d.ts +38 -14
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +81 -42
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.js +2 -2
- package/dist/schema/generate-id.js.map +1 -1
- package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
- package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +123 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/schema-output/drizzle.d.ts +30 -0
- package/dist/schema-output/drizzle.d.ts.map +1 -0
- package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
- package/dist/schema-output/drizzle.js.map +1 -0
- package/dist/schema-output/prisma.d.ts +17 -0
- package/dist/schema-output/prisma.d.ts.map +1 -0
- package/dist/schema-output/prisma.js +296 -0
- package/dist/schema-output/prisma.js.map +1 -0
- package/dist/util/default-database-adapter.js +61 -0
- package/dist/util/default-database-adapter.js.map +1 -0
- package/dist/with-database.d.ts +1 -1
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +12 -3
- package/dist/with-database.js.map +1 -1
- package/package.json +43 -28
- package/src/adapters/adapters.ts +30 -24
- package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
- package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
- package/src/adapters/drizzle/test-utils.ts +12 -8
- package/src/adapters/generic-sql/driver-config.ts +38 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
- package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
- package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
- package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
- package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
- package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
- package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
- package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
- package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
- package/src/adapters/generic-sql/query/select-builder.ts +6 -2
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
- package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
- package/src/adapters/generic-sql/query/where-builder.ts +90 -38
- package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
- package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
- package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
- package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
- package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
- package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
- package/src/adapters/generic-sql/uow-decoder.ts +21 -3
- package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
- package/src/adapters/generic-sql/uow-encoder.ts +50 -11
- package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
- package/src/adapters/in-memory/condition-evaluator.ts +275 -0
- package/src/adapters/in-memory/errors.ts +20 -0
- package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
- package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
- package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
- package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
- package/src/adapters/in-memory/index.ts +3 -0
- package/src/adapters/in-memory/options.test.ts +41 -0
- package/src/adapters/in-memory/options.ts +87 -0
- package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
- package/src/adapters/in-memory/reference-resolution.ts +67 -0
- package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
- package/src/adapters/in-memory/sorted-array-index.ts +228 -0
- package/src/adapters/in-memory/store.test.ts +68 -0
- package/src/adapters/in-memory/store.ts +145 -0
- package/src/adapters/in-memory/value-comparison.ts +53 -0
- package/src/adapters/in-memory/value-normalization.test.ts +57 -0
- package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
- package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
- package/src/adapters/shared/uow-operation-compiler.ts +26 -16
- package/src/adapters/sql/index.ts +12 -0
- package/src/db-fragment-definition-builder.test.ts +30 -12
- package/src/db-fragment-definition-builder.ts +142 -73
- package/src/db-fragment-instantiator.test.ts +105 -13
- package/src/db-fragment-integration.test.ts +9 -7
- package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
- package/src/dispatchers/cloudflare-do/index.ts +104 -0
- package/src/dispatchers/node/index.test.ts +91 -0
- package/src/dispatchers/node/index.ts +87 -0
- package/src/fragments/internal-fragment.routes.ts +42 -0
- package/src/fragments/internal-fragment.schema.ts +51 -0
- package/src/fragments/internal-fragment.test.ts +458 -8
- package/src/fragments/internal-fragment.ts +322 -63
- package/src/hooks/durable-hooks-processor.test.ts +117 -0
- package/src/hooks/durable-hooks-processor.ts +67 -0
- package/src/hooks/hooks.test.ts +165 -5
- package/src/hooks/hooks.ts +197 -9
- package/src/migration-engine/auto-from-schema.test.ts +14 -14
- package/src/migration-engine/auto-from-schema.ts +5 -2
- package/src/migration-engine/create.test.ts +2 -2
- package/src/migration-engine/generation-engine.test.ts +229 -104
- package/src/migration-engine/generation-engine.ts +94 -64
- package/src/migration-engine/shared.ts +1 -0
- package/src/mod.ts +64 -26
- package/src/naming/sql-naming.ts +180 -0
- package/src/outbox/outbox-builder.ts +241 -0
- package/src/outbox/outbox.test.ts +253 -0
- package/src/outbox/outbox.ts +137 -0
- package/src/query/column-defaults.ts +41 -3
- package/src/query/condition-builder.test.ts +3 -3
- package/src/query/cursor.test.ts +116 -18
- package/src/query/cursor.ts +75 -26
- package/src/query/db-now.ts +6 -0
- package/src/query/query-type.test.ts +2 -2
- package/src/query/serialize/create-sql-serializer.ts +7 -2
- package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
- package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
- package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
- package/src/query/serialize/sql-serializer.ts +4 -4
- package/src/query/simple-query-interface.ts +5 -0
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
- package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
- package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
- package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
- package/src/query/unit-of-work/unit-of-work.ts +203 -18
- package/src/query/value-decoding.test.ts +13 -2
- package/src/query/value-decoding.ts +17 -4
- package/src/query/value-encoding.test.ts +85 -2
- package/src/query/value-encoding.ts +56 -6
- package/src/schema/create.test.ts +129 -42
- package/src/schema/create.ts +185 -47
- package/src/schema/generate-id.test.ts +2 -2
- package/src/schema/generate-id.ts +2 -2
- package/src/schema/serialize.test.ts +14 -2
- package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
- package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
- package/src/schema/type-conversion/type-mapping.test.ts +25 -1
- package/src/schema/validator.test.ts +197 -0
- package/src/schema/validator.ts +231 -0
- package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
- package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
- package/src/schema-output/prisma.test.ts +536 -0
- package/src/schema-output/prisma.ts +573 -0
- package/src/util/default-database-adapter.ts +106 -0
- package/src/with-database.ts +22 -3
- package/tsdown.config.ts +6 -4
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
- package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
- package/dist/adapters/drizzle/generate.d.ts +0 -30
- package/dist/adapters/drizzle/generate.d.ts.map +0 -1
- package/dist/adapters/drizzle/generate.js.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.js +0 -17
- package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
- package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
- package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
- package/dist/adapters/shared/table-name-mapper.js +0 -43
- package/dist/adapters/shared/table-name-mapper.js.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/schema-generator/schema-generator.d.ts +0 -15
- package/dist/schema-generator/schema-generator.d.ts.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
- package/src/adapters/kysely/kysely-adapter.ts +0 -27
- package/src/adapters/shared/table-name-mapper.ts +0 -50
- package/src/schema-generator/schema-generator.ts +0 -12
|
@@ -2,6 +2,7 @@ import type { AnyColumn } from "../../../schema/create";
|
|
|
2
2
|
import type { Condition } from "../../../query/condition-builder";
|
|
3
3
|
import { decodeCursor, serializeCursorValues, type Cursor } from "../../../query/cursor";
|
|
4
4
|
import type { DriverConfig } from "../driver-config";
|
|
5
|
+
import type { SQLiteStorageMode } from "../sqlite-storage";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Build a cursor condition for pagination.
|
|
@@ -15,6 +16,7 @@ import type { DriverConfig } from "../driver-config";
|
|
|
15
16
|
* @param orderDirection - Direction of ordering (asc/desc)
|
|
16
17
|
* @param isAfter - True for "after" cursor (forward pagination), false for "before" (backward)
|
|
17
18
|
* @param driverConfig - The driver configuration for value serialization
|
|
19
|
+
* @param sqliteStorageMode - Optional SQLite storage mode for date/bigint serialization
|
|
18
20
|
* @returns A Condition object for the cursor, or undefined if no cursor
|
|
19
21
|
* @throws Error if multi-column cursors are not supported by the implementation
|
|
20
22
|
*/
|
|
@@ -24,6 +26,7 @@ export function buildCursorCondition(
|
|
|
24
26
|
orderDirection: "asc" | "desc",
|
|
25
27
|
isAfter: boolean,
|
|
26
28
|
driverConfig: DriverConfig,
|
|
29
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
27
30
|
): Condition | undefined {
|
|
28
31
|
if (!cursor || indexColumns.length === 0) {
|
|
29
32
|
return undefined;
|
|
@@ -31,7 +34,12 @@ export function buildCursorCondition(
|
|
|
31
34
|
|
|
32
35
|
// Decode cursor if it's a string, otherwise use it as-is
|
|
33
36
|
const cursorObj = typeof cursor === "string" ? decodeCursor(cursor) : cursor;
|
|
34
|
-
const serializedValues = serializeCursorValues(
|
|
37
|
+
const serializedValues = serializeCursorValues(
|
|
38
|
+
cursorObj,
|
|
39
|
+
indexColumns,
|
|
40
|
+
driverConfig,
|
|
41
|
+
sqliteStorageMode,
|
|
42
|
+
);
|
|
35
43
|
|
|
36
44
|
// Determine comparison operator based on direction and after/before
|
|
37
45
|
const useGreaterThan =
|
|
@@ -40,7 +48,7 @@ export function buildCursorCondition(
|
|
|
40
48
|
if (indexColumns.length === 1) {
|
|
41
49
|
// Simple single-column case
|
|
42
50
|
const col = indexColumns[0]!;
|
|
43
|
-
const val = serializedValues[col.
|
|
51
|
+
const val = serializedValues[col.name];
|
|
44
52
|
const operator = useGreaterThan ? ">" : "<";
|
|
45
53
|
return {
|
|
46
54
|
type: "compare",
|
|
@@ -48,9 +56,36 @@ export function buildCursorCondition(
|
|
|
48
56
|
operator,
|
|
49
57
|
b: val,
|
|
50
58
|
};
|
|
51
|
-
} else {
|
|
52
|
-
throw new Error(
|
|
53
|
-
"Multi-column cursor pagination is not yet supported in Generic SQL implementation",
|
|
54
|
-
);
|
|
55
59
|
}
|
|
60
|
+
|
|
61
|
+
const operator = useGreaterThan ? ">" : "<";
|
|
62
|
+
const orConditions: Condition[] = [];
|
|
63
|
+
const isNullish = (value: unknown): value is null | undefined =>
|
|
64
|
+
value === null || value === undefined;
|
|
65
|
+
const buildEqualityCondition = (column: AnyColumn, value: unknown): Condition =>
|
|
66
|
+
isNullish(value)
|
|
67
|
+
? { type: "compare", a: column, operator: "is", b: null }
|
|
68
|
+
: { type: "compare", a: column, operator: "=", b: value };
|
|
69
|
+
|
|
70
|
+
for (let i = 0; i < indexColumns.length; i += 1) {
|
|
71
|
+
const col = indexColumns[i]!;
|
|
72
|
+
const val = serializedValues[col.name];
|
|
73
|
+
const andItems: Condition[] = [];
|
|
74
|
+
|
|
75
|
+
for (let j = 0; j < i; j += 1) {
|
|
76
|
+
const prevCol = indexColumns[j]!;
|
|
77
|
+
andItems.push(buildEqualityCondition(prevCol, serializedValues[prevCol.name]));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
andItems.push({
|
|
81
|
+
type: "compare",
|
|
82
|
+
a: col,
|
|
83
|
+
operator,
|
|
84
|
+
b: val,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
orConditions.push(andItems.length === 1 ? andItems[0]! : { type: "and", items: andItems });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return { type: "or", items: orConditions };
|
|
56
91
|
}
|
|
@@ -5,7 +5,7 @@ import { schema, column, idColumn, referenceColumn, FragnoId } from "../../../sc
|
|
|
5
5
|
import { Cursor } from "../../../query/cursor";
|
|
6
6
|
|
|
7
7
|
// Test schema with indexes
|
|
8
|
-
const testSchema = schema((s) => {
|
|
8
|
+
const testSchema = schema("test", (s) => {
|
|
9
9
|
return s
|
|
10
10
|
.addTable("users", (t) => {
|
|
11
11
|
return t
|
|
@@ -17,7 +17,7 @@ const testSchema = schema((s) => {
|
|
|
17
17
|
.addColumn("createdAt", column("timestamp"))
|
|
18
18
|
.addColumn("invitedBy", referenceColumn().nullable())
|
|
19
19
|
.createIndex("idx_email", ["email"], { unique: true })
|
|
20
|
-
.createIndex("
|
|
20
|
+
.createIndex("idx_users_name", ["name"])
|
|
21
21
|
.createIndex("idx_age", ["age"]);
|
|
22
22
|
})
|
|
23
23
|
.addTable("posts", (t) => {
|
|
@@ -37,21 +37,21 @@ const testSchema = schema((s) => {
|
|
|
37
37
|
.addColumn("content", column("string"))
|
|
38
38
|
.addColumn("postId", referenceColumn())
|
|
39
39
|
.addColumn("authorId", referenceColumn())
|
|
40
|
-
.createIndex("
|
|
40
|
+
.createIndex("idx_comments_post", ["postId"])
|
|
41
41
|
.createIndex("idx_author", ["authorId"]);
|
|
42
42
|
})
|
|
43
43
|
.addTable("tags", (t) => {
|
|
44
44
|
return t
|
|
45
45
|
.addColumn("id", idColumn())
|
|
46
46
|
.addColumn("name", column("string"))
|
|
47
|
-
.createIndex("
|
|
47
|
+
.createIndex("idx_tags_name", ["name"]);
|
|
48
48
|
})
|
|
49
49
|
.addTable("post_tags", (t) => {
|
|
50
50
|
return t
|
|
51
51
|
.addColumn("id", idColumn())
|
|
52
52
|
.addColumn("postId", referenceColumn())
|
|
53
53
|
.addColumn("tagId", referenceColumn())
|
|
54
|
-
.createIndex("
|
|
54
|
+
.createIndex("idx_post_tags_post", ["postId"])
|
|
55
55
|
.createIndex("idx_tag", ["tagId"]);
|
|
56
56
|
})
|
|
57
57
|
.addReference("author", {
|
|
@@ -87,7 +87,7 @@ const testSchema = schema((s) => {
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
// Schema with custom-named id columns
|
|
90
|
-
const customIdSchema = schema((s) => {
|
|
90
|
+
const customIdSchema = schema("customid", (s) => {
|
|
91
91
|
return s
|
|
92
92
|
.addTable("products", (t) => {
|
|
93
93
|
return t
|
|
@@ -232,7 +232,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
232
232
|
|
|
233
233
|
expect(result).not.toBeNull();
|
|
234
234
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
235
|
-
`"update "users" set "name" = ?, "_version" =
|
|
235
|
+
`"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
|
|
236
236
|
);
|
|
237
237
|
expect(result!.expectedAffectedRows).toBeNull();
|
|
238
238
|
});
|
|
@@ -253,7 +253,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
253
253
|
|
|
254
254
|
expect(result).not.toBeNull();
|
|
255
255
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
256
|
-
`"update "users" set "name" = ?, "_version" =
|
|
256
|
+
`"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where ("users"."id" = ? and "users"."_version" = ?)"`,
|
|
257
257
|
);
|
|
258
258
|
expect(result!.expectedAffectedRows).toBe(1n);
|
|
259
259
|
});
|
|
@@ -396,7 +396,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
396
396
|
|
|
397
397
|
expect(result).not.toBeNull();
|
|
398
398
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
399
|
-
`"update "posts" set "userId" = (select "_internalId" from "users" where "id" = ? limit ?), "_version" =
|
|
399
|
+
`"update "posts" set "userId" = (select "_internalId" from "users" where "id" = ? limit ?), "_version" = coalesce("_version", 0) + 1 where "posts"."id" = ?"`,
|
|
400
400
|
);
|
|
401
401
|
});
|
|
402
402
|
|
|
@@ -418,7 +418,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
418
418
|
// Should not have nested SELECT for the userId value
|
|
419
419
|
expect(result!.query.sql).not.toMatch(/\(select.*from.*users/i);
|
|
420
420
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
421
|
-
`"update "posts" set "userId" = ?, "_version" =
|
|
421
|
+
`"update "posts" set "userId" = ?, "_version" = coalesce("_version", 0) + 1 where "posts"."id" = ?"`,
|
|
422
422
|
);
|
|
423
423
|
});
|
|
424
424
|
|
|
@@ -440,7 +440,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
440
440
|
|
|
441
441
|
expect(result).not.toBeNull();
|
|
442
442
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
443
|
-
`"update "users" set "name" = ?, "email" = ?, "isActive" = ?, "_version" =
|
|
443
|
+
`"update "users" set "name" = ?, "email" = ?, "isActive" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
|
|
444
444
|
);
|
|
445
445
|
});
|
|
446
446
|
});
|
|
@@ -612,7 +612,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
612
612
|
|
|
613
613
|
expect(result).not.toBeNull();
|
|
614
614
|
expect(result!.query.sql).toMatchInlineSnapshot(
|
|
615
|
-
`"update "products" set "price" = ?, "_version" =
|
|
615
|
+
`"update "products" set "price" = ?, "_version" = coalesce("_version", 0) + 1 where "products"."productId" = ?"`,
|
|
616
616
|
);
|
|
617
617
|
});
|
|
618
618
|
|
|
@@ -757,11 +757,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
757
757
|
type: "find",
|
|
758
758
|
schema: testSchema,
|
|
759
759
|
table: testSchema.tables.users,
|
|
760
|
-
indexName: "
|
|
760
|
+
indexName: "idx_users_name",
|
|
761
761
|
options: {
|
|
762
|
-
useIndex: "
|
|
762
|
+
useIndex: "idx_users_name",
|
|
763
763
|
select: true,
|
|
764
|
-
orderByIndex: { indexName: "
|
|
764
|
+
orderByIndex: { indexName: "idx_users_name", direction: "asc" },
|
|
765
765
|
},
|
|
766
766
|
});
|
|
767
767
|
|
|
@@ -799,7 +799,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
799
799
|
test("should compile find with cursor pagination using after", () => {
|
|
800
800
|
const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
|
|
801
801
|
const cursor = new Cursor({
|
|
802
|
-
indexName: "
|
|
802
|
+
indexName: "idx_users_name",
|
|
803
803
|
orderDirection: "asc",
|
|
804
804
|
pageSize: 10,
|
|
805
805
|
indexValues: { name: "Alice" },
|
|
@@ -809,11 +809,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
809
809
|
type: "find",
|
|
810
810
|
schema: testSchema,
|
|
811
811
|
table: testSchema.tables.users,
|
|
812
|
-
indexName: "
|
|
812
|
+
indexName: "idx_users_name",
|
|
813
813
|
options: {
|
|
814
|
-
useIndex: "
|
|
814
|
+
useIndex: "idx_users_name",
|
|
815
815
|
select: true,
|
|
816
|
-
orderByIndex: { indexName: "
|
|
816
|
+
orderByIndex: { indexName: "idx_users_name", direction: "asc" },
|
|
817
817
|
after: cursor,
|
|
818
818
|
pageSize: 10,
|
|
819
819
|
},
|
|
@@ -829,7 +829,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
829
829
|
test("should compile find with cursor pagination using before", () => {
|
|
830
830
|
const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
|
|
831
831
|
const cursor = new Cursor({
|
|
832
|
-
indexName: "
|
|
832
|
+
indexName: "idx_users_name",
|
|
833
833
|
orderDirection: "desc",
|
|
834
834
|
pageSize: 10,
|
|
835
835
|
indexValues: { name: "Bob" },
|
|
@@ -839,11 +839,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
839
839
|
type: "find",
|
|
840
840
|
schema: testSchema,
|
|
841
841
|
table: testSchema.tables.users,
|
|
842
|
-
indexName: "
|
|
842
|
+
indexName: "idx_users_name",
|
|
843
843
|
options: {
|
|
844
|
-
useIndex: "
|
|
844
|
+
useIndex: "idx_users_name",
|
|
845
845
|
select: true,
|
|
846
|
-
orderByIndex: { indexName: "
|
|
846
|
+
orderByIndex: { indexName: "idx_users_name", direction: "desc" },
|
|
847
847
|
before: cursor,
|
|
848
848
|
pageSize: 10,
|
|
849
849
|
},
|
|
@@ -859,7 +859,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
859
859
|
test("should compile find with cursor pagination and additional where conditions", () => {
|
|
860
860
|
const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
|
|
861
861
|
const cursor = new Cursor({
|
|
862
|
-
indexName: "
|
|
862
|
+
indexName: "idx_users_name",
|
|
863
863
|
orderDirection: "asc",
|
|
864
864
|
pageSize: 5,
|
|
865
865
|
indexValues: { name: "Alice" },
|
|
@@ -869,12 +869,12 @@ describe("GenericSQLUOWOperationCompiler", () => {
|
|
|
869
869
|
type: "find",
|
|
870
870
|
schema: testSchema,
|
|
871
871
|
table: testSchema.tables.users,
|
|
872
|
-
indexName: "
|
|
872
|
+
indexName: "idx_users_name",
|
|
873
873
|
options: {
|
|
874
|
-
useIndex: "
|
|
874
|
+
useIndex: "idx_users_name",
|
|
875
875
|
select: true,
|
|
876
876
|
where: (eb) => eb("isActive", "=", true),
|
|
877
|
-
orderByIndex: { indexName: "
|
|
877
|
+
orderByIndex: { indexName: "idx_users_name", direction: "asc" },
|
|
878
878
|
after: cursor,
|
|
879
879
|
pageSize: 5,
|
|
880
880
|
},
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { UOWOperationCompiler } from "../../shared/uow-operation-compiler";
|
|
2
2
|
import type { CompiledQuery } from "kysely";
|
|
3
3
|
import type { DriverConfig } from "../driver-config";
|
|
4
|
-
import type {
|
|
4
|
+
import type { NamingResolver } from "../../../naming/sql-naming";
|
|
5
|
+
import type { SQLiteStorageMode } from "../sqlite-storage";
|
|
5
6
|
import type {
|
|
6
7
|
RetrievalOperation,
|
|
7
8
|
MutationOperation,
|
|
@@ -24,26 +25,40 @@ import { createColdKysely } from "../migration/cold-kysely";
|
|
|
24
25
|
* high-level business logic like cursor pagination, version checking, and index resolution.
|
|
25
26
|
*/
|
|
26
27
|
export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<CompiledQuery> {
|
|
28
|
+
private readonly sqliteStorageMode?: SQLiteStorageMode;
|
|
29
|
+
|
|
27
30
|
constructor(
|
|
28
31
|
driverConfig: DriverConfig,
|
|
29
|
-
|
|
32
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
33
|
+
resolverFactory?: (schema: AnySchema, namespace: string | null) => NamingResolver,
|
|
30
34
|
) {
|
|
31
|
-
super(driverConfig,
|
|
35
|
+
super(driverConfig, resolverFactory);
|
|
36
|
+
this.sqliteStorageMode = sqliteStorageMode;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
/**
|
|
35
40
|
* Get SQL compiler for a specific namespace
|
|
36
41
|
*/
|
|
37
|
-
private getSQLCompiler(
|
|
38
|
-
|
|
42
|
+
private getSQLCompiler(
|
|
43
|
+
schema: AnySchema,
|
|
44
|
+
namespace: string | null | undefined,
|
|
45
|
+
): SQLQueryCompiler {
|
|
46
|
+
const resolver = this.getNamingResolver(schema, namespace ?? null);
|
|
39
47
|
const kysely = createColdKysely(this.driverConfig.databaseType);
|
|
40
|
-
|
|
48
|
+
const schemaName = resolver.getSchemaName();
|
|
49
|
+
const scopedKysely = schemaName ? kysely.withSchema(schemaName) : kysely;
|
|
50
|
+
return createSQLQueryCompiler(
|
|
51
|
+
scopedKysely,
|
|
52
|
+
this.driverConfig,
|
|
53
|
+
this.sqliteStorageMode,
|
|
54
|
+
resolver,
|
|
55
|
+
);
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
override compileCount(
|
|
44
59
|
op: RetrievalOperation<AnySchema> & { type: "count" },
|
|
45
60
|
): CompiledQuery | null {
|
|
46
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
61
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
47
62
|
|
|
48
63
|
// Build where condition
|
|
49
64
|
let conditions = op.options.where
|
|
@@ -61,7 +76,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
override compileFind(op: RetrievalOperation<AnySchema> & { type: "find" }): CompiledQuery | null {
|
|
64
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
79
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
65
80
|
|
|
66
81
|
// Extract options
|
|
67
82
|
const {
|
|
@@ -116,6 +131,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
116
131
|
orderDirection,
|
|
117
132
|
!!after,
|
|
118
133
|
this.driverConfig,
|
|
134
|
+
this.sqliteStorageMode,
|
|
119
135
|
);
|
|
120
136
|
|
|
121
137
|
// Combine user where clause with cursor condition
|
|
@@ -160,7 +176,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
160
176
|
const compiledOptions = buildFindOptions(op.table, {
|
|
161
177
|
...findManyOptions,
|
|
162
178
|
where: combinedWhere ? () => combinedWhere! : undefined,
|
|
163
|
-
orderBy: orderBy?.map(([col, dir]) => [col.
|
|
179
|
+
orderBy: orderBy?.map(([col, dir]) => [col.name, dir]),
|
|
164
180
|
limit: effectiveLimit,
|
|
165
181
|
});
|
|
166
182
|
|
|
@@ -174,11 +190,12 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
174
190
|
override compileCreate(
|
|
175
191
|
op: MutationOperation<AnySchema> & { type: "create" },
|
|
176
192
|
): CompiledMutation<CompiledQuery> | null {
|
|
177
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
193
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
178
194
|
const table = this.getTable(op.schema, op.table);
|
|
179
195
|
|
|
180
196
|
return {
|
|
181
197
|
query: sqlCompiler.compileCreate(table, op.values),
|
|
198
|
+
operation: op,
|
|
182
199
|
op: "create",
|
|
183
200
|
expectedAffectedRows: null, // creates don't need affected row checks
|
|
184
201
|
expectedReturnedRows: null,
|
|
@@ -188,7 +205,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
188
205
|
override compileUpdate(
|
|
189
206
|
op: MutationOperation<AnySchema> & { type: "update" },
|
|
190
207
|
): CompiledMutation<CompiledQuery> | null {
|
|
191
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
208
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
192
209
|
const table = this.getTable(op.schema, op.table);
|
|
193
210
|
const idColumn = table.getIdColumn();
|
|
194
211
|
const versionColumn = table.getVersionColumn();
|
|
@@ -200,12 +217,9 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
200
217
|
const conditionsResult =
|
|
201
218
|
versionToCheck !== undefined
|
|
202
219
|
? buildCondition(table.columns, (eb) =>
|
|
203
|
-
eb.and(
|
|
204
|
-
eb(idColumn.ormName, "=", externalId),
|
|
205
|
-
eb(versionColumn.ormName, "=", versionToCheck),
|
|
206
|
-
),
|
|
220
|
+
eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", versionToCheck)),
|
|
207
221
|
)
|
|
208
|
-
: buildCondition(table.columns, (eb) => eb(idColumn.
|
|
222
|
+
: buildCondition(table.columns, (eb) => eb(idColumn.name, "=", externalId));
|
|
209
223
|
|
|
210
224
|
if (conditionsResult === false) {
|
|
211
225
|
return null;
|
|
@@ -229,6 +243,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
229
243
|
|
|
230
244
|
return {
|
|
231
245
|
query,
|
|
246
|
+
operation: op,
|
|
232
247
|
op: "update",
|
|
233
248
|
expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
|
|
234
249
|
expectedReturnedRows: useReturningForCheck ? 1 : null,
|
|
@@ -238,7 +253,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
238
253
|
override compileDelete(
|
|
239
254
|
op: MutationOperation<AnySchema> & { type: "delete" },
|
|
240
255
|
): CompiledMutation<CompiledQuery> | null {
|
|
241
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
256
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
242
257
|
const table = this.getTable(op.schema, op.table);
|
|
243
258
|
const idColumn = table.getIdColumn();
|
|
244
259
|
const versionColumn = table.getVersionColumn();
|
|
@@ -250,12 +265,9 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
250
265
|
const conditionsResult =
|
|
251
266
|
versionToCheck !== undefined
|
|
252
267
|
? buildCondition(table.columns, (eb) =>
|
|
253
|
-
eb.and(
|
|
254
|
-
eb(idColumn.ormName, "=", externalId),
|
|
255
|
-
eb(versionColumn.ormName, "=", versionToCheck),
|
|
256
|
-
),
|
|
268
|
+
eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", versionToCheck)),
|
|
257
269
|
)
|
|
258
|
-
: buildCondition(table.columns, (eb) => eb(idColumn.
|
|
270
|
+
: buildCondition(table.columns, (eb) => eb(idColumn.name, "=", externalId));
|
|
259
271
|
|
|
260
272
|
if (conditionsResult === false) {
|
|
261
273
|
return null;
|
|
@@ -278,6 +290,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
278
290
|
|
|
279
291
|
return {
|
|
280
292
|
query,
|
|
293
|
+
operation: op,
|
|
281
294
|
op: "delete",
|
|
282
295
|
expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
|
|
283
296
|
expectedReturnedRows: useReturningForCheck ? 1 : null,
|
|
@@ -287,7 +300,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
287
300
|
override compileCheck(
|
|
288
301
|
op: MutationOperation<AnySchema> & { type: "check" },
|
|
289
302
|
): CompiledMutation<CompiledQuery> {
|
|
290
|
-
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
303
|
+
const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
|
|
291
304
|
const table = this.getTable(op.schema, op.table);
|
|
292
305
|
const idColumn = table.getIdColumn();
|
|
293
306
|
const versionColumn = table.getVersionColumn();
|
|
@@ -297,7 +310,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
297
310
|
|
|
298
311
|
// Build a SELECT 1 query to check if the row exists with the correct version
|
|
299
312
|
const condition = buildCondition(table.columns, (eb) =>
|
|
300
|
-
eb.and(eb(idColumn.
|
|
313
|
+
eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", version)),
|
|
301
314
|
);
|
|
302
315
|
|
|
303
316
|
if (typeof condition === "boolean") {
|
|
@@ -306,6 +319,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
|
|
|
306
319
|
|
|
307
320
|
return {
|
|
308
321
|
query: sqlCompiler.compileCheck(table, condition),
|
|
322
|
+
operation: op,
|
|
309
323
|
op: "check",
|
|
310
324
|
expectedAffectedRows: null,
|
|
311
325
|
expectedReturnedRows: 1, // Check that exactly 1 row was returned
|
|
@@ -3,7 +3,7 @@ import { column, idColumn, referenceColumn, schema } from "../../../schema/creat
|
|
|
3
3
|
import { mapSelect, extendSelect } from "./select-builder";
|
|
4
4
|
|
|
5
5
|
describe("select-builder", () => {
|
|
6
|
-
const testSchema = schema((s) => {
|
|
6
|
+
const testSchema = schema("test", (s) => {
|
|
7
7
|
return s
|
|
8
8
|
.addTable("users", (t) => {
|
|
9
9
|
return t
|
|
@@ -35,7 +35,7 @@ describe("select-builder", () => {
|
|
|
35
35
|
|
|
36
36
|
describe("mapSelect", () => {
|
|
37
37
|
it("should map select clause with array of keys", () => {
|
|
38
|
-
const result = mapSelect(["id", "name", "email"], usersTable);
|
|
38
|
+
const result = mapSelect(["id", "name", "email"], usersTable, undefined);
|
|
39
39
|
expect(result).toEqual([
|
|
40
40
|
"users.id as id",
|
|
41
41
|
"users.name as name",
|
|
@@ -46,7 +46,7 @@ describe("select-builder", () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it("should map select all columns when true", () => {
|
|
49
|
-
const result = mapSelect(true, usersTable);
|
|
49
|
+
const result = mapSelect(true, usersTable, undefined);
|
|
50
50
|
expect(result).toEqual([
|
|
51
51
|
"users.id as id",
|
|
52
52
|
"users.name as name",
|
|
@@ -60,7 +60,9 @@ describe("select-builder", () => {
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
it("should map select with relation prefix", () => {
|
|
63
|
-
const result = mapSelect(["id", "name"], usersTable, {
|
|
63
|
+
const result = mapSelect(["id", "name"], usersTable, undefined, {
|
|
64
|
+
relation: "author",
|
|
65
|
+
});
|
|
64
66
|
expect(result).toEqual([
|
|
65
67
|
"users.id as author:id",
|
|
66
68
|
"users.name as author:name",
|
|
@@ -70,7 +72,9 @@ describe("select-builder", () => {
|
|
|
70
72
|
});
|
|
71
73
|
|
|
72
74
|
it("should map select with custom table name", () => {
|
|
73
|
-
const result = mapSelect(["id", "title"], postsTable, {
|
|
75
|
+
const result = mapSelect(["id", "title"], postsTable, undefined, {
|
|
76
|
+
tableName: "p",
|
|
77
|
+
});
|
|
74
78
|
expect(result).toEqual([
|
|
75
79
|
"p.id as id",
|
|
76
80
|
"p.title as title",
|
|
@@ -80,7 +84,7 @@ describe("select-builder", () => {
|
|
|
80
84
|
});
|
|
81
85
|
|
|
82
86
|
it("should map select with both relation and custom table name", () => {
|
|
83
|
-
const result = mapSelect(["id", "title"], postsTable, {
|
|
87
|
+
const result = mapSelect(["id", "title"], postsTable, undefined, {
|
|
84
88
|
relation: "posts",
|
|
85
89
|
tableName: "p",
|
|
86
90
|
});
|
|
@@ -93,7 +97,7 @@ describe("select-builder", () => {
|
|
|
93
97
|
});
|
|
94
98
|
|
|
95
99
|
it("should handle single column select", () => {
|
|
96
|
-
const result = mapSelect(["name"], usersTable);
|
|
100
|
+
const result = mapSelect(["name"], usersTable, undefined);
|
|
97
101
|
expect(result).toEqual([
|
|
98
102
|
"users.name as name",
|
|
99
103
|
"users._internalId as _internalId",
|
|
@@ -104,7 +108,7 @@ describe("select-builder", () => {
|
|
|
104
108
|
it("should skip hidden columns when explicitly selecting", () => {
|
|
105
109
|
// When an array is passed, hidden columns should not be included in the select
|
|
106
110
|
// (unless they are in the array), but they should always be added at the end
|
|
107
|
-
const result = mapSelect(["name", "email"], usersTable);
|
|
111
|
+
const result = mapSelect(["name", "email"], usersTable, undefined);
|
|
108
112
|
// Should not duplicate _internalId or _version in the main select
|
|
109
113
|
expect(result).toEqual([
|
|
110
114
|
"users.name as name",
|
|
@@ -116,19 +120,19 @@ describe("select-builder", () => {
|
|
|
116
120
|
|
|
117
121
|
it("should always include hidden columns", () => {
|
|
118
122
|
// Hidden columns (_internalId, _version) should always be included
|
|
119
|
-
const result = mapSelect(["name"], usersTable);
|
|
123
|
+
const result = mapSelect(["name"], usersTable, undefined);
|
|
120
124
|
expect(result.some((col) => col.includes("_internalId"))).toBe(true);
|
|
121
125
|
expect(result.some((col) => col.includes("_version"))).toBe(true);
|
|
122
126
|
});
|
|
123
127
|
|
|
124
128
|
it("should handle empty select array", () => {
|
|
125
|
-
const result = mapSelect([], usersTable);
|
|
129
|
+
const result = mapSelect([], usersTable, undefined);
|
|
126
130
|
// Should still include hidden columns
|
|
127
131
|
expect(result).toEqual(["users._internalId as _internalId", "users._version as _version"]);
|
|
128
132
|
});
|
|
129
133
|
|
|
130
134
|
it("should work with different table schemas", () => {
|
|
131
|
-
const result = mapSelect(["id", "title", "content"], postsTable);
|
|
135
|
+
const result = mapSelect(["id", "title", "content"], postsTable, undefined);
|
|
132
136
|
expect(result).toEqual([
|
|
133
137
|
"posts.id as id",
|
|
134
138
|
"posts.title as title",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AnyTable } from "../../../schema/create";
|
|
2
2
|
import type { AnySelectClause } from "../../../query/simple-query-interface";
|
|
3
|
+
import type { NamingResolver } from "../../../naming/sql-naming";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Maps a select clause to SQL column names with optional aliases.
|
|
@@ -18,6 +19,7 @@ import type { AnySelectClause } from "../../../query/simple-query-interface";
|
|
|
18
19
|
export function mapSelect(
|
|
19
20
|
select: AnySelectClause,
|
|
20
21
|
table: AnyTable,
|
|
22
|
+
resolver: NamingResolver | undefined,
|
|
21
23
|
options: {
|
|
22
24
|
relation?: string;
|
|
23
25
|
tableName?: string;
|
|
@@ -37,7 +39,8 @@ export function mapSelect(
|
|
|
37
39
|
|
|
38
40
|
// Add the column to the select list
|
|
39
41
|
const name = relation ? `${relation}:${key}` : key;
|
|
40
|
-
|
|
42
|
+
const columnName = resolver ? resolver.getColumnName(table.name, col.name) : col.name;
|
|
43
|
+
out.push(`${tableName}.${columnName} as ${name}`);
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
// Always include hidden columns (for FragnoId construction with internal ID and version)
|
|
@@ -45,7 +48,8 @@ export function mapSelect(
|
|
|
45
48
|
const col = table.columns[key];
|
|
46
49
|
if (col.isHidden && !keys.includes(key)) {
|
|
47
50
|
const name = relation ? `${relation}:${key}` : key;
|
|
48
|
-
|
|
51
|
+
const columnName = resolver ? resolver.getColumnName(table.name, col.name) : col.name;
|
|
52
|
+
out.push(`${tableName}.${columnName} as ${name}`);
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -2,6 +2,7 @@ import { describe, test, expect } from "vitest";
|
|
|
2
2
|
import { Kysely, SqliteDialect } from "kysely";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
import { schema, column, idColumn, referenceColumn } from "../../../schema/create";
|
|
5
|
+
import { createNamingResolver, type SqlNamingStrategy } from "../../../naming/sql-naming";
|
|
5
6
|
import { PostgreSQLQueryCompiler } from "./dialect/postgres";
|
|
6
7
|
import { MySQLQueryCompiler } from "./dialect/mysql";
|
|
7
8
|
import { SQLiteQueryCompiler } from "./dialect/sqlite";
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
} from "../driver-config";
|
|
13
14
|
|
|
14
15
|
// Test schema
|
|
15
|
-
const testSchema = schema((s) => {
|
|
16
|
+
const testSchema = schema("test", (s) => {
|
|
16
17
|
return s
|
|
17
18
|
.addTable("users", (t) => {
|
|
18
19
|
return t
|
|
@@ -130,7 +131,7 @@ describe("SQLQueryCompiler", () => {
|
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
expect(query.sql).toMatchInlineSnapshot(
|
|
133
|
-
`"update "users" set "name" = ?, "_version" =
|
|
134
|
+
`"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
|
|
134
135
|
);
|
|
135
136
|
});
|
|
136
137
|
|
|
@@ -191,5 +192,54 @@ describe("SQLQueryCompiler", () => {
|
|
|
191
192
|
);
|
|
192
193
|
expect(query.sql).toContain("returning");
|
|
193
194
|
});
|
|
195
|
+
|
|
196
|
+
test("compileUpdate succeeds when version column needs quoting", async () => {
|
|
197
|
+
const db = new Kysely({
|
|
198
|
+
dialect: new SqliteDialect({ database: new Database(":memory:") }),
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
await db.schema
|
|
202
|
+
.createTable("users")
|
|
203
|
+
.addColumn("id", "text")
|
|
204
|
+
.addColumn("name", "text")
|
|
205
|
+
.addColumn("users-version", "integer")
|
|
206
|
+
.execute();
|
|
207
|
+
|
|
208
|
+
const namingStrategy: SqlNamingStrategy = {
|
|
209
|
+
namespaceScope: "suffix",
|
|
210
|
+
namespaceToSchema: (namespace) => namespace,
|
|
211
|
+
tableName: (logicalTable) => logicalTable,
|
|
212
|
+
columnName: (logicalColumn, logicalTable) =>
|
|
213
|
+
logicalColumn === "_version" ? `${logicalTable}-version` : logicalColumn,
|
|
214
|
+
indexName: (logicalIndex) => logicalIndex,
|
|
215
|
+
uniqueIndexName: (logicalIndex) => logicalIndex,
|
|
216
|
+
foreignKeyName: ({ referenceName }) => referenceName,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const resolver = createNamingResolver(testSchema, null, namingStrategy);
|
|
220
|
+
const compiler = new SQLiteQueryCompiler(
|
|
221
|
+
db,
|
|
222
|
+
new BetterSQLite3DriverConfig(),
|
|
223
|
+
undefined,
|
|
224
|
+
resolver,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const query = compiler.compileUpdate(testSchema.tables.users, {
|
|
228
|
+
set: { name: "Jane" },
|
|
229
|
+
where: {
|
|
230
|
+
type: "compare",
|
|
231
|
+
a: testSchema.tables.users.columns.id,
|
|
232
|
+
operator: "=",
|
|
233
|
+
b: "user123",
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
expect(query.sql).toContain('coalesce("users-version", 0) + 1');
|
|
238
|
+
try {
|
|
239
|
+
await expect(db.executeQuery(query)).resolves.toBeDefined();
|
|
240
|
+
} finally {
|
|
241
|
+
await db.destroy();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
194
244
|
});
|
|
195
245
|
});
|