@fragno-dev/db 0.1.15 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/.turbo/turbo-build.log +242 -179
  2. package/CHANGELOG.md +23 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +5 -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 -21
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -54
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +3 -0
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +36 -28
  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 -18
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -165
  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} +47 -61
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{drizzle/shared.d.ts → shared/table-name-mapper.d.ts} +2 -4
  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 +53 -19
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +89 -19
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/fragments/internal-fragment.d.ts +39 -5
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  85. package/dist/fragments/internal-fragment.js +82 -10
  86. package/dist/fragments/internal-fragment.js.map +1 -1
  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 +23 -61
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +34 -10
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +47 -16
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/{rou3@0.7.8 → rou3@0.7.10}/node_modules/rou3/dist/index.js +1 -1
  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/fragment-instantiator.js +69 -31
  102. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  103. package/dist/query/column-defaults.js +27 -0
  104. package/dist/query/column-defaults.js.map +1 -0
  105. package/dist/query/cursor.d.ts +4 -4
  106. package/dist/query/cursor.d.ts.map +1 -1
  107. package/dist/query/cursor.js +8 -6
  108. package/dist/query/cursor.js.map +1 -1
  109. package/dist/query/orm/orm.d.ts +1 -1
  110. package/dist/query/orm/orm.js.map +1 -1
  111. package/dist/query/serialize/create-sql-serializer.js +30 -0
  112. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  113. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  114. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  115. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  116. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  117. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  118. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  119. package/dist/query/serialize/sql-serializer.js +67 -0
  120. package/dist/query/serialize/sql-serializer.js.map +1 -0
  121. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +5 -5
  122. package/dist/query/simple-query-interface.d.ts.map +1 -0
  123. package/dist/query/{execute-unit-of-work.d.ts → unit-of-work/execute-unit-of-work.d.ts} +13 -3
  124. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  125. package/dist/query/{execute-unit-of-work.js → unit-of-work/execute-unit-of-work.js} +17 -4
  126. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  127. package/dist/query/{retry-policy.d.ts → unit-of-work/retry-policy.d.ts} +1 -1
  128. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  129. package/dist/query/{retry-policy.js → unit-of-work/retry-policy.js} +1 -1
  130. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  131. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +51 -18
  132. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  133. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +58 -11
  134. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  135. package/dist/query/value-decoding.js +71 -0
  136. package/dist/query/value-decoding.js.map +1 -0
  137. package/dist/query/value-encoding.js +124 -0
  138. package/dist/query/value-encoding.js.map +1 -0
  139. package/dist/schema/create.d.ts +3 -0
  140. package/dist/schema/create.d.ts.map +1 -1
  141. package/dist/schema/create.js +4 -0
  142. package/dist/schema/create.js.map +1 -1
  143. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  144. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  145. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  146. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  147. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  148. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  149. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  150. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  151. package/dist/schema/type-conversion/type-mapping.js +63 -0
  152. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  153. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  154. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  155. package/dist/sql-driver/connection/connection-provider.js +19 -0
  156. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  157. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  158. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  159. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  160. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  161. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  162. package/dist/sql-driver/dialects/dialects.js +3 -0
  163. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  164. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  165. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  166. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  167. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  168. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  169. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  170. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  171. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  172. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  173. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  174. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  175. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  176. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  177. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  178. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  179. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  180. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  181. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  182. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  183. package/dist/sql-driver/sql-driver.d.ts +38 -0
  184. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  185. package/dist/sql-driver/sql-driver.js +1 -0
  186. package/dist/sql-driver/sql.js +50 -0
  187. package/dist/sql-driver/sql.js.map +1 -0
  188. package/dist/with-database.d.ts +6 -2
  189. package/dist/with-database.d.ts.map +1 -1
  190. package/dist/with-database.js +1 -1
  191. package/dist/with-database.js.map +1 -1
  192. package/package.json +37 -10
  193. package/src/adapters/adapters.ts +8 -5
  194. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +60 -169
  195. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +31 -55
  196. package/src/adapters/drizzle/drizzle-adapter.ts +15 -107
  197. package/src/adapters/drizzle/generate.test.ts +2 -2
  198. package/src/adapters/drizzle/generate.ts +78 -34
  199. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  200. package/src/adapters/drizzle/shared.ts +0 -34
  201. package/src/adapters/drizzle/test-utils.ts +3 -3
  202. package/src/adapters/generic-sql/README.md +14 -0
  203. package/src/adapters/generic-sql/driver-config.ts +144 -0
  204. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  205. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  206. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  207. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  208. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  209. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  210. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  211. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  212. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  213. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  214. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  215. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  216. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  217. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  218. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  219. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  220. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  221. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  222. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  223. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  224. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  225. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  226. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  227. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  228. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  229. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  230. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  231. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  232. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  233. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  234. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  235. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  236. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  237. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +26 -76
  238. package/src/adapters/kysely/{kysely-adapter-sqlite.test.ts → kysely-adapter-sqlocal.test.ts} +76 -17
  239. package/src/adapters/kysely/kysely-adapter.ts +10 -250
  240. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +110 -104
  241. package/src/adapters/shared/table-name-mapper.ts +50 -0
  242. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  243. package/src/db-fragment-definition-builder.test.ts +2 -2
  244. package/src/db-fragment-definition-builder.ts +281 -50
  245. package/src/db-fragment-instantiator.test.ts +78 -2
  246. package/src/db-fragment-integration.test.ts +14 -16
  247. package/src/fragments/internal-fragment.test.ts +434 -45
  248. package/src/fragments/internal-fragment.ts +184 -20
  249. package/src/hooks/hooks.test.ts +575 -0
  250. package/src/hooks/hooks.ts +179 -0
  251. package/src/migration-engine/generation-engine.test.ts +44 -54
  252. package/src/migration-engine/generation-engine.ts +48 -94
  253. package/src/mod.ts +117 -29
  254. package/src/query/column-defaults.ts +49 -0
  255. package/src/query/cursor.test.ts +31 -6
  256. package/src/query/cursor.ts +11 -7
  257. package/src/query/orm/orm.ts +1 -1
  258. package/src/query/query-type.test.ts +9 -9
  259. package/src/query/serialize/create-sql-serializer.ts +34 -0
  260. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  261. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  262. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  263. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  264. package/src/query/serialize/sql-serializer.ts +143 -0
  265. package/src/query/{query.ts → simple-query-interface.ts} +2 -2
  266. package/src/query/{execute-unit-of-work.test.ts → unit-of-work/execute-unit-of-work.test.ts} +16 -16
  267. package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +49 -8
  268. package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +41 -43
  269. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +5 -3
  270. package/src/query/{unit-of-work.test.ts → unit-of-work/unit-of-work.test.ts} +100 -9
  271. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +135 -32
  272. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -427
  273. package/src/query/value-decoding.ts +113 -0
  274. package/src/query/value-encoding.test.ts +390 -0
  275. package/src/query/value-encoding.ts +168 -0
  276. package/src/schema/create.test.ts +5 -1
  277. package/src/schema/create.ts +5 -0
  278. package/src/schema/serialize.test.ts +165 -407
  279. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  280. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  281. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  282. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  283. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  284. package/src/schema/type-conversion/type-mapping.ts +153 -0
  285. package/src/shared/connection-pool.ts +5 -5
  286. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  287. package/src/sql-driver/connection/connection-provider.ts +27 -0
  288. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  289. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  290. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  291. package/src/sql-driver/dialects/dialects.ts +1 -0
  292. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  293. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  294. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  295. package/src/sql-driver/query-executor/plugin.ts +22 -0
  296. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  297. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  298. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  299. package/src/sql-driver/sql-driver.ts +53 -0
  300. package/src/sql-driver/sql.ts +57 -0
  301. package/src/sql-driver/sqlocal.test.ts +117 -0
  302. package/src/with-database.ts +35 -23
  303. package/tsdown.config.ts +7 -2
  304. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  305. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  306. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  307. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  308. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  309. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  310. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  311. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -334
  312. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  313. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -123
  314. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  315. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -160
  316. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  317. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  318. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  319. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  320. package/dist/adapters/drizzle/shared.js +0 -35
  321. package/dist/adapters/drizzle/shared.js.map +0 -1
  322. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  323. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  324. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  325. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  326. package/dist/adapters/kysely/kysely-query-compiler.js +0 -67
  327. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  328. package/dist/adapters/kysely/kysely-query.d.ts +0 -23
  329. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  330. package/dist/adapters/kysely/kysely-query.js +0 -230
  331. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  332. package/dist/adapters/kysely/kysely-shared.d.ts +0 -14
  333. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  334. package/dist/adapters/kysely/kysely-shared.js +0 -33
  335. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  336. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -193
  337. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  338. package/dist/adapters/kysely/kysely-uow-executor.js +0 -93
  339. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  340. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  341. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  342. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  343. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  344. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  345. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  346. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  347. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  348. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  349. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  350. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  351. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  352. package/dist/adapters/kysely/migration/execute.js +0 -34
  353. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  354. package/dist/migration-engine/create.d.ts +0 -37
  355. package/dist/migration-engine/create.d.ts.map +0 -1
  356. package/dist/migration-engine/create.js +0 -58
  357. package/dist/migration-engine/create.js.map +0 -1
  358. package/dist/migration-engine/shared.d.ts +0 -112
  359. package/dist/migration-engine/shared.d.ts.map +0 -1
  360. package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +0 -1
  361. package/dist/query/execute-unit-of-work.d.ts.map +0 -1
  362. package/dist/query/execute-unit-of-work.js.map +0 -1
  363. package/dist/query/query.d.ts.map +0 -1
  364. package/dist/query/result-transform.js +0 -170
  365. package/dist/query/result-transform.js.map +0 -1
  366. package/dist/query/retry-policy.d.ts.map +0 -1
  367. package/dist/query/retry-policy.js.map +0 -1
  368. package/dist/query/unit-of-work.d.ts.map +0 -1
  369. package/dist/query/unit-of-work.js.map +0 -1
  370. package/dist/schema/serialize.js +0 -111
  371. package/dist/schema/serialize.js.map +0 -1
  372. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -122
  373. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  374. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  375. package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +0 -1442
  376. package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +0 -1414
  377. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1400
  378. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -677
  379. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -228
  380. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -309
  381. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  382. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  383. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  384. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  385. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  386. package/src/adapters/kysely/kysely-query-compiler.ts +0 -127
  387. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  388. package/src/adapters/kysely/kysely-query.ts +0 -399
  389. package/src/adapters/kysely/kysely-shared.ts +0 -57
  390. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -986
  391. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -350
  392. package/src/adapters/kysely/kysely-uow-executor.ts +0 -164
  393. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -794
  394. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  395. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  396. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  397. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  398. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  399. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  400. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  401. package/src/adapters/kysely/migration/execute.ts +0 -50
  402. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  403. package/src/query/result-transform.ts +0 -274
  404. package/src/schema/serialize.ts +0 -407
  405. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
  406. /package/src/query/{retry-policy.test.ts → unit-of-work/retry-policy.test.ts} +0 -0
  407. /package/src/query/{retry-policy.ts → unit-of-work/retry-policy.ts} +0 -0
