@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,318 +0,0 @@
1
- import type { CompiledQuery, Kysely } from "kysely";
2
- import type { AnyColumn, AnySchema, FragnoId } from "../../schema/create";
3
- import type {
4
- CompiledMutation,
5
- MutationOperation,
6
- RetrievalOperation,
7
- UOWCompiler,
8
- } from "../../query/unit-of-work";
9
- import { createKyselyQueryCompiler } from "./kysely-query-compiler";
10
- import { createKyselyQueryBuilder } from "./kysely-query-builder";
11
- import { buildCondition, type Condition } from "../../query/condition-builder";
12
- import { decodeCursor, serializeCursorValues } from "../../query/cursor";
13
- import type { AnySelectClause } from "../../query/query";
14
- import { type TableNameMapper, createTableNameMapper } from "./kysely-shared";
15
- import type { ConnectionPool } from "../../shared/connection-pool";
16
- import type { SQLProvider } from "../../shared/providers";
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- type KyselyAny = Kysely<any>;
20
-
21
- /**
22
- * Create a Kysely-specific Unit of Work compiler
23
- *
24
- * This compiler translates UOW operations into Kysely CompiledQuery objects
25
- * that can be executed as a batch/transaction.
26
- *
27
- * @param pool - Connection pool for acquiring database connections
28
- * @param provider - SQL provider (postgresql, mysql, sqlite, etc.)
29
- * @param mapper - Optional table name mapper for namespace prefixing (fallback for operations without explicit namespace)
30
- * @returns A UOWCompiler instance for Kysely
31
- */
32
- export function createKyselyUOWCompiler(
33
- pool: ConnectionPool<KyselyAny>,
34
- provider: SQLProvider,
35
- mapper?: TableNameMapper,
36
- ): UOWCompiler<CompiledQuery> {
37
- // Get kysely instance for query building (compilation doesn't execute, just builds SQL)
38
- const kysely = pool.getDatabaseSync();
39
-
40
- /**
41
- * Get the mapper for a specific operation
42
- * Uses operation's namespace if provided, otherwise falls back to the default mapper
43
- */
44
- function getMapperForOperation(namespace: string | undefined): TableNameMapper | undefined {
45
- if (namespace) {
46
- return createTableNameMapper(namespace);
47
- }
48
- return mapper;
49
- }
50
-
51
- // Cache query compilers and builders by namespace for performance
52
- const compilerCache = new Map<string | undefined, ReturnType<typeof createKyselyQueryCompiler>>();
53
- const builderCache = new Map<string | undefined, ReturnType<typeof createKyselyQueryBuilder>>();
54
-
55
- function getQueryCompiler(schema: AnySchema, namespace: string | undefined) {
56
- const cacheKey = namespace;
57
- let compiler = compilerCache.get(cacheKey);
58
- if (!compiler) {
59
- const opMapper = getMapperForOperation(namespace);
60
- compiler = createKyselyQueryCompiler(schema, pool, provider, opMapper);
61
- compilerCache.set(cacheKey, compiler);
62
- }
63
- return compiler;
64
- }
65
-
66
- function getQueryBuilder(namespace: string | undefined) {
67
- const cacheKey = namespace;
68
- let builder = builderCache.get(cacheKey);
69
- if (!builder) {
70
- const opMapper = getMapperForOperation(namespace);
71
- builder = createKyselyQueryBuilder(kysely, provider, opMapper);
72
- builderCache.set(cacheKey, builder);
73
- }
74
- return builder;
75
- }
76
-
77
- function toTable(schema: AnySchema, name: unknown) {
78
- const table = schema.tables[name as string];
79
- if (!table) {
80
- throw new Error(`Invalid table name ${name}.`);
81
- }
82
- return table;
83
- }
84
-
85
- return {
86
- compileRetrievalOperation(op: RetrievalOperation<AnySchema>): CompiledQuery | null {
87
- const queryCompiler = getQueryCompiler(op.schema, op.namespace);
88
- switch (op.type) {
89
- case "count": {
90
- return queryCompiler.count(op.table.name, {
91
- where: op.options.where,
92
- });
93
- }
94
-
95
- case "find": {
96
- // Map UOW FindOptions to query compiler's FindManyOptions
97
- const {
98
- useIndex: _useIndex,
99
- orderByIndex,
100
- joins: join,
101
- after,
102
- before,
103
- pageSize,
104
- ...findManyOptions
105
- } = op.options;
106
-
107
- // Get index columns for ordering and cursor pagination
108
- let indexColumns: AnyColumn[] = [];
109
- let orderDirection: "asc" | "desc" = "asc";
110
-
111
- if (orderByIndex) {
112
- const index = op.table.indexes[orderByIndex.indexName];
113
- orderDirection = orderByIndex.direction;
114
-
115
- if (!index) {
116
- // If _primary index doesn't exist, fall back to internal ID column
117
- // (which is the actual primary key and maintains insertion order)
118
- if (orderByIndex.indexName === "_primary") {
119
- indexColumns = [op.table.getIdColumn()];
120
- } else {
121
- throw new Error(
122
- `Index "${orderByIndex.indexName}" not found on table "${op.table.name}"`,
123
- );
124
- }
125
- } else {
126
- // Order by all columns in the index with the specified direction
127
- indexColumns = index.columns;
128
- }
129
- }
130
-
131
- // Convert orderByIndex to orderBy format
132
- let orderBy: [AnyColumn, "asc" | "desc"][] | undefined;
133
- if (indexColumns.length > 0) {
134
- orderBy = indexColumns.map((col) => [col, orderDirection]);
135
- }
136
-
137
- // Handle cursor pagination - build a cursor condition
138
- let cursorCondition: Condition | undefined;
139
-
140
- if ((after || before) && indexColumns.length > 0) {
141
- const cursor = after || before;
142
- // Decode cursor if it's a string, otherwise use it as-is
143
- const cursorObj = typeof cursor === "string" ? decodeCursor(cursor!) : cursor!;
144
- const serializedValues = serializeCursorValues(cursorObj, indexColumns, provider);
145
-
146
- // Build tuple comparison for cursor pagination
147
- // For "after" with "asc": (col1, col2, ...) > (val1, val2, ...)
148
- // For "before" with "desc": reverse the comparison
149
- const isAfter = !!after;
150
- const useGreaterThan =
151
- (isAfter && orderDirection === "asc") || (!isAfter && orderDirection === "desc");
152
-
153
- if (indexColumns.length === 1) {
154
- // Simple single-column case
155
- const col = indexColumns[0]!;
156
- const val = serializedValues[col.ormName];
157
- const operator = useGreaterThan ? ">" : "<";
158
- cursorCondition = {
159
- type: "compare",
160
- a: col,
161
- operator,
162
- b: val,
163
- };
164
- } else {
165
- // Multi-column tuple comparison - not yet supported for Kysely
166
- throw new Error(
167
- "Multi-column cursor pagination is not yet supported in Kysely Unit of Work implementation",
168
- );
169
- }
170
- }
171
-
172
- // Combine user where clause with cursor condition
173
- let combinedWhere: Condition | undefined;
174
- if (findManyOptions.where) {
175
- const whereResult = buildCondition(op.table.columns, findManyOptions.where);
176
- if (whereResult === true) {
177
- combinedWhere = undefined;
178
- } else if (whereResult === false) {
179
- return null;
180
- } else {
181
- combinedWhere = whereResult;
182
- }
183
- }
184
-
185
- if (cursorCondition) {
186
- if (combinedWhere) {
187
- combinedWhere = {
188
- type: "and",
189
- items: [combinedWhere, cursorCondition],
190
- };
191
- } else {
192
- combinedWhere = cursorCondition;
193
- }
194
- }
195
-
196
- // When we have joins or need to bypass buildFindOptions, use operation-specific queryBuilder
197
- if (join && join.length > 0) {
198
- const queryBuilder = getQueryBuilder(op.namespace);
199
- return queryBuilder.findMany(op.table, {
200
- // Safe cast: select from UOW matches SimplifyFindOptions requirement
201
- select: (findManyOptions.select ?? true) as AnySelectClause,
202
- where: combinedWhere,
203
- orderBy,
204
- limit: pageSize,
205
- join,
206
- });
207
- }
208
-
209
- return queryCompiler.findMany(op.table.name, {
210
- ...findManyOptions,
211
- where: combinedWhere ? () => combinedWhere! : undefined,
212
- orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),
213
- limit: pageSize,
214
- });
215
- }
216
- }
217
- },
218
-
219
- compileMutationOperation(
220
- op: MutationOperation<AnySchema>,
221
- ): CompiledMutation<CompiledQuery> | null {
222
- const queryCompiler = getQueryCompiler(op.schema, op.namespace);
223
- switch (op.type) {
224
- case "create":
225
- // queryCompiler.create() calls encodeValues() which handles runtime defaults
226
- return {
227
- query: queryCompiler.create(op.table, op.values),
228
- expectedAffectedRows: null, // creates don't need affected row checks
229
- };
230
-
231
- case "update": {
232
- const table = toTable(op.schema, op.table);
233
- const idColumn = table.getIdColumn();
234
- const versionColumn = table.getVersionColumn();
235
-
236
- const externalId = typeof op.id === "string" ? op.id : op.id.externalId;
237
- const versionToCheck = getVersionToCheck(op.id, op.checkVersion);
238
-
239
- // Build WHERE clause that filters by ID and optionally by version
240
- const whereClause =
241
- versionToCheck !== undefined
242
- ? () =>
243
- buildCondition(table.columns, (eb) =>
244
- eb.and(
245
- eb(idColumn.ormName, "=", externalId),
246
- eb(versionColumn.ormName, "=", versionToCheck),
247
- ),
248
- )
249
- : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
250
-
251
- const query = queryCompiler.updateMany(op.table, {
252
- where: whereClause,
253
- set: op.set,
254
- });
255
-
256
- return query
257
- ? {
258
- query,
259
- expectedAffectedRows: op.checkVersion ? 1 : null,
260
- }
261
- : null;
262
- }
263
-
264
- case "delete": {
265
- const table = toTable(op.schema, op.table);
266
- const idColumn = table.getIdColumn();
267
- const versionColumn = table.getVersionColumn();
268
-
269
- // Extract external ID based on whether op.id is FragnoId or string
270
- const externalId = typeof op.id === "string" ? op.id : op.id.externalId;
271
- const versionToCheck = getVersionToCheck(op.id, op.checkVersion);
272
-
273
- // Build WHERE clause that filters by ID and optionally by version
274
- const whereClause =
275
- versionToCheck !== undefined
276
- ? () =>
277
- buildCondition(table.columns, (eb) =>
278
- eb.and(
279
- eb(idColumn.ormName, "=", externalId),
280
- eb(versionColumn.ormName, "=", versionToCheck),
281
- ),
282
- )
283
- : () => buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
284
-
285
- const query = queryCompiler.deleteMany(op.table, {
286
- where: whereClause,
287
- });
288
-
289
- return query
290
- ? {
291
- query,
292
- expectedAffectedRows: op.checkVersion ? 1 : null,
293
- }
294
- : null;
295
- }
296
- }
297
- },
298
- };
299
- }
300
-
301
- /**
302
- * Get the version to check for a given ID and checkVersion flag.
303
- * @returns The version to check or undefined if no check is required.
304
- * @throws Error if the ID is a string and checkVersion is true.
305
- */
306
- function getVersionToCheck(id: FragnoId | string, checkVersion: boolean): number | undefined {
307
- if (!checkVersion) {
308
- return undefined;
309
- }
310
-
311
- if (typeof id === "string") {
312
- throw new Error(
313
- `Cannot use checkVersion with a string ID. Version checking requires a FragnoId with version information.`,
314
- );
315
- }
316
-
317
- return id.version;
318
- }
@@ -1,145 +0,0 @@
1
- import type { CompiledQuery, Kysely, QueryResult } from "kysely";
2
- import type { CompiledMutation, MutationResult } from "../../query/unit-of-work";
3
-
4
- function getAffectedRows(result: QueryResult<unknown>): number {
5
- const affectedRows =
6
- result.numAffectedRows ??
7
- result.numChangedRows ??
8
- // PGLite returns `affectedRows` instead of `numAffectedRows` or `numChangedRows`
9
- ("affectedRows" in result &&
10
- (typeof result["affectedRows"] === "number" || typeof result["affectedRows"] === "bigint")
11
- ? result["affectedRows"]
12
- : undefined);
13
-
14
- if (affectedRows === undefined) {
15
- throw new Error("No affected rows found");
16
- }
17
-
18
- if (affectedRows > Number.MAX_SAFE_INTEGER) {
19
- throw new Error(
20
- `affectedRows BigInt value ${affectedRows.toString()} exceeds JS safe integer range`,
21
- );
22
- }
23
-
24
- return Number(affectedRows);
25
- }
26
-
27
- /**
28
- * Execute the retrieval phase of a Unit of Work using Kysely
29
- *
30
- * All retrieval queries are executed inside a single transaction to ensure
31
- * snapshot isolation - all reads see a consistent view of the database.
32
- *
33
- * @param kysely - The Kysely database instance
34
- * @param retrievalBatch - Array of compiled retrieval queries
35
- * @returns Array of query results matching the retrieval operations order
36
- *
37
- * @example
38
- * ```ts
39
- * const retrievalResults = await executeKyselyRetrievalPhase(kysely, compiled.retrievalBatch);
40
- * const [users, posts] = retrievalResults;
41
- * ```
42
- */
43
- export async function executeKyselyRetrievalPhase(
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- kysely: Kysely<any>,
46
- retrievalBatch: CompiledQuery[],
47
- ): Promise<unknown[]> {
48
- // If no retrieval operations, return empty array immediately
49
- if (retrievalBatch.length === 0) {
50
- return [];
51
- }
52
-
53
- const retrievalResults: unknown[] = [];
54
-
55
- // Execute all retrieval queries inside a transaction for snapshot isolation
56
- await kysely.transaction().execute(async (tx) => {
57
- for (const compiledQuery of retrievalBatch) {
58
- const result = await tx.executeQuery(compiledQuery);
59
- retrievalResults.push(result.rows);
60
- }
61
- });
62
-
63
- return retrievalResults;
64
- }
65
-
66
- /**
67
- * Execute the mutation phase of a Unit of Work using Kysely
68
- *
69
- * All mutation queries are executed in a transaction with optimistic locking.
70
- * If any version check fails, the entire transaction is rolled back and
71
- * success=false is returned.
72
- *
73
- * @param kysely - The Kysely database instance
74
- * @param mutationBatch - Array of compiled mutation queries with expected affected rows
75
- * @returns Object with success flag and internal IDs from create operations
76
- *
77
- * @example
78
- * ```ts
79
- * const { success, createdInternalIds } = await executeKyselyMutationPhase(kysely, compiled.mutationBatch);
80
- * if (!success) {
81
- * console.log("Version conflict detected, retrying...");
82
- * }
83
- * ```
84
- */
85
- export async function executeKyselyMutationPhase(
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
- kysely: Kysely<any>,
88
- mutationBatch: CompiledMutation<CompiledQuery>[],
89
- ): Promise<MutationResult> {
90
- // If there are no mutations, return success immediately
91
- if (mutationBatch.length === 0) {
92
- return { success: true, createdInternalIds: [] };
93
- }
94
-
95
- const createdInternalIds: (bigint | null)[] = [];
96
-
97
- // Execute mutation batch in a transaction
98
- try {
99
- await kysely.transaction().execute(async (tx) => {
100
- for (const compiledMutation of mutationBatch) {
101
- const result = await tx.executeQuery(compiledMutation.query);
102
-
103
- // For creates (expectedAffectedRows === null), try to extract internal ID
104
- if (compiledMutation.expectedAffectedRows === null) {
105
- // Check if result has rows (RETURNING clause supported)
106
- if (Array.isArray(result.rows) && result.rows.length > 0) {
107
- const row = result.rows[0] as Record<string, unknown>;
108
- if ("_internalId" in row || "_internal_id" in row) {
109
- const internalId = (row["_internalId"] ?? row["_internal_id"]) as bigint;
110
- createdInternalIds.push(internalId);
111
- } else {
112
- // RETURNING supported but _internalId not found
113
- createdInternalIds.push(null);
114
- }
115
- } else {
116
- // No RETURNING support (e.g., MySQL)
117
- createdInternalIds.push(null);
118
- }
119
- } else {
120
- // Check affected rows for updates/deletes
121
- const affectedRows = getAffectedRows(result);
122
-
123
- if (affectedRows !== compiledMutation.expectedAffectedRows) {
124
- // Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows
125
- // This means either the row doesn't exist or the version has changed
126
- throw new Error(
127
- `Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,
128
- );
129
- }
130
- }
131
- }
132
- });
133
-
134
- return { success: true, createdInternalIds };
135
- } catch (error) {
136
- // Transaction failed - could be version conflict or other constraint violation
137
- // Return success=false to indicate the UOW should be retried
138
- if (error instanceof Error && error.message.includes("Version conflict")) {
139
- return { success: false };
140
- }
141
-
142
- // Other database errors should be thrown
143
- throw error;
144
- }
145
- }