@fragno-dev/db 0.2.2 → 0.3.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 (355) hide show
  1. package/.turbo/turbo-build.log +202 -140
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +30 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +39 -29
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +18 -7
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +116 -54
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +79 -2
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +150 -32
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +42 -1
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +72 -6
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +15 -8
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  165. package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
  166. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  167. package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
  168. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  169. package/dist/query/unit-of-work/unit-of-work.js +86 -5
  170. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  171. package/dist/query/value-decoding.js +9 -6
  172. package/dist/query/value-decoding.js.map +1 -1
  173. package/dist/query/value-encoding.js +29 -9
  174. package/dist/query/value-encoding.js.map +1 -1
  175. package/dist/schema/create.d.ts +38 -14
  176. package/dist/schema/create.d.ts.map +1 -1
  177. package/dist/schema/create.js +81 -42
  178. package/dist/schema/create.js.map +1 -1
  179. package/dist/schema/generate-id.js +2 -2
  180. package/dist/schema/generate-id.js.map +1 -1
  181. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  182. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  183. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  184. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  185. package/dist/schema/validator.d.ts +10 -0
  186. package/dist/schema/validator.d.ts.map +1 -0
  187. package/dist/schema/validator.js +123 -0
  188. package/dist/schema/validator.js.map +1 -0
  189. package/dist/schema-output/drizzle.d.ts +30 -0
  190. package/dist/schema-output/drizzle.d.ts.map +1 -0
  191. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  192. package/dist/schema-output/drizzle.js.map +1 -0
  193. package/dist/schema-output/prisma.d.ts +17 -0
  194. package/dist/schema-output/prisma.d.ts.map +1 -0
  195. package/dist/schema-output/prisma.js +296 -0
  196. package/dist/schema-output/prisma.js.map +1 -0
  197. package/dist/util/default-database-adapter.js +61 -0
  198. package/dist/util/default-database-adapter.js.map +1 -0
  199. package/dist/with-database.d.ts +1 -1
  200. package/dist/with-database.d.ts.map +1 -1
  201. package/dist/with-database.js +12 -3
  202. package/dist/with-database.js.map +1 -1
  203. package/package.json +43 -28
  204. package/src/adapters/adapters.ts +30 -24
  205. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  206. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  207. package/src/adapters/drizzle/test-utils.ts +12 -8
  208. package/src/adapters/generic-sql/driver-config.ts +38 -0
  209. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  210. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  211. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  212. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  213. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  214. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  215. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  216. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  217. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  218. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  219. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  220. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  221. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  222. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  223. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  224. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  225. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  226. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  227. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  228. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  229. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  230. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  231. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  232. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  233. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  234. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  235. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  236. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  237. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
  238. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
  239. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  240. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  241. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  242. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  243. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  244. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  245. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  246. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  247. package/src/adapters/in-memory/errors.ts +20 -0
  248. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  249. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  250. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  251. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  252. package/src/adapters/in-memory/index.ts +3 -0
  253. package/src/adapters/in-memory/options.test.ts +41 -0
  254. package/src/adapters/in-memory/options.ts +87 -0
  255. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  256. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  257. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  258. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  259. package/src/adapters/in-memory/store.test.ts +68 -0
  260. package/src/adapters/in-memory/store.ts +145 -0
  261. package/src/adapters/in-memory/value-comparison.ts +53 -0
  262. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  263. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  264. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  265. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  266. package/src/adapters/sql/index.ts +12 -0
  267. package/src/db-fragment-definition-builder.test.ts +30 -12
  268. package/src/db-fragment-definition-builder.ts +142 -73
  269. package/src/db-fragment-instantiator.test.ts +105 -13
  270. package/src/db-fragment-integration.test.ts +9 -7
  271. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  272. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  273. package/src/dispatchers/node/index.test.ts +91 -0
  274. package/src/dispatchers/node/index.ts +87 -0
  275. package/src/fragments/internal-fragment.routes.ts +42 -0
  276. package/src/fragments/internal-fragment.schema.ts +51 -0
  277. package/src/fragments/internal-fragment.test.ts +458 -8
  278. package/src/fragments/internal-fragment.ts +322 -63
  279. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  280. package/src/hooks/durable-hooks-processor.ts +67 -0
  281. package/src/hooks/hooks.test.ts +165 -5
  282. package/src/hooks/hooks.ts +197 -9
  283. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  284. package/src/migration-engine/auto-from-schema.ts +5 -2
  285. package/src/migration-engine/create.test.ts +2 -2
  286. package/src/migration-engine/generation-engine.test.ts +229 -104
  287. package/src/migration-engine/generation-engine.ts +94 -64
  288. package/src/migration-engine/shared.ts +1 -0
  289. package/src/mod.ts +64 -26
  290. package/src/naming/sql-naming.ts +180 -0
  291. package/src/outbox/outbox-builder.ts +241 -0
  292. package/src/outbox/outbox.test.ts +253 -0
  293. package/src/outbox/outbox.ts +137 -0
  294. package/src/query/column-defaults.ts +41 -3
  295. package/src/query/condition-builder.test.ts +3 -3
  296. package/src/query/cursor.test.ts +116 -18
  297. package/src/query/cursor.ts +75 -26
  298. package/src/query/db-now.ts +6 -0
  299. package/src/query/query-type.test.ts +2 -2
  300. package/src/query/serialize/create-sql-serializer.ts +7 -2
  301. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  302. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  303. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  304. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  305. package/src/query/serialize/sql-serializer.ts +4 -4
  306. package/src/query/simple-query-interface.ts +5 -0
  307. package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
  308. package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
  309. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
  310. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  311. package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
  312. package/src/query/unit-of-work/unit-of-work.ts +203 -18
  313. package/src/query/value-decoding.test.ts +13 -2
  314. package/src/query/value-decoding.ts +17 -4
  315. package/src/query/value-encoding.test.ts +85 -2
  316. package/src/query/value-encoding.ts +56 -6
  317. package/src/schema/create.test.ts +129 -42
  318. package/src/schema/create.ts +185 -47
  319. package/src/schema/generate-id.test.ts +2 -2
  320. package/src/schema/generate-id.ts +2 -2
  321. package/src/schema/serialize.test.ts +14 -2
  322. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  323. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  324. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  325. package/src/schema/validator.test.ts +197 -0
  326. package/src/schema/validator.ts +231 -0
  327. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  328. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  329. package/src/schema-output/prisma.test.ts +536 -0
  330. package/src/schema-output/prisma.ts +573 -0
  331. package/src/util/default-database-adapter.ts +106 -0
  332. package/src/with-database.ts +22 -3
  333. package/tsdown.config.ts +6 -4
  334. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  335. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  337. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  338. package/dist/adapters/drizzle/generate.d.ts +0 -30
  339. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/generate.js.map +0 -1
  341. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  342. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  343. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  344. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  345. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  346. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  347. package/dist/adapters/shared/table-name-mapper.js +0 -43
  348. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  349. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  350. package/dist/schema-generator/schema-generator.d.ts +0 -15
  351. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  352. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  353. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  354. package/src/adapters/shared/table-name-mapper.ts +0 -50
  355. package/src/schema-generator/schema-generator.ts +0 -12
