@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.
Files changed (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1,636 +0,0 @@
1
- import * as Drizzle from "drizzle-orm";
2
- import type { AnyColumn, AnySchema, AnyTable, FragnoId } from "../../schema/create";
3
- import { Column } from "../../schema/create";
4
- import type {
5
- CompiledMutation,
6
- MutationOperation,
7
- RetrievalOperation,
8
- UOWCompiler,
9
- } from "../../query/unit-of-work";
10
- import { buildCondition, type Condition } from "../../query/condition-builder";
11
- import {
12
- type ColumnType,
13
- type TableType,
14
- type TableNameMapper,
15
- parseDrizzle,
16
- type DBType,
17
- createTableNameMapper,
18
- } from "./shared";
19
- import { encodeValues, ReferenceSubquery } from "../../query/result-transform";
20
- import { serialize } from "../../schema/serialize";
21
- import { decodeCursor, serializeCursorValues } from "../../query/cursor";
22
- import type { CompiledJoin } from "../../query/orm/orm";
23
- import { getOrderedJoinColumns } from "./join-column-utils";
24
- import type { ConnectionPool } from "../../shared/connection-pool";
25
-
26
- export type DrizzleCompiledQuery = {
27
- sql: string;
28
- params: unknown[];
29
- };
30
-
31
- /**
32
- * Create a Drizzle-specific Unit of Work compiler
33
- *
34
- * This compiler translates UOW operations into Drizzle query functions
35
- * that can be executed as a batch/transaction.
36
- *
37
- * @param pool - Connection pool for acquiring database connections
38
- * @param provider - SQL provider (sqlite, mysql, postgresql)
39
- * @param mapper - Optional table name mapper for namespace prefixing (fallback for operations without explicit namespace)
40
- * @returns A UOWCompiler instance for Drizzle
41
- */
42
- export function createDrizzleUOWCompiler(
43
- pool: ConnectionPool<DBType>,
44
- provider: "sqlite" | "mysql" | "postgresql",
45
- mapper?: TableNameMapper,
46
- ): UOWCompiler<DrizzleCompiledQuery> {
47
- // Get db synchronously for compilation (doesn't execute, just builds SQL)
48
- // TODO: We don't even need a Drizzle instance with a db client attached here. `drizzle({ schema })` is enough.
49
- const dbRaw = pool.getDatabaseSync();
50
- const [db, drizzleTables] = parseDrizzle(dbRaw);
51
-
52
- /**
53
- * Get the mapper for a specific operation
54
- * Uses operation's namespace if provided, otherwise falls back to the default mapper
55
- */
56
- function getMapperForOperation(namespace: string | undefined): TableNameMapper | undefined {
57
- if (namespace) {
58
- return createTableNameMapper(namespace);
59
- }
60
- return mapper;
61
- }
62
-
63
- /**
64
- * Convert a Fragno table to a Drizzle table
65
- * @throws Error if table is not found in Drizzle schema
66
- */
67
- function toDrizzleTable(table: AnyTable, namespace: string | undefined): TableType {
68
- // Get the mapper for this operation's namespace
69
- const opMapper = getMapperForOperation(namespace);
70
-
71
- // Map logical table name to physical table name using the operation-specific mapper
72
- const physicalTableName = opMapper ? opMapper.toPhysical(table.ormName) : table.ormName;
73
- const out = drizzleTables[physicalTableName];
74
- if (out) {
75
- return out;
76
- }
77
-
78
- throw new Error(
79
- `[Drizzle] Unknown table name ${physicalTableName} (logical: ${table.ormName}), is it included in your Drizzle schema?`,
80
- );
81
- }
82
-
83
- /**
84
- * Convert a Fragno column to a Drizzle column
85
- * @throws Error if column is not found in Drizzle table
86
- */
87
- function toDrizzleColumn(
88
- schema: AnySchema,
89
- namespace: string | undefined,
90
- col: AnyColumn,
91
- ): ColumnType {
92
- const fragnoTable = schema.tables[col.tableName];
93
- if (!fragnoTable) {
94
- throw new Error(`[Drizzle] Unknown table ${col.tableName} for column ${col.ormName}.`);
95
- }
96
-
97
- const table = toDrizzleTable(fragnoTable, namespace);
98
- const out = table[col.ormName];
99
- if (out) {
100
- return out;
101
- }
102
-
103
- throw new Error(`[Drizzle] Unknown column name ${col.ormName} in ${fragnoTable.ormName}.`);
104
- }
105
-
106
- /**
107
- * Build a WHERE clause from a condition using Drizzle's query builder
108
- */
109
- function buildWhere(
110
- schema: AnySchema,
111
- namespace: string | undefined,
112
- condition: Condition,
113
- ): Drizzle.SQL | undefined {
114
- if (condition.type === "compare") {
115
- const left = toDrizzleColumn(schema, namespace, condition.a);
116
- const op = condition.operator;
117
- let right = condition.b;
118
- if (right instanceof Column) {
119
- right = toDrizzleColumn(schema, namespace, right);
120
- } else {
121
- // Handle string references - convert external ID to internal ID via subquery
122
- if (condition.a.role === "reference" && typeof right === "string") {
123
- // Find the table that contains this column
124
- const table = Object.values(schema.tables).find((t) =>
125
- Object.values(t.columns).includes(condition.a),
126
- );
127
- if (table) {
128
- // Find relation that uses this column
129
- const relation = Object.values(table.relations).find((rel) =>
130
- rel.on.some(([localCol]) => localCol === condition.a.ormName),
131
- );
132
- if (relation) {
133
- const refTable = relation.table;
134
- const internalIdCol = refTable.getInternalIdColumn();
135
- const idCol = refTable.getIdColumn();
136
- const physicalTableName = mapper
137
- ? mapper.toPhysical(refTable.ormName)
138
- : refTable.ormName;
139
-
140
- // Build a SQL subquery using Drizzle's sql template
141
- right = Drizzle.sql`(select ${Drizzle.sql.identifier(internalIdCol.name)} from ${Drizzle.sql.identifier(physicalTableName)} where ${Drizzle.sql.identifier(idCol.name)} = ${right} limit 1)`;
142
- }
143
- }
144
- } else {
145
- // Serialize non-Column values (e.g., FragnoId -> string, Date -> number for SQLite)
146
- right = serialize(right, condition.a, provider);
147
- }
148
- }
149
-
150
- switch (op) {
151
- case "=":
152
- return Drizzle.eq(left, right);
153
- case "!=":
154
- return Drizzle.ne(left, right);
155
- case ">":
156
- return Drizzle.gt(left, right);
157
- case ">=":
158
- return Drizzle.gte(left, right);
159
- case "<":
160
- return Drizzle.lt(left, right);
161
- case "<=":
162
- return Drizzle.lte(left, right);
163
- case "in": {
164
- return Drizzle.inArray(left, right as never[]);
165
- }
166
- case "not in":
167
- return Drizzle.notInArray(left, right as never[]);
168
- case "is":
169
- return right === null ? Drizzle.isNull(left) : Drizzle.eq(left, right);
170
- case "is not":
171
- return right === null ? Drizzle.isNotNull(left) : Drizzle.ne(left, right);
172
- case "contains": {
173
- right =
174
- typeof right === "string" ? `%${right}%` : Drizzle.sql`concat('%', ${right}, '%')`;
175
- return Drizzle.like(left, right as string);
176
- }
177
- case "not contains": {
178
- right =
179
- typeof right === "string" ? `%${right}%` : Drizzle.sql`concat('%', ${right}, '%')`;
180
- return Drizzle.notLike(left, right as string);
181
- }
182
- case "ends with": {
183
- right = typeof right === "string" ? `%${right}` : Drizzle.sql`concat('%', ${right})`;
184
- return Drizzle.like(left, right as string);
185
- }
186
- case "not ends with": {
187
- right = typeof right === "string" ? `%${right}` : Drizzle.sql`concat('%', ${right})`;
188
- return Drizzle.notLike(left, right as string);
189
- }
190
- case "starts with": {
191
- right = typeof right === "string" ? `${right}%` : Drizzle.sql`concat(${right}, '%')`;
192
- return Drizzle.like(left, right as string);
193
- }
194
- case "not starts with": {
195
- right = typeof right === "string" ? `${right}%` : Drizzle.sql`concat(${right}, '%')`;
196
- return Drizzle.notLike(left, right as string);
197
- }
198
-
199
- default:
200
- throw new Error(`Unsupported operator: ${op}`);
201
- }
202
- }
203
-
204
- if (condition.type === "and") {
205
- return Drizzle.and(...condition.items.map((item) => buildWhere(schema, namespace, item)));
206
- }
207
-
208
- if (condition.type === "not") {
209
- const result = buildWhere(schema, namespace, condition.item);
210
- if (!result) {
211
- return;
212
- }
213
-
214
- return Drizzle.not(result);
215
- }
216
-
217
- return Drizzle.or(...condition.items.map((item) => buildWhere(schema, namespace, item)));
218
- }
219
-
220
- /**
221
- * Process reference subqueries in encoded values, converting them to Drizzle SQL subqueries
222
- */
223
- function processReferenceSubqueries(values: Record<string, unknown>): Record<string, unknown> {
224
- const processed: Record<string, unknown> = {};
225
-
226
- for (const [key, value] of Object.entries(values)) {
227
- if (value instanceof ReferenceSubquery) {
228
- const refTable = value.referencedTable;
229
- const externalId = value.externalIdValue;
230
- const internalIdCol = refTable.getInternalIdColumn();
231
- const idCol = refTable.getIdColumn();
232
-
233
- // Map logical table name to physical table name using the mapper
234
- const physicalTableName = mapper ? mapper.toPhysical(refTable.ormName) : refTable.ormName;
235
-
236
- // Build a SQL subquery using Drizzle's sql template
237
- // This creates a subquery: (SELECT _internalId FROM table WHERE id = ? LIMIT 1)
238
- // Safe cast: we're building a SQL subquery that returns a single bigint value
239
- processed[key] =
240
- Drizzle.sql`(select ${Drizzle.sql.identifier(internalIdCol.name)} from ${Drizzle.sql.identifier(physicalTableName)} where ${Drizzle.sql.identifier(idCol.name)} = ${externalId} limit 1)`;
241
- } else {
242
- processed[key] = value;
243
- }
244
- }
245
-
246
- return processed;
247
- }
248
-
249
- /**
250
- * Get table from schema by name
251
- * @throws Error if table is not found in schema
252
- */
253
- function getTable(schema: AnySchema, name: unknown): AnyTable {
254
- const table = schema.tables[name as string];
255
- if (!table) {
256
- throw new Error(`Invalid table name ${name}.`);
257
- }
258
- return table;
259
- }
260
-
261
- /**
262
- * Get the version to check for a given ID and checkVersion flag.
263
- * @returns The version to check or undefined if no check is required.
264
- * @throws Error if the ID is a string and checkVersion is true.
265
- */
266
- function getVersionToCheck(id: FragnoId | string, checkVersion: boolean): number | undefined {
267
- if (!checkVersion) {
268
- return undefined;
269
- }
270
-
271
- if (typeof id === "string") {
272
- throw new Error(
273
- `Cannot use checkVersion with a string ID. Version checking requires a FragnoId with version information.`,
274
- );
275
- }
276
-
277
- return id.version;
278
- }
279
-
280
- /**
281
- * Process joins recursively to support nested joins with orderBy and limit
282
- */
283
- function processJoins(
284
- schema: AnySchema,
285
- namespace: string | undefined,
286
- joins: CompiledJoin[],
287
- ): Record<string, Drizzle.DBQueryConfig<"many", boolean>> {
288
- const result: Record<string, Drizzle.DBQueryConfig<"many", boolean>> = {};
289
-
290
- for (const join of joins) {
291
- const { options, relation } = join;
292
-
293
- if (!options) {
294
- continue;
295
- }
296
-
297
- const targetTable = relation.table;
298
- const joinName = relation.name;
299
-
300
- // Build columns for this join using shared utility
301
- const selectOption = options.select === undefined ? true : options.select;
302
- const orderedColumns = getOrderedJoinColumns(targetTable, selectOption);
303
- const joinColumns: Record<string, boolean> = {};
304
- for (const colName of orderedColumns) {
305
- joinColumns[colName] = true;
306
- }
307
-
308
- // Build orderBy for this join
309
- let joinOrderBy: Drizzle.SQL[] | undefined;
310
- if (options.orderBy && options.orderBy.length > 0) {
311
- joinOrderBy = options.orderBy.map(([col, direction]) => {
312
- const drizzleCol = toDrizzleColumn(schema, namespace, col);
313
- return direction === "asc" ? Drizzle.asc(drizzleCol) : Drizzle.desc(drizzleCol);
314
- });
315
- }
316
-
317
- // Build WHERE clause for this join if provided
318
- let joinWhere: Drizzle.SQL | undefined;
319
- if (options.where) {
320
- joinWhere = buildWhere(schema, namespace, options.where);
321
- }
322
-
323
- // Build the join config
324
- const joinConfig: Drizzle.DBQueryConfig<"many", boolean> = {
325
- columns: joinColumns,
326
- orderBy: joinOrderBy,
327
- limit: options.limit,
328
- where: joinWhere,
329
- };
330
-
331
- // Recursively process nested joins
332
- if (options.join && options.join.length > 0) {
333
- joinConfig.with = processJoins(schema, namespace, options.join);
334
- }
335
-
336
- result[joinName] = joinConfig;
337
- }
338
-
339
- return result;
340
- }
341
-
342
- return {
343
- compileRetrievalOperation(op: RetrievalOperation<AnySchema>): DrizzleCompiledQuery | null {
344
- const schema = op.schema;
345
- switch (op.type) {
346
- case "count": {
347
- // Build WHERE clause
348
- let whereClause: Drizzle.SQL | undefined;
349
- if (op.options.where) {
350
- const condition = buildCondition(op.table.columns, op.options.where);
351
- if (condition === false) {
352
- // Never matches - return null
353
- return null;
354
- }
355
- if (condition !== true) {
356
- whereClause = buildWhere(schema, op.namespace, condition);
357
- }
358
- }
359
-
360
- const drizzleTable = toDrizzleTable(op.table, op.namespace);
361
- const query = db.select({ count: Drizzle.count() }).from(drizzleTable);
362
-
363
- const compiledQuery = whereClause ? query.where(whereClause).toSQL() : query.toSQL();
364
- return compiledQuery;
365
- }
366
-
367
- case "find": {
368
- const {
369
- useIndex: _useIndex,
370
- orderByIndex,
371
- joins,
372
- after,
373
- before,
374
- pageSize,
375
- ...findOptions
376
- } = op.options;
377
-
378
- // Get index columns for ordering and cursor pagination
379
- let indexColumns: AnyColumn[] = [];
380
- let orderDirection: "asc" | "desc" = "asc";
381
-
382
- if (orderByIndex) {
383
- const index = op.table.indexes[orderByIndex.indexName];
384
- orderDirection = orderByIndex.direction;
385
-
386
- if (!index) {
387
- // If _primary index doesn't exist, fall back to ID column
388
- if (orderByIndex.indexName === "_primary") {
389
- indexColumns = [op.table.getIdColumn()];
390
- } else {
391
- throw new Error(
392
- `Index "${orderByIndex.indexName}" not found on table "${op.table.name}"`,
393
- );
394
- }
395
- } else {
396
- indexColumns = index.columns;
397
- }
398
- }
399
-
400
- // Convert orderByIndex to orderBy format
401
- let orderBy: Drizzle.SQL[] | undefined;
402
- if (indexColumns.length > 0) {
403
- orderBy = indexColumns.map((col) => {
404
- const drizzleCol = toDrizzleColumn(schema, op.namespace, col);
405
- return orderDirection === "asc" ? Drizzle.asc(drizzleCol) : Drizzle.desc(drizzleCol);
406
- });
407
- }
408
-
409
- // Build query configuration
410
- const columns: Record<string, boolean> = {};
411
- const select = findOptions.select;
412
-
413
- if (select === true || select === undefined) {
414
- for (const col of Object.values(op.table.columns)) {
415
- columns[col.ormName] = true;
416
- }
417
- } else {
418
- for (const k of select) {
419
- columns[op.table.columns[k].ormName] = true;
420
- }
421
- // Always include hidden columns (for FragnoId construction with internal ID and version)
422
- for (const col of Object.values(op.table.columns)) {
423
- if (col.isHidden && !columns[col.ormName]) {
424
- columns[col.ormName] = true;
425
- }
426
- }
427
- }
428
-
429
- // Build WHERE clause with cursor conditions
430
- const whereClauses: Drizzle.SQL[] = [];
431
-
432
- // Add user-defined where clause
433
- if (findOptions.where) {
434
- const condition = buildCondition(op.table.columns, findOptions.where);
435
- if (condition === false) {
436
- // Never matches - return null to indicate this query should be skipped
437
- return null;
438
- }
439
- if (condition !== true) {
440
- const clause = buildWhere(schema, op.namespace, condition);
441
- if (clause) {
442
- whereClauses.push(clause);
443
- }
444
- }
445
- }
446
-
447
- // Add cursor-based pagination conditions
448
- if ((after || before) && indexColumns.length > 0) {
449
- const cursor = after || before;
450
- // Decode cursor if it's a string, otherwise use it as-is
451
- const cursorObj = typeof cursor === "string" ? decodeCursor(cursor!) : cursor!;
452
- const serializedValues = serializeCursorValues(cursorObj, indexColumns, provider);
453
-
454
- // Build tuple comparison for cursor pagination
455
- // For "after" with "asc": (col1, col2, ...) > (val1, val2, ...)
456
- // For "before" with "desc": reverse the comparison
457
- const isAfter = !!after;
458
- const useGreaterThan =
459
- (isAfter && orderDirection === "asc") || (!isAfter && orderDirection === "desc");
460
-
461
- if (indexColumns.length === 1) {
462
- // Simple single-column case
463
- const col = toDrizzleColumn(schema, op.namespace, indexColumns[0]!);
464
- const val = serializedValues[indexColumns[0]!.ormName];
465
- whereClauses.push(useGreaterThan ? Drizzle.gt(col, val) : Drizzle.lt(col, val));
466
- } else {
467
- // Multi-column tuple comparison using SQL
468
- const drizzleCols = indexColumns.map((c) => toDrizzleColumn(schema, op.namespace, c));
469
- const vals = indexColumns.map((c) => serializedValues[c.ormName]);
470
- const operator = useGreaterThan ? ">" : "<";
471
- // Safe cast: building a SQL comparison expression for cursor pagination
472
- // Build the tuple comparison: (col1, col2) > (val1, val2)
473
- const colsSQL = Drizzle.sql.join(drizzleCols, Drizzle.sql.raw(", "));
474
- const valsSQL = Drizzle.sql.join(
475
- vals.map((v) => Drizzle.sql`${v}`),
476
- Drizzle.sql.raw(", "),
477
- );
478
- whereClauses.push(
479
- Drizzle.sql`(${colsSQL}) ${Drizzle.sql.raw(operator)} (${valsSQL})`,
480
- );
481
- }
482
- }
483
-
484
- const whereClause = whereClauses.length > 0 ? Drizzle.and(...whereClauses) : undefined;
485
-
486
- const queryConfig: Drizzle.DBQueryConfig<"many", boolean> = {
487
- columns,
488
- limit: pageSize,
489
- where: whereClause,
490
- orderBy,
491
- with: {},
492
- };
493
-
494
- // Process joins recursively to support nested joins
495
- if (joins) {
496
- queryConfig.with = processJoins(schema, op.namespace, joins);
497
- }
498
-
499
- // For multi-schema support: get the mapper for the operation's namespace
500
- const opMapper = getMapperForOperation(op.namespace);
501
- const physicalTableName = opMapper
502
- ? opMapper.toPhysical(op.table.ormName)
503
- : op.table.ormName;
504
- const tableQuery = db.query[physicalTableName];
505
-
506
- if (!tableQuery) {
507
- throw new Error(
508
- `[Drizzle] Table ${op.table.ormName} (physical: ${physicalTableName}) not found in db.query. ` +
509
- `Available tables: ${Object.keys(db.query).join(", ")}`,
510
- );
511
- }
512
-
513
- const compiledQuery = tableQuery.findMany(queryConfig).toSQL();
514
- return compiledQuery;
515
- }
516
- }
517
- },
518
-
519
- compileMutationOperation(
520
- op: MutationOperation<AnySchema>,
521
- ): CompiledMutation<DrizzleCompiledQuery> | null {
522
- const schema = op.schema;
523
- switch (op.type) {
524
- case "create": {
525
- const table = getTable(schema, op.table);
526
- const drizzleTable = toDrizzleTable(table, op.namespace);
527
- // encodeValues now handles runtime defaults automatically
528
- const encodedValues = encodeValues(op.values, table, true, provider);
529
- const values = processReferenceSubqueries(encodedValues);
530
-
531
- const compiledQuery = db.insert(drizzleTable).values(values).toSQL();
532
- return {
533
- query: compiledQuery,
534
- expectedAffectedRows: null, // creates don't need affected row checks
535
- };
536
- }
537
-
538
- case "update": {
539
- const table = getTable(schema, op.table);
540
- const idColumn = table.getIdColumn();
541
- const versionColumn = table.getVersionColumn();
542
- const drizzleTable = toDrizzleTable(table, op.namespace);
543
-
544
- const externalId = typeof op.id === "string" ? op.id : op.id.externalId;
545
- const versionToCheck = getVersionToCheck(op.id, op.checkVersion);
546
-
547
- // Build WHERE clause that filters by ID and optionally by version
548
- const condition =
549
- versionToCheck !== undefined
550
- ? buildCondition(table.columns, (eb) =>
551
- eb.and(
552
- eb(idColumn.ormName, "=", externalId),
553
- eb(versionColumn.ormName, "=", versionToCheck),
554
- ),
555
- )
556
- : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
557
-
558
- // Handle boolean cases
559
- if (condition === false) {
560
- // Never matches - skip this operation
561
- return null;
562
- }
563
-
564
- const whereClause =
565
- condition === true ? undefined : buildWhere(schema, op.namespace, condition);
566
- const encodedSetValues = encodeValues(op.set, table, false, provider);
567
- const setValues = processReferenceSubqueries(encodedSetValues);
568
-
569
- // Automatically increment _version for optimistic concurrency control
570
- // Safe cast: we're building a SQL expression for incrementing the version
571
- setValues[versionColumn.ormName] = Drizzle.sql.raw(
572
- `COALESCE(${versionColumn.ormName}, 0) + 1`,
573
- ) as unknown;
574
-
575
- const compiledQuery = db.update(drizzleTable).set(setValues).where(whereClause).toSQL();
576
- return {
577
- query: compiledQuery,
578
- expectedAffectedRows: op.checkVersion ? 1 : null,
579
- };
580
- }
581
-
582
- case "delete": {
583
- const table = getTable(schema, op.table);
584
- const idColumn = table.getIdColumn();
585
- const versionColumn = table.getVersionColumn();
586
- const drizzleTable = toDrizzleTable(table, op.namespace);
587
-
588
- if (!op.id) {
589
- throw new Error(
590
- `[Drizzle] Delete operation on table "${op.table}" has undefined id. ` +
591
- `Make sure you're passing a valid FragnoId or string ID.`,
592
- );
593
- }
594
-
595
- const externalId = typeof op.id === "string" ? op.id : op.id.externalId;
596
-
597
- if (!externalId) {
598
- throw new Error(
599
- `[Drizzle] Delete operation on table "${op.table}" has invalid id. ` +
600
- `The FragnoId object exists but has no externalId. ` +
601
- `Received: ${JSON.stringify(op.id)}. ` +
602
- `Make sure the record was properly loaded from the database.`,
603
- );
604
- }
605
- const versionToCheck = getVersionToCheck(op.id, op.checkVersion);
606
-
607
- // Build WHERE clause that filters by ID and optionally by version
608
- const condition =
609
- versionToCheck !== undefined
610
- ? buildCondition(table.columns, (eb) =>
611
- eb.and(
612
- eb(idColumn.ormName, "=", externalId),
613
- eb(versionColumn.ormName, "=", versionToCheck),
614
- ),
615
- )
616
- : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
617
-
618
- // Handle boolean cases
619
- if (condition === false) {
620
- // Never matches - skip this operation
621
- return null;
622
- }
623
-
624
- const whereClause =
625
- condition === true ? undefined : buildWhere(schema, op.namespace, condition);
626
-
627
- const compiledQuery = db.delete(drizzleTable).where(whereClause).toSQL();
628
- return {
629
- query: compiledQuery,
630
- expectedAffectedRows: op.checkVersion ? 1 : null,
631
- };
632
- }
633
- }
634
- },
635
- };
636
- }