@fragno-dev/db 0.1.14 → 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 -139
- package/CHANGELOG.md +47 -0
- package/README.md +123 -8
- package/dist/adapters/adapters.d.ts +19 -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 -19
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
- package/dist/adapters/drizzle/generate.d.ts +7 -1
- package/dist/adapters/drizzle/generate.d.ts.map +1 -1
- package/dist/adapters/drizzle/generate.js +46 -45
- 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 -16
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-adapter.js +6 -159
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
- package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
- package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
- 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 +186 -0
- package/dist/db-fragment-definition-builder.d.ts.map +1 -0
- package/dist/db-fragment-definition-builder.js +207 -0
- package/dist/db-fragment-definition-builder.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +53 -0
- package/dist/fragments/internal-fragment.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.js +111 -0
- package/dist/fragments/internal-fragment.js.map +1 -0
- 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 +38 -56
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/mod.d.ts +35 -23
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +48 -45
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/packages/fragno/dist/api/bind-services.js +20 -0
- package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
- package/dist/packages/fragno/dist/api/error.js +48 -0
- package/dist/packages/fragno/dist/api/error.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
- package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
- package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
- package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
- package/dist/packages/fragno/dist/api/internal/route.js +10 -0
- package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
- package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
- package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
- package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
- package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
- package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
- package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
- package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
- package/dist/packages/fragno/dist/api/route.js +17 -0
- package/dist/packages/fragno/dist/api/route.js.map +1 -0
- package/dist/packages/fragno/dist/internal/symbols.js +10 -0
- package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
- package/dist/query/column-defaults.js +27 -0
- package/dist/query/column-defaults.js.map +1 -0
- package/dist/query/cursor.d.ts +14 -6
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +16 -7
- 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} +6 -6
- package/dist/query/simple-query-interface.d.ts.map +1 -0
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
- package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/query/unit-of-work/retry-policy.js +61 -0
- 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} +145 -58
- 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} +435 -198
- 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 +32 -0
- package/dist/with-database.d.ts.map +1 -0
- package/dist/with-database.js +34 -0
- package/dist/with-database.js.map +1 -0
- package/package.json +43 -9
- package/src/adapters/adapters.ts +23 -4
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
- package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
- package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
- package/src/adapters/drizzle/generate.test.ts +102 -269
- package/src/adapters/drizzle/generate.ts +89 -63
- 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 +36 -5
- 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 +90 -96
- package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
- package/src/adapters/kysely/kysely-adapter.ts +10 -242
- package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
- 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 +887 -0
- package/src/db-fragment-definition-builder.ts +737 -0
- package/src/db-fragment-instantiator.test.ts +543 -0
- package/src/db-fragment-integration.test.ts +406 -0
- package/src/fragments/internal-fragment.test.ts +549 -0
- package/src/fragments/internal-fragment.ts +249 -0
- package/src/hooks/hooks.test.ts +575 -0
- package/src/hooks/hooks.ts +179 -0
- package/src/migration-engine/generation-engine.test.ts +60 -27
- package/src/migration-engine/generation-engine.ts +99 -92
- package/src/mod.ts +139 -78
- package/src/query/column-defaults.ts +49 -0
- package/src/query/cursor.test.ts +147 -3
- package/src/query/cursor.ts +25 -8
- 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} +4 -4
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
- package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
- package/src/query/unit-of-work/retry-policy.test.ts +217 -0
- package/src/query/unit-of-work/retry-policy.ts +141 -0
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
- package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
- package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
- package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
- package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
- 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 +152 -0
- package/tsdown.config.ts +8 -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 -315
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
- 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 +0 -14
- 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 -66
- package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-query.d.ts +0 -22
- package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-query.js +0 -223
- package/dist/adapters/kysely/kysely-query.js.map +0 -1
- package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-shared.js +0 -18
- package/dist/adapters/kysely/kysely-shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
- 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/bind-services.d.ts +0 -7
- package/dist/bind-services.d.ts.map +0 -1
- package/dist/bind-services.js +0 -14
- package/dist/bind-services.js.map +0 -1
- package/dist/fragment.d.ts +0 -173
- package/dist/fragment.d.ts.map +0 -1
- package/dist/fragment.js +0 -191
- package/dist/fragment.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/query/query.d.ts.map +0 -1
- package/dist/query/result-transform.js +0 -168
- package/dist/query/result-transform.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 -106
- package/dist/schema/serialize.js.map +0 -1
- package/dist/shared/settings-schema.js +0 -36
- package/dist/shared/settings-schema.js.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
- 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.test.ts +0 -1383
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
- package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
- 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 -132
- package/src/adapters/kysely/kysely-query.test.ts +0 -498
- package/src/adapters/kysely/kysely-query.ts +0 -390
- package/src/adapters/kysely/kysely-shared.ts +0 -23
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
- package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
- package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
- package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
- 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/bind-services.test.ts +0 -214
- package/src/bind-services.ts +0 -37
- package/src/db-fragment.test.ts +0 -800
- package/src/fragment.ts +0 -727
- package/src/query/result-transform.ts +0 -271
- package/src/query/unit-of-work-multi-schema.test.ts +0 -64
- package/src/query/unit-of-work.test.ts +0 -943
- package/src/schema/serialize.ts +0 -396
- package/src/shared/settings-schema.ts +0 -61
- package/src/uow-context-integration.test.ts +0 -102
- package/src/uow-context.test.ts +0 -182
- /package/dist/query/{query.js → simple-query-interface.js} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { UnitOfWorkEncoder } from "./uow-encoder";
|
|
3
|
+
import { schema, column, idColumn, referenceColumn } from "../../schema/create";
|
|
4
|
+
import {
|
|
5
|
+
BetterSQLite3DriverConfig,
|
|
6
|
+
MySQL2DriverConfig,
|
|
7
|
+
NodePostgresDriverConfig,
|
|
8
|
+
} from "./driver-config";
|
|
9
|
+
|
|
10
|
+
describe("UnitOfWorkEncoder", () => {
|
|
11
|
+
const testSchema = schema((s) => {
|
|
12
|
+
return s
|
|
13
|
+
.addTable("users", (t) => {
|
|
14
|
+
return t
|
|
15
|
+
.addColumn("id", idColumn())
|
|
16
|
+
.addColumn("name", column("string"))
|
|
17
|
+
.addColumn("age", column("integer").nullable())
|
|
18
|
+
.addColumn("isActive", column("bool"))
|
|
19
|
+
.addColumn("createdAt", column("timestamp"));
|
|
20
|
+
})
|
|
21
|
+
.addTable("posts", (t) => {
|
|
22
|
+
return t
|
|
23
|
+
.addColumn("id", idColumn())
|
|
24
|
+
.addColumn("userId", referenceColumn())
|
|
25
|
+
.addColumn("title", column("string"));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const usersTable = testSchema.tables.users;
|
|
30
|
+
const postsTable = testSchema.tables.posts;
|
|
31
|
+
|
|
32
|
+
describe("SQLite encoding", () => {
|
|
33
|
+
const sqliteConfig = new BetterSQLite3DriverConfig();
|
|
34
|
+
|
|
35
|
+
// Mock Kysely instance (only needed for reference subquery processing)
|
|
36
|
+
const db = {} as any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
37
|
+
const encoder = new UnitOfWorkEncoder(sqliteConfig, db);
|
|
38
|
+
|
|
39
|
+
it("should serialize Date to number for sqlite", () => {
|
|
40
|
+
const date = new Date("2024-01-15T10:30:00Z");
|
|
41
|
+
const result = encoder.encodeForDatabase({
|
|
42
|
+
values: { createdAt: date },
|
|
43
|
+
table: usersTable,
|
|
44
|
+
generateDefaults: false,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(result).toEqual({ createdAt: date.getTime() });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("should serialize boolean to number for sqlite", () => {
|
|
51
|
+
const result = encoder.encodeForDatabase({
|
|
52
|
+
values: { isActive: true },
|
|
53
|
+
table: usersTable,
|
|
54
|
+
generateDefaults: false,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(result).toEqual({ isActive: 1 });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should serialize bigint to Number for reference columns in sqlite", () => {
|
|
61
|
+
const result = encoder.encodeForDatabase({
|
|
62
|
+
values: { userId: BigInt(456) },
|
|
63
|
+
table: postsTable,
|
|
64
|
+
generateDefaults: false,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Reference columns should be converted to Number for SQLite
|
|
68
|
+
expect(result).toEqual({ userId: 456 });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should handle multiple fields", () => {
|
|
72
|
+
const date = new Date("2024-01-15T10:30:00Z");
|
|
73
|
+
const result = encoder.encodeForDatabase({
|
|
74
|
+
values: {
|
|
75
|
+
name: "Alice",
|
|
76
|
+
age: 30,
|
|
77
|
+
isActive: false,
|
|
78
|
+
createdAt: date,
|
|
79
|
+
},
|
|
80
|
+
table: usersTable,
|
|
81
|
+
generateDefaults: false,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(result).toEqual({
|
|
85
|
+
name: "Alice",
|
|
86
|
+
age: 30,
|
|
87
|
+
isActive: 0,
|
|
88
|
+
createdAt: date.getTime(),
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should handle null values", () => {
|
|
93
|
+
const result = encoder.encodeForDatabase({
|
|
94
|
+
values: { age: null },
|
|
95
|
+
table: usersTable,
|
|
96
|
+
generateDefaults: false,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(result).toEqual({ age: null });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("should generate defaults when requested", () => {
|
|
103
|
+
const result = encoder.encodeForDatabase({
|
|
104
|
+
values: { title: "Test" },
|
|
105
|
+
table: postsTable,
|
|
106
|
+
generateDefaults: true,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Should have generated an ID
|
|
110
|
+
expect(result["id"]).toBeDefined();
|
|
111
|
+
expect(typeof result["id"]).toBe("string");
|
|
112
|
+
expect(result["title"]).toBe("Test");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("PostgreSQL encoding", () => {
|
|
117
|
+
const postgresConfig = new NodePostgresDriverConfig();
|
|
118
|
+
|
|
119
|
+
// Mock Kysely instance
|
|
120
|
+
const db = {} as any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
121
|
+
const encoder = new UnitOfWorkEncoder(postgresConfig, db);
|
|
122
|
+
|
|
123
|
+
it("should keep Date as Date for postgresql", () => {
|
|
124
|
+
const date = new Date("2024-01-15T10:30:00Z");
|
|
125
|
+
const result = encoder.encodeForDatabase({
|
|
126
|
+
values: { createdAt: date },
|
|
127
|
+
table: usersTable,
|
|
128
|
+
generateDefaults: false,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(result).toEqual({ createdAt: date });
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should keep boolean as boolean for postgresql", () => {
|
|
135
|
+
const result = encoder.encodeForDatabase({
|
|
136
|
+
values: { isActive: true },
|
|
137
|
+
table: usersTable,
|
|
138
|
+
generateDefaults: false,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
expect(result).toEqual({ isActive: true });
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("should keep bigint as bigint for reference columns in postgresql", () => {
|
|
145
|
+
const result = encoder.encodeForDatabase({
|
|
146
|
+
values: { userId: BigInt(456) },
|
|
147
|
+
table: postsTable,
|
|
148
|
+
generateDefaults: false,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
expect(result).toEqual({ userId: BigInt(456) });
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("MySQL encoding", () => {
|
|
156
|
+
const mysqlConfig = new MySQL2DriverConfig();
|
|
157
|
+
|
|
158
|
+
// Mock Kysely instance
|
|
159
|
+
const db = {} as any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
160
|
+
const encoder = new UnitOfWorkEncoder(mysqlConfig, db);
|
|
161
|
+
|
|
162
|
+
it("should keep Date as Date for mysql", () => {
|
|
163
|
+
const date = new Date("2024-01-15T10:30:00Z");
|
|
164
|
+
const result = encoder.encodeForDatabase({
|
|
165
|
+
values: { createdAt: date },
|
|
166
|
+
table: usersTable,
|
|
167
|
+
generateDefaults: false,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
expect(result).toEqual({ createdAt: date });
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("should keep boolean as boolean for mysql", () => {
|
|
174
|
+
const result = encoder.encodeForDatabase({
|
|
175
|
+
values: { isActive: true },
|
|
176
|
+
table: usersTable,
|
|
177
|
+
generateDefaults: false,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
expect(result).toEqual({ isActive: true });
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { AnyTable, AnyColumn } from "../../schema/create";
|
|
2
|
+
import type { DriverConfig } from "./driver-config";
|
|
3
|
+
import {
|
|
4
|
+
createSQLSerializer,
|
|
5
|
+
type SQLSerializer,
|
|
6
|
+
} from "../../query/serialize/create-sql-serializer";
|
|
7
|
+
import { encodeValues } from "../../query/value-encoding";
|
|
8
|
+
import { processReferenceSubqueries } from "./query/where-builder";
|
|
9
|
+
import type { TableNameMapper } from "../shared/table-name-mapper";
|
|
10
|
+
import type { Kysely } from "kysely";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Encoder class for Unit of Work mutation operations.
|
|
14
|
+
*
|
|
15
|
+
* Handles the complete transformation from application values to database-ready values
|
|
16
|
+
* in three clear steps:
|
|
17
|
+
* 1. Resolution - Resolve FragnoId/FragnoReference objects and generate defaults
|
|
18
|
+
* 2. Reference Processing - Create subqueries for external ID lookups
|
|
19
|
+
* 3. Serialization - Apply database-specific type conversions
|
|
20
|
+
*
|
|
21
|
+
* This class mirrors the UnitOfWorkDecoder pattern for symmetry.
|
|
22
|
+
*/
|
|
23
|
+
export class UnitOfWorkEncoder {
|
|
24
|
+
readonly #serializer: SQLSerializer;
|
|
25
|
+
readonly #db: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
26
|
+
readonly #mapper?: TableNameMapper;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
driverConfig: DriverConfig,
|
|
30
|
+
db: Kysely<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
31
|
+
mapper?: TableNameMapper,
|
|
32
|
+
) {
|
|
33
|
+
this.#serializer = createSQLSerializer(driverConfig);
|
|
34
|
+
this.#db = db;
|
|
35
|
+
this.#mapper = mapper;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Encode application values to database-ready format.
|
|
40
|
+
*
|
|
41
|
+
* This is the main entry point that handles all encoding steps:
|
|
42
|
+
* 1. **Resolution**: Transform ORM names to DB columns, resolve FragnoId/FragnoReference,
|
|
43
|
+
* generate defaults (CUIDs for IDs, etc.)
|
|
44
|
+
* 2. **Reference Processing**: Convert external ID strings to subqueries for internal ID lookup
|
|
45
|
+
* 3. **Serialization**: Apply database-specific conversions (Date → number for SQLite, etc.)
|
|
46
|
+
*
|
|
47
|
+
* @param options - Encoding options
|
|
48
|
+
* @param options.values - Application values to encode
|
|
49
|
+
* @param options.table - Table schema definition
|
|
50
|
+
* @param options.generateDefaults - Whether to generate default values for undefined columns
|
|
51
|
+
* @returns Database-ready values
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const encoded = encoder.encodeForDatabase({
|
|
56
|
+
* values: { userId: FragnoId(...), createdAt: new Date(), isActive: true },
|
|
57
|
+
* table: usersTable,
|
|
58
|
+
* generateDefaults: true
|
|
59
|
+
* });
|
|
60
|
+
* // For SQLite: { user_id: 456, created_at: 1705316400000, is_active: 1 }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
encodeForDatabase(options: {
|
|
64
|
+
values: Record<string, unknown>;
|
|
65
|
+
table: AnyTable;
|
|
66
|
+
generateDefaults: boolean;
|
|
67
|
+
}): Record<string, unknown> {
|
|
68
|
+
// Step 1: Resolution - Resolve FragnoId/FragnoReference and generate defaults
|
|
69
|
+
const resolved = encodeValues(options.values, options.table, options.generateDefaults);
|
|
70
|
+
|
|
71
|
+
// Step 2: Reference Processing - Convert external IDs to subqueries
|
|
72
|
+
const processed = processReferenceSubqueries(resolved, this.#db, this.#mapper);
|
|
73
|
+
|
|
74
|
+
// Step 3: Serialization - Apply database-specific type conversions
|
|
75
|
+
const serialized = this.serializeValues(processed, options.table);
|
|
76
|
+
|
|
77
|
+
return serialized;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Serialize resolved values to database format.
|
|
82
|
+
*
|
|
83
|
+
* Applies database-specific type conversions:
|
|
84
|
+
* - SQLite: Date → number, boolean → 0/1, bigint → Buffer (or Number for reference columns)
|
|
85
|
+
* - PostgreSQL: Mostly pass-through (database handles types natively)
|
|
86
|
+
* - MySQL: Mostly pass-through
|
|
87
|
+
*
|
|
88
|
+
* @param values - Resolved values (after resolution and reference processing)
|
|
89
|
+
* @param table - The table schema definition
|
|
90
|
+
* @returns Serialized values ready for database driver
|
|
91
|
+
*/
|
|
92
|
+
private serializeValues(
|
|
93
|
+
values: Record<string, unknown>,
|
|
94
|
+
table: AnyTable,
|
|
95
|
+
): Record<string, unknown> {
|
|
96
|
+
const result: Record<string, unknown> = {};
|
|
97
|
+
|
|
98
|
+
for (const [dbColumnName, value] of Object.entries(values)) {
|
|
99
|
+
// Find the column definition by database column name
|
|
100
|
+
const col = this.findColumnByDbName(table, dbColumnName);
|
|
101
|
+
|
|
102
|
+
if (!col) {
|
|
103
|
+
// Not a regular column (might be a special value like sql.raw())
|
|
104
|
+
// Pass through as-is
|
|
105
|
+
result[dbColumnName] = value;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Serialize the value using the column definition and database type
|
|
110
|
+
result[dbColumnName] = this.#serializer.serialize(value, col);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Find a column definition by its database column name.
|
|
118
|
+
*
|
|
119
|
+
* @param table - The table to search
|
|
120
|
+
* @param dbColumnName - The database column name (e.g., "user_id")
|
|
121
|
+
* @returns The column definition or undefined if not found
|
|
122
|
+
*/
|
|
123
|
+
private findColumnByDbName(table: AnyTable, dbColumnName: string): AnyColumn | undefined {
|
|
124
|
+
for (const col of Object.values(table.columns)) {
|
|
125
|
+
if (col.name === dbColumnName) {
|
|
126
|
+
return col;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Kysely } from "kysely";
|
|
2
1
|
import { KyselyPGlite } from "kysely-pglite";
|
|
3
|
-
import {
|
|
2
|
+
import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
|
|
4
3
|
import { KyselyAdapter } from "./kysely-adapter";
|
|
5
4
|
import {
|
|
6
5
|
column,
|
|
@@ -11,6 +10,8 @@ import {
|
|
|
11
10
|
type FragnoReference,
|
|
12
11
|
} from "../../schema/create";
|
|
13
12
|
import { Cursor } from "../../query/cursor";
|
|
13
|
+
import { PGLiteDriverConfig } from "../generic-sql/driver-config";
|
|
14
|
+
import { internalSchema } from "../../fragments/internal-fragment";
|
|
14
15
|
|
|
15
16
|
describe("KyselyAdapter PGLite", () => {
|
|
16
17
|
const testSchema = schema((s) => {
|
|
@@ -95,19 +96,14 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
95
96
|
});
|
|
96
97
|
});
|
|
97
98
|
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
|
-
let kysely: Kysely<any>;
|
|
100
99
|
let adapter: KyselyAdapter;
|
|
101
100
|
|
|
102
101
|
beforeAll(async () => {
|
|
103
102
|
const { dialect } = await KyselyPGlite.create();
|
|
104
|
-
kysely = new Kysely({
|
|
105
|
-
dialect,
|
|
106
|
-
});
|
|
107
103
|
|
|
108
104
|
adapter = new KyselyAdapter({
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
dialect,
|
|
106
|
+
driverConfig: new PGLiteDriverConfig(),
|
|
111
107
|
});
|
|
112
108
|
}, 12000);
|
|
113
109
|
|
|
@@ -115,72 +111,26 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
115
111
|
const schemaVersion = await adapter.getSchemaVersion("test");
|
|
116
112
|
expect(schemaVersion).toBeUndefined();
|
|
117
113
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
assert(preparedMigration.getSQL);
|
|
123
|
-
|
|
124
|
-
expect(preparedMigration.getSQL()).toMatchInlineSnapshot(`
|
|
125
|
-
"create table "users_test" ("id" varchar(30) not null unique, "name" text not null, "age" integer, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
126
|
-
|
|
127
|
-
create index "name_idx" on "users_test" ("name");
|
|
128
|
-
|
|
129
|
-
create index "age_idx" on "users_test" ("age");
|
|
130
|
-
|
|
131
|
-
create table "emails_test" ("id" varchar(30) not null unique, "user_id" bigint not null, "email" text not null, "is_primary" boolean default false not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
132
|
-
|
|
133
|
-
create unique index "unique_email" on "emails_test" ("email");
|
|
134
|
-
|
|
135
|
-
create index "user_emails" on "emails_test" ("user_id");
|
|
136
|
-
|
|
137
|
-
create table "posts_test" ("id" varchar(30) not null unique, "user_id" bigint not null, "title" text not null, "content" text not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
138
|
-
|
|
139
|
-
create index "posts_user_idx" on "posts_test" ("user_id");
|
|
140
|
-
|
|
141
|
-
create table "tags_test" ("id" varchar(30) not null unique, "name" text not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
142
|
-
|
|
143
|
-
create index "tag_name" on "tags_test" ("name");
|
|
144
|
-
|
|
145
|
-
create table "post_tags_test" ("id" varchar(30) not null unique, "post_id" bigint not null, "tag_id" bigint not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
146
|
-
|
|
147
|
-
create index "pt_post" on "post_tags_test" ("post_id");
|
|
148
|
-
|
|
149
|
-
create index "pt_tag" on "post_tags_test" ("tag_id");
|
|
150
|
-
|
|
151
|
-
create table "comments_test" ("id" varchar(30) not null unique, "post_id" bigint not null, "user_id" bigint not null, "text" text not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
|
|
152
|
-
|
|
153
|
-
create index "comments_post_idx" on "comments_test" ("post_id");
|
|
154
|
-
|
|
155
|
-
create index "comments_user_idx" on "comments_test" ("user_id");
|
|
156
|
-
|
|
157
|
-
alter table "emails_test" add constraint "emails_users_user_fk" foreign key ("user_id") references "users_test" ("_internalId") on delete restrict on update restrict;
|
|
158
|
-
|
|
159
|
-
alter table "posts_test" add constraint "posts_users_author_fk" foreign key ("user_id") references "users_test" ("_internalId") on delete restrict on update restrict;
|
|
160
|
-
|
|
161
|
-
alter table "post_tags_test" add constraint "post_tags_posts_post_fk" foreign key ("post_id") references "posts_test" ("_internalId") on delete restrict on update restrict;
|
|
162
|
-
|
|
163
|
-
alter table "post_tags_test" add constraint "post_tags_tags_tag_fk" foreign key ("tag_id") references "tags_test" ("_internalId") on delete restrict on update restrict;
|
|
164
|
-
|
|
165
|
-
alter table "comments_test" add constraint "comments_posts_post_fk" foreign key ("post_id") references "posts_test" ("_internalId") on delete restrict on update restrict;
|
|
166
|
-
|
|
167
|
-
alter table "comments_test" add constraint "comments_users_commenter_fk" foreign key ("user_id") references "users_test" ("_internalId") on delete restrict on update restrict;"
|
|
168
|
-
`);
|
|
114
|
+
{
|
|
115
|
+
const migrations = adapter.prepareMigrations(internalSchema, "");
|
|
116
|
+
await migrations.executeWithDriver(adapter.driver, 0);
|
|
117
|
+
}
|
|
169
118
|
|
|
170
|
-
|
|
119
|
+
{
|
|
120
|
+
const migrations = adapter.prepareMigrations(testSchema, "test");
|
|
121
|
+
await migrations.executeWithDriver(adapter.driver, 0);
|
|
122
|
+
}
|
|
171
123
|
|
|
172
124
|
const queryEngine = adapter.createQueryEngine(testSchema, "test");
|
|
173
125
|
|
|
174
|
-
// Create a user
|
|
175
126
|
const userId = await queryEngine.create("users", {
|
|
176
127
|
name: "John Doe",
|
|
177
128
|
age: 30,
|
|
178
129
|
});
|
|
179
130
|
|
|
180
|
-
// create() now returns just the ID
|
|
181
131
|
expect(userId).toMatchObject({
|
|
182
132
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
183
|
-
internalId: expect.any(
|
|
133
|
+
internalId: expect.any(BigInt),
|
|
184
134
|
});
|
|
185
135
|
|
|
186
136
|
expect(userId.version).toBe(0);
|
|
@@ -191,7 +141,7 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
191
141
|
expect(getUser).toMatchObject({
|
|
192
142
|
id: expect.objectContaining({
|
|
193
143
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
194
|
-
internalId: expect.any(
|
|
144
|
+
internalId: expect.any(BigInt),
|
|
195
145
|
}),
|
|
196
146
|
name: "John Doe",
|
|
197
147
|
});
|
|
@@ -212,12 +162,12 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
212
162
|
|
|
213
163
|
expect(email1Id).toMatchObject({
|
|
214
164
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
215
|
-
internalId: expect.any(
|
|
165
|
+
internalId: expect.any(BigInt),
|
|
216
166
|
});
|
|
217
167
|
|
|
218
168
|
expect(email2Id).toMatchObject({
|
|
219
169
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
220
|
-
internalId: expect.any(
|
|
170
|
+
internalId: expect.any(BigInt),
|
|
221
171
|
});
|
|
222
172
|
|
|
223
173
|
// Update user name
|
|
@@ -244,17 +194,17 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
244
194
|
expect(emailsWithUsers[0]).toEqual({
|
|
245
195
|
id: expect.objectContaining({
|
|
246
196
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
247
|
-
internalId: expect.any(
|
|
197
|
+
internalId: expect.any(BigInt),
|
|
248
198
|
}),
|
|
249
199
|
user_id: expect.objectContaining({
|
|
250
|
-
internalId: expect.any(
|
|
200
|
+
internalId: expect.any(BigInt),
|
|
251
201
|
}),
|
|
252
202
|
email: expect.stringMatching(/\.com$/),
|
|
253
203
|
is_primary: expect.any(Boolean),
|
|
254
204
|
user: {
|
|
255
205
|
id: expect.objectContaining({
|
|
256
206
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
257
|
-
internalId: expect.any(
|
|
207
|
+
internalId: expect.any(BigInt),
|
|
258
208
|
}),
|
|
259
209
|
name: "Jane Doe",
|
|
260
210
|
age: 30,
|
|
@@ -498,10 +448,10 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
498
448
|
externalId: expect.any(String),
|
|
499
449
|
}),
|
|
500
450
|
post_id: expect.objectContaining({
|
|
501
|
-
internalId: expect.any(
|
|
451
|
+
internalId: expect.any(BigInt),
|
|
502
452
|
}),
|
|
503
453
|
tag_id: expect.objectContaining({
|
|
504
|
-
internalId: expect.any(
|
|
454
|
+
internalId: expect.any(BigInt),
|
|
505
455
|
}),
|
|
506
456
|
post: {
|
|
507
457
|
title: expect.any(String),
|
|
@@ -640,7 +590,7 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
640
590
|
expect(comment).toMatchObject({
|
|
641
591
|
id: expect.objectContaining({
|
|
642
592
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
643
|
-
internalId: expect.any(
|
|
593
|
+
internalId: expect.any(BigInt),
|
|
644
594
|
}),
|
|
645
595
|
text: "Great post!",
|
|
646
596
|
// Post join (first level)
|
|
@@ -687,15 +637,15 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
687
637
|
expect(createdIds1).toMatchObject([
|
|
688
638
|
expect.objectContaining({
|
|
689
639
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
690
|
-
internalId: expect.any(
|
|
640
|
+
internalId: expect.any(BigInt),
|
|
691
641
|
}),
|
|
692
642
|
expect.objectContaining({
|
|
693
643
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
694
|
-
internalId: expect.any(
|
|
644
|
+
internalId: expect.any(BigInt),
|
|
695
645
|
}),
|
|
696
646
|
expect.objectContaining({
|
|
697
647
|
externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
|
|
698
|
-
internalId: expect.any(
|
|
648
|
+
internalId: expect.any(BigInt),
|
|
699
649
|
}),
|
|
700
650
|
]);
|
|
701
651
|
|
|
@@ -878,10 +828,11 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
878
828
|
it("should support cursor-based pagination with findWithCursor()", async () => {
|
|
879
829
|
const queryEngine = adapter.createQueryEngine(testSchema, "test");
|
|
880
830
|
|
|
881
|
-
// Create
|
|
831
|
+
// Create exactly 15 users for precise pagination testing with unique prefix
|
|
882
832
|
const prefix = "CursorPagTest";
|
|
833
|
+
|
|
883
834
|
const userIds: FragnoId[] = [];
|
|
884
|
-
for (let i = 1; i <=
|
|
835
|
+
for (let i = 1; i <= 15; i++) {
|
|
885
836
|
const userId = await queryEngine.create("users", {
|
|
886
837
|
name: `${prefix} ${i.toString().padStart(2, "0")}`,
|
|
887
838
|
age: 20 + i,
|
|
@@ -889,29 +840,35 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
889
840
|
userIds.push(userId);
|
|
890
841
|
}
|
|
891
842
|
|
|
892
|
-
// Fetch first page with cursor (
|
|
843
|
+
// Fetch first page with cursor (pageSize=10, total=15 items)
|
|
893
844
|
const firstPage = await queryEngine.findWithCursor("users", (b) =>
|
|
894
|
-
b
|
|
845
|
+
b
|
|
846
|
+
.whereIndex("name_idx", (eb) => eb("name", "starts with", prefix))
|
|
847
|
+
.orderByIndex("name_idx", "asc")
|
|
848
|
+
.pageSize(10),
|
|
895
849
|
);
|
|
896
850
|
|
|
897
|
-
// Check structure
|
|
851
|
+
// Check structure and hasNextPage
|
|
898
852
|
expect(firstPage).toHaveProperty("items");
|
|
899
853
|
expect(firstPage).toHaveProperty("cursor");
|
|
854
|
+
expect(firstPage).toHaveProperty("hasNextPage");
|
|
900
855
|
expect(Array.isArray(firstPage.items)).toBe(true);
|
|
901
|
-
expect(firstPage.items
|
|
902
|
-
|
|
903
|
-
|
|
856
|
+
expect(firstPage.items).toHaveLength(10);
|
|
857
|
+
expect(firstPage.hasNextPage).toBe(true);
|
|
858
|
+
expect(firstPage.cursor).toBeInstanceOf(Cursor);
|
|
904
859
|
|
|
905
|
-
// Fetch second page using cursor
|
|
860
|
+
// Fetch second page using cursor (last page with 5 remaining items)
|
|
906
861
|
const secondPage = await queryEngine.findWithCursor("users", (b) =>
|
|
907
862
|
b
|
|
908
|
-
.whereIndex("name_idx")
|
|
863
|
+
.whereIndex("name_idx", (eb) => eb("name", "starts with", prefix))
|
|
909
864
|
.after(firstPage.cursor!)
|
|
910
865
|
.orderByIndex("name_idx", "asc")
|
|
911
866
|
.pageSize(10),
|
|
912
867
|
);
|
|
913
868
|
|
|
914
|
-
expect(secondPage.items
|
|
869
|
+
expect(secondPage.items).toHaveLength(5);
|
|
870
|
+
expect(secondPage.hasNextPage).toBe(false);
|
|
871
|
+
expect(secondPage.cursor).toBeUndefined();
|
|
915
872
|
|
|
916
873
|
// Verify no overlap - all names in second page should be different from first page
|
|
917
874
|
const firstPageNames = new Set(firstPage.items.map((u) => u.name));
|
|
@@ -926,12 +883,16 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
926
883
|
const secondPageFirst = secondPage.items[0].name;
|
|
927
884
|
expect(firstPageLast < secondPageFirst).toBe(true);
|
|
928
885
|
|
|
929
|
-
//
|
|
930
|
-
const
|
|
931
|
-
b
|
|
886
|
+
// Test empty results
|
|
887
|
+
const emptyPage = await queryEngine.findWithCursor("users", (b) =>
|
|
888
|
+
b
|
|
889
|
+
.whereIndex("name_idx", (eb) => eb("name", "starts with", "NonExistentPrefix"))
|
|
890
|
+
.orderByIndex("name_idx", "asc")
|
|
891
|
+
.pageSize(10),
|
|
932
892
|
);
|
|
933
|
-
|
|
934
|
-
expect(
|
|
893
|
+
expect(emptyPage.items).toHaveLength(0);
|
|
894
|
+
expect(emptyPage.hasNextPage).toBe(false);
|
|
895
|
+
expect(emptyPage.cursor).toBeUndefined();
|
|
935
896
|
});
|
|
936
897
|
|
|
937
898
|
it("should support findWithCursor() in Unit of Work", async () => {
|
|
@@ -960,14 +921,47 @@ describe("KyselyAdapter PGLite", () => {
|
|
|
960
921
|
|
|
961
922
|
const [result] = await uow.executeRetrieve();
|
|
962
923
|
|
|
963
|
-
// Verify result structure
|
|
924
|
+
// Verify result structure including hasNextPage
|
|
964
925
|
expect(result).toHaveProperty("items");
|
|
965
926
|
expect(result).toHaveProperty("cursor");
|
|
927
|
+
expect(result).toHaveProperty("hasNextPage");
|
|
966
928
|
expect(Array.isArray(result.items)).toBe(true);
|
|
967
929
|
expect(result.items.length).toBeGreaterThan(0);
|
|
930
|
+
expect(typeof result.hasNextPage).toBe("boolean");
|
|
931
|
+
expect(result.cursor).toBeInstanceOf(Cursor);
|
|
932
|
+
});
|
|
968
933
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
934
|
+
it("should fail check() when version changes", async () => {
|
|
935
|
+
const queryEngine = adapter.createQueryEngine(testSchema, "test");
|
|
936
|
+
|
|
937
|
+
// Create a user
|
|
938
|
+
const userId = await queryEngine.create("users", {
|
|
939
|
+
name: "Version Conflict User",
|
|
940
|
+
age: 40,
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
// Update the user to increment their version
|
|
944
|
+
await queryEngine.updateMany("users", (b) =>
|
|
945
|
+
b.whereIndex("primary", (eb) => eb("id", "=", userId)).set({ age: 41 }),
|
|
946
|
+
);
|
|
947
|
+
|
|
948
|
+
// Try to check with the old version (should fail)
|
|
949
|
+
const uow = queryEngine.createUnitOfWork("check-stale-version");
|
|
950
|
+
uow.check("users", userId); // This has version 0, but the user now has version 1
|
|
951
|
+
uow.create("posts", {
|
|
952
|
+
user_id: userId,
|
|
953
|
+
title: "Should Not Be Created",
|
|
954
|
+
content: "Content",
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
const { success } = await uow.executeMutations();
|
|
958
|
+
expect(success).toBe(false);
|
|
959
|
+
|
|
960
|
+
// Verify the post was NOT created
|
|
961
|
+
const posts = await queryEngine.find("posts", (b) =>
|
|
962
|
+
b.whereIndex("posts_user_idx", (eb) => eb("user_id", "=", userId)),
|
|
963
|
+
);
|
|
964
|
+
const conflictPosts = posts.filter((p) => p.title === "Should Not Be Created");
|
|
965
|
+
expect(conflictPosts).toHaveLength(0);
|
|
972
966
|
});
|
|
973
967
|
});
|