@@ -2,6 +2,7 @@ import type { AnyColumn } from "../../../schema/create";
2
2
  import type { Condition } from "../../../query/condition-builder";
3
3
  import { decodeCursor, serializeCursorValues, type Cursor } from "../../../query/cursor";
4
4
  import type { DriverConfig } from "../driver-config";
5
+ import type { SQLiteStorageMode } from "../sqlite-storage";
5
6
 
6
7
  /**
7
8
  * Build a cursor condition for pagination.
@@ -15,6 +16,7 @@ import type { DriverConfig } from "../driver-config";
15
16
  * @param orderDirection - Direction of ordering (asc/desc)
16
17
  * @param isAfter - True for "after" cursor (forward pagination), false for "before" (backward)
17
18
  * @param driverConfig - The driver configuration for value serialization
19
+ * @param sqliteStorageMode - Optional SQLite storage mode for date/bigint serialization
18
20
  * @returns A Condition object for the cursor, or undefined if no cursor
19
21
  * @throws Error if multi-column cursors are not supported by the implementation
20
22
  */
@@ -24,6 +26,7 @@ export function buildCursorCondition(
24
26
  orderDirection: "asc" | "desc",
25
27
  isAfter: boolean,
26
28
  driverConfig: DriverConfig,
29
+ sqliteStorageMode?: SQLiteStorageMode,
27
30
  ): Condition | undefined {
28
31
  if (!cursor || indexColumns.length === 0) {
29
32
  return undefined;
@@ -31,7 +34,12 @@ export function buildCursorCondition(
31
34
 
32
35
  // Decode cursor if it's a string, otherwise use it as-is
33
36
  const cursorObj = typeof cursor === "string" ? decodeCursor(cursor) : cursor;
34
- const serializedValues = serializeCursorValues(cursorObj, indexColumns, driverConfig);
37
+ const serializedValues = serializeCursorValues(
38
+ cursorObj,
39
+ indexColumns,
40
+ driverConfig,
41
+ sqliteStorageMode,
42
+ );
35
43
 
36
44
  // Determine comparison operator based on direction and after/before
37
45
  const useGreaterThan =
@@ -40,7 +48,7 @@ export function buildCursorCondition(
40
48
  if (indexColumns.length === 1) {
41
49
  // Simple single-column case
42
50
  const col = indexColumns[0]!;
43
- const val = serializedValues[col.ormName];
51
+ const val = serializedValues[col.name];
44
52
  const operator = useGreaterThan ? ">" : "<";
45
53
  return {
46
54
  type: "compare",
@@ -48,9 +56,36 @@ export function buildCursorCondition(
48
56
  operator,
49
57
  b: val,
50
58
  };
51
- } else {
52
- throw new Error(
53
- "Multi-column cursor pagination is not yet supported in Generic SQL implementation",
54
- );
55
59
  }
60
+
61
+ const operator = useGreaterThan ? ">" : "<";
62
+ const orConditions: Condition[] = [];
63
+ const isNullish = (value: unknown): value is null | undefined =>
64
+ value === null || value === undefined;
65
+ const buildEqualityCondition = (column: AnyColumn, value: unknown): Condition =>
66
+ isNullish(value)
67
+ ? { type: "compare", a: column, operator: "is", b: null }
68
+ : { type: "compare", a: column, operator: "=", b: value };
69
+
70
+ for (let i = 0; i < indexColumns.length; i += 1) {
71
+ const col = indexColumns[i]!;
72
+ const val = serializedValues[col.name];
73
+ const andItems: Condition[] = [];
74
+
75
+ for (let j = 0; j < i; j += 1) {
76
+ const prevCol = indexColumns[j]!;
77
+ andItems.push(buildEqualityCondition(prevCol, serializedValues[prevCol.name]));
78
+ }
79
+
80
+ andItems.push({
81
+ type: "compare",
82
+ a: col,
83
+ operator,
84
+ b: val,
85
+ });
86
+
87
+ orConditions.push(andItems.length === 1 ? andItems[0]! : { type: "and", items: andItems });
88
+ }
89
+
90
+ return { type: "or", items: orConditions };
56
91
  }
@@ -5,7 +5,7 @@ import { schema, column, idColumn, referenceColumn, FragnoId } from "../../../sc
5
5
  import { Cursor } from "../../../query/cursor";
6
6
 
7
7
  // Test schema with indexes
8
- const testSchema = schema((s) => {
8
+ const testSchema = schema("test", (s) => {
9
9
  return s
10
10
  .addTable("users", (t) => {
11
11
  return t
@@ -17,7 +17,7 @@ const testSchema = schema((s) => {
17
17
  .addColumn("createdAt", column("timestamp"))
18
18
  .addColumn("invitedBy", referenceColumn().nullable())
19
19
  .createIndex("idx_email", ["email"], { unique: true })
20
- .createIndex("idx_name", ["name"])
20
+ .createIndex("idx_users_name", ["name"])
21
21
  .createIndex("idx_age", ["age"]);
22
22
  })
23
23
  .addTable("posts", (t) => {
@@ -37,21 +37,21 @@ const testSchema = schema((s) => {
37
37
  .addColumn("content", column("string"))
38
38
  .addColumn("postId", referenceColumn())
39
39
  .addColumn("authorId", referenceColumn())
40
- .createIndex("idx_post", ["postId"])
40
+ .createIndex("idx_comments_post", ["postId"])
41
41
  .createIndex("idx_author", ["authorId"]);
42
42
  })
43
43
  .addTable("tags", (t) => {
44
44
  return t
45
45
  .addColumn("id", idColumn())
46
46
  .addColumn("name", column("string"))
47
- .createIndex("idx_name", ["name"]);
47
+ .createIndex("idx_tags_name", ["name"]);
48
48
  })
49
49
  .addTable("post_tags", (t) => {
50
50
  return t
51
51
  .addColumn("id", idColumn())
52
52
  .addColumn("postId", referenceColumn())
53
53
  .addColumn("tagId", referenceColumn())
54
- .createIndex("idx_post", ["postId"])
54
+ .createIndex("idx_post_tags_post", ["postId"])
55
55
  .createIndex("idx_tag", ["tagId"]);
56
56
  })
57
57
  .addReference("author", {
@@ -87,7 +87,7 @@ const testSchema = schema((s) => {
87
87
  });
88
88
 
89
89
  // Schema with custom-named id columns
90
- const customIdSchema = schema((s) => {
90
+ const customIdSchema = schema("customid", (s) => {
91
91
  return s
92
92
  .addTable("products", (t) => {
93
93
  return t
@@ -232,7 +232,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
232
232
 
233
233
  expect(result).not.toBeNull();
234
234
  expect(result!.query.sql).toMatchInlineSnapshot(
235
- `"update "users" set "name" = ?, "_version" = COALESCE(_version, 0) + 1 where "users"."id" = ?"`,
235
+ `"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
236
236
  );
237
237
  expect(result!.expectedAffectedRows).toBeNull();
238
238
  });
@@ -253,7 +253,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
253
253
 
254
254
  expect(result).not.toBeNull();
255
255
  expect(result!.query.sql).toMatchInlineSnapshot(
256
- `"update "users" set "name" = ?, "_version" = COALESCE(_version, 0) + 1 where ("users"."id" = ? and "users"."_version" = ?)"`,
256
+ `"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where ("users"."id" = ? and "users"."_version" = ?)"`,
257
257
  );
258
258
  expect(result!.expectedAffectedRows).toBe(1n);
259
259
  });
@@ -396,7 +396,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
396
396
 
397
397
  expect(result).not.toBeNull();
398
398
  expect(result!.query.sql).toMatchInlineSnapshot(
399
- `"update "posts" set "userId" = (select "_internalId" from "users" where "id" = ? limit ?), "_version" = COALESCE(_version, 0) + 1 where "posts"."id" = ?"`,
399
+ `"update "posts" set "userId" = (select "_internalId" from "users" where "id" = ? limit ?), "_version" = coalesce("_version", 0) + 1 where "posts"."id" = ?"`,
400
400
  );
401
401
  });
402
402
 
@@ -418,7 +418,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
418
418
  // Should not have nested SELECT for the userId value
419
419
  expect(result!.query.sql).not.toMatch(/\(select.*from.*users/i);
420
420
  expect(result!.query.sql).toMatchInlineSnapshot(
421
- `"update "posts" set "userId" = ?, "_version" = COALESCE(_version, 0) + 1 where "posts"."id" = ?"`,
421
+ `"update "posts" set "userId" = ?, "_version" = coalesce("_version", 0) + 1 where "posts"."id" = ?"`,
422
422
  );
423
423
  });
424
424
 
@@ -440,7 +440,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
440
440
 
441
441
  expect(result).not.toBeNull();
442
442
  expect(result!.query.sql).toMatchInlineSnapshot(
443
- `"update "users" set "name" = ?, "email" = ?, "isActive" = ?, "_version" = COALESCE(_version, 0) + 1 where "users"."id" = ?"`,
443
+ `"update "users" set "name" = ?, "email" = ?, "isActive" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
444
444
  );
445
445
  });
446
446
  });
@@ -612,7 +612,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
612
612
 
613
613
  expect(result).not.toBeNull();
614
614
  expect(result!.query.sql).toMatchInlineSnapshot(
615
- `"update "products" set "price" = ?, "_version" = COALESCE(_version, 0) + 1 where "products"."productId" = ?"`,
615
+ `"update "products" set "price" = ?, "_version" = coalesce("_version", 0) + 1 where "products"."productId" = ?"`,
616
616
  );
617
617
  });
618
618
 
@@ -757,11 +757,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
757
757
  type: "find",
758
758
  schema: testSchema,
759
759
  table: testSchema.tables.users,
760
- indexName: "idx_name",
760
+ indexName: "idx_users_name",
761
761
  options: {
762
- useIndex: "idx_name",
762
+ useIndex: "idx_users_name",
763
763
  select: true,
764
- orderByIndex: { indexName: "idx_name", direction: "asc" },
764
+ orderByIndex: { indexName: "idx_users_name", direction: "asc" },
765
765
  },
766
766
  });
767
767
 
@@ -799,7 +799,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
799
799
  test("should compile find with cursor pagination using after", () => {
800
800
  const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
801
801
  const cursor = new Cursor({
802
- indexName: "idx_name",
802
+ indexName: "idx_users_name",
803
803
  orderDirection: "asc",
804
804
  pageSize: 10,
805
805
  indexValues: { name: "Alice" },
@@ -809,11 +809,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
809
809
  type: "find",
810
810
  schema: testSchema,
811
811
  table: testSchema.tables.users,
812
- indexName: "idx_name",
812
+ indexName: "idx_users_name",
813
813
  options: {
814
- useIndex: "idx_name",
814
+ useIndex: "idx_users_name",
815
815
  select: true,
816
- orderByIndex: { indexName: "idx_name", direction: "asc" },
816
+ orderByIndex: { indexName: "idx_users_name", direction: "asc" },
817
817
  after: cursor,
818
818
  pageSize: 10,
819
819
  },
@@ -829,7 +829,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
829
829
  test("should compile find with cursor pagination using before", () => {
830
830
  const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
831
831
  const cursor = new Cursor({
832
- indexName: "idx_name",
832
+ indexName: "idx_users_name",
833
833
  orderDirection: "desc",
834
834
  pageSize: 10,
835
835
  indexValues: { name: "Bob" },
@@ -839,11 +839,11 @@ describe("GenericSQLUOWOperationCompiler", () => {
839
839
  type: "find",
840
840
  schema: testSchema,
841
841
  table: testSchema.tables.users,
842
- indexName: "idx_name",
842
+ indexName: "idx_users_name",
843
843
  options: {
844
- useIndex: "idx_name",
844
+ useIndex: "idx_users_name",
845
845
  select: true,
846
- orderByIndex: { indexName: "idx_name", direction: "desc" },
846
+ orderByIndex: { indexName: "idx_users_name", direction: "desc" },
847
847
  before: cursor,
848
848
  pageSize: 10,
849
849
  },
@@ -859,7 +859,7 @@ describe("GenericSQLUOWOperationCompiler", () => {
859
859
  test("should compile find with cursor pagination and additional where conditions", () => {
860
860
  const compiler = new GenericSQLUOWOperationCompiler(driverConfig);
861
861
  const cursor = new Cursor({
862
- indexName: "idx_name",
862
+ indexName: "idx_users_name",
863
863
  orderDirection: "asc",
864
864
  pageSize: 5,
865
865
  indexValues: { name: "Alice" },
@@ -869,12 +869,12 @@ describe("GenericSQLUOWOperationCompiler", () => {
869
869
  type: "find",
870
870
  schema: testSchema,
871
871
  table: testSchema.tables.users,
872
- indexName: "idx_name",
872
+ indexName: "idx_users_name",
873
873
  options: {
874
- useIndex: "idx_name",
874
+ useIndex: "idx_users_name",
875
875
  select: true,
876
876
  where: (eb) => eb("isActive", "=", true),
877
- orderByIndex: { indexName: "idx_name", direction: "asc" },
877
+ orderByIndex: { indexName: "idx_users_name", direction: "asc" },
878
878
  after: cursor,
879
879
  pageSize: 5,
880
880
  },
@@ -1,7 +1,8 @@
1
1
  import { UOWOperationCompiler } from "../../shared/uow-operation-compiler";
2
2
  import type { CompiledQuery } from "kysely";
3
3
  import type { DriverConfig } from "../driver-config";
4
- import type { TableNameMapper } from "../../shared/table-name-mapper";
4
+ import type { NamingResolver } from "../../../naming/sql-naming";
5
+ import type { SQLiteStorageMode } from "../sqlite-storage";
5
6
  import type {
6
7
  RetrievalOperation,
7
8
  MutationOperation,
@@ -24,26 +25,40 @@ import { createColdKysely } from "../migration/cold-kysely";
24
25
  * high-level business logic like cursor pagination, version checking, and index resolution.
25
26
  */
26
27
  export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<CompiledQuery> {
28
+ private readonly sqliteStorageMode?: SQLiteStorageMode;
29
+
27
30
  constructor(
28
31
  driverConfig: DriverConfig,
29
- mapperFactory?: (namespace: string | undefined) => TableNameMapper | undefined,
32
+ sqliteStorageMode?: SQLiteStorageMode,
33
+ resolverFactory?: (schema: AnySchema, namespace: string | null) => NamingResolver,
30
34
  ) {
31
- super(driverConfig, mapperFactory);
35
+ super(driverConfig, resolverFactory);
36
+ this.sqliteStorageMode = sqliteStorageMode;
32
37
  }
33
38
 
34
39
  /**
35
40
  * Get SQL compiler for a specific namespace
36
41
  */
37
- private getSQLCompiler(namespace: string | undefined): SQLQueryCompiler {
38
- const mapper = this.getMapperForOperation(namespace);
42
+ private getSQLCompiler(
43
+ schema: AnySchema,
44
+ namespace: string | null | undefined,
45
+ ): SQLQueryCompiler {
46
+ const resolver = this.getNamingResolver(schema, namespace ?? null);
39
47
  const kysely = createColdKysely(this.driverConfig.databaseType);
40
- return createSQLQueryCompiler(kysely, this.driverConfig, mapper);
48
+ const schemaName = resolver.getSchemaName();
49
+ const scopedKysely = schemaName ? kysely.withSchema(schemaName) : kysely;
50
+ return createSQLQueryCompiler(
51
+ scopedKysely,
52
+ this.driverConfig,
53
+ this.sqliteStorageMode,
54
+ resolver,
55
+ );
41
56
  }
42
57
 
43
58
  override compileCount(
44
59
  op: RetrievalOperation<AnySchema> & { type: "count" },
45
60
  ): CompiledQuery | null {
46
- const sqlCompiler = this.getSQLCompiler(op.namespace);
61
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
47
62
 
48
63
  // Build where condition
49
64
  let conditions = op.options.where
@@ -61,7 +76,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
61
76
  }
62
77
 
63
78
  override compileFind(op: RetrievalOperation<AnySchema> & { type: "find" }): CompiledQuery | null {
64
- const sqlCompiler = this.getSQLCompiler(op.namespace);
79
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
65
80
 
66
81
  // Extract options
67
82
  const {
@@ -116,6 +131,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
116
131
  orderDirection,
117
132
  !!after,
118
133
  this.driverConfig,
134
+ this.sqliteStorageMode,
119
135
  );
120
136
 
121
137
  // Combine user where clause with cursor condition
@@ -160,7 +176,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
160
176
  const compiledOptions = buildFindOptions(op.table, {
161
177
  ...findManyOptions,
162
178
  where: combinedWhere ? () => combinedWhere! : undefined,
163
- orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),
179
+ orderBy: orderBy?.map(([col, dir]) => [col.name, dir]),
164
180
  limit: effectiveLimit,
165
181
  });
166
182
 
@@ -174,11 +190,12 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
174
190
  override compileCreate(
175
191
  op: MutationOperation<AnySchema> & { type: "create" },
176
192
  ): CompiledMutation<CompiledQuery> | null {
177
- const sqlCompiler = this.getSQLCompiler(op.namespace);
193
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
178
194
  const table = this.getTable(op.schema, op.table);
179
195
 
180
196
  return {
181
197
  query: sqlCompiler.compileCreate(table, op.values),
198
+ operation: op,
182
199
  op: "create",
183
200
  expectedAffectedRows: null, // creates don't need affected row checks
184
201
  expectedReturnedRows: null,
@@ -188,7 +205,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
188
205
  override compileUpdate(
189
206
  op: MutationOperation<AnySchema> & { type: "update" },
190
207
  ): CompiledMutation<CompiledQuery> | null {
191
- const sqlCompiler = this.getSQLCompiler(op.namespace);
208
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
192
209
  const table = this.getTable(op.schema, op.table);
193
210
  const idColumn = table.getIdColumn();
194
211
  const versionColumn = table.getVersionColumn();
@@ -200,12 +217,9 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
200
217
  const conditionsResult =
201
218
  versionToCheck !== undefined
202
219
  ? buildCondition(table.columns, (eb) =>
203
- eb.and(
204
- eb(idColumn.ormName, "=", externalId),
205
- eb(versionColumn.ormName, "=", versionToCheck),
206
- ),
220
+ eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", versionToCheck)),
207
221
  )
208
- : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
222
+ : buildCondition(table.columns, (eb) => eb(idColumn.name, "=", externalId));
209
223
 
210
224
  if (conditionsResult === false) {
211
225
  return null;
@@ -229,6 +243,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
229
243
 
230
244
  return {
231
245
  query,
246
+ operation: op,
232
247
  op: "update",
233
248
  expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
234
249
  expectedReturnedRows: useReturningForCheck ? 1 : null,
@@ -238,7 +253,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
238
253
  override compileDelete(
239
254
  op: MutationOperation<AnySchema> & { type: "delete" },
240
255
  ): CompiledMutation<CompiledQuery> | null {
241
- const sqlCompiler = this.getSQLCompiler(op.namespace);
256
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
242
257
  const table = this.getTable(op.schema, op.table);
243
258
  const idColumn = table.getIdColumn();
244
259
  const versionColumn = table.getVersionColumn();
@@ -250,12 +265,9 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
250
265
  const conditionsResult =
251
266
  versionToCheck !== undefined
252
267
  ? buildCondition(table.columns, (eb) =>
253
- eb.and(
254
- eb(idColumn.ormName, "=", externalId),
255
- eb(versionColumn.ormName, "=", versionToCheck),
256
- ),
268
+ eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", versionToCheck)),
257
269
  )
258
- : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
270
+ : buildCondition(table.columns, (eb) => eb(idColumn.name, "=", externalId));
259
271
 
260
272
  if (conditionsResult === false) {
261
273
  return null;
@@ -278,6 +290,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
278
290
 
279
291
  return {
280
292
  query,
293
+ operation: op,
281
294
  op: "delete",
282
295
  expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
283
296
  expectedReturnedRows: useReturningForCheck ? 1 : null,
@@ -287,7 +300,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
287
300
  override compileCheck(
288
301
  op: MutationOperation<AnySchema> & { type: "check" },
289
302
  ): CompiledMutation<CompiledQuery> {
290
- const sqlCompiler = this.getSQLCompiler(op.namespace);
303
+ const sqlCompiler = this.getSQLCompiler(op.schema, op.namespace);
291
304
  const table = this.getTable(op.schema, op.table);
292
305
  const idColumn = table.getIdColumn();
293
306
  const versionColumn = table.getVersionColumn();
@@ -297,7 +310,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
297
310
 
298
311
  // Build a SELECT 1 query to check if the row exists with the correct version
299
312
  const condition = buildCondition(table.columns, (eb) =>
300
- eb.and(eb(idColumn.ormName, "=", externalId), eb(versionColumn.ormName, "=", version)),
313
+ eb.and(eb(idColumn.name, "=", externalId), eb(versionColumn.name, "=", version)),
301
314
  );
302
315
 
303
316
  if (typeof condition === "boolean") {
@@ -306,6 +319,7 @@ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<Compile
306
319
 
307
320
  return {
308
321
  query: sqlCompiler.compileCheck(table, condition),
322
+ operation: op,
309
323
  op: "check",
310
324
  expectedAffectedRows: null,
311
325
  expectedReturnedRows: 1, // Check that exactly 1 row was returned
@@ -3,7 +3,7 @@ import { column, idColumn, referenceColumn, schema } from "../../../schema/creat
3
3
  import { mapSelect, extendSelect } from "./select-builder";
4
4
 
5
5
  describe("select-builder", () => {
6
- const testSchema = schema((s) => {
6
+ const testSchema = schema("test", (s) => {
7
7
  return s
8
8
  .addTable("users", (t) => {
9
9
  return t
@@ -35,7 +35,7 @@ describe("select-builder", () => {
35
35
 
36
36
  describe("mapSelect", () => {
37
37
  it("should map select clause with array of keys", () => {
38
- const result = mapSelect(["id", "name", "email"], usersTable);
38
+ const result = mapSelect(["id", "name", "email"], usersTable, undefined);
39
39
  expect(result).toEqual([
40
40
  "users.id as id",
41
41
  "users.name as name",
@@ -46,7 +46,7 @@ describe("select-builder", () => {
46
46
  });
47
47
 
48
48
  it("should map select all columns when true", () => {
49
- const result = mapSelect(true, usersTable);
49
+ const result = mapSelect(true, usersTable, undefined);
50
50
  expect(result).toEqual([
51
51
  "users.id as id",
52
52
  "users.name as name",
@@ -60,7 +60,9 @@ describe("select-builder", () => {
60
60
  });
61
61
 
62
62
  it("should map select with relation prefix", () => {
63
- const result = mapSelect(["id", "name"], usersTable, { relation: "author" });
63
+ const result = mapSelect(["id", "name"], usersTable, undefined, {
64
+ relation: "author",
65
+ });
64
66
  expect(result).toEqual([
65
67
  "users.id as author:id",
66
68
  "users.name as author:name",
@@ -70,7 +72,9 @@ describe("select-builder", () => {
70
72
  });
71
73
 
72
74
  it("should map select with custom table name", () => {
73
- const result = mapSelect(["id", "title"], postsTable, { tableName: "p" });
75
+ const result = mapSelect(["id", "title"], postsTable, undefined, {
76
+ tableName: "p",
77
+ });
74
78
  expect(result).toEqual([
75
79
  "p.id as id",
76
80
  "p.title as title",
@@ -80,7 +84,7 @@ describe("select-builder", () => {
80
84
  });
81
85
 
82
86
  it("should map select with both relation and custom table name", () => {
83
- const result = mapSelect(["id", "title"], postsTable, {
87
+ const result = mapSelect(["id", "title"], postsTable, undefined, {
84
88
  relation: "posts",
85
89
  tableName: "p",
86
90
  });
@@ -93,7 +97,7 @@ describe("select-builder", () => {
93
97
  });
94
98
 
95
99
  it("should handle single column select", () => {
96
- const result = mapSelect(["name"], usersTable);
100
+ const result = mapSelect(["name"], usersTable, undefined);
97
101
  expect(result).toEqual([
98
102
  "users.name as name",
99
103
  "users._internalId as _internalId",
@@ -104,7 +108,7 @@ describe("select-builder", () => {
104
108
  it("should skip hidden columns when explicitly selecting", () => {
105
109
  // When an array is passed, hidden columns should not be included in the select
106
110
  // (unless they are in the array), but they should always be added at the end
107
- const result = mapSelect(["name", "email"], usersTable);
111
+ const result = mapSelect(["name", "email"], usersTable, undefined);
108
112
  // Should not duplicate _internalId or _version in the main select
109
113
  expect(result).toEqual([
110
114
  "users.name as name",
@@ -116,19 +120,19 @@ describe("select-builder", () => {
116
120
 
117
121
  it("should always include hidden columns", () => {
118
122
  // Hidden columns (_internalId, _version) should always be included
119
- const result = mapSelect(["name"], usersTable);
123
+ const result = mapSelect(["name"], usersTable, undefined);
120
124
  expect(result.some((col) => col.includes("_internalId"))).toBe(true);
121
125
  expect(result.some((col) => col.includes("_version"))).toBe(true);
122
126
  });
123
127
 
124
128
  it("should handle empty select array", () => {
125
- const result = mapSelect([], usersTable);
129
+ const result = mapSelect([], usersTable, undefined);
126
130
  // Should still include hidden columns
127
131
  expect(result).toEqual(["users._internalId as _internalId", "users._version as _version"]);
128
132
  });
129
133
 
130
134
  it("should work with different table schemas", () => {
131
- const result = mapSelect(["id", "title", "content"], postsTable);
135
+ const result = mapSelect(["id", "title", "content"], postsTable, undefined);
132
136
  expect(result).toEqual([
133
137
  "posts.id as id",
134
138
  "posts.title as title",
@@ -1,5 +1,6 @@
1
1
  import type { AnyTable } from "../../../schema/create";
2
2
  import type { AnySelectClause } from "../../../query/simple-query-interface";
3
+ import type { NamingResolver } from "../../../naming/sql-naming";
3
4
 
4
5
  /**
5
6
  * Maps a select clause to SQL column names with optional aliases.
@@ -18,6 +19,7 @@ import type { AnySelectClause } from "../../../query/simple-query-interface";
18
19
  export function mapSelect(
19
20
  select: AnySelectClause,
20
21
  table: AnyTable,
22
+ resolver: NamingResolver | undefined,
21
23
  options: {
22
24
  relation?: string;
23
25
  tableName?: string;
@@ -37,7 +39,8 @@ export function mapSelect(
37
39
 
38
40
  // Add the column to the select list
39
41
  const name = relation ? `${relation}:${key}` : key;
40
- out.push(`${tableName}.${col.name} as ${name}`);
42
+ const columnName = resolver ? resolver.getColumnName(table.name, col.name) : col.name;
43
+ out.push(`${tableName}.${columnName} as ${name}`);
41
44
  }
42
45
 
43
46
  // Always include hidden columns (for FragnoId construction with internal ID and version)
@@ -45,7 +48,8 @@ export function mapSelect(
45
48
  const col = table.columns[key];
46
49
  if (col.isHidden && !keys.includes(key)) {
47
50
  const name = relation ? `${relation}:${key}` : key;
48
- out.push(`${tableName}.${col.name} as ${name}`);
51
+ const columnName = resolver ? resolver.getColumnName(table.name, col.name) : col.name;
52
+ out.push(`${tableName}.${columnName} as ${name}`);
49
53
  }
50
54
  }
51
55
 
@@ -2,6 +2,7 @@ import { describe, test, expect } from "vitest";
2
2
  import { Kysely, SqliteDialect } from "kysely";
3
3
  import Database from "better-sqlite3";
4
4
  import { schema, column, idColumn, referenceColumn } from "../../../schema/create";
5
+ import { createNamingResolver, type SqlNamingStrategy } from "../../../naming/sql-naming";
5
6
  import { PostgreSQLQueryCompiler } from "./dialect/postgres";
6
7
  import { MySQLQueryCompiler } from "./dialect/mysql";
7
8
  import { SQLiteQueryCompiler } from "./dialect/sqlite";
@@ -12,7 +13,7 @@ import {
12
13
  } from "../driver-config";
13
14
 
14
15
  // Test schema
15
- const testSchema = schema((s) => {
16
+ const testSchema = schema("test", (s) => {
16
17
  return s
17
18
  .addTable("users", (t) => {
18
19
  return t
@@ -130,7 +131,7 @@ describe("SQLQueryCompiler", () => {
130
131
  });
131
132
 
132
133
  expect(query.sql).toMatchInlineSnapshot(
133
- `"update "users" set "name" = ?, "_version" = COALESCE(_version, 0) + 1 where "users"."id" = ?"`,
134
+ `"update "users" set "name" = ?, "_version" = coalesce("_version", 0) + 1 where "users"."id" = ?"`,
134
135
  );
135
136
  });
136
137
 
@@ -191,5 +192,54 @@ describe("SQLQueryCompiler", () => {
191
192
  );
192
193
  expect(query.sql).toContain("returning");
193
194
  });
195
+
196
+ test("compileUpdate succeeds when version column needs quoting", async () => {
197
+ const db = new Kysely({
198
+ dialect: new SqliteDialect({ database: new Database(":memory:") }),
199
+ });
200
+
201
+ await db.schema
202
+ .createTable("users")
203
+ .addColumn("id", "text")
204
+ .addColumn("name", "text")
205
+ .addColumn("users-version", "integer")
206
+ .execute();
207
+
208
+ const namingStrategy: SqlNamingStrategy = {
209
+ namespaceScope: "suffix",
210
+ namespaceToSchema: (namespace) => namespace,
211
+ tableName: (logicalTable) => logicalTable,
212
+ columnName: (logicalColumn, logicalTable) =>
213
+ logicalColumn === "_version" ? `${logicalTable}-version` : logicalColumn,
214
+ indexName: (logicalIndex) => logicalIndex,
215
+ uniqueIndexName: (logicalIndex) => logicalIndex,
216
+ foreignKeyName: ({ referenceName }) => referenceName,
217
+ };
218
+
219
+ const resolver = createNamingResolver(testSchema, null, namingStrategy);
220
+ const compiler = new SQLiteQueryCompiler(
221
+ db,
222
+ new BetterSQLite3DriverConfig(),
223
+ undefined,
224
+ resolver,
225
+ );
226
+
227
+ const query = compiler.compileUpdate(testSchema.tables.users, {
228
+ set: { name: "Jane" },
229
+ where: {
230
+ type: "compare",
231
+ a: testSchema.tables.users.columns.id,
232
+ operator: "=",
233
+ b: "user123",
234
+ },
235
+ });
236
+
237
+ expect(query.sql).toContain('coalesce("users-version", 0) + 1');
238
+ try {
239
+ await expect(db.executeQuery(query)).resolves.toBeDefined();
240
+ } finally {
241
+ await db.destroy();
242
+ }
243
+ });
194
244
  });
195
245
  });