@fragno-dev/db 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1,1344 +0,0 @@
1
- import { Kysely, PostgresDialect } from "kysely";
2
- import { beforeAll, describe, expect, it } from "vitest";
3
- import { column, idColumn, referenceColumn, schema } from "../../schema/create";
4
- import {
5
- fullSQLName,
6
- buildWhere,
7
- mapSelect,
8
- extendSelect,
9
- createKyselyQueryBuilder,
10
- } from "./kysely-query-builder";
11
- import type { Kysely as KyselyType } from "kysely";
12
-
13
- describe("query-builder", () => {
14
- const testSchema = schema((s) => {
15
- return s
16
- .addTable("users", (t) => {
17
- return t
18
- .addColumn("id", idColumn())
19
- .addColumn("name", column("string"))
20
- .addColumn("email", column("string"))
21
- .addColumn("age", column("integer").nullable())
22
- .addColumn("isActive", column("bool"))
23
- .addColumn("createdAt", column("timestamp"));
24
- })
25
- .addTable("posts", (t) => {
26
- return t
27
- .addColumn("id", idColumn())
28
- .addColumn("title", column("string"))
29
- .addColumn("content", column("string"))
30
- .addColumn("userId", referenceColumn())
31
- .addColumn("viewCount", column("integer").defaultTo(0))
32
- .addColumn("publishedAt", column("timestamp").nullable());
33
- })
34
- .addReference("author", {
35
- type: "one",
36
- from: { table: "posts", column: "userId" },
37
- to: { table: "users", column: "id" },
38
- });
39
- });
40
-
41
- const usersTable = testSchema.tables.users;
42
- const postsTable = testSchema.tables.posts;
43
-
44
- describe("fullSQLName", () => {
45
- it("should return fully qualified column name", () => {
46
- const result = fullSQLName(usersTable.columns.name);
47
- expect(result).toBe("users.name");
48
- });
49
-
50
- it("should work with different tables", () => {
51
- const result = fullSQLName(postsTable.columns.title);
52
- expect(result).toBe("posts.title");
53
- });
54
-
55
- it("should work with id column", () => {
56
- const result = fullSQLName(usersTable.columns.id);
57
- expect(result).toBe("users.id");
58
- });
59
- });
60
-
61
- describe("buildWhere", () => {
62
- // Mock expression builder for testing
63
- const createMockEB = () => {
64
- const mockEB = ((col: string, op: string, val: unknown) => {
65
- return { type: "compare", col, op, val };
66
- }) as any; // eslint-disable-line @typescript-eslint/no-explicit-any
67
-
68
- mockEB.and = (conditions: unknown[]) => {
69
- return { type: "and", conditions };
70
- };
71
-
72
- mockEB.or = (conditions: unknown[]) => {
73
- return { type: "or", conditions };
74
- };
75
-
76
- mockEB.not = (condition: unknown) => {
77
- return { type: "not", condition };
78
- };
79
-
80
- mockEB.ref = (name: string) => {
81
- return { type: "ref", name };
82
- };
83
-
84
- return mockEB;
85
- };
86
-
87
- describe("comparison operators", () => {
88
- it("should build simple equality comparison", () => {
89
- const condition = {
90
- type: "compare" as const,
91
- a: usersTable.columns.name,
92
- operator: "=" as const,
93
- b: "John",
94
- };
95
-
96
- const result = buildWhere(condition, createMockEB(), "postgresql");
97
- expect(result).toEqual({
98
- type: "compare",
99
- col: "users.name",
100
- op: "=",
101
- val: "John",
102
- });
103
- });
104
-
105
- it("should build greater than comparison", () => {
106
- const condition = {
107
- type: "compare" as const,
108
- a: usersTable.columns.age,
109
- operator: ">" as const,
110
- b: 18,
111
- };
112
-
113
- const result = buildWhere(condition, createMockEB(), "postgresql");
114
- expect(result).toEqual({
115
- type: "compare",
116
- col: "users.age",
117
- op: ">",
118
- val: 18,
119
- });
120
- });
121
-
122
- it("should build less than comparison", () => {
123
- const condition = {
124
- type: "compare" as const,
125
- a: usersTable.columns.age,
126
- operator: "<" as const,
127
- b: 65,
128
- };
129
-
130
- const result = buildWhere(condition, createMockEB(), "postgresql");
131
- expect(result).toEqual({
132
- type: "compare",
133
- col: "users.age",
134
- op: "<",
135
- val: 65,
136
- });
137
- });
138
-
139
- it("should build not equals comparison", () => {
140
- const condition = {
141
- type: "compare" as const,
142
- a: usersTable.columns.isActive,
143
- operator: "!=" as const,
144
- b: true,
145
- };
146
-
147
- const result = buildWhere(condition, createMockEB(), "postgresql");
148
- expect(result).toEqual({
149
- type: "compare",
150
- col: "users.isActive",
151
- op: "!=",
152
- val: true,
153
- });
154
- });
155
- });
156
-
157
- describe("string operators", () => {
158
- it("should build contains operator", () => {
159
- const condition = {
160
- type: "compare" as const,
161
- a: usersTable.columns.name,
162
- operator: "contains" as const,
163
- b: "john",
164
- };
165
-
166
- const result = buildWhere(condition, createMockEB(), "postgresql");
167
- expect(result).toEqual({
168
- type: "compare",
169
- col: "users.name",
170
- op: "like",
171
- val: "%john%",
172
- });
173
- });
174
-
175
- it("should build not contains operator", () => {
176
- const condition = {
177
- type: "compare" as const,
178
- a: usersTable.columns.name,
179
- operator: "not contains" as const,
180
- b: "admin",
181
- };
182
-
183
- const result = buildWhere(condition, createMockEB(), "postgresql");
184
- expect(result).toEqual({
185
- type: "compare",
186
- col: "users.name",
187
- op: "not like",
188
- val: "%admin%",
189
- });
190
- });
191
-
192
- it("should build starts with operator", () => {
193
- const condition = {
194
- type: "compare" as const,
195
- a: usersTable.columns.email,
196
- operator: "starts with" as const,
197
- b: "admin",
198
- };
199
-
200
- const result = buildWhere(condition, createMockEB(), "postgresql");
201
- expect(result).toEqual({
202
- type: "compare",
203
- col: "users.email",
204
- op: "like",
205
- val: "admin%",
206
- });
207
- });
208
-
209
- it("should build not starts with operator", () => {
210
- const condition = {
211
- type: "compare" as const,
212
- a: usersTable.columns.email,
213
- operator: "not starts with" as const,
214
- b: "test",
215
- };
216
-
217
- const result = buildWhere(condition, createMockEB(), "postgresql");
218
- expect(result).toEqual({
219
- type: "compare",
220
- col: "users.email",
221
- op: "not like",
222
- val: "test%",
223
- });
224
- });
225
-
226
- it("should build ends with operator", () => {
227
- const condition = {
228
- type: "compare" as const,
229
- a: usersTable.columns.email,
230
- operator: "ends with" as const,
231
- b: "@example.com",
232
- };
233
-
234
- const result = buildWhere(condition, createMockEB(), "postgresql");
235
- expect(result).toEqual({
236
- type: "compare",
237
- col: "users.email",
238
- op: "like",
239
- val: "%@example.com",
240
- });
241
- });
242
-
243
- it("should build not ends with operator", () => {
244
- const condition = {
245
- type: "compare" as const,
246
- a: usersTable.columns.email,
247
- operator: "not ends with" as const,
248
- b: "@spam.com",
249
- };
250
-
251
- const result = buildWhere(condition, createMockEB(), "postgresql");
252
- expect(result).toEqual({
253
- type: "compare",
254
- col: "users.email",
255
- op: "not like",
256
- val: "%@spam.com",
257
- });
258
- });
259
- });
260
-
261
- describe("column to column comparison", () => {
262
- it("should compare two columns", () => {
263
- const condition = {
264
- type: "compare" as const,
265
- a: usersTable.columns.name,
266
- operator: "=" as const,
267
- b: usersTable.columns.email,
268
- };
269
-
270
- const eb = createMockEB();
271
- const result = buildWhere(condition, eb, "postgresql");
272
- expect(result).toEqual({
273
- type: "compare",
274
- col: "users.name",
275
- op: "=",
276
- val: { type: "ref", name: "users.email" },
277
- });
278
- });
279
- });
280
-
281
- describe("logical operators", () => {
282
- it("should build AND condition", () => {
283
- const condition = {
284
- type: "and" as const,
285
- items: [
286
- {
287
- type: "compare" as const,
288
- a: usersTable.columns.age,
289
- operator: ">" as const,
290
- b: 18,
291
- },
292
- {
293
- type: "compare" as const,
294
- a: usersTable.columns.isActive,
295
- operator: "=" as const,
296
- b: true,
297
- },
298
- ],
299
- };
300
-
301
- const result = buildWhere(condition, createMockEB(), "postgresql");
302
- expect(result).toEqual({
303
- type: "and",
304
- conditions: [
305
- { type: "compare", col: "users.age", op: ">", val: 18 },
306
- { type: "compare", col: "users.isActive", op: "=", val: true },
307
- ],
308
- });
309
- });
310
-
311
- it("should build OR condition", () => {
312
- const condition = {
313
- type: "or" as const,
314
- items: [
315
- {
316
- type: "compare" as const,
317
- a: usersTable.columns.name,
318
- operator: "=" as const,
319
- b: "John",
320
- },
321
- {
322
- type: "compare" as const,
323
- a: usersTable.columns.name,
324
- operator: "=" as const,
325
- b: "Jane",
326
- },
327
- ],
328
- };
329
-
330
- const result = buildWhere(condition, createMockEB(), "postgresql");
331
- expect(result).toEqual({
332
- type: "or",
333
- conditions: [
334
- { type: "compare", col: "users.name", op: "=", val: "John" },
335
- { type: "compare", col: "users.name", op: "=", val: "Jane" },
336
- ],
337
- });
338
- });
339
-
340
- it("should build NOT condition", () => {
341
- const condition = {
342
- type: "not" as const,
343
- item: {
344
- type: "compare" as const,
345
- a: usersTable.columns.isActive,
346
- operator: "=" as const,
347
- b: false,
348
- },
349
- };
350
-
351
- const result = buildWhere(condition, createMockEB(), "postgresql");
352
- expect(result).toEqual({
353
- type: "not",
354
- condition: { type: "compare", col: "users.isActive", op: "=", val: false },
355
- });
356
- });
357
-
358
- it("should build nested conditions", () => {
359
- const condition = {
360
- type: "and" as const,
361
- items: [
362
- {
363
- type: "compare" as const,
364
- a: usersTable.columns.isActive,
365
- operator: "=" as const,
366
- b: true,
367
- },
368
- {
369
- type: "or" as const,
370
- items: [
371
- {
372
- type: "compare" as const,
373
- a: usersTable.columns.age,
374
- operator: ">" as const,
375
- b: 18,
376
- },
377
- {
378
- type: "compare" as const,
379
- a: usersTable.columns.age,
380
- operator: "<" as const,
381
- b: 65,
382
- },
383
- ],
384
- },
385
- ],
386
- };
387
-
388
- const result = buildWhere(condition, createMockEB(), "postgresql");
389
- expect(result).toHaveProperty("type", "and");
390
- expect(result).toHaveProperty("conditions");
391
- });
392
- });
393
- });
394
-
395
- describe("mapSelect", () => {
396
- it("should map select clause with array of keys", () => {
397
- const result = mapSelect(["id", "name", "email"], usersTable);
398
- expect(result).toEqual([
399
- "users.id as id",
400
- "users.name as name",
401
- "users.email as email",
402
- "users._internalId as _internalId",
403
- "users._version as _version",
404
- ]);
405
- });
406
-
407
- it("should map select all columns when true", () => {
408
- const result = mapSelect(true, usersTable);
409
- expect(result).toEqual([
410
- "users.id as id",
411
- "users.name as name",
412
- "users.email as email",
413
- "users.age as age",
414
- "users.isActive as isActive",
415
- "users.createdAt as createdAt",
416
- "users._internalId as _internalId",
417
- "users._version as _version",
418
- ]);
419
- });
420
-
421
- it("should map select with relation prefix", () => {
422
- const result = mapSelect(["id", "name"], usersTable, { relation: "author" });
423
- expect(result).toEqual([
424
- "users.id as author:id",
425
- "users.name as author:name",
426
- "users._internalId as author:_internalId",
427
- "users._version as author:_version",
428
- ]);
429
- });
430
-
431
- it("should map select with custom table name", () => {
432
- const result = mapSelect(["id", "title"], postsTable, { tableName: "p" });
433
- expect(result).toEqual([
434
- "p.id as id",
435
- "p.title as title",
436
- "p._internalId as _internalId",
437
- "p._version as _version",
438
- ]);
439
- });
440
-
441
- it("should map select with both relation and custom table name", () => {
442
- const result = mapSelect(["id", "title"], postsTable, {
443
- relation: "posts",
444
- tableName: "p",
445
- });
446
- expect(result).toEqual([
447
- "p.id as posts:id",
448
- "p.title as posts:title",
449
- "p._internalId as posts:_internalId",
450
- "p._version as posts:_version",
451
- ]);
452
- });
453
-
454
- it("should handle single column select", () => {
455
- const result = mapSelect(["name"], usersTable);
456
- expect(result).toEqual([
457
- "users.name as name",
458
- "users._internalId as _internalId",
459
- "users._version as _version",
460
- ]);
461
- });
462
- });
463
-
464
- describe("extendSelect", () => {
465
- it("should extend array select with new key", () => {
466
- const builder = extendSelect(["name", "email"]);
467
- builder.extend("id");
468
- const compiled = builder.compile();
469
-
470
- expect(compiled.result).toEqual(["name", "email", "id"]);
471
- expect(compiled.extendedKeys).toEqual(["id"]);
472
- });
473
-
474
- it("should not duplicate existing keys", () => {
475
- const builder = extendSelect(["name", "email"]);
476
- builder.extend("name");
477
- const compiled = builder.compile();
478
-
479
- expect(compiled.result).toEqual(["name", "email"]);
480
- expect(compiled.extendedKeys).toEqual([]);
481
- });
482
-
483
- it("should handle true select clause", () => {
484
- const builder = extendSelect(true);
485
- builder.extend("id");
486
- const compiled = builder.compile();
487
-
488
- expect(compiled.result).toBe(true);
489
- expect(compiled.extendedKeys).toEqual([]);
490
- });
491
-
492
- it("should track multiple extended keys", () => {
493
- const builder = extendSelect(["name"]);
494
- builder.extend("id");
495
- builder.extend("email");
496
- builder.extend("age");
497
- const compiled = builder.compile();
498
-
499
- expect(compiled.result).toEqual(["name", "id", "email", "age"]);
500
- expect(compiled.extendedKeys).toEqual(["id", "email", "age"]);
501
- });
502
-
503
- it("should remove extended keys from record", () => {
504
- const builder = extendSelect(["name", "email"]);
505
- builder.extend("id");
506
- const compiled = builder.compile();
507
-
508
- const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
509
- compiled.removeExtendedKeys(record);
510
-
511
- expect(record).toEqual({ name: "John", email: "john@example.com", age: 30 });
512
- });
513
-
514
- it("should not remove non-extended keys", () => {
515
- const builder = extendSelect(["name", "email", "id"]);
516
- builder.extend("age");
517
- const compiled = builder.compile();
518
-
519
- const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
520
- compiled.removeExtendedKeys(record);
521
-
522
- expect(record).toEqual({ id: "123", name: "John", email: "john@example.com" });
523
- });
524
-
525
- it("should handle empty extended keys", () => {
526
- const builder = extendSelect(["name", "email"]);
527
- const compiled = builder.compile();
528
-
529
- const record = { name: "John", email: "john@example.com" };
530
- compiled.removeExtendedKeys(record);
531
-
532
- expect(record).toEqual({ name: "John", email: "john@example.com" });
533
- });
534
- });
535
-
536
- describe("queryCompiler", () => {
537
- let kysely: KyselyType<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
538
-
539
- beforeAll(async () => {
540
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Fake Postgres connection information
541
- kysely = new Kysely({ dialect: new PostgresDialect({} as any) });
542
- });
543
-
544
- describe("count", () => {
545
- it("should compile count query without where clause", () => {
546
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
547
- const query = compiler.count(usersTable, {});
548
-
549
- expect(query.sql).toMatchInlineSnapshot(`"select count(*) as "count" from "users""`);
550
- });
551
-
552
- it("should compile count query with where clause", () => {
553
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
554
- const where = {
555
- type: "compare" as const,
556
- a: usersTable.columns.isActive,
557
- operator: "=" as const,
558
- b: true,
559
- };
560
- const query = compiler.count(usersTable, { where });
561
-
562
- expect(query.sql).toMatchInlineSnapshot(
563
- `"select count(*) as "count" from "users" where "users"."isActive" = $1"`,
564
- );
565
- });
566
- });
567
-
568
- describe("create", () => {
569
- it("should compile insert query for postgresql", () => {
570
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
571
- const query = compiler.create(usersTable, {
572
- name: "John",
573
- email: "john@example.com",
574
- });
575
-
576
- expect(query.sql).toMatchInlineSnapshot(
577
- `"insert into "users" ("id", "name", "email") values ($1, $2, $3) returning "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version""`,
578
- );
579
- });
580
-
581
- it("should compile insert query for sqlite", () => {
582
- const compiler = createKyselyQueryBuilder(kysely, "sqlite");
583
- const query = compiler.create(usersTable, {
584
- name: "John",
585
- email: "john@example.com",
586
- });
587
-
588
- expect(query.sql).toMatchInlineSnapshot(
589
- `"insert into "users" ("id", "name", "email") values ($1, $2, $3) returning "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version""`,
590
- );
591
- });
592
-
593
- it("should compile insert query for mssql", () => {
594
- const compiler = createKyselyQueryBuilder(kysely, "mssql");
595
- const query = compiler.create(usersTable, {
596
- name: "John",
597
- email: "john@example.com",
598
- });
599
-
600
- expect(query.sql).toMatchInlineSnapshot(
601
- `"insert into "users" ("id", "name", "email") output "inserted"."id" as "id", "inserted"."name" as "name", "inserted"."email" as "email", "inserted"."age" as "age", "inserted"."isActive" as "isActive", "inserted"."createdAt" as "createdAt", "inserted"."_internalId" as "_internalId", "inserted"."_version" as "_version" values ($1, $2, $3)"`,
602
- );
603
- });
604
-
605
- it("should compile insert with string reference (external ID)", () => {
606
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
607
- const query = compiler.create(postsTable, {
608
- title: "My Post",
609
- content: "Post content",
610
- userId: "user-external-id-123",
611
- });
612
-
613
- expect(query.sql).toMatchInlineSnapshot(
614
- `"insert into "posts" ("id", "title", "content", "userId") values ($1, $2, $3, (select "_internalId" from "users" where "id" = $4 limit $5)) returning "posts"."id" as "id", "posts"."title" as "title", "posts"."content" as "content", "posts"."userId" as "userId", "posts"."viewCount" as "viewCount", "posts"."publishedAt" as "publishedAt", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version""`,
615
- );
616
- expect(query.sql).toContain("select");
617
- expect(query.sql).toContain("users");
618
- });
619
- });
620
-
621
- describe("reference column subquery handling", () => {
622
- it("should generate subquery for string reference in create", () => {
623
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
624
- const query = compiler.create(postsTable, {
625
- title: "New Post",
626
- content: "Content here",
627
- userId: "user-abc-123",
628
- });
629
-
630
- // Should contain a subquery to look up the internal ID
631
- expect(query.sql).toContain("select");
632
- expect(query.sql).toContain("_internalId");
633
- expect(query.sql).toContain("users");
634
- expect(query.parameters).toContain("user-abc-123");
635
- expect(query.sql).toMatchInlineSnapshot(
636
- `"insert into "posts" ("id", "title", "content", "userId") values ($1, $2, $3, (select "_internalId" from "users" where "id" = $4 limit $5)) returning "posts"."id" as "id", "posts"."title" as "title", "posts"."content" as "content", "posts"."userId" as "userId", "posts"."viewCount" as "viewCount", "posts"."publishedAt" as "publishedAt", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version""`,
637
- );
638
- });
639
-
640
- it("should generate subqueries for string references in createMany", () => {
641
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
642
- const query = compiler.createMany(postsTable, [
643
- {
644
- title: "Post 1",
645
- content: "Content 1",
646
- userId: "user-id-1",
647
- },
648
- {
649
- title: "Post 2",
650
- content: "Content 2",
651
- userId: "user-id-2",
652
- },
653
- ]);
654
-
655
- // Should contain subqueries for both references
656
- expect(query.sql).toContain("select");
657
- expect(query.sql).toContain("_internalId");
658
- expect(query.sql).toContain("users");
659
- expect(query.parameters).toContain("user-id-1");
660
- expect(query.parameters).toContain("user-id-2");
661
- expect(query.sql).toMatchInlineSnapshot(
662
- `"insert into "posts" ("id", "title", "content", "userId") values ($1, $2, $3, (select "_internalId" from "users" where "id" = $4 limit $5)), ($6, $7, $8, (select "_internalId" from "users" where "id" = $9 limit $10))"`,
663
- );
664
- });
665
-
666
- it("should generate subquery for string reference in updateMany", () => {
667
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
668
- const where = {
669
- type: "compare" as const,
670
- a: postsTable.columns.id,
671
- operator: "=" as const,
672
- b: "post-123",
673
- };
674
- const query = compiler.updateMany(postsTable, {
675
- set: { userId: "new-user-id-456" },
676
- where,
677
- });
678
-
679
- expect(query.sql).toMatchInlineSnapshot(
680
- `"update "posts" set "userId" = (select "_internalId" from "users" where "id" = $1 limit $2), "_version" = COALESCE(_version, 0) + 1 where "posts"."id" = $3"`,
681
- );
682
- // Should contain a subquery to look up the internal ID
683
- expect(query.sql).toContain("select");
684
- expect(query.sql).toContain("_internalId");
685
- expect(query.sql).toContain("users");
686
- expect(query.parameters).toContain("new-user-id-456");
687
- });
688
-
689
- it("should handle bigint reference without subquery", () => {
690
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
691
- // Passing a bigint directly should not generate a subquery
692
- const query = compiler.create(postsTable, {
693
- title: "Direct ID Post",
694
- content: "Content",
695
- userId: 12345n,
696
- });
697
-
698
- // For bigint, it should not generate a subquery
699
- // PostgreSQL uses INSERT...RETURNING so it will have "returning" keyword
700
- expect(query.sql).toContain("insert");
701
- expect(query.sql).toContain("returning");
702
- // Should not have nested SELECT for the userId value
703
- expect(query.sql).not.toMatch(/\(select.*from.*users/i);
704
- expect(query.sql).toMatchInlineSnapshot(
705
- `"insert into "posts" ("id", "title", "content", "userId") values ($1, $2, $3, $4) returning "posts"."id" as "id", "posts"."title" as "title", "posts"."content" as "content", "posts"."userId" as "userId", "posts"."viewCount" as "viewCount", "posts"."publishedAt" as "publishedAt", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version""`,
706
- );
707
- });
708
- });
709
-
710
- describe("findMany", () => {
711
- it("should compile basic select query", () => {
712
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
713
- const query = compiler.findMany(usersTable, {
714
- select: ["id", "name"],
715
- });
716
-
717
- expect(query.sql).toMatchInlineSnapshot(
718
- `"select "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
719
- );
720
- });
721
-
722
- it("should compile select all columns", () => {
723
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
724
- const query = compiler.findMany(usersTable, {
725
- select: true,
726
- });
727
-
728
- expect(query.sql).toMatchInlineSnapshot(
729
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
730
- );
731
- });
732
-
733
- it("should compile select with where clause", () => {
734
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
735
- const where = {
736
- type: "compare" as const,
737
- a: usersTable.columns.age,
738
- operator: ">" as const,
739
- b: 18,
740
- };
741
- const query = compiler.findMany(usersTable, {
742
- select: true,
743
- where,
744
- });
745
-
746
- expect(query.sql).toMatchInlineSnapshot(
747
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" where "users"."age" > $1"`,
748
- );
749
- });
750
-
751
- it("should compile select with limit and offset", () => {
752
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
753
- const query = compiler.findMany(usersTable, {
754
- select: true,
755
- limit: 10,
756
- offset: 20,
757
- });
758
-
759
- expect(query.sql).toMatchInlineSnapshot(
760
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" limit $1 offset $2"`,
761
- );
762
- });
763
-
764
- it("should compile select with single order by", () => {
765
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
766
- const query = compiler.findMany(usersTable, {
767
- select: true,
768
- orderBy: [[usersTable.columns.name, "asc"]],
769
- });
770
-
771
- expect(query.sql).toMatchInlineSnapshot(
772
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" order by "users"."name" asc"`,
773
- );
774
- });
775
-
776
- it("should compile select with multiple order by", () => {
777
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
778
- const query = compiler.findMany(usersTable, {
779
- select: true,
780
- orderBy: [
781
- [usersTable.columns.name, "asc"],
782
- [usersTable.columns.age, "desc"],
783
- ],
784
- });
785
-
786
- expect(query.sql).toMatchInlineSnapshot(
787
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" order by "users"."name" asc, "users"."age" desc"`,
788
- );
789
- });
790
-
791
- it("should compile complete query with all options", () => {
792
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
793
- const where = {
794
- type: "and" as const,
795
- items: [
796
- {
797
- type: "compare" as const,
798
- a: usersTable.columns.isActive,
799
- operator: "=" as const,
800
- b: true,
801
- },
802
- {
803
- type: "compare" as const,
804
- a: usersTable.columns.age,
805
- operator: ">=" as const,
806
- b: 18,
807
- },
808
- ],
809
- };
810
- const query = compiler.findMany(usersTable, {
811
- select: ["id", "name", "email"],
812
- where,
813
- orderBy: [[usersTable.columns.name, "asc"]],
814
- limit: 10,
815
- offset: 5,
816
- });
817
-
818
- expect(query.sql).toMatchInlineSnapshot(
819
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" where ("users"."isActive" = $1 and "users"."age" >= $2) order by "users"."name" asc limit $3 offset $4"`,
820
- );
821
- });
822
-
823
- it("should use TOP for mssql limit", () => {
824
- const compiler = createKyselyQueryBuilder(kysely, "mssql");
825
- const query = compiler.findMany(usersTable, {
826
- select: true,
827
- limit: 5,
828
- });
829
-
830
- expect(query.sql).toMatchInlineSnapshot(
831
- `"select top(5) "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
832
- );
833
- });
834
- });
835
-
836
- describe("updateMany", () => {
837
- it("should compile update query without where", () => {
838
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
839
- const query = compiler.updateMany(usersTable, {
840
- set: { name: "Updated Name" },
841
- });
842
-
843
- expect(query.sql).toMatchInlineSnapshot(
844
- `"update "users" set "name" = $1, "_version" = COALESCE(_version, 0) + 1"`,
845
- );
846
- });
847
-
848
- it("should compile update query with where", () => {
849
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
850
- const where = {
851
- type: "compare" as const,
852
- a: usersTable.columns.id,
853
- operator: "=" as const,
854
- b: "123",
855
- };
856
- const query = compiler.updateMany(usersTable, {
857
- set: { name: "Updated Name" },
858
- where,
859
- });
860
-
861
- expect(query.sql).toMatchInlineSnapshot(
862
- `"update "users" set "name" = $1, "_version" = COALESCE(_version, 0) + 1 where "users"."id" = $2"`,
863
- );
864
- });
865
-
866
- it("should compile update query with multiple fields", () => {
867
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
868
- const where = {
869
- type: "compare" as const,
870
- a: usersTable.columns.isActive,
871
- operator: "=" as const,
872
- b: false,
873
- };
874
- const query = compiler.updateMany(usersTable, {
875
- set: { name: "Updated Name", email: "updated@example.com", isActive: true },
876
- where,
877
- });
878
-
879
- expect(query.sql).toMatchInlineSnapshot(
880
- `"update "users" set "name" = $1, "email" = $2, "isActive" = $3, "_version" = COALESCE(_version, 0) + 1 where "users"."isActive" = $4"`,
881
- );
882
- });
883
- });
884
-
885
- describe("upsertCheck", () => {
886
- it("should compile upsert check query without where", () => {
887
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
888
- const query = compiler.upsertCheck(usersTable, undefined);
889
-
890
- expect(query.sql).toMatchInlineSnapshot(`"select "id" as "id" from "users" limit $1"`);
891
- });
892
-
893
- it("should compile upsert check query with where", () => {
894
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
895
- const where = {
896
- type: "compare" as const,
897
- a: usersTable.columns.email,
898
- operator: "=" as const,
899
- b: "test@example.com",
900
- };
901
- const query = compiler.upsertCheck(usersTable, where);
902
-
903
- expect(query.sql).toMatchInlineSnapshot(
904
- `"select "id" as "id" from "users" where "users"."email" = $1 limit $2"`,
905
- );
906
- });
907
- });
908
-
909
- describe("upsertUpdate", () => {
910
- it("should compile upsert update query", () => {
911
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
912
- const where = {
913
- type: "compare" as const,
914
- a: usersTable.columns.email,
915
- operator: "=" as const,
916
- b: "test@example.com",
917
- };
918
- const query = compiler.upsertUpdate(usersTable, { name: "Updated" }, where);
919
-
920
- expect(query.sql).toMatchInlineSnapshot(
921
- `"update "users" set "name" = $1 where "users"."email" = $2"`,
922
- );
923
- });
924
-
925
- it("should compile upsert update query without where", () => {
926
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
927
- const query = compiler.upsertUpdate(usersTable, { name: "Updated" }, undefined);
928
-
929
- expect(query.sql).toMatchInlineSnapshot(`"update "users" set "name" = $1"`);
930
- });
931
-
932
- it("should compile upsert update query with top", () => {
933
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
934
- const where = {
935
- type: "compare" as const,
936
- a: usersTable.columns.email,
937
- operator: "=" as const,
938
- b: "test@example.com",
939
- };
940
- const query = compiler.upsertUpdate(usersTable, { name: "Updated" }, where, true);
941
-
942
- expect(query.sql).toMatchInlineSnapshot(
943
- `"update top(1) "users" set "name" = $1 where "users"."email" = $2"`,
944
- );
945
- });
946
- });
947
-
948
- describe("upsertUpdateById", () => {
949
- it("should compile upsert update by id query", () => {
950
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
951
- const query = compiler.upsertUpdateById(usersTable, { name: "Updated" }, "123");
952
-
953
- expect(query.sql).toMatchInlineSnapshot(`"update "users" set "name" = $1 where "id" = $2"`);
954
- });
955
-
956
- it("should compile upsert update by id with multiple fields", () => {
957
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
958
- const query = compiler.upsertUpdateById(
959
- usersTable,
960
- { name: "Updated", email: "updated@example.com" },
961
- "456",
962
- );
963
-
964
- expect(query.sql).toMatchInlineSnapshot(
965
- `"update "users" set "name" = $1, "email" = $2 where "id" = $3"`,
966
- );
967
- });
968
- });
969
-
970
- describe("createMany", () => {
971
- it("should compile bulk insert query", () => {
972
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
973
- const query = compiler.createMany(usersTable, [
974
- { name: "John", email: "john@example.com" },
975
- { name: "Jane", email: "jane@example.com" },
976
- ]);
977
-
978
- expect(query.sql).toMatchInlineSnapshot(
979
- `"insert into "users" ("id", "name", "email") values ($1, $2, $3), ($4, $5, $6)"`,
980
- );
981
- });
982
-
983
- it("should handle single record in array", () => {
984
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
985
- const query = compiler.createMany(usersTable, [
986
- { name: "John", email: "john@example.com" },
987
- ]);
988
-
989
- expect(query.sql).toMatchInlineSnapshot(
990
- `"insert into "users" ("id", "name", "email") values ($1, $2, $3)"`,
991
- );
992
- });
993
-
994
- it("should handle many records", () => {
995
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
996
- const query = compiler.createMany(usersTable, [
997
- { name: "John", email: "john@example.com" },
998
- { name: "Jane", email: "jane@example.com" },
999
- { name: "Bob", email: "bob@example.com" },
1000
- ]);
1001
-
1002
- expect(query.sql).toMatchInlineSnapshot(
1003
- `"insert into "users" ("id", "name", "email") values ($1, $2, $3), ($4, $5, $6), ($7, $8, $9)"`,
1004
- );
1005
- });
1006
- });
1007
-
1008
- describe("deleteMany", () => {
1009
- it("should compile delete query without where", () => {
1010
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1011
- const query = compiler.deleteMany(usersTable, {});
1012
-
1013
- expect(query.sql).toMatchInlineSnapshot(`"delete from "users""`);
1014
- });
1015
-
1016
- it("should compile delete query with where", () => {
1017
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1018
- const where = {
1019
- type: "compare" as const,
1020
- a: usersTable.columns.isActive,
1021
- operator: "=" as const,
1022
- b: false,
1023
- };
1024
- const query = compiler.deleteMany(usersTable, { where });
1025
-
1026
- expect(query.sql).toMatchInlineSnapshot(
1027
- `"delete from "users" where "users"."isActive" = $1"`,
1028
- );
1029
- });
1030
-
1031
- it("should compile delete query with complex where", () => {
1032
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1033
- const where = {
1034
- type: "and" as const,
1035
- items: [
1036
- {
1037
- type: "compare" as const,
1038
- a: usersTable.columns.isActive,
1039
- operator: "=" as const,
1040
- b: false,
1041
- },
1042
- {
1043
- type: "compare" as const,
1044
- a: usersTable.columns.age,
1045
- operator: "<" as const,
1046
- b: 18,
1047
- },
1048
- ],
1049
- };
1050
- const query = compiler.deleteMany(usersTable, { where });
1051
-
1052
- expect(query.sql).toMatchInlineSnapshot(
1053
- `"delete from "users" where ("users"."isActive" = $1 and "users"."age" < $2)"`,
1054
- );
1055
- });
1056
- });
1057
-
1058
- describe("findById", () => {
1059
- it("should compile find by id query", () => {
1060
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1061
- const query = compiler.findById(usersTable, "123");
1062
-
1063
- expect(query.sql).toMatchInlineSnapshot(
1064
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" where "id" = $1 limit $2"`,
1065
- );
1066
- });
1067
-
1068
- it("should compile find by id query with numeric id", () => {
1069
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1070
- const query = compiler.findById(usersTable, 456);
1071
-
1072
- expect(query.sql).toMatchInlineSnapshot(
1073
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" where "id" = $1 limit $2"`,
1074
- );
1075
- });
1076
- });
1077
-
1078
- describe("id column selection", () => {
1079
- it("should select id column explicitly", () => {
1080
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1081
- const query = compiler.findMany(usersTable, {
1082
- select: ["id"],
1083
- });
1084
-
1085
- expect(query.sql).toMatchInlineSnapshot(
1086
- `"select "users"."id" as "id", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
1087
- );
1088
- });
1089
-
1090
- it("should include _internalId when id is selected", () => {
1091
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1092
- const query = compiler.findMany(usersTable, {
1093
- select: ["id", "name"],
1094
- });
1095
-
1096
- expect(query.sql).toContain("_internalId");
1097
- expect(query.sql).toMatchInlineSnapshot(
1098
- `"select "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
1099
- );
1100
- });
1101
-
1102
- it("should handle id column in where clause", () => {
1103
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1104
- const where = {
1105
- type: "compare" as const,
1106
- a: usersTable.columns.id,
1107
- operator: "=" as const,
1108
- b: "test-id-123",
1109
- };
1110
- const query = compiler.findMany(usersTable, {
1111
- select: ["id", "name"],
1112
- where,
1113
- });
1114
-
1115
- expect(query.sql).toMatchInlineSnapshot(
1116
- `"select "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" where "users"."id" = $1"`,
1117
- );
1118
- });
1119
-
1120
- it("should handle id column in order by", () => {
1121
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1122
- const query = compiler.findMany(usersTable, {
1123
- select: ["id", "name"],
1124
- orderBy: [[usersTable.columns.id, "asc"]],
1125
- });
1126
-
1127
- expect(query.sql).toMatchInlineSnapshot(
1128
- `"select "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" order by "users"."id" asc"`,
1129
- );
1130
- });
1131
- });
1132
-
1133
- describe("special columns - _internalId and _version", () => {
1134
- it("should not explicitly select _internalId when not requested", () => {
1135
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1136
- const query = compiler.findMany(usersTable, {
1137
- select: ["name", "email"],
1138
- });
1139
-
1140
- // Hidden columns (_internalId, _version) are always included for internal use
1141
- expect(query.sql).toContain("_internalId");
1142
- expect(query.sql).toContain("_version");
1143
- });
1144
-
1145
- it("should handle selecting _internalId explicitly if column exists", () => {
1146
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1147
- // This tests what happens if someone tries to select _internalId directly
1148
- // Depending on implementation, this might work or might be filtered out
1149
- const query = compiler.findMany(usersTable, {
1150
- select: ["id", "name"],
1151
- });
1152
-
1153
- // _internalId is automatically added when id is selected
1154
- expect(query.sql).toContain("_internalId");
1155
- expect(query.sql).toMatchInlineSnapshot(
1156
- `"select "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
1157
- );
1158
- });
1159
-
1160
- it("should handle _version column if it exists in schema", () => {
1161
- // Note: The test schema doesn't have _version column
1162
- // This is a placeholder to document the behavior
1163
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1164
- const query = compiler.findMany(usersTable, {
1165
- select: true,
1166
- });
1167
-
1168
- // _version would be included if it exists in the schema
1169
- expect(query.sql).toMatchInlineSnapshot(
1170
- `"select "users"."id" as "id", "users"."name" as "name", "users"."email" as "email", "users"."age" as "age", "users"."isActive" as "isActive", "users"."createdAt" as "createdAt", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users""`,
1171
- );
1172
- });
1173
- });
1174
-
1175
- describe("custom-named id columns", () => {
1176
- // Schema with custom-named id column
1177
- const customIdSchema = schema((s) => {
1178
- return s
1179
- .addTable("products", (t) => {
1180
- return t
1181
- .addColumn("productId", idColumn())
1182
- .addColumn("name", column("string"))
1183
- .addColumn("price", column("integer"));
1184
- })
1185
- .addTable("orders", (t) => {
1186
- return t
1187
- .addColumn("orderId", idColumn())
1188
- .addColumn("productRef", referenceColumn())
1189
- .addColumn("quantity", column("integer"));
1190
- })
1191
- .addReference("product", {
1192
- type: "one",
1193
- from: { table: "orders", column: "productRef" },
1194
- to: { table: "products", column: "productId" },
1195
- });
1196
- });
1197
-
1198
- const productsTable = customIdSchema.tables.products;
1199
- const ordersTable = customIdSchema.tables.orders;
1200
-
1201
- it("should compile select with custom id column name", () => {
1202
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1203
- const query = compiler.findMany(productsTable, {
1204
- select: ["productId", "name"],
1205
- });
1206
-
1207
- expect(query.sql).toContain("productId");
1208
- expect(query.sql).toMatchInlineSnapshot(
1209
- `"select "products"."productId" as "productId", "products"."name" as "name", "products"."_internalId" as "_internalId", "products"."_version" as "_version" from "products""`,
1210
- );
1211
- });
1212
-
1213
- it("should compile select all with custom id column name", () => {
1214
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1215
- const query = compiler.findMany(productsTable, {
1216
- select: true,
1217
- });
1218
-
1219
- expect(query.sql).toContain("productId");
1220
- expect(query.sql).toMatchInlineSnapshot(
1221
- `"select "products"."productId" as "productId", "products"."name" as "name", "products"."price" as "price", "products"."_internalId" as "_internalId", "products"."_version" as "_version" from "products""`,
1222
- );
1223
- });
1224
-
1225
- it("should handle custom id column in where clause", () => {
1226
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1227
- const where = {
1228
- type: "compare" as const,
1229
- a: productsTable.columns.productId,
1230
- operator: "=" as const,
1231
- b: "prod-123",
1232
- };
1233
- const query = compiler.findMany(productsTable, {
1234
- select: true,
1235
- where,
1236
- });
1237
-
1238
- expect(query.sql).toMatchInlineSnapshot(
1239
- `"select "products"."productId" as "productId", "products"."name" as "name", "products"."price" as "price", "products"."_internalId" as "_internalId", "products"."_version" as "_version" from "products" where "products"."productId" = $1"`,
1240
- );
1241
- });
1242
-
1243
- it("should handle custom id column in order by", () => {
1244
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1245
- const query = compiler.findMany(productsTable, {
1246
- select: true,
1247
- orderBy: [[productsTable.columns.productId, "desc"]],
1248
- });
1249
-
1250
- expect(query.sql).toMatchInlineSnapshot(
1251
- `"select "products"."productId" as "productId", "products"."name" as "name", "products"."price" as "price", "products"."_internalId" as "_internalId", "products"."_version" as "_version" from "products" order by "products"."productId" desc"`,
1252
- );
1253
- });
1254
-
1255
- it("should compile insert with custom id column", () => {
1256
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1257
- const query = compiler.create(productsTable, {
1258
- name: "Widget",
1259
- price: 1000,
1260
- });
1261
-
1262
- expect(query.sql).toMatchInlineSnapshot(
1263
- `"insert into "products" ("productId", "name", "price") values ($1, $2, $3) returning "products"."productId" as "productId", "products"."name" as "name", "products"."price" as "price", "products"."_internalId" as "_internalId", "products"."_version" as "_version""`,
1264
- );
1265
- });
1266
-
1267
- it("should compile update with custom id column in where", () => {
1268
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1269
- const where = {
1270
- type: "compare" as const,
1271
- a: productsTable.columns.productId,
1272
- operator: "=" as const,
1273
- b: "prod-456",
1274
- };
1275
- const query = compiler.updateMany(productsTable, {
1276
- set: { price: 2000 },
1277
- where,
1278
- });
1279
-
1280
- expect(query.sql).toMatchInlineSnapshot(
1281
- `"update "products" set "price" = $1, "_version" = COALESCE(_version, 0) + 1 where "products"."productId" = $2"`,
1282
- );
1283
- });
1284
-
1285
- it("should handle references to custom id columns", () => {
1286
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1287
- const where = {
1288
- type: "compare" as const,
1289
- a: ordersTable.columns.orderId,
1290
- operator: "=" as const,
1291
- b: "order-789",
1292
- };
1293
- const query = compiler.findMany(ordersTable, {
1294
- select: ["orderId", "productRef", "quantity"],
1295
- where,
1296
- });
1297
-
1298
- expect(query.sql).toMatchInlineSnapshot(
1299
- `"select "orders"."orderId" as "orderId", "orders"."productRef" as "productRef", "orders"."quantity" as "quantity", "orders"."_internalId" as "_internalId", "orders"."_version" as "_version" from "orders" where "orders"."orderId" = $1"`,
1300
- );
1301
- });
1302
- });
1303
-
1304
- describe("special column name conflicts", () => {
1305
- // Schema where regular columns might conflict with special names
1306
- const conflictSchema = schema((s) => {
1307
- return s.addTable("logs", (t) => {
1308
- return t
1309
- .addColumn("id", idColumn())
1310
- .addColumn("message", column("string"))
1311
- .addColumn("level", column("string"));
1312
- });
1313
- });
1314
-
1315
- const logsTable = conflictSchema.tables.logs;
1316
-
1317
- it("should handle table with both id and _internalId", () => {
1318
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1319
- const query = compiler.findMany(logsTable, {
1320
- select: ["id", "message"],
1321
- });
1322
-
1323
- // Should select both id and _internalId
1324
- expect(query.sql).toContain("id");
1325
- expect(query.sql).toContain("_internalId");
1326
- expect(query.sql).toMatchInlineSnapshot(
1327
- `"select "logs"."id" as "id", "logs"."message" as "message", "logs"."_internalId" as "_internalId", "logs"."_version" as "_version" from "logs""`,
1328
- );
1329
- });
1330
-
1331
- it("should handle selecting only non-id columns", () => {
1332
- const compiler = createKyselyQueryBuilder(kysely, "postgresql");
1333
- const query = compiler.findMany(logsTable, {
1334
- select: ["message", "level"],
1335
- });
1336
-
1337
- // Should NOT include id when not selected, but hidden columns are always included
1338
- expect(query.sql).not.toContain('"id"');
1339
- expect(query.sql).toContain("_internalId");
1340
- expect(query.sql).toContain("_version");
1341
- });
1342
- });
1343
- });
1344
- });