@fragno-dev/db 0.2.1 → 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 +206 -140
- package/CHANGELOG.md +67 -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 +38 -28
- 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 +45 -96
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +121 -99
- 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 +172 -9
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +193 -74
- 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 +47 -4
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +106 -39
- 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 +17 -10
- 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 +351 -100
- 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 +440 -267
- 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 +67 -22
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +110 -13
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +8 -5
- 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 +40 -14
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +82 -42
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.d.ts +20 -0
- package/dist/schema/generate-id.d.ts.map +1 -0
- package/dist/schema/generate-id.js +28 -0
- package/dist/schema/generate-id.js.map +1 -0
- 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} +49 -35
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +48 -32
- 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 +88 -54
- package/src/db-fragment-definition-builder.ts +201 -322
- package/src/db-fragment-instantiator.test.ts +169 -101
- package/src/db-fragment-integration.test.ts +301 -149
- 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 +730 -274
- package/src/fragments/internal-fragment.ts +447 -154
- 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 +411 -259
- package/src/hooks/hooks.ts +265 -66
- 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 +78 -30
- 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 +1512 -1458
- package/src/query/unit-of-work/execute-unit-of-work.ts +1708 -596
- package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +32 -32
- 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 +231 -36
- package/src/query/unit-of-work/unit-of-work.ts +229 -31
- 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 +187 -47
- package/src/schema/generate-id.test.ts +57 -0
- package/src/schema/generate-id.ts +38 -0
- 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
- package/src/shared/config.ts +0 -10
- package/src/shared/connection-pool.ts +0 -24
- package/src/shared/prisma.ts +0 -45
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { PGlite } from "@electric-sql/pglite";
|
|
2
2
|
import { KyselyPGlite } from "kysely-pglite";
|
|
3
|
-
import {
|
|
3
|
+
import { SqlAdapter } from "./generic-sql-adapter";
|
|
4
4
|
import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
|
|
5
5
|
import { column, idColumn, referenceColumn, schema } from "../../schema/create";
|
|
6
6
|
import { Cursor } from "../../query/cursor";
|
|
7
|
-
import { PGLiteDriverConfig } from "
|
|
7
|
+
import { PGLiteDriverConfig } from "./driver-config";
|
|
8
8
|
import type { CompiledQuery } from "../../sql-driver/sql-driver";
|
|
9
9
|
import { internalSchema } from "../../fragments/internal-fragment";
|
|
10
10
|
|
|
11
|
-
describe("
|
|
11
|
+
describe("SqlAdapter PGLite", () => {
|
|
12
12
|
let pgliteDatabase: PGlite;
|
|
13
|
-
let adapter:
|
|
13
|
+
let adapter: SqlAdapter;
|
|
14
14
|
|
|
15
|
-
const testSchema = schema((s) => {
|
|
15
|
+
const testSchema = schema("test", (s) => {
|
|
16
16
|
return s
|
|
17
17
|
.addTable("users", (t) => {
|
|
18
18
|
return t
|
|
@@ -73,7 +73,7 @@ describe("DrizzleAdapter PGLite", () => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
const schema2 = schema((s) => {
|
|
76
|
+
const schema2 = schema("schema2", (s) => {
|
|
77
77
|
return s
|
|
78
78
|
.addTable("products", (t) => {
|
|
79
79
|
return t
|
|
@@ -98,7 +98,7 @@ describe("DrizzleAdapter PGLite", () => {
|
|
|
98
98
|
|
|
99
99
|
const { dialect } = new KyselyPGlite(pgliteDatabase);
|
|
100
100
|
|
|
101
|
-
adapter = new
|
|
101
|
+
adapter = new SqlAdapter({
|
|
102
102
|
dialect,
|
|
103
103
|
driverConfig: new PGLiteDriverConfig(),
|
|
104
104
|
});
|
|
@@ -321,7 +321,7 @@ describe("DrizzleAdapter PGLite", () => {
|
|
|
321
321
|
|
|
322
322
|
const [query] = queries;
|
|
323
323
|
expect(query.sql).toMatchInlineSnapshot(
|
|
324
|
-
`"select "user"."name" as "user:name", "user"."id" as "user:id", "user"."age" as "user:age", "user"."_internalId" as "user:_internalId", "user"."_version" as "user:_version", "
|
|
324
|
+
`"select "user"."name" as "user:name", "user"."id" as "user:id", "user"."age" as "user:age", "user"."_internalId" as "user:_internalId", "user"."_version" as "user:_version", "namespace"."emails"."id" as "id", "namespace"."emails"."user_id" as "user_id", "namespace"."emails"."email" as "email", "namespace"."emails"."is_primary" as "is_primary", "namespace"."emails"."_internalId" as "_internalId", "namespace"."emails"."_version" as "_version" from "namespace"."emails" left join "namespace"."users" as "user" on "namespace"."emails"."user_id" = "user"."_internalId""`,
|
|
325
325
|
);
|
|
326
326
|
|
|
327
327
|
expect(email).toMatchObject({
|
|
@@ -502,7 +502,7 @@ describe("DrizzleAdapter PGLite", () => {
|
|
|
502
502
|
|
|
503
503
|
const [query] = queries;
|
|
504
504
|
expect(query.sql).toMatchInlineSnapshot(
|
|
505
|
-
`"select "post"."id" as "post:id", "post"."title" as "post:title", "post"."content" as "post:content", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "post_author"."id" as "post:author:id", "post_author"."name" as "post:author:name", "post_author"."age" as "post:author:age", "post_author"."_internalId" as "post:author:_internalId", "post_author"."_version" as "post:author:_version", "commenter"."id" as "commenter:id", "commenter"."name" as "commenter:name", "commenter"."_internalId" as "commenter:_internalId", "commenter"."_version" as "commenter:_version", "
|
|
505
|
+
`"select "post"."id" as "post:id", "post"."title" as "post:title", "post"."content" as "post:content", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "post_author"."id" as "post:author:id", "post_author"."name" as "post:author:name", "post_author"."age" as "post:author:age", "post_author"."_internalId" as "post:author:_internalId", "post_author"."_version" as "post:author:_version", "commenter"."id" as "commenter:id", "commenter"."name" as "commenter:name", "commenter"."_internalId" as "commenter:_internalId", "commenter"."_version" as "commenter:_version", "namespace"."comments"."id" as "id", "namespace"."comments"."post_id" as "post_id", "namespace"."comments"."user_id" as "user_id", "namespace"."comments"."text" as "text", "namespace"."comments"."_internalId" as "_internalId", "namespace"."comments"."_version" as "_version" from "namespace"."comments" left join "namespace"."posts" as "post" on "namespace"."comments"."post_id" = "post"."_internalId" left join "namespace"."users" as "post_author" on "post"."user_id" = "post_author"."_internalId" left join "namespace"."users" as "commenter" on "namespace"."comments"."user_id" = "commenter"."_internalId""`,
|
|
506
506
|
);
|
|
507
507
|
});
|
|
508
508
|
|
|
@@ -614,11 +614,11 @@ describe("DrizzleAdapter PGLite", () => {
|
|
|
614
614
|
|
|
615
615
|
const [insertUserQuery, insertPostQuery] = queries;
|
|
616
616
|
expect(insertUserQuery.sql).toMatchInlineSnapshot(
|
|
617
|
-
`"insert into "
|
|
617
|
+
`"insert into "namespace"."users" ("id", "name", "age") values ($1, $2, $3) returning "namespace"."users"."id" as "id", "namespace"."users"."name" as "name", "namespace"."users"."age" as "age", "namespace"."users"."_internalId" as "_internalId", "namespace"."users"."_version" as "_version""`,
|
|
618
618
|
);
|
|
619
619
|
expect(insertUserQuery.parameters).toEqual([userId.externalId, "UOW Test User", 35]);
|
|
620
620
|
expect(insertPostQuery.sql).toMatchInlineSnapshot(
|
|
621
|
-
`"insert into "
|
|
621
|
+
`"insert into "namespace"."posts" ("id", "user_id", "title", "content") values ($1, (select "_internalId" from "namespace"."users" where "id" = $2 limit $3), $4, $5) returning "namespace"."posts"."id" as "id", "namespace"."posts"."user_id" as "user_id", "namespace"."posts"."title" as "title", "namespace"."posts"."content" as "content", "namespace"."posts"."created_at" as "created_at", "namespace"."posts"."_internalId" as "_internalId", "namespace"."posts"."_version" as "_version""`,
|
|
622
622
|
);
|
|
623
623
|
expect(insertPostQuery.parameters).toEqual([
|
|
624
624
|
postId.externalId,
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import SQLite from "better-sqlite3";
|
|
2
|
-
import { beforeAll, describe, expect, expectTypeOf, it
|
|
3
|
-
import { column, idColumn, referenceColumn, schema, type FragnoId } from "
|
|
2
|
+
import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
|
|
3
|
+
import { column, idColumn, referenceColumn, schema, type FragnoId } from "../../schema/create";
|
|
4
4
|
import {
|
|
5
5
|
Cursor,
|
|
6
|
-
|
|
6
|
+
createServiceTxBuilder,
|
|
7
|
+
createHandlerTxBuilder,
|
|
7
8
|
ExponentialBackoffRetryPolicy,
|
|
8
9
|
type DatabaseAdapter,
|
|
9
|
-
} from "
|
|
10
|
+
} from "../../mod";
|
|
10
11
|
import { SqliteDialect } from "kysely";
|
|
11
|
-
import { SqlDriverAdapter } from "
|
|
12
|
-
import { BetterSQLite3DriverConfig } from "
|
|
13
|
-
import {
|
|
14
|
-
import { internalSchema } from "
|
|
12
|
+
import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter";
|
|
13
|
+
import { BetterSQLite3DriverConfig } from "./driver-config";
|
|
14
|
+
import { SqlAdapter } from "./generic-sql-adapter";
|
|
15
|
+
import { internalSchema } from "../../fragments/internal-fragment";
|
|
15
16
|
|
|
16
|
-
describe("
|
|
17
|
-
const testSchema = schema((s) => {
|
|
17
|
+
describe("SqlAdapter with better-sqlite3", () => {
|
|
18
|
+
const testSchema = schema("test", (s) => {
|
|
18
19
|
return s
|
|
19
20
|
.addTable("users", (t) => {
|
|
20
21
|
return t
|
|
@@ -72,7 +73,7 @@ describe("GenericSQLAdapter with DrizzleAdapter better-sqlite3", () => {
|
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
// Second schema for multi-schema testing
|
|
75
|
-
const schema2 = schema((s) => {
|
|
76
|
+
const schema2 = schema("schema2", (s) => {
|
|
76
77
|
return s
|
|
77
78
|
.addTable("products", (t) => {
|
|
78
79
|
return t
|
|
@@ -104,7 +105,7 @@ describe("GenericSQLAdapter with DrizzleAdapter better-sqlite3", () => {
|
|
|
104
105
|
});
|
|
105
106
|
const sqlAdapter = new SqlDriverAdapter(dialect);
|
|
106
107
|
const driverConfig = new BetterSQLite3DriverConfig();
|
|
107
|
-
const genericAdapter = new
|
|
108
|
+
const genericAdapter = new SqlAdapter({ dialect, driverConfig });
|
|
108
109
|
|
|
109
110
|
{
|
|
110
111
|
const migrations = genericAdapter.prepareMigrations(internalSchema, "");
|
|
@@ -793,7 +794,7 @@ describe("GenericSQLAdapter with DrizzleAdapter better-sqlite3", () => {
|
|
|
793
794
|
expect(emptyPage.cursor).toBeUndefined();
|
|
794
795
|
});
|
|
795
796
|
|
|
796
|
-
it("should support
|
|
797
|
+
it("should support handlerTx with retry logic", async () => {
|
|
797
798
|
const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
|
|
798
799
|
|
|
799
800
|
// Create a test user
|
|
@@ -807,31 +808,44 @@ describe("GenericSQLAdapter with DrizzleAdapter better-sqlite3", () => {
|
|
|
807
808
|
.find("users", (b) => b.whereIndex("name_idx", (eb) => eb("name", "=", "Execute UOW User")))
|
|
808
809
|
.executeRetrieve();
|
|
809
810
|
|
|
810
|
-
// Use
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
createUnitOfWork: () => queryEngine.createUnitOfWork("execute-uow-update"),
|
|
828
|
-
retryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 3, initialDelayMs: 1 }),
|
|
811
|
+
// Use handlerTx to increment age with optimistic locking
|
|
812
|
+
let currentUow: ReturnType<typeof queryEngine.createUnitOfWork> | null = null;
|
|
813
|
+
|
|
814
|
+
// Service that retrieves user by ID
|
|
815
|
+
const getUserById = (userId: typeof user.id) => {
|
|
816
|
+
return createServiceTxBuilder(testSchema, currentUow!)
|
|
817
|
+
.retrieve((uow) =>
|
|
818
|
+
uow.find("users", (b) => b.whereIndex("primary", (eb) => eb("id", "=", userId))),
|
|
819
|
+
)
|
|
820
|
+
.transformRetrieve(([users]) => users[0] ?? null)
|
|
821
|
+
.build();
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
const result = await createHandlerTxBuilder({
|
|
825
|
+
createUnitOfWork: () => {
|
|
826
|
+
currentUow = queryEngine.createUnitOfWork("execute-uow-update");
|
|
827
|
+
return currentUow;
|
|
829
828
|
},
|
|
830
|
-
|
|
829
|
+
retryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 3, initialDelayMs: 1 }),
|
|
830
|
+
})
|
|
831
|
+
.withServiceCalls(() => [getUserById(user.id)])
|
|
832
|
+
.mutate(({ forSchema, serviceIntermediateResult: [foundUser] }) => {
|
|
833
|
+
if (!foundUser) {
|
|
834
|
+
throw new Error("User not found");
|
|
835
|
+
}
|
|
836
|
+
const newAge = foundUser.age! + 1;
|
|
837
|
+
forSchema(testSchema).update("users", foundUser.id, (b) => b.set({ age: newAge }).check());
|
|
838
|
+
return { previousAge: foundUser.age, newAge };
|
|
839
|
+
})
|
|
840
|
+
.transform(({ mutateResult }) => {
|
|
841
|
+
// Verify the age was incremented correctly
|
|
842
|
+
expect(mutateResult.newAge).toBe(mutateResult.previousAge! + 1);
|
|
843
|
+
return mutateResult;
|
|
844
|
+
})
|
|
845
|
+
.execute();
|
|
831
846
|
|
|
832
847
|
// Verify the operation succeeded
|
|
833
|
-
|
|
834
|
-
expect(result.mutationResult).toEqual({
|
|
848
|
+
expect(result).toEqual({
|
|
835
849
|
previousAge: 42,
|
|
836
850
|
newAge: 43,
|
|
837
851
|
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import SQLite from "better-sqlite3";
|
|
2
2
|
import { SqliteDialect } from "kysely";
|
|
3
|
-
import {
|
|
4
|
-
import { beforeAll, describe, expect, expectTypeOf, it
|
|
3
|
+
import { SqlAdapter } from "./generic-sql-adapter";
|
|
4
|
+
import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
|
|
5
5
|
import { column, idColumn, referenceColumn, schema, type FragnoId } from "../../schema/create";
|
|
6
6
|
import { Cursor } from "../../query/cursor";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
createServiceTxBuilder,
|
|
9
|
+
createHandlerTxBuilder,
|
|
10
|
+
} from "../../query/unit-of-work/execute-unit-of-work";
|
|
8
11
|
import { ExponentialBackoffRetryPolicy } from "../../query/unit-of-work/retry-policy";
|
|
9
|
-
import { BetterSQLite3DriverConfig } from "
|
|
12
|
+
import { BetterSQLite3DriverConfig } from "./driver-config";
|
|
10
13
|
import { internalSchema } from "../../fragments/internal-fragment";
|
|
11
14
|
|
|
12
|
-
describe("
|
|
13
|
-
const testSchema = schema((s) => {
|
|
15
|
+
describe("SqlAdapter SQLite", () => {
|
|
16
|
+
const testSchema = schema("test", (s) => {
|
|
14
17
|
return s
|
|
15
18
|
.addTable("users", (t) => {
|
|
16
19
|
return t
|
|
@@ -68,7 +71,7 @@ describe("DrizzleAdapter SQLite", () => {
|
|
|
68
71
|
});
|
|
69
72
|
|
|
70
73
|
// Second schema for multi-schema testing
|
|
71
|
-
const schema2 = schema((s) => {
|
|
74
|
+
const schema2 = schema("schema2", (s) => {
|
|
72
75
|
return s
|
|
73
76
|
.addTable("products", (t) => {
|
|
74
77
|
return t
|
|
@@ -91,7 +94,7 @@ describe("DrizzleAdapter SQLite", () => {
|
|
|
91
94
|
});
|
|
92
95
|
});
|
|
93
96
|
|
|
94
|
-
let adapter:
|
|
97
|
+
let adapter: SqlAdapter;
|
|
95
98
|
let sqliteDatabase: InstanceType<typeof SQLite>;
|
|
96
99
|
|
|
97
100
|
beforeAll(async () => {
|
|
@@ -101,7 +104,7 @@ describe("DrizzleAdapter SQLite", () => {
|
|
|
101
104
|
database: sqliteDatabase,
|
|
102
105
|
});
|
|
103
106
|
|
|
104
|
-
adapter = new
|
|
107
|
+
adapter = new SqlAdapter({
|
|
105
108
|
dialect,
|
|
106
109
|
driverConfig: new BetterSQLite3DriverConfig(),
|
|
107
110
|
});
|
|
@@ -793,7 +796,7 @@ describe("DrizzleAdapter SQLite", () => {
|
|
|
793
796
|
expect(emptyPage.cursor).toBeUndefined();
|
|
794
797
|
});
|
|
795
798
|
|
|
796
|
-
it("should support
|
|
799
|
+
it("should support handlerTx with retry logic", async () => {
|
|
797
800
|
const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
|
|
798
801
|
|
|
799
802
|
// Create a test user
|
|
@@ -807,31 +810,44 @@ describe("DrizzleAdapter SQLite", () => {
|
|
|
807
810
|
.find("users", (b) => b.whereIndex("name_idx", (eb) => eb("name", "=", "Execute UOW User")))
|
|
808
811
|
.executeRetrieve();
|
|
809
812
|
|
|
810
|
-
// Use
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
createUnitOfWork: () => queryEngine.createUnitOfWork("execute-uow-update"),
|
|
828
|
-
retryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 3, initialDelayMs: 1 }),
|
|
813
|
+
// Use handlerTx to increment age with optimistic locking
|
|
814
|
+
let currentUow: ReturnType<typeof queryEngine.createUnitOfWork> | null = null;
|
|
815
|
+
|
|
816
|
+
// Service that retrieves user by ID
|
|
817
|
+
const getUserById = (userId: typeof user.id) => {
|
|
818
|
+
return createServiceTxBuilder(testSchema, currentUow!)
|
|
819
|
+
.retrieve((uow) =>
|
|
820
|
+
uow.find("users", (b) => b.whereIndex("primary", (eb) => eb("id", "=", userId))),
|
|
821
|
+
)
|
|
822
|
+
.transformRetrieve(([users]) => users[0] ?? null)
|
|
823
|
+
.build();
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
const result = await createHandlerTxBuilder({
|
|
827
|
+
createUnitOfWork: () => {
|
|
828
|
+
currentUow = queryEngine.createUnitOfWork("execute-uow-update");
|
|
829
|
+
return currentUow;
|
|
829
830
|
},
|
|
830
|
-
|
|
831
|
+
retryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 3, initialDelayMs: 1 }),
|
|
832
|
+
})
|
|
833
|
+
.withServiceCalls(() => [getUserById(user.id)])
|
|
834
|
+
.mutate(({ forSchema, serviceIntermediateResult: [foundUser] }) => {
|
|
835
|
+
if (!foundUser) {
|
|
836
|
+
throw new Error("User not found");
|
|
837
|
+
}
|
|
838
|
+
const newAge = foundUser.age! + 1;
|
|
839
|
+
forSchema(testSchema).update("users", foundUser.id, (b) => b.set({ age: newAge }).check());
|
|
840
|
+
return { previousAge: foundUser.age, newAge };
|
|
841
|
+
})
|
|
842
|
+
.transform(({ mutateResult }) => {
|
|
843
|
+
// Verify the age was incremented correctly
|
|
844
|
+
expect(mutateResult.newAge).toBe(mutateResult.previousAge! + 1);
|
|
845
|
+
return mutateResult;
|
|
846
|
+
})
|
|
847
|
+
.execute();
|
|
831
848
|
|
|
832
849
|
// Verify the operation succeeded
|
|
833
|
-
|
|
834
|
-
expect(result.mutationResult).toEqual({
|
|
850
|
+
expect(result).toEqual({
|
|
835
851
|
previousAge: 42,
|
|
836
852
|
newAge: 43,
|
|
837
853
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { SQLocalKysely } from "sqlocal/kysely";
|
|
2
2
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { SqlAdapter } from "./generic-sql-adapter";
|
|
4
4
|
import { column, idColumn, referenceColumn, schema } from "../../schema/create";
|
|
5
|
-
import { SQLocalDriverConfig } from "
|
|
5
|
+
import { SQLocalDriverConfig } from "./driver-config";
|
|
6
6
|
|
|
7
|
-
describe("
|
|
8
|
-
const testSchema = schema((s) => {
|
|
7
|
+
describe("SqlAdapter SQLite", () => {
|
|
8
|
+
const testSchema = schema("test", (s) => {
|
|
9
9
|
return s
|
|
10
10
|
.addTable("accounts", (t) => {
|
|
11
11
|
return t
|
|
@@ -33,11 +33,11 @@ describe("KyselyAdapter SQLite", () => {
|
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
let adapter:
|
|
36
|
+
let adapter: SqlAdapter;
|
|
37
37
|
|
|
38
38
|
beforeAll(async () => {
|
|
39
39
|
const { dialect } = new SQLocalKysely(":memory:");
|
|
40
|
-
adapter = new
|
|
40
|
+
adapter = new SqlAdapter({
|
|
41
41
|
dialect,
|
|
42
42
|
driverConfig: new SQLocalDriverConfig(),
|
|
43
43
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type SQLiteDateStorage = "epoch-ms" | "iso-text";
|
|
2
|
+
export type SQLiteBigintStorage = "blob" | "integer";
|
|
3
|
+
|
|
4
|
+
export interface SQLiteStorageMode {
|
|
5
|
+
timestampStorage: SQLiteDateStorage;
|
|
6
|
+
dateStorage: SQLiteDateStorage;
|
|
7
|
+
bigintStorage: SQLiteBigintStorage;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const sqliteStorageDefault: SQLiteStorageMode = {
|
|
11
|
+
timestampStorage: "epoch-ms",
|
|
12
|
+
dateStorage: "epoch-ms",
|
|
13
|
+
bigintStorage: "blob",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const sqliteStoragePrisma: SQLiteStorageMode = {
|
|
17
|
+
timestampStorage: "iso-text",
|
|
18
|
+
dateStorage: "iso-text",
|
|
19
|
+
bigintStorage: "integer",
|
|
20
|
+
};
|
|
@@ -8,7 +8,7 @@ import type { AnySchema } from "../../schema/create";
|
|
|
8
8
|
describe("UnitOfWorkDecoder", () => {
|
|
9
9
|
const driverConfig = new SQLocalDriverConfig();
|
|
10
10
|
|
|
11
|
-
const testSchema = schema((s) => {
|
|
11
|
+
const testSchema = schema("test", (s) => {
|
|
12
12
|
return s
|
|
13
13
|
.addTable("users", (t) => {
|
|
14
14
|
return t
|
|
@@ -4,6 +4,8 @@ import type { AnySchema, AnyTable } from "../../schema/create";
|
|
|
4
4
|
import { decodeResult } from "../../query/value-decoding";
|
|
5
5
|
import { createCursorFromRecord, type Cursor, type CursorResult } from "../../query/cursor";
|
|
6
6
|
import type { DriverConfig } from "./driver-config";
|
|
7
|
+
import type { SQLiteStorageMode } from "./sqlite-storage";
|
|
8
|
+
import type { NamingResolver } from "../../naming/sql-naming";
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Decoder class for Unit of Work retrieval results.
|
|
@@ -13,9 +15,17 @@ import type { DriverConfig } from "./driver-config";
|
|
|
13
15
|
*/
|
|
14
16
|
export class UnitOfWorkDecoder implements UOWDecoder<unknown> {
|
|
15
17
|
readonly #driverConfig: DriverConfig;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
readonly #sqliteStorageMode?: SQLiteStorageMode;
|
|
19
|
+
readonly #resolver?: NamingResolver;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
driverConfig: DriverConfig,
|
|
23
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
24
|
+
resolver?: NamingResolver,
|
|
25
|
+
) {
|
|
18
26
|
this.#driverConfig = driverConfig;
|
|
27
|
+
this.#sqliteStorageMode = sqliteStorageMode;
|
|
28
|
+
this.#resolver = resolver;
|
|
19
29
|
}
|
|
20
30
|
|
|
21
31
|
/**
|
|
@@ -60,7 +70,15 @@ export class UnitOfWorkDecoder implements UOWDecoder<unknown> {
|
|
|
60
70
|
return this.decodeCountResult(rows);
|
|
61
71
|
}
|
|
62
72
|
|
|
63
|
-
const decodedRows = rows.map((row) =>
|
|
73
|
+
const decodedRows = rows.map((row) =>
|
|
74
|
+
decodeResult(
|
|
75
|
+
row,
|
|
76
|
+
operation.table,
|
|
77
|
+
this.#driverConfig,
|
|
78
|
+
this.#sqliteStorageMode,
|
|
79
|
+
this.#resolver,
|
|
80
|
+
),
|
|
81
|
+
);
|
|
64
82
|
|
|
65
83
|
if (operation.withCursor) {
|
|
66
84
|
return this.decodeCursorResult(decodedRows, operation.table, operation);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { Kysely, PostgresDialect } from "kysely";
|
|
2
3
|
import { UnitOfWorkEncoder } from "./uow-encoder";
|
|
3
4
|
import { schema, column, idColumn, referenceColumn } from "../../schema/create";
|
|
5
|
+
import { dbNow } from "../../query/db-now";
|
|
4
6
|
import {
|
|
5
7
|
BetterSQLite3DriverConfig,
|
|
6
8
|
MySQL2DriverConfig,
|
|
@@ -8,7 +10,7 @@ import {
|
|
|
8
10
|
} from "./driver-config";
|
|
9
11
|
|
|
10
12
|
describe("UnitOfWorkEncoder", () => {
|
|
11
|
-
const testSchema = schema((s) => {
|
|
13
|
+
const testSchema = schema("test", (s) => {
|
|
12
14
|
return s
|
|
13
15
|
.addTable("users", (t) => {
|
|
14
16
|
return t
|
|
@@ -16,7 +18,8 @@ describe("UnitOfWorkEncoder", () => {
|
|
|
16
18
|
.addColumn("name", column("string"))
|
|
17
19
|
.addColumn("age", column("integer").nullable())
|
|
18
20
|
.addColumn("isActive", column("bool"))
|
|
19
|
-
.addColumn("createdAt", column("timestamp"))
|
|
21
|
+
.addColumn("createdAt", column("timestamp"))
|
|
22
|
+
.addColumn("birthDate", column("date").nullable());
|
|
20
23
|
})
|
|
21
24
|
.addTable("posts", (t) => {
|
|
22
25
|
return t
|
|
@@ -111,6 +114,34 @@ describe("UnitOfWorkEncoder", () => {
|
|
|
111
114
|
expect(typeof result["id"]).toBe("string");
|
|
112
115
|
expect(result["title"]).toBe("Test");
|
|
113
116
|
});
|
|
117
|
+
|
|
118
|
+
it("should use sqlite dateStorage for dbNow date columns", () => {
|
|
119
|
+
type TestDB = { users: { id: string; birthDate: unknown } };
|
|
120
|
+
const dialectConfig = {} as unknown as ConstructorParameters<typeof PostgresDialect>[0];
|
|
121
|
+
const sqliteDb = new Kysely<TestDB>({
|
|
122
|
+
dialect: new PostgresDialect(dialectConfig),
|
|
123
|
+
});
|
|
124
|
+
const encoderWithStorage = new UnitOfWorkEncoder(sqliteConfig, sqliteDb, {
|
|
125
|
+
timestampStorage: "epoch-ms",
|
|
126
|
+
dateStorage: "iso-text",
|
|
127
|
+
bigintStorage: "blob",
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const result = encoderWithStorage.encodeForDatabase({
|
|
131
|
+
values: { birthDate: dbNow() },
|
|
132
|
+
table: usersTable,
|
|
133
|
+
generateDefaults: false,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const query = sqliteDb
|
|
137
|
+
.updateTable("users")
|
|
138
|
+
.set({ birthDate: result["birthDate"] as unknown })
|
|
139
|
+
.where("id", "=", "test");
|
|
140
|
+
|
|
141
|
+
const sqlText = query.compile().sql;
|
|
142
|
+
expect(sqlText).toContain("CURRENT_TIMESTAMP");
|
|
143
|
+
expect(sqlText).not.toContain("julianday");
|
|
144
|
+
});
|
|
114
145
|
});
|
|
115
146
|
|
|
116
147
|
describe("PostgreSQL encoding", () => {
|
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
} from "../../query/serialize/create-sql-serializer";
|
|
7
7
|
import { encodeValues } from "../../query/value-encoding";
|
|
8
8
|
import { processReferenceSubqueries } from "./query/where-builder";
|
|
9
|
-
import type {
|
|
10
|
-
import type
|
|
9
|
+
import type { NamingResolver } from "../../naming/sql-naming";
|
|
10
|
+
import { sql, type Kysely } from "kysely";
|
|
11
|
+
import { isDbNow } from "../../query/db-now";
|
|
12
|
+
import { sqliteStorageDefault, type SQLiteStorageMode } from "./sqlite-storage";
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Encoder class for Unit of Work mutation operations.
|
|
@@ -21,18 +23,23 @@ import type { Kysely } from "kysely";
|
|
|
21
23
|
* This class mirrors the UnitOfWorkDecoder pattern for symmetry.
|
|
22
24
|
*/
|
|
23
25
|
export class UnitOfWorkEncoder {
|
|
26
|
+
readonly #driverConfig: DriverConfig;
|
|
24
27
|
readonly #serializer: SQLSerializer;
|
|
25
28
|
readonly #db: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
26
|
-
readonly #
|
|
29
|
+
readonly #sqliteStorageMode?: SQLiteStorageMode;
|
|
30
|
+
readonly #resolver?: NamingResolver;
|
|
27
31
|
|
|
28
32
|
constructor(
|
|
29
33
|
driverConfig: DriverConfig,
|
|
30
34
|
db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
31
|
-
|
|
35
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
36
|
+
resolver?: NamingResolver,
|
|
32
37
|
) {
|
|
33
|
-
this.#
|
|
38
|
+
this.#driverConfig = driverConfig;
|
|
39
|
+
this.#serializer = createSQLSerializer(driverConfig, sqliteStorageMode);
|
|
34
40
|
this.#db = db;
|
|
35
|
-
this.#
|
|
41
|
+
this.#sqliteStorageMode = sqliteStorageMode;
|
|
42
|
+
this.#resolver = resolver;
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
/**
|
|
@@ -66,10 +73,16 @@ export class UnitOfWorkEncoder {
|
|
|
66
73
|
generateDefaults: boolean;
|
|
67
74
|
}): Record<string, unknown> {
|
|
68
75
|
// Step 1: Resolution - Resolve FragnoId/FragnoReference and generate defaults
|
|
69
|
-
const resolved = encodeValues(
|
|
76
|
+
const resolved = encodeValues(
|
|
77
|
+
options.values,
|
|
78
|
+
options.table,
|
|
79
|
+
options.generateDefaults,
|
|
80
|
+
{},
|
|
81
|
+
this.#resolver,
|
|
82
|
+
);
|
|
70
83
|
|
|
71
84
|
// Step 2: Reference Processing - Convert external IDs to subqueries
|
|
72
|
-
const processed = processReferenceSubqueries(resolved, this.#db, this.#
|
|
85
|
+
const processed = processReferenceSubqueries(resolved, this.#db, this.#resolver);
|
|
73
86
|
|
|
74
87
|
// Step 3: Serialization - Apply database-specific type conversions
|
|
75
88
|
const serialized = this.serializeValues(processed, options.table);
|
|
@@ -94,10 +107,11 @@ export class UnitOfWorkEncoder {
|
|
|
94
107
|
table: AnyTable,
|
|
95
108
|
): Record<string, unknown> {
|
|
96
109
|
const result: Record<string, unknown> = {};
|
|
110
|
+
const columnMap = this.#resolver ? this.#resolver.getColumnNameMap(table) : undefined;
|
|
97
111
|
|
|
98
112
|
for (const [dbColumnName, value] of Object.entries(values)) {
|
|
99
113
|
// Find the column definition by database column name
|
|
100
|
-
const col = this.findColumnByDbName(table, dbColumnName);
|
|
114
|
+
const col = this.findColumnByDbName(table, dbColumnName, columnMap);
|
|
101
115
|
|
|
102
116
|
if (!col) {
|
|
103
117
|
// Not a regular column (might be a special value like sql.raw())
|
|
@@ -106,6 +120,22 @@ export class UnitOfWorkEncoder {
|
|
|
106
120
|
continue;
|
|
107
121
|
}
|
|
108
122
|
|
|
123
|
+
if (isDbNow(value)) {
|
|
124
|
+
if (this.#driverConfig.databaseType === "sqlite") {
|
|
125
|
+
const storageMode = this.#sqliteStorageMode ?? sqliteStorageDefault;
|
|
126
|
+
const storage =
|
|
127
|
+
col.type === "date" ? storageMode.dateStorage : storageMode.timestampStorage;
|
|
128
|
+
if ((col.type === "timestamp" || col.type === "date") && storage === "epoch-ms") {
|
|
129
|
+
result[dbColumnName] = sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;
|
|
130
|
+
} else {
|
|
131
|
+
result[dbColumnName] = sql`CURRENT_TIMESTAMP`;
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
result[dbColumnName] = sql`CURRENT_TIMESTAMP`;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
109
139
|
// Serialize the value using the column definition and database type
|
|
110
140
|
result[dbColumnName] = this.#serializer.serialize(value, col);
|
|
111
141
|
}
|
|
@@ -120,9 +150,18 @@ export class UnitOfWorkEncoder {
|
|
|
120
150
|
* @param dbColumnName - The database column name (e.g., "user_id")
|
|
121
151
|
* @returns The column definition or undefined if not found
|
|
122
152
|
*/
|
|
123
|
-
private findColumnByDbName(
|
|
153
|
+
private findColumnByDbName(
|
|
154
|
+
table: AnyTable,
|
|
155
|
+
dbColumnName: string,
|
|
156
|
+
columnMap?: Record<string, string>,
|
|
157
|
+
): AnyColumn | undefined {
|
|
158
|
+
const logicalName = columnMap?.[dbColumnName] ?? dbColumnName;
|
|
159
|
+
const direct = table.columns[logicalName];
|
|
160
|
+
if (direct) {
|
|
161
|
+
return direct;
|
|
162
|
+
}
|
|
124
163
|
for (const col of Object.values(table.columns)) {
|
|
125
|
-
if (col.name ===
|
|
164
|
+
if (col.name === logicalName) {
|
|
126
165
|
return col;
|
|
127
166
|
}
|
|
128
167
|
}
|