@fragno-dev/db 0.1.15 → 0.2.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 +242 -179
- package/CHANGELOG.md +23 -0
- package/README.md +123 -8
- package/dist/adapters/adapters.d.ts +5 -5
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -21
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +7 -54
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
- package/dist/adapters/drizzle/generate.d.ts +3 -0
- package/dist/adapters/drizzle/generate.d.ts.map +1 -1
- package/dist/adapters/drizzle/generate.js +36 -28
- package/dist/adapters/drizzle/generate.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
- package/dist/adapters/generic-sql/driver-config.js +94 -0
- package/dist/adapters/generic-sql/driver-config.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.js +18 -0
- package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/select-builder.js +69 -0
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/where-builder.js +129 -0
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
- package/dist/adapters/generic-sql/result-interpreter.js +74 -0
- package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +105 -0
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
- package/dist/adapters/generic-sql/uow-encoder.js +93 -0
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts +5 -18
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-adapter.js +6 -165
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
- package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +47 -61
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
- package/dist/adapters/{drizzle/shared.d.ts → shared/table-name-mapper.d.ts} +2 -4
- package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
- package/dist/adapters/shared/table-name-mapper.js +43 -0
- package/dist/adapters/shared/table-name-mapper.js.map +1 -0
- package/dist/adapters/shared/uow-operation-compiler.js +105 -0
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
- package/dist/db-fragment-definition-builder.d.ts +53 -19
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +89 -19
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/fragments/internal-fragment.d.ts +39 -5
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +82 -10
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/hooks/hooks.d.ts +51 -0
- package/dist/hooks/hooks.d.ts.map +1 -0
- package/dist/hooks/hooks.js +88 -0
- package/dist/hooks/hooks.js.map +1 -0
- package/dist/migration-engine/generation-engine.d.ts +0 -2
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +23 -61
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/mod.d.ts +34 -10
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +47 -16
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.pnpm/{rou3@0.7.8 → rou3@0.7.10}/node_modules/rou3/dist/index.js +1 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +69 -31
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/query/column-defaults.js +27 -0
- package/dist/query/column-defaults.js.map +1 -0
- package/dist/query/cursor.d.ts +4 -4
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +8 -6
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/orm/orm.d.ts +1 -1
- package/dist/query/orm/orm.js.map +1 -1
- package/dist/query/serialize/create-sql-serializer.js +30 -0
- package/dist/query/serialize/create-sql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
- package/dist/query/serialize/sql-serializer.js +67 -0
- package/dist/query/serialize/sql-serializer.js.map +1 -0
- package/dist/query/{query.d.ts → simple-query-interface.d.ts} +5 -5
- package/dist/query/simple-query-interface.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.d.ts → unit-of-work/execute-unit-of-work.d.ts} +13 -3
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.js → unit-of-work/execute-unit-of-work.js} +17 -4
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/query/{retry-policy.d.ts → unit-of-work/retry-policy.d.ts} +1 -1
- package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/query/{retry-policy.js → unit-of-work/retry-policy.js} +1 -1
- package/dist/query/unit-of-work/retry-policy.js.map +1 -0
- package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +51 -18
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +58 -11
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
- package/dist/query/value-decoding.js +71 -0
- package/dist/query/value-decoding.js.map +1 -0
- package/dist/query/value-encoding.js +124 -0
- package/dist/query/value-encoding.js.map +1 -0
- package/dist/schema/create.d.ts +3 -0
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +4 -0
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
- package/dist/schema/type-conversion/dialect/mysql.js +57 -0
- package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
- package/dist/schema/type-conversion/dialect/postgres.js +56 -0
- package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
- package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
- package/dist/schema/type-conversion/type-mapping.js +63 -0
- package/dist/schema/type-conversion/type-mapping.js.map +1 -0
- package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
- package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
- package/dist/sql-driver/connection/connection-provider.js +19 -0
- package/dist/sql-driver/connection/connection-provider.js.map +1 -0
- package/dist/sql-driver/connection/single-connection-provider.js +23 -0
- package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
- package/dist/sql-driver/dialects/dialects.d.ts +2 -0
- package/dist/sql-driver/dialects/dialects.js +3 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.js +56 -0
- package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
- package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
- package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
- package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
- package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
- package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
- package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.js +68 -0
- package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
- package/dist/sql-driver/sql-driver.d.ts +38 -0
- package/dist/sql-driver/sql-driver.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver.js +1 -0
- package/dist/sql-driver/sql.js +50 -0
- package/dist/sql-driver/sql.js.map +1 -0
- package/dist/with-database.d.ts +6 -2
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +1 -1
- package/dist/with-database.js.map +1 -1
- package/package.json +37 -10
- package/src/adapters/adapters.ts +8 -5
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +60 -169
- package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +31 -55
- package/src/adapters/drizzle/drizzle-adapter.ts +15 -107
- package/src/adapters/drizzle/generate.test.ts +2 -2
- package/src/adapters/drizzle/generate.ts +78 -34
- package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
- package/src/adapters/drizzle/shared.ts +0 -34
- package/src/adapters/drizzle/test-utils.ts +3 -3
- package/src/adapters/generic-sql/README.md +14 -0
- package/src/adapters/generic-sql/driver-config.ts +144 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
- package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
- package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
- package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
- package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
- package/src/adapters/generic-sql/migration/executor.ts +33 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
- package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
- package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
- package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
- package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
- package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
- package/src/adapters/generic-sql/query/select-builder.ts +137 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
- package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
- package/src/adapters/generic-sql/query/where-builder.ts +211 -0
- package/src/adapters/generic-sql/result-interpreter.ts +102 -0
- package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
- package/src/adapters/generic-sql/uow-decoder.ts +152 -0
- package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
- package/src/adapters/generic-sql/uow-encoder.ts +131 -0
- package/src/adapters/kysely/kysely-adapter-pglite.test.ts +26 -76
- package/src/adapters/kysely/{kysely-adapter-sqlite.test.ts → kysely-adapter-sqlocal.test.ts} +76 -17
- package/src/adapters/kysely/kysely-adapter.ts +10 -250
- package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +110 -104
- package/src/adapters/shared/table-name-mapper.ts +50 -0
- package/src/adapters/shared/uow-operation-compiler.ts +211 -0
- package/src/db-fragment-definition-builder.test.ts +2 -2
- package/src/db-fragment-definition-builder.ts +281 -50
- package/src/db-fragment-instantiator.test.ts +78 -2
- package/src/db-fragment-integration.test.ts +14 -16
- package/src/fragments/internal-fragment.test.ts +434 -45
- package/src/fragments/internal-fragment.ts +184 -20
- package/src/hooks/hooks.test.ts +575 -0
- package/src/hooks/hooks.ts +179 -0
- package/src/migration-engine/generation-engine.test.ts +44 -54
- package/src/migration-engine/generation-engine.ts +48 -94
- package/src/mod.ts +117 -29
- package/src/query/column-defaults.ts +49 -0
- package/src/query/cursor.test.ts +31 -6
- package/src/query/cursor.ts +11 -7
- package/src/query/orm/orm.ts +1 -1
- package/src/query/query-type.test.ts +9 -9
- package/src/query/serialize/create-sql-serializer.ts +34 -0
- package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
- package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
- package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
- package/src/query/serialize/sql-serializer.ts +143 -0
- package/src/query/{query.ts → simple-query-interface.ts} +2 -2
- package/src/query/{execute-unit-of-work.test.ts → unit-of-work/execute-unit-of-work.test.ts} +16 -16
- package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +49 -8
- package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +41 -43
- package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +5 -3
- package/src/query/{unit-of-work.test.ts → unit-of-work/unit-of-work.test.ts} +100 -9
- package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +135 -32
- package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -427
- package/src/query/value-decoding.ts +113 -0
- package/src/query/value-encoding.test.ts +390 -0
- package/src/query/value-encoding.ts +168 -0
- package/src/schema/create.test.ts +5 -1
- package/src/schema/create.ts +5 -0
- package/src/schema/serialize.test.ts +165 -407
- package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
- package/src/schema/type-conversion/dialect/mysql.ts +64 -0
- package/src/schema/type-conversion/dialect/postgres.ts +62 -0
- package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
- package/src/schema/type-conversion/type-mapping.test.ts +137 -0
- package/src/schema/type-conversion/type-mapping.ts +153 -0
- package/src/shared/connection-pool.ts +5 -5
- package/src/sql-driver/better-sqlite3.test.ts +126 -0
- package/src/sql-driver/connection/connection-provider.ts +27 -0
- package/src/sql-driver/connection/single-connection-provider.ts +42 -0
- package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
- package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
- package/src/sql-driver/dialects/dialects.ts +1 -0
- package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
- package/src/sql-driver/driver/runtime-driver.ts +91 -0
- package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
- package/src/sql-driver/query-executor/plugin.ts +22 -0
- package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
- package/src/sql-driver/query-executor/query-executor.ts +44 -0
- package/src/sql-driver/sql-driver-adapter.ts +96 -0
- package/src/sql-driver/sql-driver.ts +53 -0
- package/src/sql-driver/sql.ts +57 -0
- package/src/sql-driver/sqlocal.test.ts +117 -0
- package/src/with-database.ts +35 -23
- package/tsdown.config.ts +7 -2
- package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
- package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
- package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -334
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -123
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -160
- package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
- package/dist/adapters/drizzle/join-column-utils.js +0 -28
- package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
- package/dist/adapters/drizzle/shared.d.ts.map +0 -1
- package/dist/adapters/drizzle/shared.js +0 -35
- package/dist/adapters/drizzle/shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
- package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-builder.js +0 -321
- package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-compiler.js +0 -67
- package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-query.d.ts +0 -23
- package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-query.js +0 -230
- package/dist/adapters/kysely/kysely-query.js.map +0 -1
- package/dist/adapters/kysely/kysely-shared.d.ts +0 -14
- package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-shared.js +0 -33
- package/dist/adapters/kysely/kysely-shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-compiler.js +0 -193
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-executor.js +0 -93
- package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-base.js +0 -128
- package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-factory.js +0 -34
- package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
- package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
- package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
- package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
- package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
- package/dist/adapters/kysely/migration/execute.js +0 -34
- package/dist/adapters/kysely/migration/execute.js.map +0 -1
- package/dist/migration-engine/create.d.ts +0 -37
- package/dist/migration-engine/create.d.ts.map +0 -1
- package/dist/migration-engine/create.js +0 -58
- package/dist/migration-engine/create.js.map +0 -1
- package/dist/migration-engine/shared.d.ts +0 -112
- package/dist/migration-engine/shared.d.ts.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/query/execute-unit-of-work.d.ts.map +0 -1
- package/dist/query/execute-unit-of-work.js.map +0 -1
- package/dist/query/query.d.ts.map +0 -1
- package/dist/query/result-transform.js +0 -170
- package/dist/query/result-transform.js.map +0 -1
- package/dist/query/retry-policy.d.ts.map +0 -1
- package/dist/query/retry-policy.js.map +0 -1
- package/dist/query/unit-of-work.d.ts.map +0 -1
- package/dist/query/unit-of-work.js.map +0 -1
- package/dist/schema/serialize.js +0 -111
- package/dist/schema/serialize.js.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -122
- package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
- package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
- package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +0 -1442
- package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +0 -1414
- package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1400
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -677
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -228
- package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -309
- package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
- package/src/adapters/drizzle/join-column-utils.ts +0 -39
- package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
- package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
- package/src/adapters/kysely/kysely-query-builder.ts +0 -666
- package/src/adapters/kysely/kysely-query-compiler.ts +0 -127
- package/src/adapters/kysely/kysely-query.test.ts +0 -498
- package/src/adapters/kysely/kysely-query.ts +0 -399
- package/src/adapters/kysely/kysely-shared.ts +0 -57
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -986
- package/src/adapters/kysely/kysely-uow-compiler.ts +0 -350
- package/src/adapters/kysely/kysely-uow-executor.ts +0 -164
- package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -794
- package/src/adapters/kysely/migration/execute-base.ts +0 -256
- package/src/adapters/kysely/migration/execute-factory.ts +0 -53
- package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
- package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
- package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
- package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
- package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
- package/src/adapters/kysely/migration/execute.ts +0 -50
- package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
- package/src/query/result-transform.ts +0 -274
- package/src/schema/serialize.ts +0 -407
- /package/dist/query/{query.js → simple-query-interface.js} +0 -0
- /package/src/query/{retry-policy.test.ts → unit-of-work/retry-policy.test.ts} +0 -0
- /package/src/query/{retry-policy.ts → unit-of-work/retry-policy.ts} +0 -0
|
@@ -2,7 +2,7 @@ import { mkdir, writeFile, rm, access } from "node:fs/promises";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { generateSchema, type SupportedProvider } from "./generate";
|
|
4
4
|
import type { Schema } from "../../schema/create";
|
|
5
|
-
import {
|
|
5
|
+
import { internalSchema } from "../../fragments/internal-fragment";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Writes a Fragno schema to a temporary TypeScript file and dynamically imports it.
|
|
@@ -42,10 +42,10 @@ export async function writeAndLoadSchema(
|
|
|
42
42
|
// Always include settings schema first (as done in generation-engine.ts), then the test schema
|
|
43
43
|
// De-duplicate: if the test schema IS the settings schema, don't add it twice
|
|
44
44
|
const fragments: Array<{ namespace: string; schema: Schema }> = [
|
|
45
|
-
{ namespace: "", schema:
|
|
45
|
+
{ namespace: "", schema: internalSchema },
|
|
46
46
|
];
|
|
47
47
|
|
|
48
|
-
if (schema !==
|
|
48
|
+
if (schema !== internalSchema) {
|
|
49
49
|
fragments.push({ namespace: namespace ?? "", schema });
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Generic SQL Adapter
|
|
2
|
+
|
|
3
|
+
## Goals:
|
|
4
|
+
|
|
5
|
+
- Follow roughly the Kysely interfaces so that we can use Kysely adapters.
|
|
6
|
+
- Use this to replace ALL query execution logic.
|
|
7
|
+
- "Own" the result transformation step.
|
|
8
|
+
- Optionally able to create SQL migrations internally.
|
|
9
|
+
- Be able to map names (tables, columns, constraints, etc)
|
|
10
|
+
- Be able to run migrations directly from the Fragment
|
|
11
|
+
|
|
12
|
+
## Non-goal:
|
|
13
|
+
|
|
14
|
+
- Generate schemas in ORM-specific DSLs, this is left to the ORM adapters.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export const supportedDatabases = ["sqlite", "postgresql", "mysql"] as const;
|
|
2
|
+
export type SupportedDatabase = (typeof supportedDatabases)[number];
|
|
3
|
+
|
|
4
|
+
export const supportedDriverTypes = [
|
|
5
|
+
"sqlocal",
|
|
6
|
+
"cloudflare_durable_objects",
|
|
7
|
+
"better-sqlite3",
|
|
8
|
+
"pg",
|
|
9
|
+
"pglite",
|
|
10
|
+
"mysql2",
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
13
|
+
export type SupportedDriverType = (typeof supportedDriverTypes)[number];
|
|
14
|
+
|
|
15
|
+
export abstract class DriverConfig<T extends SupportedDriverType = SupportedDriverType> {
|
|
16
|
+
abstract readonly driverType: T;
|
|
17
|
+
abstract readonly databaseType: SupportedDatabase;
|
|
18
|
+
|
|
19
|
+
abstract readonly supportsReturning: boolean;
|
|
20
|
+
abstract readonly supportsJson: boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Column name for internal ID in RETURNING results.
|
|
24
|
+
* Only defined if supportsReturning is true.
|
|
25
|
+
*/
|
|
26
|
+
abstract readonly internalIdColumn: string | undefined;
|
|
27
|
+
|
|
28
|
+
get supportsRowsAffected(): boolean {
|
|
29
|
+
return !!this.extractAffectedRows;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Extract the number of affected rows from a query result.
|
|
34
|
+
* Only implemented for drivers that support affected rows reporting.
|
|
35
|
+
*
|
|
36
|
+
* @param result - The query result from the SQL driver
|
|
37
|
+
* @returns The number of affected rows as bigint
|
|
38
|
+
* @throws Error if affected rows information is not found in the result
|
|
39
|
+
*/
|
|
40
|
+
extractAffectedRows?(result: Record<string, unknown>): bigint;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class SQLocalDriverConfig extends DriverConfig<"sqlocal"> {
|
|
44
|
+
override readonly driverType = "sqlocal";
|
|
45
|
+
override readonly databaseType = "sqlite";
|
|
46
|
+
override readonly supportsReturning = true;
|
|
47
|
+
override readonly supportsJson = false;
|
|
48
|
+
override readonly internalIdColumn = "_internalId";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class CloudflareDurableObjectsDriverConfig extends DriverConfig<"cloudflare_durable_objects"> {
|
|
52
|
+
override readonly driverType = "cloudflare_durable_objects";
|
|
53
|
+
override readonly databaseType = "sqlite";
|
|
54
|
+
override readonly supportsReturning = true;
|
|
55
|
+
override readonly supportsJson = false;
|
|
56
|
+
override readonly internalIdColumn = "_internalId";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class BetterSQLite3DriverConfig extends DriverConfig<"better-sqlite3"> {
|
|
60
|
+
override readonly driverType = "better-sqlite3";
|
|
61
|
+
override readonly databaseType = "sqlite";
|
|
62
|
+
override readonly supportsReturning = true;
|
|
63
|
+
override readonly supportsJson = false;
|
|
64
|
+
override readonly internalIdColumn = "_internalId";
|
|
65
|
+
|
|
66
|
+
override extractAffectedRows(result: Record<string, unknown>): bigint {
|
|
67
|
+
if ("numAffectedRows" in result) {
|
|
68
|
+
const value = result["numAffectedRows"];
|
|
69
|
+
if (typeof value === "bigint") {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
if (typeof value === "number") {
|
|
73
|
+
return BigInt(value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw new Error(
|
|
78
|
+
`No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class NodePostgresDriverConfig extends DriverConfig<"pg"> {
|
|
84
|
+
override readonly driverType = "pg";
|
|
85
|
+
override readonly databaseType = "postgresql";
|
|
86
|
+
override readonly supportsReturning = true;
|
|
87
|
+
override readonly supportsJson = true;
|
|
88
|
+
override readonly internalIdColumn = "_internalId";
|
|
89
|
+
|
|
90
|
+
override extractAffectedRows(result: Record<string, unknown>): bigint {
|
|
91
|
+
if ("numAffectedRows" in result) {
|
|
92
|
+
const value = result["numAffectedRows"];
|
|
93
|
+
if (typeof value === "bigint") {
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
if (typeof value === "number") {
|
|
97
|
+
return BigInt(value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if ("numChangedRows" in result) {
|
|
101
|
+
const value = result["numChangedRows"];
|
|
102
|
+
if (typeof value === "bigint") {
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
if (typeof value === "number") {
|
|
106
|
+
return BigInt(value);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
throw new Error(
|
|
110
|
+
`No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export class PGLiteDriverConfig extends DriverConfig<"pglite"> {
|
|
116
|
+
override readonly driverType = "pglite";
|
|
117
|
+
override readonly databaseType = "postgresql";
|
|
118
|
+
override readonly supportsReturning = true;
|
|
119
|
+
override readonly supportsJson = true;
|
|
120
|
+
override readonly internalIdColumn = "_internalId";
|
|
121
|
+
|
|
122
|
+
override extractAffectedRows(result: Record<string, unknown>): bigint {
|
|
123
|
+
if ("affectedRows" in result) {
|
|
124
|
+
const value = result["affectedRows"];
|
|
125
|
+
if (typeof value === "bigint") {
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
if (typeof value === "number") {
|
|
129
|
+
return BigInt(value);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
throw new Error(
|
|
133
|
+
`No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export class MySQL2DriverConfig extends DriverConfig<"mysql2"> {
|
|
139
|
+
override readonly driverType = "mysql2";
|
|
140
|
+
override readonly databaseType = "mysql";
|
|
141
|
+
override readonly supportsReturning = false;
|
|
142
|
+
override readonly supportsJson = true;
|
|
143
|
+
override readonly internalIdColumn = undefined;
|
|
144
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SQLocalKysely } from "sqlocal/kysely";
|
|
2
|
+
import { assert, describe, expect, it } from "vitest";
|
|
3
|
+
import { SQLocalDriverConfig } from "./driver-config";
|
|
4
|
+
import { GenericSQLAdapter } from "./generic-sql-adapter";
|
|
5
|
+
import { column, idColumn, schema } from "../../schema/create";
|
|
6
|
+
import { internalSchema } from "../../fragments/internal-fragment";
|
|
7
|
+
|
|
8
|
+
describe("GenericSQLAdapter", () => {
|
|
9
|
+
const testSchema = schema((s) => {
|
|
10
|
+
return s.addTable("products", (t) => {
|
|
11
|
+
return t
|
|
12
|
+
.addColumn("id", idColumn())
|
|
13
|
+
.addColumn("name", column("string"))
|
|
14
|
+
.addColumn("price", column("integer"))
|
|
15
|
+
.createIndex("name_idx", ["name"]);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("Should be able to query using GenericSQLAdapter", async () => {
|
|
20
|
+
const { dialect } = new SQLocalKysely(":memory:");
|
|
21
|
+
const driverConfig = new SQLocalDriverConfig();
|
|
22
|
+
|
|
23
|
+
const adapter = new GenericSQLAdapter({ dialect, driverConfig });
|
|
24
|
+
|
|
25
|
+
// Create settings table first (needed for version tracking)
|
|
26
|
+
const settingsMigrations = adapter.prepareMigrations(internalSchema, "");
|
|
27
|
+
await settingsMigrations.executeWithDriver(adapter.driver, 0);
|
|
28
|
+
|
|
29
|
+
// Now run the actual test schema migrations (use a different namespace)
|
|
30
|
+
const migrations = adapter.prepareMigrations(testSchema, "test");
|
|
31
|
+
await migrations.executeWithDriver(adapter.driver, 0);
|
|
32
|
+
|
|
33
|
+
const queryEngine = adapter.createQueryEngine(testSchema, "test");
|
|
34
|
+
|
|
35
|
+
await queryEngine.create("products", {
|
|
36
|
+
name: "test",
|
|
37
|
+
price: 100,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const product = await queryEngine.findFirst("products", (b) =>
|
|
41
|
+
b.whereIndex("name_idx", (eb) => eb("name", "=", "test")),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
assert(product);
|
|
45
|
+
expect(product.name).toBe("test");
|
|
46
|
+
expect(product.price).toBe(100);
|
|
47
|
+
|
|
48
|
+
await adapter.close();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
|
|
2
|
+
import {
|
|
3
|
+
fragnoDatabaseAdapterNameFakeSymbol,
|
|
4
|
+
fragnoDatabaseAdapterVersionFakeSymbol,
|
|
5
|
+
type DatabaseAdapter,
|
|
6
|
+
type DatabaseContextStorage,
|
|
7
|
+
type TableNameMapper,
|
|
8
|
+
} from "../adapters";
|
|
9
|
+
import type { CompiledQuery, Dialect, QueryResult } from "../../sql-driver/sql-driver";
|
|
10
|
+
import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter";
|
|
11
|
+
import { sql } from "../../sql-driver/sql";
|
|
12
|
+
import type { AnySchema } from "../../schema/create";
|
|
13
|
+
import { createTableNameMapper } from "../shared/table-name-mapper";
|
|
14
|
+
import type { SimpleQueryInterface } from "../../query/simple-query-interface";
|
|
15
|
+
import { createExecutor } from "./generic-sql-uow-executor";
|
|
16
|
+
import { UnitOfWorkDecoder } from "./uow-decoder";
|
|
17
|
+
import { createPreparedMigrations, type PreparedMigrations } from "./migration/prepared-migrations";
|
|
18
|
+
import type { DriverConfig } from "./driver-config";
|
|
19
|
+
import { GenericSQLUOWOperationCompiler } from "./query/generic-sql-uow-operation-compiler";
|
|
20
|
+
import { createUOWCompilerFromOperationCompiler } from "../shared/uow-operation-compiler";
|
|
21
|
+
import {
|
|
22
|
+
fromUnitOfWorkCompiler,
|
|
23
|
+
type UnitOfWorkFactory,
|
|
24
|
+
} from "../shared/from-unit-of-work-compiler";
|
|
25
|
+
|
|
26
|
+
export interface UnitOfWorkConfig {
|
|
27
|
+
onQuery?: (query: CompiledQuery) => void;
|
|
28
|
+
dryRun?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface GenericSQLOptions {
|
|
32
|
+
dialect: Dialect;
|
|
33
|
+
driverConfig: DriverConfig;
|
|
34
|
+
uowConfig?: UnitOfWorkConfig;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class GenericSQLAdapter implements DatabaseAdapter<UnitOfWorkConfig> {
|
|
38
|
+
readonly dialect: Dialect;
|
|
39
|
+
readonly driverConfig: DriverConfig;
|
|
40
|
+
readonly uowConfig?: UnitOfWorkConfig;
|
|
41
|
+
|
|
42
|
+
#schemaNamespaceMap = new WeakMap<AnySchema, string>();
|
|
43
|
+
#contextStorage: RequestContextStorage<DatabaseContextStorage>;
|
|
44
|
+
|
|
45
|
+
#driver: SqlDriverAdapter;
|
|
46
|
+
|
|
47
|
+
constructor({ dialect, driverConfig, uowConfig }: GenericSQLOptions) {
|
|
48
|
+
this.dialect = dialect;
|
|
49
|
+
this.driverConfig = driverConfig;
|
|
50
|
+
this.uowConfig = uowConfig;
|
|
51
|
+
|
|
52
|
+
this.#schemaNamespaceMap = new WeakMap<AnySchema, string>();
|
|
53
|
+
this.#contextStorage = new RequestContextStorage();
|
|
54
|
+
|
|
55
|
+
this.#driver = new SqlDriverAdapter(dialect);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get driver(): SqlDriverAdapter {
|
|
59
|
+
return this.#driver;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get [fragnoDatabaseAdapterNameFakeSymbol](): string {
|
|
63
|
+
return "generic-sql";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
get [fragnoDatabaseAdapterVersionFakeSymbol](): number {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get contextStorage(): RequestContextStorage<DatabaseContextStorage> {
|
|
71
|
+
return this.#contextStorage;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
close(): Promise<void> {
|
|
75
|
+
return this.#driver.destroy();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async isConnectionHealthy(): Promise<boolean> {
|
|
79
|
+
const result = await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect));
|
|
80
|
+
return result.rows[0]["healthy"] === 1;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
prepareMigrations<T extends AnySchema>(schema: T, namespace: string): PreparedMigrations {
|
|
84
|
+
return createPreparedMigrations({
|
|
85
|
+
schema,
|
|
86
|
+
namespace,
|
|
87
|
+
database: this.driverConfig.databaseType,
|
|
88
|
+
mapper: namespace ? this.createTableNameMapper(namespace) : undefined,
|
|
89
|
+
driver: this.#driver,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
createTableNameMapper(namespace: string): TableNameMapper {
|
|
94
|
+
return createTableNameMapper(namespace, false);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async getSchemaVersion(namespace: string): Promise<string | undefined> {
|
|
98
|
+
const key = `${namespace}.schema_version`;
|
|
99
|
+
const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${key};`.compile(
|
|
100
|
+
this.dialect,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
let result: QueryResult<Record<string, unknown>>;
|
|
104
|
+
try {
|
|
105
|
+
result = await this.#driver.executeQuery(query);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (error instanceof Error && error.message.includes("fragno_db_settings")) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const value = result.rows[0]["value"];
|
|
114
|
+
|
|
115
|
+
if (!value) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (typeof value !== "string") {
|
|
120
|
+
throw new Error(`Schema version for namespace ${namespace} is not a string`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
createQueryEngine<T extends AnySchema>(
|
|
127
|
+
schema: T,
|
|
128
|
+
namespace: string,
|
|
129
|
+
): SimpleQueryInterface<T, UnitOfWorkConfig> {
|
|
130
|
+
this.#schemaNamespaceMap.set(schema, namespace);
|
|
131
|
+
|
|
132
|
+
const operationCompiler = new GenericSQLUOWOperationCompiler(this.driverConfig, (ns) =>
|
|
133
|
+
ns ? this.createTableNameMapper(ns) : undefined,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const factory: UnitOfWorkFactory = {
|
|
137
|
+
compiler: createUOWCompilerFromOperationCompiler(operationCompiler),
|
|
138
|
+
executor: createExecutor(this.#driver, this.driverConfig, false),
|
|
139
|
+
decoder: new UnitOfWorkDecoder(this.driverConfig),
|
|
140
|
+
uowConfig: this.uowConfig,
|
|
141
|
+
schemaNamespaceMap: this.#schemaNamespaceMap,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return fromUnitOfWorkCompiler(schema, factory);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CompiledMutation,
|
|
3
|
+
MutationResult,
|
|
4
|
+
UOWExecutor,
|
|
5
|
+
} from "../../query/unit-of-work/unit-of-work";
|
|
6
|
+
import type { CompiledQuery } from "../../sql-driver/sql-driver";
|
|
7
|
+
import type { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter";
|
|
8
|
+
import type { DriverConfig } from "./driver-config";
|
|
9
|
+
import { ResultInterpreter } from "./result-interpreter";
|
|
10
|
+
|
|
11
|
+
export async function executeRetrieval(
|
|
12
|
+
adapter: SqlDriverAdapter,
|
|
13
|
+
retrievalBatch: CompiledQuery[],
|
|
14
|
+
): Promise<unknown[]> {
|
|
15
|
+
if (retrievalBatch.length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const retrievalResults: unknown[] = [];
|
|
20
|
+
|
|
21
|
+
await adapter.transaction(async (tx) => {
|
|
22
|
+
for (const compiledQuery of retrievalBatch) {
|
|
23
|
+
const result = await tx.executeQuery(compiledQuery);
|
|
24
|
+
retrievalResults.push(result.rows);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return retrievalResults;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function executeMutation(
|
|
32
|
+
adapter: SqlDriverAdapter,
|
|
33
|
+
driverConfig: DriverConfig,
|
|
34
|
+
mutationBatch: CompiledMutation<CompiledQuery>[],
|
|
35
|
+
): Promise<MutationResult> {
|
|
36
|
+
if (mutationBatch.length === 0) {
|
|
37
|
+
return { success: true, createdInternalIds: [] };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const createdInternalIds: (bigint | null)[] = [];
|
|
41
|
+
const resultInterpreter = new ResultInterpreter(driverConfig);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await adapter.transaction(async (tx) => {
|
|
45
|
+
for (const compiledMutation of mutationBatch) {
|
|
46
|
+
const result = await tx.executeQuery(compiledMutation.query);
|
|
47
|
+
|
|
48
|
+
// Extract internal ID for INSERT operations
|
|
49
|
+
if (compiledMutation.op === "create") {
|
|
50
|
+
// Only try to extract internal ID if driver supports RETURNING
|
|
51
|
+
// If not supported, push null (expected case - system falls back to subqueries)
|
|
52
|
+
if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {
|
|
53
|
+
const internalId = resultInterpreter.getCreatedInternalId(result);
|
|
54
|
+
createdInternalIds.push(internalId);
|
|
55
|
+
} else {
|
|
56
|
+
// Driver doesn't support RETURNING - this is expected, push null
|
|
57
|
+
createdInternalIds.push(null);
|
|
58
|
+
}
|
|
59
|
+
} else if (
|
|
60
|
+
(compiledMutation.op === "update" || compiledMutation.op === "delete") &&
|
|
61
|
+
compiledMutation.expectedAffectedRows !== null
|
|
62
|
+
) {
|
|
63
|
+
// Check affected rows for updates/deletes
|
|
64
|
+
const affectedRows = resultInterpreter.getAffectedRows(result);
|
|
65
|
+
|
|
66
|
+
if (affectedRows !== compiledMutation.expectedAffectedRows) {
|
|
67
|
+
// Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows
|
|
68
|
+
// This means either the row doesn't exist or the version has changed
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// "check" operations are handled below via expectedReturnedRows
|
|
75
|
+
|
|
76
|
+
if (compiledMutation.expectedReturnedRows !== null) {
|
|
77
|
+
// For SELECT queries (check operations), verify row count
|
|
78
|
+
const returnedRowCount = resultInterpreter.getReturnedRowCount(result);
|
|
79
|
+
|
|
80
|
+
if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) {
|
|
81
|
+
// Version conflict detected - the SELECT didn't return the expected number of rows
|
|
82
|
+
// This means either the row doesn't exist or the version has changed
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return { success: true, createdInternalIds };
|
|
92
|
+
} catch (error) {
|
|
93
|
+
// Transaction failed - could be version conflict or other constraint violation
|
|
94
|
+
// Return success=false to indicate the UOW should be retried
|
|
95
|
+
if (error instanceof Error && error.message.includes("Version conflict")) {
|
|
96
|
+
return { success: false };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Other database errors should be thrown
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function createExecutor(
|
|
105
|
+
adapter: SqlDriverAdapter,
|
|
106
|
+
driverConfig: DriverConfig,
|
|
107
|
+
dryRun?: boolean,
|
|
108
|
+
): UOWExecutor<CompiledQuery, unknown> {
|
|
109
|
+
return {
|
|
110
|
+
async executeRetrievalPhase(retrievalBatch: CompiledQuery[]) {
|
|
111
|
+
// In dryRun mode, skip execution and return empty results
|
|
112
|
+
if (dryRun) {
|
|
113
|
+
return retrievalBatch.map(() => []);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return executeRetrieval(adapter, retrievalBatch);
|
|
117
|
+
},
|
|
118
|
+
async executeMutationPhase(mutationBatch: CompiledMutation<CompiledQuery>[]) {
|
|
119
|
+
// In dryRun mode, skip execution and return success with mock internal IDs
|
|
120
|
+
if (dryRun) {
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
createdInternalIds: mutationBatch.map(() => null),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return executeMutation(adapter, driverConfig, mutationBatch);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DummyDriver,
|
|
3
|
+
Kysely,
|
|
4
|
+
MysqlAdapter,
|
|
5
|
+
MysqlIntrospector,
|
|
6
|
+
MysqlQueryCompiler,
|
|
7
|
+
PostgresAdapter,
|
|
8
|
+
PostgresIntrospector,
|
|
9
|
+
PostgresQueryCompiler,
|
|
10
|
+
SqliteAdapter,
|
|
11
|
+
SqliteIntrospector,
|
|
12
|
+
SqliteQueryCompiler,
|
|
13
|
+
} from "kysely";
|
|
14
|
+
import type { SupportedDatabase } from "../driver-config";
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
type KyselyAny = Kysely<any>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Kysely instance that can only build queries, not execute them.
|
|
21
|
+
* This is used for SQL generation without requiring a database connection.
|
|
22
|
+
*/
|
|
23
|
+
export function createColdKysely(database: SupportedDatabase): KyselyAny {
|
|
24
|
+
switch (database) {
|
|
25
|
+
case "postgresql":
|
|
26
|
+
return new Kysely({
|
|
27
|
+
dialect: {
|
|
28
|
+
createAdapter: () => new PostgresAdapter(),
|
|
29
|
+
createDriver: () => new DummyDriver(),
|
|
30
|
+
createIntrospector: (db) => new PostgresIntrospector(db),
|
|
31
|
+
createQueryCompiler: () => new PostgresQueryCompiler(),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
case "mysql":
|
|
36
|
+
return new Kysely({
|
|
37
|
+
dialect: {
|
|
38
|
+
createAdapter: () => new MysqlAdapter(),
|
|
39
|
+
createDriver: () => new DummyDriver(),
|
|
40
|
+
createIntrospector: (db) => new MysqlIntrospector(db),
|
|
41
|
+
createQueryCompiler: () => new MysqlQueryCompiler(),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
case "sqlite":
|
|
46
|
+
return new Kysely({
|
|
47
|
+
dialect: {
|
|
48
|
+
createAdapter: () => new SqliteAdapter(),
|
|
49
|
+
createDriver: () => new DummyDriver(),
|
|
50
|
+
createIntrospector: (db) => new SqliteIntrospector(db),
|
|
51
|
+
createQueryCompiler: () => new SqliteQueryCompiler(),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|