@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
@@ -0,0 +1,195 @@
1
+ import { describe, test, expect } from "vitest";
2
+ import { Kysely, SqliteDialect } from "kysely";
3
+ import Database from "better-sqlite3";
4
+ import { schema, column, idColumn, referenceColumn } from "../../../schema/create";
5
+ import { PostgreSQLQueryCompiler } from "./dialect/postgres";
6
+ import { MySQLQueryCompiler } from "./dialect/mysql";
7
+ import { SQLiteQueryCompiler } from "./dialect/sqlite";
8
+ import {
9
+ BetterSQLite3DriverConfig,
10
+ NodePostgresDriverConfig,
11
+ MySQL2DriverConfig,
12
+ } from "../driver-config";
13
+
14
+ // Test schema
15
+ const testSchema = schema((s) => {
16
+ return s
17
+ .addTable("users", (t) => {
18
+ return t
19
+ .addColumn("id", idColumn())
20
+ .addColumn("name", column("string"))
21
+ .addColumn("email", column("string"))
22
+ .addColumn("age", column("integer").nullable());
23
+ })
24
+ .addTable("posts", (t) => {
25
+ return t
26
+ .addColumn("id", idColumn())
27
+ .addColumn("title", column("string"))
28
+ .addColumn("content", column("string"))
29
+ .addColumn("userId", referenceColumn());
30
+ });
31
+ });
32
+
33
+ describe("SQLQueryCompiler", () => {
34
+ describe("PostgreSQLQueryCompiler", () => {
35
+ test("compileCount generates correct SQL", () => {
36
+ const db = new Kysely({
37
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
38
+ });
39
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
40
+
41
+ const query = compiler.compileCount(testSchema.tables.users, {});
42
+
43
+ expect(query.sql).toMatchInlineSnapshot(`"select count(*) as "count" from "users""`);
44
+ });
45
+
46
+ test("compileCount with where clause", () => {
47
+ const db = new Kysely({
48
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
49
+ });
50
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
51
+
52
+ const query = compiler.compileCount(testSchema.tables.users, {
53
+ where: {
54
+ type: "compare",
55
+ a: testSchema.tables.users.columns.age,
56
+ operator: ">",
57
+ b: 18,
58
+ },
59
+ });
60
+
61
+ expect(query.sql).toMatchInlineSnapshot(
62
+ `"select count(*) as "count" from "users" where "users"."age" > ?"`,
63
+ );
64
+ });
65
+
66
+ test("compileFindMany generates correct SQL", () => {
67
+ const db = new Kysely({
68
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
69
+ });
70
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
71
+
72
+ const query = compiler.compileFindMany(testSchema.tables.users, {
73
+ select: true,
74
+ limit: 10,
75
+ });
76
+
77
+ expect(query.sql).toMatchInlineSnapshot(
78
+ `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" limit ?"`,
79
+ );
80
+ });
81
+
82
+ test("compileFindMany with orderBy", () => {
83
+ const db = new Kysely({
84
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
85
+ });
86
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
87
+
88
+ const query = compiler.compileFindMany(testSchema.tables.users, {
89
+ select: true,
90
+ orderBy: [[testSchema.tables.users.columns.name, "asc"]],
91
+ limit: 5,
92
+ });
93
+
94
+ expect(query.sql).toMatchInlineSnapshot(
95
+ `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" order by "users"."name" asc limit ?"`,
96
+ );
97
+ });
98
+
99
+ test("compileCreate generates correct SQL", () => {
100
+ const db = new Kysely({
101
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
102
+ });
103
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
104
+
105
+ const query = compiler.compileCreate(testSchema.tables.users, {
106
+ name: "John",
107
+ email: "john@example.com",
108
+ age: 30,
109
+ });
110
+
111
+ expect(query.sql).toMatchInlineSnapshot(
112
+ `"insert into "users" ("id", "name", "email", "age") values (?, ?, ?, ?) returning "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."_internalId" as "_internalId", "users"."_version" as "_version""`,
113
+ );
114
+ });
115
+
116
+ test("compileUpdate generates correct SQL", () => {
117
+ const db = new Kysely({
118
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
119
+ });
120
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
121
+
122
+ const query = compiler.compileUpdate(testSchema.tables.users, {
123
+ set: { name: "Jane" },
124
+ where: {
125
+ type: "compare",
126
+ a: testSchema.tables.users.columns.id,
127
+ operator: "=",
128
+ b: "user123",
129
+ },
130
+ });
131
+
132
+ expect(query.sql).toMatchInlineSnapshot(
133
+ `"update "users" set "name" = ?, "_version" = COALESCE(_version, 0) + 1 where "users"."id" = ?"`,
134
+ );
135
+ });
136
+
137
+ test("compileDelete generates correct SQL", () => {
138
+ const db = new Kysely({
139
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
140
+ });
141
+ const compiler = new PostgreSQLQueryCompiler(db, new NodePostgresDriverConfig());
142
+
143
+ const query = compiler.compileDelete(testSchema.tables.users, {
144
+ where: {
145
+ type: "compare",
146
+ a: testSchema.tables.users.columns.id,
147
+ operator: "=",
148
+ b: "user123",
149
+ },
150
+ });
151
+
152
+ expect(query.sql).toMatchInlineSnapshot(`"delete from "users" where "users"."id" = ?"`);
153
+ });
154
+ });
155
+
156
+ describe("MySQLQueryCompiler", () => {
157
+ test("compileCreate does not include RETURNING", () => {
158
+ const db = new Kysely({
159
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
160
+ });
161
+ const compiler = new MySQLQueryCompiler(db, new MySQL2DriverConfig());
162
+
163
+ const query = compiler.compileCreate(testSchema.tables.users, {
164
+ name: "John",
165
+ email: "john@example.com",
166
+ age: 30,
167
+ });
168
+
169
+ expect(query.sql).toMatchInlineSnapshot(
170
+ `"insert into "users" ("id", "name", "email", "age") values (?, ?, ?, ?)"`,
171
+ );
172
+ expect(query.sql).not.toContain("returning");
173
+ });
174
+ });
175
+
176
+ describe("SQLiteQueryCompiler", () => {
177
+ test("compileCreate includes RETURNING", () => {
178
+ const db = new Kysely({
179
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
180
+ });
181
+ const compiler = new SQLiteQueryCompiler(db, new BetterSQLite3DriverConfig());
182
+
183
+ const query = compiler.compileCreate(testSchema.tables.users, {
184
+ name: "John",
185
+ email: "john@example.com",
186
+ age: 30,
187
+ });
188
+
189
+ expect(query.sql).toMatchInlineSnapshot(
190
+ `"insert into "users" ("id", "name", "email", "age") values (?, ?, ?, ?) returning "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."_internalId" as "_internalId", "users"."_version" as "_version""`,
191
+ );
192
+ expect(query.sql).toContain("returning");
193
+ });
194
+ });
195
+ });
@@ -0,0 +1,367 @@
1
+ import type {
2
+ CompiledQuery,
3
+ Kysely,
4
+ ExpressionBuilder,
5
+ ExpressionWrapper,
6
+ SelectQueryBuilder,
7
+ InsertQueryBuilder,
8
+ } from "kysely";
9
+ import { sql } from "kysely";
10
+ import type { SqlBool } from "kysely";
11
+ import type { AnyColumn, AnyTable } from "../../../schema/create";
12
+ import type { Condition } from "../../../query/condition-builder";
13
+ import type { DriverConfig, SupportedDatabase } from "../driver-config";
14
+ import type { TableNameMapper } from "../../shared/table-name-mapper";
15
+ import { buildWhere, fullSQLName } from "./where-builder";
16
+ import { mapSelect, extendSelect } from "./select-builder";
17
+ import type { CompiledJoin } from "../../../query/orm/orm";
18
+ import { UnitOfWorkEncoder } from "../uow-encoder";
19
+
20
+ /**
21
+ * Type helpers for Kysely query builders.
22
+ *
23
+ * These use `any` for database schema types because at this abstraction layer,
24
+ * we cannot know the specific database schema - we work with generic query
25
+ * compilation that needs to work across any schema.
26
+ */
27
+
28
+ // oxlint-disable-next-line no-explicit-any
29
+ export type AnyKysely = Kysely<any>;
30
+
31
+ // oxlint-disable-next-line no-explicit-any
32
+ export type AnyExpressionBuilder = ExpressionBuilder<any, any>;
33
+
34
+ // oxlint-disable-next-line no-explicit-any
35
+ export type AnyExpressionWrapper = ExpressionWrapper<any, any, SqlBool>;
36
+
37
+ // oxlint-disable-next-line no-explicit-any
38
+ export type AnySelectQueryBuilder<O = any> = SelectQueryBuilder<any, any, O>;
39
+
40
+ // oxlint-disable-next-line no-explicit-any
41
+ export type AnyInsertQueryBuilder<O = any> = InsertQueryBuilder<any, any, O>;
42
+
43
+ /**
44
+ * Options for compiling a find operation
45
+ */
46
+ export interface FindManyCompilerOptions {
47
+ select: true | string[];
48
+ where?: Condition;
49
+ orderBy?: [AnyColumn, "asc" | "desc"][];
50
+ limit?: number;
51
+ offset?: number;
52
+ join?: CompiledJoin[];
53
+ }
54
+
55
+ /**
56
+ * Options for compiling a count operation
57
+ */
58
+ export interface CountCompilerOptions {
59
+ where?: Condition;
60
+ }
61
+
62
+ /**
63
+ * Options for compiling an update operation
64
+ */
65
+ export interface UpdateCompilerOptions {
66
+ where?: Condition;
67
+ set: Record<string, unknown>;
68
+ /**
69
+ * Whether to add RETURNING clause to the UPDATE query.
70
+ * Used for version conflict detection when driver supports RETURNING but not affected rows.
71
+ */
72
+ returning?: boolean;
73
+ }
74
+
75
+ /**
76
+ * Options for compiling a delete operation
77
+ */
78
+ export interface DeleteCompilerOptions {
79
+ where?: Condition;
80
+ /**
81
+ * Whether to add RETURNING clause to the DELETE query.
82
+ * Used for version conflict detection when driver supports RETURNING but not affected rows.
83
+ */
84
+ returning?: boolean;
85
+ }
86
+
87
+ /**
88
+ * Abstract base class for SQL query compilation.
89
+ *
90
+ * Similar to SQLGenerator for migrations, this class provides a framework
91
+ * for compiling runtime queries with dialect-specific behavior.
92
+ *
93
+ * Each database dialect extends this class and implements the abstract methods
94
+ * to handle database-specific SQL generation (like .limit() vs .top()).
95
+ */
96
+ export abstract class SQLQueryCompiler {
97
+ protected readonly db: AnyKysely;
98
+ protected readonly driverConfig: DriverConfig;
99
+ protected readonly database: SupportedDatabase;
100
+ protected readonly mapper?: TableNameMapper;
101
+ protected readonly encoder: UnitOfWorkEncoder;
102
+
103
+ constructor(db: AnyKysely, driverConfig: DriverConfig, mapper?: TableNameMapper) {
104
+ this.db = db;
105
+ this.driverConfig = driverConfig;
106
+ this.database = driverConfig.databaseType;
107
+ this.mapper = mapper;
108
+ this.encoder = new UnitOfWorkEncoder(driverConfig, db, mapper);
109
+ }
110
+
111
+ /**
112
+ * Apply LIMIT clause to a query.
113
+ * Different databases use different syntax (.limit() vs .top()).
114
+ */
115
+ protected abstract applyLimit<T>(query: T & { limit(limit: number): T }, limit: number): T;
116
+
117
+ /**
118
+ * Apply OFFSET clause to a query.
119
+ * Some databases may not support offset.
120
+ */
121
+ protected abstract applyOffset<T>(query: T & { offset(offset: number): T }, offset: number): T;
122
+
123
+ /**
124
+ * Apply RETURNING clause to an insert/update query.
125
+ * Returns the query with RETURNING if supported, otherwise returns as-is.
126
+ */
127
+ protected abstract applyReturning<T>(
128
+ query: T & { returning(columns: string[]): T },
129
+ columns: string[],
130
+ ): T;
131
+
132
+ /**
133
+ * Get the physical table name, applying namespace mapping if provided.
134
+ */
135
+ protected getTableName(table: AnyTable): string {
136
+ return this.mapper ? this.mapper.toPhysical(table.name) : table.name;
137
+ }
138
+
139
+ /**
140
+ * Build WHERE clause from a condition tree.
141
+ */
142
+ protected buildWhereClause(condition: Condition, eb: AnyExpressionBuilder, table: AnyTable) {
143
+ return buildWhere(condition, eb, this.driverConfig, this.mapper, table);
144
+ }
145
+
146
+ /**
147
+ * Process joins recursively to support nested joins.
148
+ */
149
+ protected processJoins<O>(
150
+ query: AnySelectQueryBuilder<O>,
151
+ joins: CompiledJoin[],
152
+ parentTable: AnyTable,
153
+ parentTableName: string,
154
+ mappedSelect: string[],
155
+ parentPath: string = "",
156
+ ): AnySelectQueryBuilder<O> {
157
+ let result = query;
158
+
159
+ for (const join of joins) {
160
+ const { options: joinOptions, relation } = join;
161
+
162
+ if (joinOptions === false) {
163
+ continue;
164
+ }
165
+
166
+ const targetTable = relation.table;
167
+ // Build the full path for this join (e.g., "author:inviter")
168
+ const fullPath = parentPath ? `${parentPath}:${relation.name}` : relation.name;
169
+ // SQL table alias uses underscores (e.g., "author_inviter")
170
+ const joinName = fullPath.replace(/:/g, "_");
171
+
172
+ // Update select
173
+ mappedSelect.push(
174
+ ...mapSelect(joinOptions.select, targetTable, {
175
+ relation: fullPath, // Use full path with colons for column aliases
176
+ tableName: joinName, // Use underscore version for table name
177
+ }),
178
+ );
179
+
180
+ result = result.leftJoin(`${this.getTableName(targetTable)} as ${joinName}`, (b) =>
181
+ b.on((eb) => {
182
+ const conditions = [];
183
+ for (const [left, right] of relation.on) {
184
+ // Foreign keys always use internal IDs
185
+ // If the relation references an external ID column (any name), translate to "_internalId"
186
+ const rightCol = targetTable.columns[right];
187
+ const actualRight = rightCol?.role === "external-id" ? "_internalId" : right;
188
+
189
+ conditions.push(
190
+ eb(
191
+ `${parentTableName}.${parentTable.columns[left].name}`,
192
+ "=",
193
+ eb.ref(`${joinName}.${targetTable.columns[actualRight].name}`),
194
+ ),
195
+ );
196
+ }
197
+
198
+ if (joinOptions.where) {
199
+ conditions.push(this.buildWhereClause(joinOptions.where, eb, targetTable));
200
+ }
201
+
202
+ return eb.and(conditions);
203
+ }),
204
+ );
205
+
206
+ // Recursively process nested joins with the full path
207
+ if (joinOptions.join && joinOptions.join.length > 0) {
208
+ result = this.processJoins(
209
+ result,
210
+ joinOptions.join,
211
+ targetTable,
212
+ joinName,
213
+ mappedSelect,
214
+ fullPath,
215
+ );
216
+ }
217
+ }
218
+
219
+ return result;
220
+ }
221
+
222
+ /**
223
+ * Compile a COUNT query.
224
+ */
225
+ compileCount(table: AnyTable, options: CountCompilerOptions): CompiledQuery {
226
+ let query = this.db
227
+ .selectFrom(this.getTableName(table))
228
+ .select(this.db.fn.countAll().as("count"));
229
+
230
+ if (options.where) {
231
+ query = query.where((b) => this.buildWhereClause(options.where!, b, table));
232
+ }
233
+
234
+ return query.compile();
235
+ }
236
+
237
+ /**
238
+ * Compile a FIND MANY query.
239
+ */
240
+ compileFindMany(table: AnyTable, options: FindManyCompilerOptions): CompiledQuery {
241
+ let query = this.db.selectFrom(this.getTableName(table));
242
+
243
+ // Apply WHERE clause
244
+ const whereQuery = options.where;
245
+ if (whereQuery) {
246
+ query = query.where((eb) => this.buildWhereClause(whereQuery, eb, table));
247
+ }
248
+
249
+ // Apply OFFSET
250
+ if (options.offset !== undefined) {
251
+ query = this.applyOffset(query, options.offset);
252
+ }
253
+
254
+ // Apply LIMIT
255
+ if (options.limit !== undefined) {
256
+ query = this.applyLimit(query, options.limit);
257
+ }
258
+
259
+ // Apply ORDER BY
260
+ if (options.orderBy) {
261
+ for (const [col, mode] of options.orderBy) {
262
+ query = query.orderBy(fullSQLName(col, this.mapper), mode);
263
+ }
264
+ }
265
+
266
+ // Build SELECT with joins
267
+ const selectBuilder = extendSelect(options.select);
268
+ const mappedSelect: string[] = [];
269
+
270
+ // Process joins if provided
271
+ if (options.join && options.join.length > 0) {
272
+ query = this.processJoins(query, options.join, table, this.getTableName(table), mappedSelect);
273
+ }
274
+
275
+ const compiledSelect = selectBuilder.compile();
276
+ mappedSelect.push(
277
+ ...mapSelect(compiledSelect.result, table, { tableName: this.getTableName(table) }),
278
+ );
279
+
280
+ return query.select(mappedSelect).compile();
281
+ }
282
+
283
+ /**
284
+ * Compile a CREATE (INSERT) query.
285
+ */
286
+ compileCreate(table: AnyTable, values: Record<string, unknown>): CompiledQuery {
287
+ // Encode application values to database format (resolves FragnoId, generates defaults, serializes)
288
+ const encodedValues = this.encoder.encodeForDatabase({
289
+ values,
290
+ table,
291
+ generateDefaults: true,
292
+ });
293
+
294
+ let insert: AnyInsertQueryBuilder = this.db
295
+ .insertInto(this.getTableName(table))
296
+ .values(encodedValues);
297
+
298
+ // Apply RETURNING if supported
299
+ if (this.driverConfig.supportsReturning) {
300
+ const columns = mapSelect(true, table, { tableName: this.getTableName(table) });
301
+ insert = this.applyReturning(insert, columns);
302
+ }
303
+
304
+ return insert.compile();
305
+ }
306
+
307
+ /**
308
+ * Compile an UPDATE query.
309
+ */
310
+ compileUpdate(table: AnyTable, options: UpdateCompilerOptions): CompiledQuery {
311
+ const encoded = this.encoder.encodeForDatabase({
312
+ values: options.set,
313
+ table,
314
+ generateDefaults: false,
315
+ });
316
+
317
+ // Add version increment (must be added after encoding, as a raw SQL expression)
318
+ const versionCol = table.getVersionColumn();
319
+ encoded[versionCol.name] = sql.raw(`COALESCE(${versionCol.name}, 0) + 1`);
320
+
321
+ let query = this.db.updateTable(this.getTableName(table)).set(encoded);
322
+
323
+ if (options.where) {
324
+ query = query.where((eb) => this.buildWhereClause(options.where!, eb, table));
325
+ }
326
+
327
+ // Apply RETURNING if requested and supported
328
+ // Use sql template tag for literal value (not a column name)
329
+ if (options.returning && this.driverConfig.supportsReturning) {
330
+ return query.returning(sql<number>`1`.as("_returned")).compile();
331
+ }
332
+
333
+ return query.compile();
334
+ }
335
+
336
+ /**
337
+ * Compile a DELETE query.
338
+ */
339
+ compileDelete(table: AnyTable, options: DeleteCompilerOptions): CompiledQuery {
340
+ let query = this.db.deleteFrom(this.getTableName(table));
341
+
342
+ if (options.where) {
343
+ query = query.where((eb) => this.buildWhereClause(options.where!, eb, table));
344
+ }
345
+
346
+ // Apply RETURNING if requested and supported
347
+ // Use sql template tag for literal value (not a column name)
348
+ if (options.returning && this.driverConfig.supportsReturning) {
349
+ return query.returning(sql<number>`1`.as("_returned")).compile();
350
+ }
351
+
352
+ return query.compile();
353
+ }
354
+
355
+ /**
356
+ * Compile a CHECK query (SELECT 1 to verify a row exists).
357
+ */
358
+ compileCheck(table: AnyTable, where: Condition): CompiledQuery {
359
+ const query = this.db
360
+ .selectFrom(this.getTableName(table))
361
+ .select(sql<number>`1`.as("exists"))
362
+ .where((eb) => this.buildWhereClause(where, eb, table))
363
+ .limit(1);
364
+
365
+ return query.compile();
366
+ }
367
+ }