@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,314 @@
|
|
|
1
|
+
import { UOWOperationCompiler } from "../../shared/uow-operation-compiler";
|
|
2
|
+
import type { CompiledQuery } from "kysely";
|
|
3
|
+
import type { DriverConfig } from "../driver-config";
|
|
4
|
+
import type { TableNameMapper } from "../../shared/table-name-mapper";
|
|
5
|
+
import type {
|
|
6
|
+
RetrievalOperation,
|
|
7
|
+
MutationOperation,
|
|
8
|
+
CompiledMutation,
|
|
9
|
+
} from "../../../query/unit-of-work/unit-of-work";
|
|
10
|
+
import type { AnyColumn, AnySchema } from "../../../schema/create";
|
|
11
|
+
import { buildCondition } from "../../../query/condition-builder";
|
|
12
|
+
import { createSQLQueryCompiler } from "./create-sql-query-compiler";
|
|
13
|
+
import { SQLQueryCompiler } from "./sql-query-compiler";
|
|
14
|
+
import { buildCursorCondition } from "./cursor-utils";
|
|
15
|
+
import type { Condition } from "../../../query/condition-builder";
|
|
16
|
+
import { buildFindOptions } from "../../../query/orm/orm";
|
|
17
|
+
import type { AnySelectClause } from "../../../query/simple-query-interface";
|
|
18
|
+
import { createColdKysely } from "../migration/cold-kysely";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generic SQL UOW Operation Compiler.
|
|
22
|
+
*
|
|
23
|
+
* Uses SQLQueryCompiler for dialect-specific SQL generation while handling
|
|
24
|
+
* high-level business logic like cursor pagination, version checking, and index resolution.
|
|
25
|
+
*/
|
|
26
|
+
export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<CompiledQuery> {
|
|
27
|
+
constructor(
|
|
28
|
+
driverConfig: DriverConfig,
|
|
29
|
+
mapperFactory?: (namespace: string | undefined) => TableNameMapper | undefined,
|
|
30
|
+
) {
|
|
31
|
+
super(driverConfig, mapperFactory);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get SQL compiler for a specific namespace
|
|
36
|
+
*/
|
|
37
|
+
private getSQLCompiler(namespace: string | undefined): SQLQueryCompiler {
|
|
38
|
+
const mapper = this.getMapperForOperation(namespace);
|
|
39
|
+
const kysely = createColdKysely(this.driverConfig.databaseType);
|
|
40
|
+
return createSQLQueryCompiler(kysely, this.driverConfig, mapper);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override compileCount(
|
|
44
|
+
op: RetrievalOperation<AnySchema> & { type: "count" },
|
|
45
|
+
): CompiledQuery | null {
|
|
46
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
47
|
+
|
|
48
|
+
// Build where condition
|
|
49
|
+
let conditions = op.options.where
|
|
50
|
+
? buildCondition(op.table.columns, op.options.where)
|
|
51
|
+
: undefined;
|
|
52
|
+
|
|
53
|
+
if (conditions === true) {
|
|
54
|
+
conditions = undefined;
|
|
55
|
+
}
|
|
56
|
+
if (conditions === false) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return sqlCompiler.compileCount(op.table, { where: conditions });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override compileFind(op: RetrievalOperation<AnySchema> & { type: "find" }): CompiledQuery | null {
|
|
64
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
65
|
+
|
|
66
|
+
// Extract options
|
|
67
|
+
const {
|
|
68
|
+
useIndex: _useIndex,
|
|
69
|
+
orderByIndex,
|
|
70
|
+
joins: join,
|
|
71
|
+
after,
|
|
72
|
+
before,
|
|
73
|
+
pageSize,
|
|
74
|
+
...findManyOptions
|
|
75
|
+
} = op.options;
|
|
76
|
+
|
|
77
|
+
// Get index columns for ordering and cursor pagination
|
|
78
|
+
let indexColumns: AnyColumn[] = [];
|
|
79
|
+
let orderDirection: "asc" | "desc" = "asc";
|
|
80
|
+
|
|
81
|
+
if (orderByIndex) {
|
|
82
|
+
const index = op.table.indexes[orderByIndex.indexName];
|
|
83
|
+
orderDirection = orderByIndex.direction;
|
|
84
|
+
|
|
85
|
+
if (!index) {
|
|
86
|
+
// If _primary index doesn't exist, fall back to internal ID column
|
|
87
|
+
if (orderByIndex.indexName === "_primary") {
|
|
88
|
+
indexColumns = [op.table.getIdColumn()];
|
|
89
|
+
} else {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Index "${orderByIndex.indexName}" not found on table "${op.table.name}"`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
// Order by all columns in the index with the specified direction
|
|
96
|
+
indexColumns = index.columns;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Convert orderByIndex to orderBy format
|
|
101
|
+
let orderBy: [AnyColumn, "asc" | "desc"][] | undefined;
|
|
102
|
+
if (indexColumns.length > 0) {
|
|
103
|
+
orderBy = indexColumns.map((col) => [col, orderDirection]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Handle cursor pagination - build a cursor condition
|
|
107
|
+
// TODO: Multi-column cursor pagination not yet supported
|
|
108
|
+
if ((after || before) && indexColumns.length > 1) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
"Multi-column cursor pagination is not yet supported in Generic SQL implementation",
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const cursorCondition = buildCursorCondition(
|
|
114
|
+
after || before,
|
|
115
|
+
indexColumns,
|
|
116
|
+
orderDirection,
|
|
117
|
+
!!after,
|
|
118
|
+
this.driverConfig,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Combine user where clause with cursor condition
|
|
122
|
+
let combinedWhere: Condition | undefined;
|
|
123
|
+
if (findManyOptions.where) {
|
|
124
|
+
const whereResult = buildCondition(op.table.columns, findManyOptions.where);
|
|
125
|
+
if (whereResult === true) {
|
|
126
|
+
combinedWhere = undefined;
|
|
127
|
+
} else if (whereResult === false) {
|
|
128
|
+
return null;
|
|
129
|
+
} else {
|
|
130
|
+
combinedWhere = whereResult;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (cursorCondition) {
|
|
135
|
+
if (combinedWhere) {
|
|
136
|
+
combinedWhere = {
|
|
137
|
+
type: "and",
|
|
138
|
+
items: [combinedWhere, cursorCondition],
|
|
139
|
+
};
|
|
140
|
+
} else {
|
|
141
|
+
combinedWhere = cursorCondition;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// For cursor pagination, fetch one extra item to determine if there's a next page
|
|
146
|
+
const effectiveLimit = pageSize && op.withCursor ? pageSize + 1 : pageSize;
|
|
147
|
+
|
|
148
|
+
// When we have joins, use the query builder directly
|
|
149
|
+
if (join && join.length > 0) {
|
|
150
|
+
return sqlCompiler.compileFindMany(op.table, {
|
|
151
|
+
select: (findManyOptions.select ?? true) as AnySelectClause,
|
|
152
|
+
where: combinedWhere,
|
|
153
|
+
orderBy,
|
|
154
|
+
limit: effectiveLimit,
|
|
155
|
+
join,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Otherwise, use buildFindOptions to process the query options
|
|
160
|
+
const compiledOptions = buildFindOptions(op.table, {
|
|
161
|
+
...findManyOptions,
|
|
162
|
+
where: combinedWhere ? () => combinedWhere! : undefined,
|
|
163
|
+
orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),
|
|
164
|
+
limit: effectiveLimit,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (compiledOptions === false) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return sqlCompiler.compileFindMany(op.table, compiledOptions);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
override compileCreate(
|
|
175
|
+
op: MutationOperation<AnySchema> & { type: "create" },
|
|
176
|
+
): CompiledMutation<CompiledQuery> | null {
|
|
177
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
178
|
+
const table = this.getTable(op.schema, op.table);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
query: sqlCompiler.compileCreate(table, op.values),
|
|
182
|
+
op: "create",
|
|
183
|
+
expectedAffectedRows: null, // creates don't need affected row checks
|
|
184
|
+
expectedReturnedRows: null,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override compileUpdate(
|
|
189
|
+
op: MutationOperation<AnySchema> & { type: "update" },
|
|
190
|
+
): CompiledMutation<CompiledQuery> | null {
|
|
191
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
192
|
+
const table = this.getTable(op.schema, op.table);
|
|
193
|
+
const idColumn = table.getIdColumn();
|
|
194
|
+
const versionColumn = table.getVersionColumn();
|
|
195
|
+
|
|
196
|
+
const externalId = this.getExternalId(op.id);
|
|
197
|
+
const versionToCheck = this.getVersionToCheck(op.id, op.checkVersion);
|
|
198
|
+
|
|
199
|
+
// Build WHERE clause that filters by ID and optionally by version
|
|
200
|
+
const conditionsResult =
|
|
201
|
+
versionToCheck !== undefined
|
|
202
|
+
? buildCondition(table.columns, (eb) =>
|
|
203
|
+
eb.and(
|
|
204
|
+
eb(idColumn.ormName, "=", externalId),
|
|
205
|
+
eb(versionColumn.ormName, "=", versionToCheck),
|
|
206
|
+
),
|
|
207
|
+
)
|
|
208
|
+
: buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
|
|
209
|
+
|
|
210
|
+
if (conditionsResult === false) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const conditions: Condition | undefined =
|
|
215
|
+
conditionsResult === true ? undefined : conditionsResult;
|
|
216
|
+
|
|
217
|
+
// Determine if we should use RETURNING-based checking
|
|
218
|
+
// Use RETURNING when driver supports it but doesn't support affected rows reporting
|
|
219
|
+
const useReturningForCheck =
|
|
220
|
+
op.checkVersion &&
|
|
221
|
+
this.driverConfig.supportsReturning &&
|
|
222
|
+
!this.driverConfig.supportsRowsAffected;
|
|
223
|
+
|
|
224
|
+
const query = sqlCompiler.compileUpdate(table, {
|
|
225
|
+
set: op.set,
|
|
226
|
+
where: conditions,
|
|
227
|
+
returning: useReturningForCheck,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
query,
|
|
232
|
+
op: "update",
|
|
233
|
+
expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
|
|
234
|
+
expectedReturnedRows: useReturningForCheck ? 1 : null,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
override compileDelete(
|
|
239
|
+
op: MutationOperation<AnySchema> & { type: "delete" },
|
|
240
|
+
): CompiledMutation<CompiledQuery> | null {
|
|
241
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
242
|
+
const table = this.getTable(op.schema, op.table);
|
|
243
|
+
const idColumn = table.getIdColumn();
|
|
244
|
+
const versionColumn = table.getVersionColumn();
|
|
245
|
+
|
|
246
|
+
const externalId = this.getExternalId(op.id);
|
|
247
|
+
const versionToCheck = this.getVersionToCheck(op.id, op.checkVersion);
|
|
248
|
+
|
|
249
|
+
// Build WHERE clause that filters by ID and optionally by version
|
|
250
|
+
const conditionsResult =
|
|
251
|
+
versionToCheck !== undefined
|
|
252
|
+
? buildCondition(table.columns, (eb) =>
|
|
253
|
+
eb.and(
|
|
254
|
+
eb(idColumn.ormName, "=", externalId),
|
|
255
|
+
eb(versionColumn.ormName, "=", versionToCheck),
|
|
256
|
+
),
|
|
257
|
+
)
|
|
258
|
+
: buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
|
|
259
|
+
|
|
260
|
+
if (conditionsResult === false) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const conditions: Condition | undefined =
|
|
265
|
+
conditionsResult === true ? undefined : conditionsResult;
|
|
266
|
+
|
|
267
|
+
// Determine if we should use RETURNING-based checking
|
|
268
|
+
// Use RETURNING when driver supports it but doesn't support affected rows reporting
|
|
269
|
+
const useReturningForCheck =
|
|
270
|
+
op.checkVersion &&
|
|
271
|
+
this.driverConfig.supportsReturning &&
|
|
272
|
+
!this.driverConfig.supportsRowsAffected;
|
|
273
|
+
|
|
274
|
+
const query = sqlCompiler.compileDelete(table, {
|
|
275
|
+
where: conditions,
|
|
276
|
+
returning: useReturningForCheck,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
query,
|
|
281
|
+
op: "delete",
|
|
282
|
+
expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
|
|
283
|
+
expectedReturnedRows: useReturningForCheck ? 1 : null,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
override compileCheck(
|
|
288
|
+
op: MutationOperation<AnySchema> & { type: "check" },
|
|
289
|
+
): CompiledMutation<CompiledQuery> {
|
|
290
|
+
const sqlCompiler = this.getSQLCompiler(op.namespace);
|
|
291
|
+
const table = this.getTable(op.schema, op.table);
|
|
292
|
+
const idColumn = table.getIdColumn();
|
|
293
|
+
const versionColumn = table.getVersionColumn();
|
|
294
|
+
|
|
295
|
+
const externalId = op.id.externalId;
|
|
296
|
+
const version = op.id.version;
|
|
297
|
+
|
|
298
|
+
// Build a SELECT 1 query to check if the row exists with the correct version
|
|
299
|
+
const condition = buildCondition(table.columns, (eb) =>
|
|
300
|
+
eb.and(eb(idColumn.ormName, "=", externalId), eb(versionColumn.ormName, "=", version)),
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
if (typeof condition === "boolean") {
|
|
304
|
+
throw new Error("Condition is a boolean, but should be a condition object.");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return {
|
|
308
|
+
query: sqlCompiler.compileCheck(table, condition),
|
|
309
|
+
op: "check",
|
|
310
|
+
expectedAffectedRows: null,
|
|
311
|
+
expectedReturnedRows: 1, // Check that exactly 1 row was returned
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
|
|
3
|
+
import { mapSelect, extendSelect } from "./select-builder";
|
|
4
|
+
|
|
5
|
+
describe("select-builder", () => {
|
|
6
|
+
const testSchema = schema((s) => {
|
|
7
|
+
return s
|
|
8
|
+
.addTable("users", (t) => {
|
|
9
|
+
return t
|
|
10
|
+
.addColumn("id", idColumn())
|
|
11
|
+
.addColumn("name", column("string"))
|
|
12
|
+
.addColumn("email", column("string"))
|
|
13
|
+
.addColumn("age", column("integer").nullable())
|
|
14
|
+
.addColumn("isActive", column("bool"))
|
|
15
|
+
.addColumn("createdAt", column("timestamp"));
|
|
16
|
+
})
|
|
17
|
+
.addTable("posts", (t) => {
|
|
18
|
+
return t
|
|
19
|
+
.addColumn("id", idColumn())
|
|
20
|
+
.addColumn("title", column("string"))
|
|
21
|
+
.addColumn("content", column("string"))
|
|
22
|
+
.addColumn("userId", referenceColumn())
|
|
23
|
+
.addColumn("viewCount", column("integer").defaultTo(0))
|
|
24
|
+
.addColumn("publishedAt", column("timestamp").nullable());
|
|
25
|
+
})
|
|
26
|
+
.addReference("author", {
|
|
27
|
+
type: "one",
|
|
28
|
+
from: { table: "posts", column: "userId" },
|
|
29
|
+
to: { table: "users", column: "id" },
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const usersTable = testSchema.tables.users;
|
|
34
|
+
const postsTable = testSchema.tables.posts;
|
|
35
|
+
|
|
36
|
+
describe("mapSelect", () => {
|
|
37
|
+
it("should map select clause with array of keys", () => {
|
|
38
|
+
const result = mapSelect(["id", "name", "email"], usersTable);
|
|
39
|
+
expect(result).toEqual([
|
|
40
|
+
"users.id as id",
|
|
41
|
+
"users.name as name",
|
|
42
|
+
"users.email as email",
|
|
43
|
+
"users._internalId as _internalId",
|
|
44
|
+
"users._version as _version",
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should map select all columns when true", () => {
|
|
49
|
+
const result = mapSelect(true, usersTable);
|
|
50
|
+
expect(result).toEqual([
|
|
51
|
+
"users.id as id",
|
|
52
|
+
"users.name as name",
|
|
53
|
+
"users.email as email",
|
|
54
|
+
"users.age as age",
|
|
55
|
+
"users.isActive as isActive",
|
|
56
|
+
"users.createdAt as createdAt",
|
|
57
|
+
"users._internalId as _internalId",
|
|
58
|
+
"users._version as _version",
|
|
59
|
+
]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should map select with relation prefix", () => {
|
|
63
|
+
const result = mapSelect(["id", "name"], usersTable, { relation: "author" });
|
|
64
|
+
expect(result).toEqual([
|
|
65
|
+
"users.id as author:id",
|
|
66
|
+
"users.name as author:name",
|
|
67
|
+
"users._internalId as author:_internalId",
|
|
68
|
+
"users._version as author:_version",
|
|
69
|
+
]);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should map select with custom table name", () => {
|
|
73
|
+
const result = mapSelect(["id", "title"], postsTable, { tableName: "p" });
|
|
74
|
+
expect(result).toEqual([
|
|
75
|
+
"p.id as id",
|
|
76
|
+
"p.title as title",
|
|
77
|
+
"p._internalId as _internalId",
|
|
78
|
+
"p._version as _version",
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should map select with both relation and custom table name", () => {
|
|
83
|
+
const result = mapSelect(["id", "title"], postsTable, {
|
|
84
|
+
relation: "posts",
|
|
85
|
+
tableName: "p",
|
|
86
|
+
});
|
|
87
|
+
expect(result).toEqual([
|
|
88
|
+
"p.id as posts:id",
|
|
89
|
+
"p.title as posts:title",
|
|
90
|
+
"p._internalId as posts:_internalId",
|
|
91
|
+
"p._version as posts:_version",
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("should handle single column select", () => {
|
|
96
|
+
const result = mapSelect(["name"], usersTable);
|
|
97
|
+
expect(result).toEqual([
|
|
98
|
+
"users.name as name",
|
|
99
|
+
"users._internalId as _internalId",
|
|
100
|
+
"users._version as _version",
|
|
101
|
+
]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should skip hidden columns when explicitly selecting", () => {
|
|
105
|
+
// When an array is passed, hidden columns should not be included in the select
|
|
106
|
+
// (unless they are in the array), but they should always be added at the end
|
|
107
|
+
const result = mapSelect(["name", "email"], usersTable);
|
|
108
|
+
// Should not duplicate _internalId or _version in the main select
|
|
109
|
+
expect(result).toEqual([
|
|
110
|
+
"users.name as name",
|
|
111
|
+
"users.email as email",
|
|
112
|
+
"users._internalId as _internalId",
|
|
113
|
+
"users._version as _version",
|
|
114
|
+
]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("should always include hidden columns", () => {
|
|
118
|
+
// Hidden columns (_internalId, _version) should always be included
|
|
119
|
+
const result = mapSelect(["name"], usersTable);
|
|
120
|
+
expect(result.some((col) => col.includes("_internalId"))).toBe(true);
|
|
121
|
+
expect(result.some((col) => col.includes("_version"))).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should handle empty select array", () => {
|
|
125
|
+
const result = mapSelect([], usersTable);
|
|
126
|
+
// Should still include hidden columns
|
|
127
|
+
expect(result).toEqual(["users._internalId as _internalId", "users._version as _version"]);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("should work with different table schemas", () => {
|
|
131
|
+
const result = mapSelect(["id", "title", "content"], postsTable);
|
|
132
|
+
expect(result).toEqual([
|
|
133
|
+
"posts.id as id",
|
|
134
|
+
"posts.title as title",
|
|
135
|
+
"posts.content as content",
|
|
136
|
+
"posts._internalId as _internalId",
|
|
137
|
+
"posts._version as _version",
|
|
138
|
+
]);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe("extendSelect", () => {
|
|
143
|
+
it("should extend array select with new key", () => {
|
|
144
|
+
const builder = extendSelect(["name", "email"]);
|
|
145
|
+
builder.extend("id");
|
|
146
|
+
const compiled = builder.compile();
|
|
147
|
+
|
|
148
|
+
expect(compiled.result).toEqual(["name", "email", "id"]);
|
|
149
|
+
expect(compiled.extendedKeys).toEqual(["id"]);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it("should not duplicate existing keys", () => {
|
|
153
|
+
const builder = extendSelect(["name", "email"]);
|
|
154
|
+
builder.extend("name");
|
|
155
|
+
const compiled = builder.compile();
|
|
156
|
+
|
|
157
|
+
expect(compiled.result).toEqual(["name", "email"]);
|
|
158
|
+
expect(compiled.extendedKeys).toEqual([]);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("should handle true select clause", () => {
|
|
162
|
+
const builder = extendSelect(true);
|
|
163
|
+
builder.extend("id");
|
|
164
|
+
const compiled = builder.compile();
|
|
165
|
+
|
|
166
|
+
expect(compiled.result).toBe(true);
|
|
167
|
+
expect(compiled.extendedKeys).toEqual([]);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("should track multiple extended keys", () => {
|
|
171
|
+
const builder = extendSelect(["name"]);
|
|
172
|
+
builder.extend("id");
|
|
173
|
+
builder.extend("email");
|
|
174
|
+
builder.extend("age");
|
|
175
|
+
const compiled = builder.compile();
|
|
176
|
+
|
|
177
|
+
expect(compiled.result).toEqual(["name", "id", "email", "age"]);
|
|
178
|
+
expect(compiled.extendedKeys).toEqual(["id", "email", "age"]);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("should remove extended keys from record", () => {
|
|
182
|
+
const builder = extendSelect(["name", "email"]);
|
|
183
|
+
builder.extend("id");
|
|
184
|
+
const compiled = builder.compile();
|
|
185
|
+
|
|
186
|
+
const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
|
|
187
|
+
compiled.removeExtendedKeys(record);
|
|
188
|
+
|
|
189
|
+
expect(record).toEqual({ name: "John", email: "john@example.com", age: 30 });
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("should not remove non-extended keys", () => {
|
|
193
|
+
const builder = extendSelect(["name", "email", "id"]);
|
|
194
|
+
builder.extend("age");
|
|
195
|
+
const compiled = builder.compile();
|
|
196
|
+
|
|
197
|
+
const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
|
|
198
|
+
compiled.removeExtendedKeys(record);
|
|
199
|
+
|
|
200
|
+
expect(record).toEqual({ id: "123", name: "John", email: "john@example.com" });
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("should handle empty extended keys", () => {
|
|
204
|
+
const builder = extendSelect(["name", "email"]);
|
|
205
|
+
const compiled = builder.compile();
|
|
206
|
+
|
|
207
|
+
const record = { name: "John", email: "john@example.com" };
|
|
208
|
+
compiled.removeExtendedKeys(record);
|
|
209
|
+
|
|
210
|
+
expect(record).toEqual({ name: "John", email: "john@example.com" });
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should handle multiple extends with duplicates", () => {
|
|
214
|
+
const builder = extendSelect(["name"]);
|
|
215
|
+
builder.extend("id");
|
|
216
|
+
builder.extend("email");
|
|
217
|
+
builder.extend("id"); // Duplicate
|
|
218
|
+
const compiled = builder.compile();
|
|
219
|
+
|
|
220
|
+
// Should not duplicate 'id'
|
|
221
|
+
expect(compiled.result).toEqual(["name", "id", "email"]);
|
|
222
|
+
expect(compiled.extendedKeys).toEqual(["id", "email"]);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("should return mutated record from removeExtendedKeys", () => {
|
|
226
|
+
const builder = extendSelect(["name"]);
|
|
227
|
+
builder.extend("id");
|
|
228
|
+
const compiled = builder.compile();
|
|
229
|
+
|
|
230
|
+
const record = { id: "123", name: "John" };
|
|
231
|
+
const result = compiled.removeExtendedKeys(record);
|
|
232
|
+
|
|
233
|
+
// Should return the same record (mutated)
|
|
234
|
+
expect(result).toBe(record);
|
|
235
|
+
expect(result).toEqual({ name: "John" });
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("should handle extending with empty original select", () => {
|
|
239
|
+
const builder = extendSelect([]);
|
|
240
|
+
builder.extend("id");
|
|
241
|
+
builder.extend("name");
|
|
242
|
+
const compiled = builder.compile();
|
|
243
|
+
|
|
244
|
+
expect(compiled.result).toEqual(["id", "name"]);
|
|
245
|
+
expect(compiled.extendedKeys).toEqual(["id", "name"]);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("should preserve original select order", () => {
|
|
249
|
+
const builder = extendSelect(["email", "name"]);
|
|
250
|
+
builder.extend("id");
|
|
251
|
+
const compiled = builder.compile();
|
|
252
|
+
|
|
253
|
+
expect(compiled.result).toEqual(["email", "name", "id"]);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { AnyTable } from "../../../schema/create";
|
|
2
|
+
import type { AnySelectClause } from "../../../query/simple-query-interface";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps a select clause to SQL column names with optional aliases.
|
|
6
|
+
*
|
|
7
|
+
* Converts application-level select clauses (either array of keys or "select all")
|
|
8
|
+
* into SQL-compatible column selections with proper aliasing for relations.
|
|
9
|
+
*
|
|
10
|
+
* @param select - The select clause (array of keys or true for all columns)
|
|
11
|
+
* @param table - The table schema containing column definitions
|
|
12
|
+
* @param options - Optional configuration
|
|
13
|
+
* @param options.relation - Relation name to prefix in aliases (for joined data)
|
|
14
|
+
* @param options.tableName - Override the table name in the SQL (defaults to table.name)
|
|
15
|
+
* @returns Array of SQL select strings in the format "tableName.columnName as alias"
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export function mapSelect(
|
|
19
|
+
select: AnySelectClause,
|
|
20
|
+
table: AnyTable,
|
|
21
|
+
options: {
|
|
22
|
+
relation?: string;
|
|
23
|
+
tableName?: string;
|
|
24
|
+
} = {},
|
|
25
|
+
): string[] {
|
|
26
|
+
const { relation, tableName = table.name } = options;
|
|
27
|
+
const out: string[] = [];
|
|
28
|
+
const keys = Array.isArray(select) ? select : Object.keys(table.columns);
|
|
29
|
+
|
|
30
|
+
for (const key of keys) {
|
|
31
|
+
const col = table.columns[key];
|
|
32
|
+
|
|
33
|
+
// Skip hidden columns when explicitly selecting
|
|
34
|
+
if (Array.isArray(select) && col.isHidden) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Add the column to the select list
|
|
39
|
+
const name = relation ? `${relation}:${key}` : key;
|
|
40
|
+
out.push(`${tableName}.${col.name} as ${name}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Always include hidden columns (for FragnoId construction with internal ID and version)
|
|
44
|
+
for (const key in table.columns) {
|
|
45
|
+
const col = table.columns[key];
|
|
46
|
+
if (col.isHidden && !keys.includes(key)) {
|
|
47
|
+
const name = relation ? `${relation}:${key}` : key;
|
|
48
|
+
out.push(`${tableName}.${col.name} as ${name}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Result type from compiling a select clause with extensions.
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export interface CompiledSelect {
|
|
60
|
+
/**
|
|
61
|
+
* The final select clause to use in the query
|
|
62
|
+
*/
|
|
63
|
+
result: AnySelectClause;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Keys that were added to the select clause (not originally requested)
|
|
67
|
+
*/
|
|
68
|
+
extendedKeys: string[];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Removes the extended keys from a record (mutates the record).
|
|
72
|
+
* Used to clean up keys that were only needed for join operations.
|
|
73
|
+
*
|
|
74
|
+
* @param record - The record to remove extended keys from
|
|
75
|
+
* @returns The same record with extended keys removed
|
|
76
|
+
*/
|
|
77
|
+
removeExtendedKeys: (record: Record<string, unknown>) => Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Builder for extending a select clause with additional keys.
|
|
82
|
+
* @internal
|
|
83
|
+
*/
|
|
84
|
+
export interface SelectBuilder {
|
|
85
|
+
/**
|
|
86
|
+
* Adds a key to the select clause if not already present.
|
|
87
|
+
* Tracks which keys were added for later removal.
|
|
88
|
+
*
|
|
89
|
+
* @param key - The key to add to the select clause
|
|
90
|
+
*/
|
|
91
|
+
extend: (key: string) => void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Compiles the select clause into its final form.
|
|
95
|
+
*
|
|
96
|
+
* @returns The compiled select information
|
|
97
|
+
*/
|
|
98
|
+
compile: () => CompiledSelect;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates a builder that can extend a select clause with additional keys.
|
|
103
|
+
*
|
|
104
|
+
* This is useful when you need to temporarily include columns for join operations
|
|
105
|
+
* or other internal processing, but don't want them in the final result.
|
|
106
|
+
*
|
|
107
|
+
* @param original - The original select clause from the user
|
|
108
|
+
* @returns A select builder with extend() and compile() methods
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
export function extendSelect(original: AnySelectClause): SelectBuilder {
|
|
112
|
+
const select = Array.isArray(original) ? new Set(original) : true;
|
|
113
|
+
const extendedKeys: string[] = [];
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
extend(key) {
|
|
117
|
+
if (select === true || select.has(key)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
select.add(key);
|
|
122
|
+
extendedKeys.push(key);
|
|
123
|
+
},
|
|
124
|
+
compile() {
|
|
125
|
+
return {
|
|
126
|
+
result: select instanceof Set ? Array.from(select) : true,
|
|
127
|
+
extendedKeys,
|
|
128
|
+
removeExtendedKeys(record) {
|
|
129
|
+
for (const key of extendedKeys) {
|
|
130
|
+
delete record[key];
|
|
131
|
+
}
|
|
132
|
+
return record;
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|