@@ -2,7 +2,7 @@ import { mkdir, writeFile, rm, access } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { generateSchema, type SupportedProvider } from "./generate";
4
4
  import type { Schema } from "../../schema/create";
5
- import { settingsSchema } from "../../fragments/internal-fragment";
5
+ import { internalSchema } from "../../fragments/internal-fragment";
6
6
 
7
7
  /**
8
8
  * Writes a Fragno schema to a temporary TypeScript file and dynamically imports it.
@@ -42,10 +42,10 @@ export async function writeAndLoadSchema(
42
42
  // Always include settings schema first (as done in generation-engine.ts), then the test schema
43
43
  // De-duplicate: if the test schema IS the settings schema, don't add it twice
44
44
  const fragments: Array<{ namespace: string; schema: Schema }> = [
45
- { namespace: "", schema: settingsSchema },
45
+ { namespace: "", schema: internalSchema },
46
46
  ];
47
47
 
48
- if (schema !== settingsSchema) {
48
+ if (schema !== internalSchema) {
49
49
  fragments.push({ namespace: namespace ?? "", schema });
50
50
  }
51
51
 
@@ -0,0 +1,14 @@
1
+ # Generic SQL Adapter
2
+
3
+ ## Goals:
4
+
5
+ - Follow roughly the Kysely interfaces so that we can use Kysely adapters.
6
+ - Use this to replace ALL query execution logic.
7
+ - "Own" the result transformation step.
8
+ - Optionally able to create SQL migrations internally.
9
+ - Be able to map names (tables, columns, constraints, etc)
10
+ - Be able to run migrations directly from the Fragment
11
+
12
+ ## Non-goal:
13
+
14
+ - Generate schemas in ORM-specific DSLs, this is left to the ORM adapters.
@@ -0,0 +1,144 @@
1
+ export const supportedDatabases = ["sqlite", "postgresql", "mysql"] as const;
2
+ export type SupportedDatabase = (typeof supportedDatabases)[number];
3
+
4
+ export const supportedDriverTypes = [
5
+ "sqlocal",
6
+ "cloudflare_durable_objects",
7
+ "better-sqlite3",
8
+ "pg",
9
+ "pglite",
10
+ "mysql2",
11
+ ] as const;
12
+
13
+ export type SupportedDriverType = (typeof supportedDriverTypes)[number];
14
+
15
+ export abstract class DriverConfig<T extends SupportedDriverType = SupportedDriverType> {
16
+ abstract readonly driverType: T;
17
+ abstract readonly databaseType: SupportedDatabase;
18
+
19
+ abstract readonly supportsReturning: boolean;
20
+ abstract readonly supportsJson: boolean;
21
+
22
+ /**
23
+ * Column name for internal ID in RETURNING results.
24
+ * Only defined if supportsReturning is true.
25
+ */
26
+ abstract readonly internalIdColumn: string | undefined;
27
+
28
+ get supportsRowsAffected(): boolean {
29
+ return !!this.extractAffectedRows;
30
+ }
31
+
32
+ /**
33
+ * Extract the number of affected rows from a query result.
34
+ * Only implemented for drivers that support affected rows reporting.
35
+ *
36
+ * @param result - The query result from the SQL driver
37
+ * @returns The number of affected rows as bigint
38
+ * @throws Error if affected rows information is not found in the result
39
+ */
40
+ extractAffectedRows?(result: Record<string, unknown>): bigint;
41
+ }
42
+
43
+ export class SQLocalDriverConfig extends DriverConfig<"sqlocal"> {
44
+ override readonly driverType = "sqlocal";
45
+ override readonly databaseType = "sqlite";
46
+ override readonly supportsReturning = true;
47
+ override readonly supportsJson = false;
48
+ override readonly internalIdColumn = "_internalId";
49
+ }
50
+
51
+ export class CloudflareDurableObjectsDriverConfig extends DriverConfig<"cloudflare_durable_objects"> {
52
+ override readonly driverType = "cloudflare_durable_objects";
53
+ override readonly databaseType = "sqlite";
54
+ override readonly supportsReturning = true;
55
+ override readonly supportsJson = false;
56
+ override readonly internalIdColumn = "_internalId";
57
+ }
58
+
59
+ export class BetterSQLite3DriverConfig extends DriverConfig<"better-sqlite3"> {
60
+ override readonly driverType = "better-sqlite3";
61
+ override readonly databaseType = "sqlite";
62
+ override readonly supportsReturning = true;
63
+ override readonly supportsJson = false;
64
+ override readonly internalIdColumn = "_internalId";
65
+
66
+ override extractAffectedRows(result: Record<string, unknown>): bigint {
67
+ if ("numAffectedRows" in result) {
68
+ const value = result["numAffectedRows"];
69
+ if (typeof value === "bigint") {
70
+ return value;
71
+ }
72
+ if (typeof value === "number") {
73
+ return BigInt(value);
74
+ }
75
+ }
76
+
77
+ throw new Error(
78
+ `No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
79
+ );
80
+ }
81
+ }
82
+
83
+ export class NodePostgresDriverConfig extends DriverConfig<"pg"> {
84
+ override readonly driverType = "pg";
85
+ override readonly databaseType = "postgresql";
86
+ override readonly supportsReturning = true;
87
+ override readonly supportsJson = true;
88
+ override readonly internalIdColumn = "_internalId";
89
+
90
+ override extractAffectedRows(result: Record<string, unknown>): bigint {
91
+ if ("numAffectedRows" in result) {
92
+ const value = result["numAffectedRows"];
93
+ if (typeof value === "bigint") {
94
+ return value;
95
+ }
96
+ if (typeof value === "number") {
97
+ return BigInt(value);
98
+ }
99
+ }
100
+ if ("numChangedRows" in result) {
101
+ const value = result["numChangedRows"];
102
+ if (typeof value === "bigint") {
103
+ return value;
104
+ }
105
+ if (typeof value === "number") {
106
+ return BigInt(value);
107
+ }
108
+ }
109
+ throw new Error(
110
+ `No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
111
+ );
112
+ }
113
+ }
114
+
115
+ export class PGLiteDriverConfig extends DriverConfig<"pglite"> {
116
+ override readonly driverType = "pglite";
117
+ override readonly databaseType = "postgresql";
118
+ override readonly supportsReturning = true;
119
+ override readonly supportsJson = true;
120
+ override readonly internalIdColumn = "_internalId";
121
+
122
+ override extractAffectedRows(result: Record<string, unknown>): bigint {
123
+ if ("affectedRows" in result) {
124
+ const value = result["affectedRows"];
125
+ if (typeof value === "bigint") {
126
+ return value;
127
+ }
128
+ if (typeof value === "number") {
129
+ return BigInt(value);
130
+ }
131
+ }
132
+ throw new Error(
133
+ `No affected rows found in result: ${JSON.stringify(result)}. Driver ${this.driverType} is expected to support affected rows.`,
134
+ );
135
+ }
136
+ }
137
+
138
+ export class MySQL2DriverConfig extends DriverConfig<"mysql2"> {
139
+ override readonly driverType = "mysql2";
140
+ override readonly databaseType = "mysql";
141
+ override readonly supportsReturning = false;
142
+ override readonly supportsJson = true;
143
+ override readonly internalIdColumn = undefined;
144
+ }
@@ -0,0 +1,50 @@
1
+ import { SQLocalKysely } from "sqlocal/kysely";
2
+ import { assert, describe, expect, it } from "vitest";
3
+ import { SQLocalDriverConfig } from "./driver-config";
4
+ import { GenericSQLAdapter } from "./generic-sql-adapter";
5
+ import { column, idColumn, schema } from "../../schema/create";
6
+ import { internalSchema } from "../../fragments/internal-fragment";
7
+
8
+ describe("GenericSQLAdapter", () => {
9
+ const testSchema = schema((s) => {
10
+ return s.addTable("products", (t) => {
11
+ return t
12
+ .addColumn("id", idColumn())
13
+ .addColumn("name", column("string"))
14
+ .addColumn("price", column("integer"))
15
+ .createIndex("name_idx", ["name"]);
16
+ });
17
+ });
18
+
19
+ it("Should be able to query using GenericSQLAdapter", async () => {
20
+ const { dialect } = new SQLocalKysely(":memory:");
21
+ const driverConfig = new SQLocalDriverConfig();
22
+
23
+ const adapter = new GenericSQLAdapter({ dialect, driverConfig });
24
+
25
+ // Create settings table first (needed for version tracking)
26
+ const settingsMigrations = adapter.prepareMigrations(internalSchema, "");
27
+ await settingsMigrations.executeWithDriver(adapter.driver, 0);
28
+
29
+ // Now run the actual test schema migrations (use a different namespace)
30
+ const migrations = adapter.prepareMigrations(testSchema, "test");
31
+ await migrations.executeWithDriver(adapter.driver, 0);
32
+
33
+ const queryEngine = adapter.createQueryEngine(testSchema, "test");
34
+
35
+ await queryEngine.create("products", {
36
+ name: "test",
37
+ price: 100,
38
+ });
39
+
40
+ const product = await queryEngine.findFirst("products", (b) =>
41
+ b.whereIndex("name_idx", (eb) => eb("name", "=", "test")),
42
+ );
43
+
44
+ assert(product);
45
+ expect(product.name).toBe("test");
46
+ expect(product.price).toBe(100);
47
+
48
+ await adapter.close();
49
+ });
50
+ });
@@ -0,0 +1,146 @@
1
+ import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
2
+ import {
3
+ fragnoDatabaseAdapterNameFakeSymbol,
4
+ fragnoDatabaseAdapterVersionFakeSymbol,
5
+ type DatabaseAdapter,
6
+ type DatabaseContextStorage,
7
+ type TableNameMapper,
8
+ } from "../adapters";
9
+ import type { CompiledQuery, Dialect, QueryResult } from "../../sql-driver/sql-driver";
10
+ import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter";
11
+ import { sql } from "../../sql-driver/sql";
12
+ import type { AnySchema } from "../../schema/create";
13
+ import { createTableNameMapper } from "../shared/table-name-mapper";
14
+ import type { SimpleQueryInterface } from "../../query/simple-query-interface";
15
+ import { createExecutor } from "./generic-sql-uow-executor";
16
+ import { UnitOfWorkDecoder } from "./uow-decoder";
17
+ import { createPreparedMigrations, type PreparedMigrations } from "./migration/prepared-migrations";
18
+ import type { DriverConfig } from "./driver-config";
19
+ import { GenericSQLUOWOperationCompiler } from "./query/generic-sql-uow-operation-compiler";
20
+ import { createUOWCompilerFromOperationCompiler } from "../shared/uow-operation-compiler";
21
+ import {
22
+ fromUnitOfWorkCompiler,
23
+ type UnitOfWorkFactory,
24
+ } from "../shared/from-unit-of-work-compiler";
25
+
26
+ export interface UnitOfWorkConfig {
27
+ onQuery?: (query: CompiledQuery) => void;
28
+ dryRun?: boolean;
29
+ }
30
+
31
+ export interface GenericSQLOptions {
32
+ dialect: Dialect;
33
+ driverConfig: DriverConfig;
34
+ uowConfig?: UnitOfWorkConfig;
35
+ }
36
+
37
+ export class GenericSQLAdapter implements DatabaseAdapter<UnitOfWorkConfig> {
38
+ readonly dialect: Dialect;
39
+ readonly driverConfig: DriverConfig;
40
+ readonly uowConfig?: UnitOfWorkConfig;
41
+
42
+ #schemaNamespaceMap = new WeakMap<AnySchema, string>();
43
+ #contextStorage: RequestContextStorage<DatabaseContextStorage>;
44
+
45
+ #driver: SqlDriverAdapter;
46
+
47
+ constructor({ dialect, driverConfig, uowConfig }: GenericSQLOptions) {
48
+ this.dialect = dialect;
49
+ this.driverConfig = driverConfig;
50
+ this.uowConfig = uowConfig;
51
+
52
+ this.#schemaNamespaceMap = new WeakMap<AnySchema, string>();
53
+ this.#contextStorage = new RequestContextStorage();
54
+
55
+ this.#driver = new SqlDriverAdapter(dialect);
56
+ }
57
+
58
+ get driver(): SqlDriverAdapter {
59
+ return this.#driver;
60
+ }
61
+
62
+ get [fragnoDatabaseAdapterNameFakeSymbol](): string {
63
+ return "generic-sql";
64
+ }
65
+
66
+ get [fragnoDatabaseAdapterVersionFakeSymbol](): number {
67
+ return 0;
68
+ }
69
+
70
+ get contextStorage(): RequestContextStorage<DatabaseContextStorage> {
71
+ return this.#contextStorage;
72
+ }
73
+
74
+ close(): Promise<void> {
75
+ return this.#driver.destroy();
76
+ }
77
+
78
+ async isConnectionHealthy(): Promise<boolean> {
79
+ const result = await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect));
80
+ return result.rows[0]["healthy"] === 1;
81
+ }
82
+
83
+ prepareMigrations<T extends AnySchema>(schema: T, namespace: string): PreparedMigrations {
84
+ return createPreparedMigrations({
85
+ schema,
86
+ namespace,
87
+ database: this.driverConfig.databaseType,
88
+ mapper: namespace ? this.createTableNameMapper(namespace) : undefined,
89
+ driver: this.#driver,
90
+ });
91
+ }
92
+
93
+ createTableNameMapper(namespace: string): TableNameMapper {
94
+ return createTableNameMapper(namespace, false);
95
+ }
96
+
97
+ async getSchemaVersion(namespace: string): Promise<string | undefined> {
98
+ const key = `${namespace}.schema_version`;
99
+ const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${key};`.compile(
100
+ this.dialect,
101
+ );
102
+
103
+ let result: QueryResult<Record<string, unknown>>;
104
+ try {
105
+ result = await this.#driver.executeQuery(query);
106
+ } catch (error) {
107
+ if (error instanceof Error && error.message.includes("fragno_db_settings")) {
108
+ return undefined;
109
+ }
110
+ throw error;
111
+ }
112
+
113
+ const value = result.rows[0]["value"];
114
+
115
+ if (!value) {
116
+ return undefined;
117
+ }
118
+
119
+ if (typeof value !== "string") {
120
+ throw new Error(`Schema version for namespace ${namespace} is not a string`);
121
+ }
122
+
123
+ return value;
124
+ }
125
+
126
+ createQueryEngine<T extends AnySchema>(
127
+ schema: T,
128
+ namespace: string,
129
+ ): SimpleQueryInterface<T, UnitOfWorkConfig> {
130
+ this.#schemaNamespaceMap.set(schema, namespace);
131
+
132
+ const operationCompiler = new GenericSQLUOWOperationCompiler(this.driverConfig, (ns) =>
133
+ ns ? this.createTableNameMapper(ns) : undefined,
134
+ );
135
+
136
+ const factory: UnitOfWorkFactory = {
137
+ compiler: createUOWCompilerFromOperationCompiler(operationCompiler),
138
+ executor: createExecutor(this.#driver, this.driverConfig, false),
139
+ decoder: new UnitOfWorkDecoder(this.driverConfig),
140
+ uowConfig: this.uowConfig,
141
+ schemaNamespaceMap: this.#schemaNamespaceMap,
142
+ };
143
+
144
+ return fromUnitOfWorkCompiler(schema, factory);
145
+ }
146
+ }
@@ -0,0 +1,130 @@
1
+ import type {
2
+ CompiledMutation,
3
+ MutationResult,
4
+ UOWExecutor,
5
+ } from "../../query/unit-of-work/unit-of-work";
6
+ import type { CompiledQuery } from "../../sql-driver/sql-driver";
7
+ import type { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter";
8
+ import type { DriverConfig } from "./driver-config";
9
+ import { ResultInterpreter } from "./result-interpreter";
10
+
11
+ export async function executeRetrieval(
12
+ adapter: SqlDriverAdapter,
13
+ retrievalBatch: CompiledQuery[],
14
+ ): Promise<unknown[]> {
15
+ if (retrievalBatch.length === 0) {
16
+ return [];
17
+ }
18
+
19
+ const retrievalResults: unknown[] = [];
20
+
21
+ await adapter.transaction(async (tx) => {
22
+ for (const compiledQuery of retrievalBatch) {
23
+ const result = await tx.executeQuery(compiledQuery);
24
+ retrievalResults.push(result.rows);
25
+ }
26
+ });
27
+
28
+ return retrievalResults;
29
+ }
30
+
31
+ export async function executeMutation(
32
+ adapter: SqlDriverAdapter,
33
+ driverConfig: DriverConfig,
34
+ mutationBatch: CompiledMutation<CompiledQuery>[],
35
+ ): Promise<MutationResult> {
36
+ if (mutationBatch.length === 0) {
37
+ return { success: true, createdInternalIds: [] };
38
+ }
39
+
40
+ const createdInternalIds: (bigint | null)[] = [];
41
+ const resultInterpreter = new ResultInterpreter(driverConfig);
42
+
43
+ try {
44
+ await adapter.transaction(async (tx) => {
45
+ for (const compiledMutation of mutationBatch) {
46
+ const result = await tx.executeQuery(compiledMutation.query);
47
+
48
+ // Extract internal ID for INSERT operations
49
+ if (compiledMutation.op === "create") {
50
+ // Only try to extract internal ID if driver supports RETURNING
51
+ // If not supported, push null (expected case - system falls back to subqueries)
52
+ if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {
53
+ const internalId = resultInterpreter.getCreatedInternalId(result);
54
+ createdInternalIds.push(internalId);
55
+ } else {
56
+ // Driver doesn't support RETURNING - this is expected, push null
57
+ createdInternalIds.push(null);
58
+ }
59
+ } else if (
60
+ (compiledMutation.op === "update" || compiledMutation.op === "delete") &&
61
+ compiledMutation.expectedAffectedRows !== null
62
+ ) {
63
+ // Check affected rows for updates/deletes
64
+ const affectedRows = resultInterpreter.getAffectedRows(result);
65
+
66
+ if (affectedRows !== compiledMutation.expectedAffectedRows) {
67
+ // Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows
68
+ // This means either the row doesn't exist or the version has changed
69
+ throw new Error(
70
+ `Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,
71
+ );
72
+ }
73
+ }
74
+ // "check" operations are handled below via expectedReturnedRows
75
+
76
+ if (compiledMutation.expectedReturnedRows !== null) {
77
+ // For SELECT queries (check operations), verify row count
78
+ const returnedRowCount = resultInterpreter.getReturnedRowCount(result);
79
+
80
+ if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) {
81
+ // Version conflict detected - the SELECT didn't return the expected number of rows
82
+ // This means either the row doesn't exist or the version has changed
83
+ throw new Error(
84
+ `Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`,
85
+ );
86
+ }
87
+ }
88
+ }
89
+ });
90
+
91
+ return { success: true, createdInternalIds };
92
+ } catch (error) {
93
+ // Transaction failed - could be version conflict or other constraint violation
94
+ // Return success=false to indicate the UOW should be retried
95
+ if (error instanceof Error && error.message.includes("Version conflict")) {
96
+ return { success: false };
97
+ }
98
+
99
+ // Other database errors should be thrown
100
+ throw error;
101
+ }
102
+ }
103
+
104
+ export function createExecutor(
105
+ adapter: SqlDriverAdapter,
106
+ driverConfig: DriverConfig,
107
+ dryRun?: boolean,
108
+ ): UOWExecutor<CompiledQuery, unknown> {
109
+ return {
110
+ async executeRetrievalPhase(retrievalBatch: CompiledQuery[]) {
111
+ // In dryRun mode, skip execution and return empty results
112
+ if (dryRun) {
113
+ return retrievalBatch.map(() => []);
114
+ }
115
+
116
+ return executeRetrieval(adapter, retrievalBatch);
117
+ },
118
+ async executeMutationPhase(mutationBatch: CompiledMutation<CompiledQuery>[]) {
119
+ // In dryRun mode, skip execution and return success with mock internal IDs
120
+ if (dryRun) {
121
+ return {
122
+ success: true,
123
+ createdInternalIds: mutationBatch.map(() => null),
124
+ };
125
+ }
126
+
127
+ return executeMutation(adapter, driverConfig, mutationBatch);
128
+ },
129
+ };
130
+ }
@@ -0,0 +1,55 @@
1
+ import {
2
+ DummyDriver,
3
+ Kysely,
4
+ MysqlAdapter,
5
+ MysqlIntrospector,
6
+ MysqlQueryCompiler,
7
+ PostgresAdapter,
8
+ PostgresIntrospector,
9
+ PostgresQueryCompiler,
10
+ SqliteAdapter,
11
+ SqliteIntrospector,
12
+ SqliteQueryCompiler,
13
+ } from "kysely";
14
+ import type { SupportedDatabase } from "../driver-config";
15
+
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ type KyselyAny = Kysely<any>;
18
+
19
+ /**
20
+ * Creates a Kysely instance that can only build queries, not execute them.
21
+ * This is used for SQL generation without requiring a database connection.
22
+ */
23
+ export function createColdKysely(database: SupportedDatabase): KyselyAny {
24
+ switch (database) {
25
+ case "postgresql":
26
+ return new Kysely({
27
+ dialect: {
28
+ createAdapter: () => new PostgresAdapter(),
29
+ createDriver: () => new DummyDriver(),
30
+ createIntrospector: (db) => new PostgresIntrospector(db),
31
+ createQueryCompiler: () => new PostgresQueryCompiler(),
32
+ },
33
+ });
34
+
35
+ case "mysql":
36
+ return new Kysely({
37
+ dialect: {
38
+ createAdapter: () => new MysqlAdapter(),
39
+ createDriver: () => new DummyDriver(),
40
+ createIntrospector: (db) => new MysqlIntrospector(db),
41
+ createQueryCompiler: () => new MysqlQueryCompiler(),
42
+ },
43
+ });
44
+
45
+ case "sqlite":
46
+ return new Kysely({
47
+ dialect: {
48
+ createAdapter: () => new SqliteAdapter(),
49
+ createDriver: () => new DummyDriver(),
50
+ createIntrospector: (db) => new SqliteIntrospector(db),
51
+ createQueryCompiler: () => new SqliteQueryCompiler(),
52
+ },
53
+ });
54
+ }
55
+ }