@uql/core 1.0.12 → 3.1.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 (464) hide show
  1. package/CHANGELOG.md +254 -0
  2. package/LICENSE.md +2 -2
  3. package/dist/browser/http/bus.d.ts +3 -0
  4. package/dist/browser/http/bus.js +14 -0
  5. package/dist/browser/http/http.d.ts +6 -0
  6. package/dist/browser/http/http.js +45 -0
  7. package/dist/browser/http/index.d.ts +2 -0
  8. package/dist/browser/http/index.js +3 -0
  9. package/dist/browser/index.d.ts +4 -0
  10. package/dist/browser/index.js +5 -0
  11. package/dist/browser/options.d.ts +4 -0
  12. package/dist/browser/options.js +14 -0
  13. package/dist/browser/querier/genericClientRepository.d.ts +17 -0
  14. package/dist/browser/querier/genericClientRepository.js +39 -0
  15. package/dist/browser/querier/httpQuerier.d.ts +20 -0
  16. package/dist/browser/querier/httpQuerier.js +71 -0
  17. package/dist/browser/querier/index.d.ts +3 -0
  18. package/dist/browser/querier/index.js +4 -0
  19. package/dist/browser/querier/querier.util.d.ts +2 -0
  20. package/dist/browser/querier/querier.util.js +17 -0
  21. package/dist/browser/type/clientQuerier.d.ts +16 -0
  22. package/dist/browser/type/clientQuerier.js +2 -0
  23. package/dist/browser/type/clientQuerierPool.d.ts +4 -0
  24. package/dist/browser/type/clientQuerierPool.js +2 -0
  25. package/dist/browser/type/clientRepository.d.ts +13 -0
  26. package/dist/browser/type/clientRepository.js +2 -0
  27. package/dist/browser/type/index.d.ts +4 -0
  28. package/dist/browser/type/index.js +5 -0
  29. package/dist/browser/type/request.d.ts +28 -0
  30. package/dist/browser/type/request.js +2 -0
  31. package/dist/browser/uql-browser.min.js +2150 -0
  32. package/dist/browser/uql-browser.min.js.map +1 -0
  33. package/dist/dialect/abstractDialect.d.ts +16 -0
  34. package/dist/dialect/abstractDialect.js +28 -0
  35. package/dist/dialect/abstractSqlDialect.d.ts +47 -0
  36. package/dist/dialect/abstractSqlDialect.js +650 -0
  37. package/dist/dialect/index.d.ts +3 -0
  38. package/dist/dialect/index.js +4 -0
  39. package/dist/dialect/queryContext.d.ts +48 -0
  40. package/dist/dialect/queryContext.js +65 -0
  41. package/{entity → dist/entity}/decorator/definition.d.ts +3 -3
  42. package/dist/entity/decorator/definition.js +214 -0
  43. package/{entity → dist/entity}/decorator/entity.d.ts +1 -1
  44. package/dist/entity/decorator/entity.js +7 -0
  45. package/{entity → dist/entity}/decorator/field.d.ts +1 -1
  46. package/dist/entity/decorator/field.js +8 -0
  47. package/{entity → dist/entity}/decorator/id.d.ts +1 -1
  48. package/dist/entity/decorator/id.js +8 -0
  49. package/dist/entity/decorator/index.d.ts +5 -0
  50. package/dist/entity/decorator/index.js +6 -0
  51. package/{entity → dist/entity}/decorator/relation.d.ts +1 -1
  52. package/dist/entity/decorator/relation.js +20 -0
  53. package/dist/entity/index.d.ts +1 -0
  54. package/dist/entity/index.js +2 -0
  55. package/dist/express/index.d.ts +2 -0
  56. package/dist/express/index.js +3 -0
  57. package/dist/express/querierMiddleware.d.ts +26 -0
  58. package/dist/express/querierMiddleware.js +190 -0
  59. package/dist/express/query.util.d.ts +2 -0
  60. package/dist/express/query.util.js +19 -0
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.js +10 -0
  63. package/dist/maria/index.d.ts +3 -0
  64. package/dist/maria/index.js +4 -0
  65. package/dist/maria/mariaDialect.d.ts +8 -0
  66. package/dist/maria/mariaDialect.js +38 -0
  67. package/dist/maria/mariaQuerierPool.test.d.ts +5 -0
  68. package/dist/maria/mariaQuerierPool.test.js +19 -0
  69. package/dist/maria/mariadbQuerier.d.ts +17 -0
  70. package/dist/maria/mariadbQuerier.js +39 -0
  71. package/dist/maria/mariadbQuerier.test.d.ts +4 -0
  72. package/dist/maria/mariadbQuerier.test.js +19 -0
  73. package/dist/maria/mariadbQuerierPool.d.ts +10 -0
  74. package/dist/maria/mariadbQuerierPool.js +17 -0
  75. package/dist/migrate/cli.d.ts +2 -0
  76. package/dist/migrate/cli.js +254 -0
  77. package/dist/migrate/generator/index.d.ts +4 -0
  78. package/dist/migrate/generator/index.js +5 -0
  79. package/dist/migrate/generator/mongoSchemaGenerator.d.ts +12 -0
  80. package/dist/migrate/generator/mongoSchemaGenerator.js +100 -0
  81. package/dist/migrate/generator/mysqlSchemaGenerator.d.ts +14 -0
  82. package/dist/migrate/generator/mysqlSchemaGenerator.js +81 -0
  83. package/dist/migrate/generator/postgresSchemaGenerator.d.ts +18 -0
  84. package/dist/migrate/generator/postgresSchemaGenerator.js +111 -0
  85. package/dist/migrate/generator/sqliteSchemaGenerator.d.ts +14 -0
  86. package/dist/migrate/generator/sqliteSchemaGenerator.js +68 -0
  87. package/dist/migrate/index.d.ts +12 -0
  88. package/dist/migrate/index.js +17 -0
  89. package/dist/migrate/introspection/index.d.ts +4 -0
  90. package/dist/migrate/introspection/index.js +5 -0
  91. package/dist/migrate/introspection/mongoIntrospector.d.ts +8 -0
  92. package/dist/migrate/introspection/mongoIntrospector.js +46 -0
  93. package/dist/migrate/introspection/mysqlIntrospector.d.ts +25 -0
  94. package/dist/migrate/introspection/mysqlIntrospector.js +220 -0
  95. package/dist/migrate/introspection/postgresIntrospector.d.ts +21 -0
  96. package/dist/migrate/introspection/postgresIntrospector.js +269 -0
  97. package/dist/migrate/introspection/sqliteIntrospector.d.ts +23 -0
  98. package/dist/migrate/introspection/sqliteIntrospector.js +212 -0
  99. package/dist/migrate/migrator-mongo.test.d.ts +1 -0
  100. package/dist/migrate/migrator-mongo.test.js +54 -0
  101. package/dist/migrate/migrator.d.ts +133 -0
  102. package/dist/migrate/migrator.js +600 -0
  103. package/dist/migrate/migrator.test.d.ts +1 -0
  104. package/dist/migrate/migrator.test.js +106 -0
  105. package/dist/migrate/schemaGenerator.d.ts +78 -0
  106. package/dist/migrate/schemaGenerator.js +363 -0
  107. package/dist/migrate/storage/databaseStorage.d.ts +24 -0
  108. package/dist/migrate/storage/databaseStorage.js +77 -0
  109. package/dist/migrate/storage/index.d.ts +2 -0
  110. package/dist/migrate/storage/index.js +3 -0
  111. package/dist/migrate/storage/jsonStorage.d.ts +15 -0
  112. package/dist/migrate/storage/jsonStorage.js +51 -0
  113. package/dist/migrate/type.d.ts +1 -0
  114. package/dist/migrate/type.js +2 -0
  115. package/dist/mongo/index.d.ts +3 -0
  116. package/dist/mongo/index.js +4 -0
  117. package/dist/mongo/mongoDialect.d.ts +34 -0
  118. package/dist/mongo/mongoDialect.js +163 -0
  119. package/dist/mongo/mongodbQuerier.d.ts +28 -0
  120. package/dist/mongo/mongodbQuerier.js +204 -0
  121. package/dist/mongo/mongodbQuerier.test.d.ts +1 -0
  122. package/dist/mongo/mongodbQuerier.test.js +36 -0
  123. package/dist/mongo/mongodbQuerierPool.d.ts +10 -0
  124. package/dist/mongo/mongodbQuerierPool.js +20 -0
  125. package/dist/mongo/mongodbQuerierPool.test.d.ts +1 -0
  126. package/dist/mongo/mongodbQuerierPool.test.js +21 -0
  127. package/dist/mysql/index.d.ts +3 -0
  128. package/dist/mysql/index.js +4 -0
  129. package/dist/mysql/mysql2Querier.d.ts +17 -0
  130. package/dist/mysql/mysql2Querier.js +43 -0
  131. package/dist/mysql/mysql2Querier.test.d.ts +4 -0
  132. package/dist/mysql/mysql2Querier.test.js +16 -0
  133. package/dist/mysql/mysql2QuerierPool.d.ts +10 -0
  134. package/dist/mysql/mysql2QuerierPool.js +17 -0
  135. package/dist/mysql/mysql2QuerierPool.test.d.ts +5 -0
  136. package/dist/mysql/mysql2QuerierPool.test.js +16 -0
  137. package/dist/mysql/mysqlDialect.d.ts +5 -0
  138. package/dist/mysql/mysqlDialect.js +15 -0
  139. package/dist/namingStrategy/defaultNamingStrategy.d.ts +9 -0
  140. package/dist/namingStrategy/defaultNamingStrategy.js +15 -0
  141. package/dist/namingStrategy/index.d.ts +2 -0
  142. package/dist/namingStrategy/index.js +3 -0
  143. package/dist/namingStrategy/snakeCaseNamingStrategy.d.ts +8 -0
  144. package/dist/namingStrategy/snakeCaseNamingStrategy.js +14 -0
  145. package/{options.d.ts → dist/options.d.ts} +1 -1
  146. package/dist/options.js +14 -0
  147. package/dist/package.json +131 -0
  148. package/dist/postgres/index.d.ts +3 -0
  149. package/dist/postgres/index.js +4 -0
  150. package/dist/postgres/pgQuerier.d.ts +17 -0
  151. package/dist/postgres/pgQuerier.js +39 -0
  152. package/dist/postgres/pgQuerier.test.d.ts +4 -0
  153. package/dist/postgres/pgQuerier.test.js +20 -0
  154. package/dist/postgres/pgQuerierPool.d.ts +10 -0
  155. package/dist/postgres/pgQuerierPool.js +17 -0
  156. package/dist/postgres/pgQuerierPool.test.d.ts +5 -0
  157. package/dist/postgres/pgQuerierPool.test.js +23 -0
  158. package/dist/postgres/postgresDialect.d.ts +13 -0
  159. package/dist/postgres/postgresDialect.js +110 -0
  160. package/dist/querier/abstractQuerier-test.d.ts +45 -0
  161. package/dist/querier/abstractQuerier-test.js +461 -0
  162. package/dist/querier/abstractQuerier.d.ts +50 -0
  163. package/dist/querier/abstractQuerier.js +278 -0
  164. package/dist/querier/abstractQuerierPool-test.d.ts +9 -0
  165. package/dist/querier/abstractQuerierPool-test.js +18 -0
  166. package/dist/querier/abstractQuerierPool.d.ts +14 -0
  167. package/dist/querier/abstractQuerierPool.js +9 -0
  168. package/dist/querier/abstractSqlQuerier-test.d.ts +9 -0
  169. package/dist/querier/abstractSqlQuerier-test.js +16 -0
  170. package/dist/querier/abstractSqlQuerier.d.ts +28 -0
  171. package/dist/querier/abstractSqlQuerier.js +133 -0
  172. package/dist/querier/decorator/index.d.ts +3 -0
  173. package/dist/querier/decorator/index.js +4 -0
  174. package/dist/querier/decorator/injectQuerier.d.ts +3 -0
  175. package/dist/querier/decorator/injectQuerier.js +33 -0
  176. package/dist/querier/decorator/serialized.d.ts +6 -0
  177. package/dist/querier/decorator/serialized.js +14 -0
  178. package/{querier → dist/querier}/decorator/transactional.d.ts +1 -1
  179. package/dist/querier/decorator/transactional.js +48 -0
  180. package/dist/querier/index.d.ts +4 -0
  181. package/dist/querier/index.js +5 -0
  182. package/dist/repository/genericRepository.d.ts +20 -0
  183. package/dist/repository/genericRepository.js +51 -0
  184. package/dist/repository/index.d.ts +1 -0
  185. package/dist/repository/index.js +2 -0
  186. package/dist/sqlite/index.d.ts +3 -0
  187. package/dist/sqlite/index.js +4 -0
  188. package/dist/sqlite/sqliteDialect.d.ts +10 -0
  189. package/dist/sqlite/sqliteDialect.js +48 -0
  190. package/dist/sqlite/sqliteQuerier.d.ts +15 -0
  191. package/dist/sqlite/sqliteQuerier.js +33 -0
  192. package/dist/sqlite/sqliteQuerier.test.d.ts +5 -0
  193. package/dist/sqlite/sqliteQuerier.test.js +19 -0
  194. package/dist/sqlite/sqliteQuerierPool.d.ts +14 -0
  195. package/dist/sqlite/sqliteQuerierPool.js +34 -0
  196. package/dist/sqlite/sqliteQuerierPool.test.d.ts +5 -0
  197. package/dist/sqlite/sqliteQuerierPool.test.js +10 -0
  198. package/dist/test/entityMock.d.ts +164 -0
  199. package/dist/test/entityMock.js +554 -0
  200. package/dist/test/index.d.ts +3 -0
  201. package/dist/test/index.js +4 -0
  202. package/dist/test/it.util.d.ts +4 -0
  203. package/dist/test/it.util.js +55 -0
  204. package/dist/test/spec.util.d.ts +14 -0
  205. package/dist/test/spec.util.js +50 -0
  206. package/{type → dist/type}/entity.d.ts +97 -4
  207. package/dist/type/entity.js +5 -0
  208. package/dist/type/index.d.ts +9 -0
  209. package/dist/type/index.js +10 -0
  210. package/dist/type/migration.d.ts +213 -0
  211. package/dist/type/migration.js +2 -0
  212. package/dist/type/namingStrategy.d.ts +17 -0
  213. package/dist/type/namingStrategy.js +2 -0
  214. package/dist/type/querier.d.ts +96 -0
  215. package/dist/type/querier.js +11 -0
  216. package/{type → dist/type}/querierPool.d.ts +7 -3
  217. package/dist/type/querierPool.js +2 -0
  218. package/{type → dist/type}/query.d.ts +170 -108
  219. package/dist/type/query.js +9 -0
  220. package/{type → dist/type}/repository.d.ts +42 -35
  221. package/dist/type/repository.js +2 -0
  222. package/{type → dist/type}/universalQuerier.d.ts +50 -28
  223. package/dist/type/universalQuerier.js +2 -0
  224. package/dist/type/utility.d.ts +13 -0
  225. package/dist/type/utility.js +2 -0
  226. package/dist/util/dialect.util.d.ts +12 -0
  227. package/dist/util/dialect.util.js +93 -0
  228. package/dist/util/index.d.ts +5 -0
  229. package/dist/util/index.js +6 -0
  230. package/dist/util/object.util.d.ts +7 -0
  231. package/dist/util/object.util.js +19 -0
  232. package/dist/util/raw.d.ts +8 -0
  233. package/dist/util/raw.js +11 -0
  234. package/dist/util/sql.util.d.ts +13 -0
  235. package/dist/util/sql.util.js +78 -0
  236. package/{util → dist/util}/string.util.d.ts +1 -0
  237. package/dist/util/string.util.js +34 -0
  238. package/package.json +85 -17
  239. package/src/@types/index.d.ts +1 -0
  240. package/src/@types/jest.d.ts +6 -0
  241. package/src/browser/http/bus.spec.ts +22 -0
  242. package/src/browser/http/bus.ts +17 -0
  243. package/src/browser/http/http.spec.ts +70 -0
  244. package/src/browser/http/http.ts +55 -0
  245. package/src/browser/http/index.ts +2 -0
  246. package/src/browser/index.ts +4 -0
  247. package/src/browser/options.spec.ts +37 -0
  248. package/src/browser/options.ts +18 -0
  249. package/src/browser/querier/genericClientRepository.spec.ts +105 -0
  250. package/src/browser/querier/genericClientRepository.ts +49 -0
  251. package/src/browser/querier/httpQuerier.ts +82 -0
  252. package/src/browser/querier/index.ts +3 -0
  253. package/src/browser/querier/querier.util.spec.ts +35 -0
  254. package/src/browser/querier/querier.util.ts +18 -0
  255. package/src/browser/type/clientQuerier.ts +45 -0
  256. package/src/browser/type/clientQuerierPool.ts +5 -0
  257. package/src/browser/type/clientRepository.ts +22 -0
  258. package/src/browser/type/index.ts +4 -0
  259. package/src/browser/type/request.ts +25 -0
  260. package/src/dialect/abstractDialect.ts +28 -0
  261. package/src/dialect/abstractSqlDialect-spec.ts +1309 -0
  262. package/src/dialect/abstractSqlDialect.ts +805 -0
  263. package/src/dialect/index.ts +3 -0
  264. package/src/dialect/namingStrategy.spec.ts +52 -0
  265. package/src/dialect/queryContext.ts +69 -0
  266. package/src/entity/decorator/definition.spec.ts +736 -0
  267. package/src/entity/decorator/definition.ts +265 -0
  268. package/src/entity/decorator/entity.ts +8 -0
  269. package/src/entity/decorator/field.ts +9 -0
  270. package/src/entity/decorator/id.ts +9 -0
  271. package/src/entity/decorator/index.ts +5 -0
  272. package/src/entity/decorator/relation.spec.ts +41 -0
  273. package/src/entity/decorator/relation.ts +34 -0
  274. package/src/entity/index.ts +1 -0
  275. package/src/express/@types/express.d.ts +8 -0
  276. package/src/express/@types/index.d.ts +1 -0
  277. package/src/express/index.ts +2 -0
  278. package/src/express/querierMiddleware.ts +217 -0
  279. package/src/express/query.util.spec.ts +40 -0
  280. package/src/express/query.util.ts +21 -0
  281. package/src/index.ts +9 -0
  282. package/src/maria/index.ts +3 -0
  283. package/src/maria/mariaDialect.spec.ts +207 -0
  284. package/src/maria/mariaDialect.ts +42 -0
  285. package/src/maria/mariaQuerierPool.test.ts +23 -0
  286. package/src/maria/mariadbQuerier.test.ts +23 -0
  287. package/src/maria/mariadbQuerier.ts +45 -0
  288. package/src/maria/mariadbQuerierPool.ts +21 -0
  289. package/src/migrate/cli.ts +301 -0
  290. package/src/migrate/generator/index.ts +4 -0
  291. package/src/migrate/generator/mongoSchemaGenerator.spec.ts +112 -0
  292. package/src/migrate/generator/mongoSchemaGenerator.ts +115 -0
  293. package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +34 -0
  294. package/src/migrate/generator/mysqlSchemaGenerator.ts +92 -0
  295. package/src/migrate/generator/postgresSchemaGenerator.spec.ts +44 -0
  296. package/src/migrate/generator/postgresSchemaGenerator.ts +127 -0
  297. package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +33 -0
  298. package/src/migrate/generator/sqliteSchemaGenerator.ts +81 -0
  299. package/src/migrate/index.ts +41 -0
  300. package/src/migrate/introspection/index.ts +4 -0
  301. package/src/migrate/introspection/mongoIntrospector.spec.ts +75 -0
  302. package/src/migrate/introspection/mongoIntrospector.ts +47 -0
  303. package/src/migrate/introspection/mysqlIntrospector.spec.ts +113 -0
  304. package/src/migrate/introspection/mysqlIntrospector.ts +278 -0
  305. package/src/migrate/introspection/postgresIntrospector.spec.ts +112 -0
  306. package/src/migrate/introspection/postgresIntrospector.ts +329 -0
  307. package/src/migrate/introspection/sqliteIntrospector.spec.ts +112 -0
  308. package/src/migrate/introspection/sqliteIntrospector.ts +296 -0
  309. package/src/migrate/migrator-mongo.test.ts +54 -0
  310. package/src/migrate/migrator.spec.ts +255 -0
  311. package/src/migrate/migrator.test.ts +94 -0
  312. package/src/migrate/migrator.ts +719 -0
  313. package/src/migrate/namingStrategy.spec.ts +22 -0
  314. package/src/migrate/schemaGenerator-advanced.spec.ts +138 -0
  315. package/src/migrate/schemaGenerator.spec.ts +190 -0
  316. package/src/migrate/schemaGenerator.ts +478 -0
  317. package/src/migrate/storage/databaseStorage.spec.ts +69 -0
  318. package/src/migrate/storage/databaseStorage.ts +100 -0
  319. package/src/migrate/storage/index.ts +2 -0
  320. package/src/migrate/storage/jsonStorage.ts +58 -0
  321. package/src/migrate/type.ts +1 -0
  322. package/src/mongo/index.ts +3 -0
  323. package/src/mongo/mongoDialect.spec.ts +251 -0
  324. package/src/mongo/mongoDialect.ts +238 -0
  325. package/src/mongo/mongodbQuerier.test.ts +45 -0
  326. package/src/mongo/mongodbQuerier.ts +256 -0
  327. package/src/mongo/mongodbQuerierPool.test.ts +25 -0
  328. package/src/mongo/mongodbQuerierPool.ts +24 -0
  329. package/src/mysql/index.ts +3 -0
  330. package/src/mysql/mysql2Querier.test.ts +20 -0
  331. package/src/mysql/mysql2Querier.ts +49 -0
  332. package/src/mysql/mysql2QuerierPool.test.ts +20 -0
  333. package/src/mysql/mysql2QuerierPool.ts +21 -0
  334. package/src/mysql/mysqlDialect.spec.ts +20 -0
  335. package/src/mysql/mysqlDialect.ts +16 -0
  336. package/src/namingStrategy/defaultNamingStrategy.ts +18 -0
  337. package/src/namingStrategy/index.spec.ts +36 -0
  338. package/src/namingStrategy/index.ts +2 -0
  339. package/src/namingStrategy/snakeCaseNamingStrategy.ts +15 -0
  340. package/src/options.spec.ts +41 -0
  341. package/src/options.ts +18 -0
  342. package/src/postgres/index.ts +3 -0
  343. package/src/postgres/manual-types.d.ts +4 -0
  344. package/src/postgres/pgQuerier.test.ts +25 -0
  345. package/src/postgres/pgQuerier.ts +45 -0
  346. package/src/postgres/pgQuerierPool.test.ts +28 -0
  347. package/src/postgres/pgQuerierPool.ts +21 -0
  348. package/src/postgres/postgresDialect.spec.ts +428 -0
  349. package/src/postgres/postgresDialect.ts +144 -0
  350. package/src/querier/abstractQuerier-test.ts +584 -0
  351. package/src/querier/abstractQuerier.ts +353 -0
  352. package/src/querier/abstractQuerierPool-test.ts +20 -0
  353. package/src/querier/abstractQuerierPool.ts +18 -0
  354. package/src/querier/abstractSqlQuerier-spec.ts +979 -0
  355. package/src/querier/abstractSqlQuerier-test.ts +21 -0
  356. package/src/querier/abstractSqlQuerier.ts +138 -0
  357. package/src/querier/decorator/index.ts +3 -0
  358. package/src/querier/decorator/injectQuerier.spec.ts +74 -0
  359. package/src/querier/decorator/injectQuerier.ts +45 -0
  360. package/src/querier/decorator/serialized.spec.ts +98 -0
  361. package/src/querier/decorator/serialized.ts +13 -0
  362. package/src/querier/decorator/transactional.spec.ts +240 -0
  363. package/src/querier/decorator/transactional.ts +56 -0
  364. package/src/querier/index.ts +4 -0
  365. package/src/repository/genericRepository.spec.ts +111 -0
  366. package/src/repository/genericRepository.ts +74 -0
  367. package/src/repository/index.ts +1 -0
  368. package/src/sqlite/index.ts +3 -0
  369. package/src/sqlite/manual-types.d.ts +4 -0
  370. package/src/sqlite/sqliteDialect.spec.ts +155 -0
  371. package/src/sqlite/sqliteDialect.ts +76 -0
  372. package/src/sqlite/sqliteQuerier.spec.ts +36 -0
  373. package/src/sqlite/sqliteQuerier.test.ts +21 -0
  374. package/src/sqlite/sqliteQuerier.ts +37 -0
  375. package/src/sqlite/sqliteQuerierPool.test.ts +12 -0
  376. package/src/sqlite/sqliteQuerierPool.ts +38 -0
  377. package/src/test/entityMock.ts +375 -0
  378. package/src/test/index.ts +3 -0
  379. package/src/test/it.util.ts +69 -0
  380. package/src/test/spec.util.ts +57 -0
  381. package/src/type/entity.ts +218 -0
  382. package/src/type/index.ts +9 -0
  383. package/src/type/migration.ts +241 -0
  384. package/src/type/namingStrategy.ts +17 -0
  385. package/src/type/querier.ts +143 -0
  386. package/src/type/querierPool.ts +26 -0
  387. package/src/type/query.ts +506 -0
  388. package/src/type/repository.ts +142 -0
  389. package/src/type/universalQuerier.ts +133 -0
  390. package/src/type/utility.ts +21 -0
  391. package/src/util/dialect.util-extra.spec.ts +96 -0
  392. package/src/util/dialect.util.spec.ts +23 -0
  393. package/src/util/dialect.util.ts +134 -0
  394. package/src/util/index.ts +5 -0
  395. package/src/util/object.util.spec.ts +29 -0
  396. package/src/util/object.util.ts +27 -0
  397. package/src/util/raw.ts +11 -0
  398. package/src/util/sql.util-extra.spec.ts +17 -0
  399. package/src/util/sql.util.spec.ts +208 -0
  400. package/src/util/sql.util.ts +104 -0
  401. package/src/util/string.util.spec.ts +46 -0
  402. package/src/util/string.util.ts +35 -0
  403. package/tsconfig.build.json +5 -0
  404. package/tsconfig.json +8 -0
  405. package/README.md +0 -177
  406. package/dialect/abstractSqlDialect.d.ts +0 -30
  407. package/dialect/abstractSqlDialect.js +0 -365
  408. package/dialect/index.d.ts +0 -4
  409. package/dialect/index.js +0 -8
  410. package/dialect/mysqlDialect.d.ts +0 -6
  411. package/dialect/mysqlDialect.js +0 -21
  412. package/dialect/postgresDialect.d.ts +0 -8
  413. package/dialect/postgresDialect.js +0 -44
  414. package/dialect/sqliteDialect.d.ts +0 -4
  415. package/dialect/sqliteDialect.js +0 -11
  416. package/entity/decorator/definition.js +0 -223
  417. package/entity/decorator/entity.js +0 -11
  418. package/entity/decorator/field.js +0 -12
  419. package/entity/decorator/id.js +0 -12
  420. package/entity/decorator/index.d.ts +0 -5
  421. package/entity/decorator/index.js +0 -12
  422. package/entity/decorator/relation.js +0 -27
  423. package/entity/index.d.ts +0 -1
  424. package/entity/index.js +0 -5
  425. package/index.d.ts +0 -1
  426. package/index.js +0 -5
  427. package/options.js +0 -20
  428. package/querier/abstractQuerier.d.ts +0 -30
  429. package/querier/abstractQuerier.js +0 -230
  430. package/querier/abstractSqlQuerier.d.ts +0 -27
  431. package/querier/abstractSqlQuerier.js +0 -88
  432. package/querier/decorator/index.d.ts +0 -2
  433. package/querier/decorator/index.js +0 -6
  434. package/querier/decorator/injectQuerier.d.ts +0 -3
  435. package/querier/decorator/injectQuerier.js +0 -39
  436. package/querier/decorator/transactional.js +0 -52
  437. package/querier/index.d.ts +0 -3
  438. package/querier/index.js +0 -7
  439. package/repository/genericRepository.d.ts +0 -19
  440. package/repository/genericRepository.js +0 -52
  441. package/repository/index.d.ts +0 -1
  442. package/repository/index.js +0 -5
  443. package/type/entity.js +0 -5
  444. package/type/index.d.ts +0 -7
  445. package/type/index.js +0 -11
  446. package/type/querier.d.ts +0 -53
  447. package/type/querier.js +0 -3
  448. package/type/querierPool.js +0 -3
  449. package/type/query.js +0 -13
  450. package/type/repository.js +0 -3
  451. package/type/universalQuerier.js +0 -3
  452. package/type/utility.d.ts +0 -12
  453. package/type/utility.js +0 -3
  454. package/util/dialect.util.d.ts +0 -17
  455. package/util/dialect.util.js +0 -114
  456. package/util/index.d.ts +0 -5
  457. package/util/index.js +0 -9
  458. package/util/object.util.d.ts +0 -3
  459. package/util/object.util.js +0 -22
  460. package/util/raw.d.ts +0 -2
  461. package/util/raw.js +0 -9
  462. package/util/sql.util.d.ts +0 -2
  463. package/util/sql.util.js +0 -55
  464. package/util/string.util.js +0 -20
@@ -0,0 +1,805 @@
1
+ import { getMeta } from '../entity/index.js';
2
+ import {
3
+ type EntityMeta,
4
+ type FieldKey,
5
+ type FieldOptions,
6
+ type NamingStrategy,
7
+ type Query,
8
+ type QueryComparisonOptions,
9
+ type QueryConflictPaths,
10
+ type QueryContext,
11
+ type QueryDialect,
12
+ type QueryOptions,
13
+ type QueryPager,
14
+ QueryRaw,
15
+ type QueryRawFnOptions,
16
+ type QuerySearch,
17
+ type QuerySelect,
18
+ type QuerySelectArray,
19
+ type QuerySelectOptions,
20
+ type QuerySort,
21
+ type QuerySortDirection,
22
+ type QueryTextSearchOptions,
23
+ type QueryWhere,
24
+ type QueryWhereArray,
25
+ type QueryWhereFieldOperatorMap,
26
+ type QueryWhereMap,
27
+ type QueryWhereOptions,
28
+ type SqlQueryDialect,
29
+ type Type,
30
+ } from '../type/index.js';
31
+
32
+ import {
33
+ buildSortMap,
34
+ buldQueryWhereAsMap,
35
+ type CallbackKey,
36
+ escapeSqlId,
37
+ fillOnFields,
38
+ filterFieldKeys,
39
+ filterRelationKeys,
40
+ flatObject,
41
+ getFieldCallbackValue,
42
+ getFieldKeys,
43
+ getKeys,
44
+ hasKeys,
45
+ isSelectingRelations,
46
+ raw,
47
+ } from '../util/index.js';
48
+
49
+ import { AbstractDialect } from './abstractDialect.js';
50
+ import { SqlQueryContext } from './queryContext.js';
51
+
52
+ export abstract class AbstractSqlDialect extends AbstractDialect implements QueryDialect, SqlQueryDialect {
53
+ constructor(
54
+ namingStrategy?: NamingStrategy,
55
+ readonly escapeIdChar: '`' | '"' = '`',
56
+ readonly beginTransactionCommand: string = 'START TRANSACTION',
57
+ readonly commitTransactionCommand: string = 'COMMIT',
58
+ readonly rollbackTransactionCommand: string = 'ROLLBACK',
59
+ ) {
60
+ super(namingStrategy);
61
+ }
62
+
63
+ createContext(): QueryContext {
64
+ return new SqlQueryContext(this);
65
+ }
66
+
67
+ addValue(values: unknown[], value: unknown): string {
68
+ values.push(value ?? null);
69
+ return this.placeholder(values.length);
70
+ }
71
+
72
+ placeholder(_index: number): string {
73
+ return '?';
74
+ }
75
+
76
+ returningId<E>(entity: Type<E>): string {
77
+ const meta = getMeta(entity);
78
+ const idName = this.resolveColumnName(meta.id, meta.fields[meta.id]);
79
+ return `RETURNING ${this.escapeId(idName)} ${this.escapeId('id')}`;
80
+ }
81
+
82
+ search<E>(ctx: QueryContext, entity: Type<E>, q: Query<E> = {}, opts: QueryOptions = {}): void {
83
+ const meta = getMeta(entity);
84
+ const tableName = this.resolveTableName(entity, meta);
85
+ const prefix = (opts.prefix ?? (opts.autoPrefix || isSelectingRelations(meta, q.$select))) ? tableName : undefined;
86
+ opts = { ...opts, prefix };
87
+ this.where<E>(ctx, entity, q.$where, opts);
88
+ this.sort<E>(ctx, entity, q.$sort, opts);
89
+ this.pager(ctx, q);
90
+ }
91
+
92
+ selectFields<E>(ctx: QueryContext, entity: Type<E>, select: QuerySelect<E>, opts: QuerySelectOptions = {}): void {
93
+ const meta = getMeta(entity);
94
+ const prefix = opts.prefix ? opts.prefix + '.' : '';
95
+ const escapedPrefix = this.escapeId(opts.prefix, true, true);
96
+
97
+ let selectArr: QuerySelectArray<E>;
98
+
99
+ if (select) {
100
+ if (Array.isArray(select)) {
101
+ selectArr = select;
102
+ } else {
103
+ const selectPositive = getKeys(select).filter((it) => select[it]) as FieldKey<E>[];
104
+ selectArr = selectPositive.length
105
+ ? selectPositive
106
+ : (getFieldKeys(meta.fields).filter((it) => !(it in select)) as FieldKey<E>[]);
107
+ }
108
+ selectArr = selectArr.filter((it) => it instanceof QueryRaw || it in meta.fields);
109
+ if (opts.prefix && !selectArr.includes(meta.id)) {
110
+ selectArr = [meta.id, ...selectArr];
111
+ }
112
+ } else {
113
+ selectArr = getFieldKeys(meta.fields) as FieldKey<E>[];
114
+ }
115
+
116
+ if (!selectArr.length) {
117
+ ctx.append(escapedPrefix + '*');
118
+ return;
119
+ }
120
+
121
+ selectArr.forEach((key, index) => {
122
+ if (index > 0) ctx.append(', ');
123
+ if (key instanceof QueryRaw) {
124
+ this.getRawValue(ctx, {
125
+ value: key,
126
+ prefix: opts.prefix,
127
+ escapedPrefix,
128
+ autoPrefixAlias: opts.autoPrefixAlias,
129
+ });
130
+ } else {
131
+ const field = meta.fields[key as FieldKey<E>];
132
+ const columnName = this.resolveColumnName(key, field);
133
+ if (field.virtual) {
134
+ this.getRawValue(ctx, {
135
+ value: raw(field.virtual.value, key as string),
136
+ prefix: opts.prefix,
137
+ escapedPrefix,
138
+ autoPrefixAlias: opts.autoPrefixAlias,
139
+ });
140
+ } else {
141
+ ctx.append(escapedPrefix + this.escapeId(columnName));
142
+ }
143
+ if (!field.virtual && (columnName !== key || opts.autoPrefixAlias)) {
144
+ const aliasStr = (prefix + key) as string;
145
+ // Replace dots with underscores for alias to avoid syntax errors
146
+ const safeAlias = aliasStr.replace(/\./g, '_');
147
+ ctx.append(' ' + this.escapeId(safeAlias, true));
148
+ }
149
+ }
150
+ });
151
+ }
152
+
153
+ select<E>(ctx: QueryContext, entity: Type<E>, select: QuerySelect<E>, opts: QueryOptions = {}): void {
154
+ const meta = getMeta(entity);
155
+ const tableName = this.resolveTableName(entity, meta);
156
+ const prefix = (opts.prefix ?? (opts.autoPrefix || isSelectingRelations(meta, select))) ? tableName : undefined;
157
+
158
+ ctx.append('SELECT ');
159
+ this.selectFields(ctx, entity, select, { prefix });
160
+ // Add related fields BEFORE FROM clause
161
+ this.selectRelationFields(ctx, entity, select, { prefix });
162
+ ctx.append(` FROM ${this.escapeId(tableName)}`);
163
+ // Add JOINs AFTER FROM clause
164
+ this.selectRelationJoins(ctx, entity, select, { prefix });
165
+ }
166
+
167
+ protected selectRelationFields<E>(
168
+ ctx: QueryContext,
169
+ entity: Type<E>,
170
+ select: QuerySelect<E>,
171
+ opts: { prefix?: string } = {},
172
+ ): void {
173
+ if (Array.isArray(select)) {
174
+ return;
175
+ }
176
+
177
+ const meta = getMeta(entity);
178
+ const tableName = this.resolveTableName(entity, meta);
179
+ const relKeys = filterRelationKeys(meta, select);
180
+ const isSelectArray = Array.isArray(select);
181
+ const prefix = opts.prefix;
182
+
183
+ for (const relKey of relKeys) {
184
+ const relOpts = meta.relations[relKey];
185
+
186
+ if (relOpts.cardinality === '1m' || relOpts.cardinality === 'mm') {
187
+ continue;
188
+ }
189
+
190
+ const isFirstLevel = prefix === tableName;
191
+ const joinRelAlias = isFirstLevel ? relKey : prefix ? prefix + '.' + relKey : relKey;
192
+ const relEntity = relOpts.entity();
193
+ const relSelect = select[relKey as string];
194
+ const relQuery = isSelectArray ? {} : Array.isArray(relSelect) ? { $select: relSelect } : relSelect;
195
+
196
+ ctx.append(', ');
197
+ this.selectFields(ctx, relEntity, relQuery.$select, {
198
+ prefix: joinRelAlias,
199
+ autoPrefixAlias: true,
200
+ });
201
+
202
+ // Recursively add nested relation fields
203
+ this.selectRelationFields(ctx, relEntity, relQuery.$select, {
204
+ prefix: joinRelAlias,
205
+ });
206
+ }
207
+ }
208
+
209
+ protected selectRelationJoins<E>(
210
+ ctx: QueryContext,
211
+ entity: Type<E>,
212
+ select: QuerySelect<E>,
213
+ opts: { prefix?: string } = {},
214
+ ): void {
215
+ if (Array.isArray(select)) {
216
+ return;
217
+ }
218
+
219
+ const meta = getMeta(entity);
220
+ const tableName = this.resolveTableName(entity, meta);
221
+ const relKeys = filterRelationKeys(meta, select);
222
+ const isSelectArray = Array.isArray(select);
223
+ const prefix = opts.prefix;
224
+
225
+ for (const relKey of relKeys) {
226
+ const relOpts = meta.relations[relKey];
227
+
228
+ if (relOpts.cardinality === '1m' || relOpts.cardinality === 'mm') {
229
+ continue;
230
+ }
231
+
232
+ const isFirstLevel = prefix === tableName;
233
+ const joinRelAlias = isFirstLevel ? (relKey as string) : prefix ? prefix + '.' + relKey : (relKey as string);
234
+ const relEntity = relOpts.entity();
235
+ const relSelect = select[relKey as string];
236
+ const relQuery = isSelectArray ? {} : Array.isArray(relSelect) ? { $select: relSelect } : relSelect;
237
+
238
+ const relMeta = getMeta(relEntity);
239
+ const relTableName = this.resolveTableName(relEntity, relMeta);
240
+ const relEntityName = this.escapeId(relTableName);
241
+ const relPath = prefix ? this.escapeId(prefix, true) : this.escapeId(tableName);
242
+ const joinType = relQuery.$required ? 'INNER' : 'LEFT';
243
+ const joinAlias = this.escapeId(joinRelAlias, true);
244
+
245
+ ctx.append(` ${joinType} JOIN ${relEntityName} ${joinAlias} ON `);
246
+ ctx.append(
247
+ relOpts.references
248
+ .map((it) => {
249
+ const foreignColumnName = this.resolveColumnName(it.foreign, relMeta.fields[it.foreign]);
250
+ const localColumnName = this.resolveColumnName(it.local, meta.fields[it.local]);
251
+ return `${joinAlias}.${this.escapeId(foreignColumnName)} = ${relPath}.${this.escapeId(localColumnName)}`;
252
+ })
253
+ .join(' AND '),
254
+ );
255
+
256
+ if (relQuery.$where) {
257
+ ctx.append(' AND ');
258
+ this.where(ctx, relEntity, relQuery.$where, { prefix: joinRelAlias, clause: false });
259
+ }
260
+
261
+ // Recursively add nested relation JOINs
262
+ this.selectRelationJoins(ctx, relEntity, relQuery.$select, {
263
+ prefix: joinRelAlias,
264
+ });
265
+ }
266
+ }
267
+
268
+ where<E>(ctx: QueryContext, entity: Type<E>, where: QueryWhere<E> = {}, opts: QueryWhereOptions = {}): void {
269
+ const meta = getMeta(entity);
270
+ const { usePrecedence, clause = 'WHERE', softDelete } = opts;
271
+
272
+ where = buldQueryWhereAsMap(meta, where);
273
+
274
+ if (meta.softDelete && (softDelete || softDelete === undefined) && !where[meta.softDelete as string]) {
275
+ where[meta.softDelete as string] = null;
276
+ }
277
+
278
+ const entries = Object.entries(where);
279
+
280
+ if (!entries.length) {
281
+ return;
282
+ }
283
+
284
+ if (clause) {
285
+ ctx.append(` ${clause} `);
286
+ }
287
+
288
+ if (usePrecedence) {
289
+ ctx.append('(');
290
+ }
291
+
292
+ entries.forEach(([key, val], index) => {
293
+ if (index > 0) {
294
+ ctx.append(' AND ');
295
+ }
296
+ this.compare(ctx, entity, key as keyof QueryWhereMap<E>, val as any, {
297
+ ...opts,
298
+ usePrecedence: entries.length > 1,
299
+ });
300
+ });
301
+
302
+ if (usePrecedence) {
303
+ ctx.append(')');
304
+ }
305
+ }
306
+
307
+ compare<E, K extends keyof QueryWhereMap<E>>(
308
+ ctx: QueryContext,
309
+ entity: Type<E>,
310
+ key: K,
311
+ val: QueryWhereMap<E>[K],
312
+ opts: QueryComparisonOptions = {},
313
+ ): void {
314
+ const meta = getMeta(entity);
315
+
316
+ if (val instanceof QueryRaw) {
317
+ if (key === '$exists' || key === '$nexists') {
318
+ ctx.append(key === '$exists' ? 'EXISTS (' : 'NOT EXISTS (');
319
+ const tableName = this.resolveTableName(entity, meta);
320
+ this.getRawValue(ctx, {
321
+ value: val,
322
+ prefix: tableName,
323
+ escapedPrefix: this.escapeId(tableName, false, true),
324
+ });
325
+ ctx.append(')');
326
+ return;
327
+ }
328
+ this.getComparisonKey(ctx, entity, key as FieldKey<E>, opts);
329
+ ctx.append(' = ');
330
+ this.getRawValue(ctx, { value: val });
331
+ return;
332
+ }
333
+
334
+ if (key === '$text') {
335
+ const search = val as QueryTextSearchOptions<E>;
336
+ const fields = search.$fields.map((fKey) => {
337
+ const field = meta.fields[fKey];
338
+ const columnName = this.resolveColumnName(fKey, field);
339
+ return this.escapeId(columnName);
340
+ });
341
+ ctx.append(`MATCH(${fields.join(', ')}) AGAINST(`);
342
+ ctx.addValue(search.$value);
343
+ ctx.append(')');
344
+ return;
345
+ }
346
+
347
+ if (key === '$and' || key === '$or' || key === '$not' || key === '$nor') {
348
+ const negateOperatorMap = {
349
+ $not: '$and',
350
+ $nor: '$or',
351
+ } as const;
352
+
353
+ const op: '$and' | '$or' = negateOperatorMap[key as string] ?? key;
354
+ const negate = key in negateOperatorMap ? 'NOT' : '';
355
+
356
+ const valArr = val as QueryWhereArray<E>;
357
+ const hasManyItems = valArr.length > 1;
358
+
359
+ if ((opts.usePrecedence || negate) && hasManyItems) {
360
+ ctx.append((negate ? negate + ' ' : '') + '(');
361
+ } else if (negate) {
362
+ ctx.append(negate + ' ');
363
+ }
364
+
365
+ valArr.forEach((whereEntry, index) => {
366
+ if (index > 0) {
367
+ ctx.append(op === '$or' ? ' OR ' : ' AND ');
368
+ }
369
+ if (whereEntry instanceof QueryRaw) {
370
+ this.getRawValue(ctx, {
371
+ value: whereEntry,
372
+ prefix: opts.prefix,
373
+ escapedPrefix: this.escapeId(opts.prefix, true, true),
374
+ });
375
+ } else {
376
+ this.where(ctx, entity, whereEntry, {
377
+ prefix: opts.prefix,
378
+ usePrecedence: hasManyItems && !Array.isArray(whereEntry) && getKeys(whereEntry).length > 1,
379
+ clause: false,
380
+ });
381
+ }
382
+ });
383
+
384
+ if ((opts.usePrecedence || negate) && hasManyItems) {
385
+ ctx.append(')');
386
+ }
387
+ return;
388
+ }
389
+
390
+ const value = Array.isArray(val) ? { $in: val } : typeof val === 'object' && val !== null ? val : { $eq: val };
391
+ const operators = getKeys(value) as (keyof QueryWhereFieldOperatorMap<E>)[];
392
+
393
+ if (operators.length > 1) {
394
+ ctx.append('(');
395
+ }
396
+
397
+ operators.forEach((op, index) => {
398
+ if (index > 0) {
399
+ ctx.append(' AND ');
400
+ }
401
+ this.compareFieldOperator(ctx, entity, key as FieldKey<E>, op, value[op], opts);
402
+ });
403
+
404
+ if (operators.length > 1) {
405
+ ctx.append(')');
406
+ }
407
+ }
408
+
409
+ compareFieldOperator<E, K extends keyof QueryWhereFieldOperatorMap<E>>(
410
+ ctx: QueryContext,
411
+ entity: Type<E>,
412
+ key: FieldKey<E>,
413
+ op: K,
414
+ val: QueryWhereFieldOperatorMap<E>[K],
415
+ opts: QueryOptions = {},
416
+ ): void {
417
+ switch (op) {
418
+ case '$eq':
419
+ this.getComparisonKey(ctx, entity, key, opts);
420
+ if (val === null) {
421
+ ctx.append(' IS NULL');
422
+ } else {
423
+ ctx.append(' = ');
424
+ ctx.addValue(val);
425
+ }
426
+ break;
427
+ case '$ne':
428
+ this.getComparisonKey(ctx, entity, key, opts);
429
+ if (val === null) {
430
+ ctx.append(' IS NOT NULL');
431
+ } else {
432
+ ctx.append(' <> ');
433
+ ctx.addValue(val);
434
+ }
435
+ break;
436
+ case '$not':
437
+ ctx.append('NOT (');
438
+ this.compare(ctx, entity, key as any, val as any, opts);
439
+ ctx.append(')');
440
+ break;
441
+ case '$gt':
442
+ this.getComparisonKey(ctx, entity, key, opts);
443
+ ctx.append(' > ');
444
+ ctx.addValue(val);
445
+ break;
446
+ case '$gte':
447
+ this.getComparisonKey(ctx, entity, key, opts);
448
+ ctx.append(' >= ');
449
+ ctx.addValue(val);
450
+ break;
451
+ case '$lt':
452
+ this.getComparisonKey(ctx, entity, key, opts);
453
+ ctx.append(' < ');
454
+ ctx.addValue(val);
455
+ break;
456
+ case '$lte':
457
+ this.getComparisonKey(ctx, entity, key, opts);
458
+ ctx.append(' <= ');
459
+ ctx.addValue(val);
460
+ break;
461
+ case '$startsWith':
462
+ this.getComparisonKey(ctx, entity, key, opts);
463
+ ctx.append(' LIKE ');
464
+ ctx.addValue(`${val}%`);
465
+ break;
466
+ case '$istartsWith':
467
+ this.getComparisonKey(ctx, entity, key, opts);
468
+ ctx.append(' LIKE ');
469
+ ctx.addValue(`${(val as string).toLowerCase()}%`);
470
+ break;
471
+ case '$endsWith':
472
+ this.getComparisonKey(ctx, entity, key, opts);
473
+ ctx.append(' LIKE ');
474
+ ctx.addValue(`%${val}`);
475
+ break;
476
+ case '$iendsWith':
477
+ this.getComparisonKey(ctx, entity, key, opts);
478
+ ctx.append(' LIKE ');
479
+ ctx.addValue(`%${(val as string).toLowerCase()}`);
480
+ break;
481
+ case '$includes':
482
+ this.getComparisonKey(ctx, entity, key, opts);
483
+ ctx.append(' LIKE ');
484
+ ctx.addValue(`%${val}%`);
485
+ break;
486
+ case '$iincludes':
487
+ this.getComparisonKey(ctx, entity, key, opts);
488
+ ctx.append(' LIKE ');
489
+ ctx.addValue(`%${(val as string).toLowerCase()}%`);
490
+ break;
491
+ case '$ilike':
492
+ this.getComparisonKey(ctx, entity, key, opts);
493
+ ctx.append(' LIKE ');
494
+ ctx.addValue((val as string).toLowerCase());
495
+ break;
496
+ case '$like':
497
+ this.getComparisonKey(ctx, entity, key, opts);
498
+ ctx.append(' LIKE ');
499
+ ctx.addValue(val);
500
+ break;
501
+ case '$in':
502
+ this.getComparisonKey(ctx, entity, key, opts);
503
+ if (Array.isArray(val) && val.length > 0) {
504
+ ctx.append(' IN (');
505
+ this.addValues(ctx, val as any[]);
506
+ ctx.append(')');
507
+ } else {
508
+ ctx.append(' IN (NULL)');
509
+ }
510
+ break;
511
+ case '$nin':
512
+ this.getComparisonKey(ctx, entity, key, opts);
513
+ if (Array.isArray(val) && val.length > 0) {
514
+ ctx.append(' NOT IN (');
515
+ this.addValues(ctx, val as any[]);
516
+ ctx.append(')');
517
+ } else {
518
+ ctx.append(' NOT IN (NULL)');
519
+ }
520
+ break;
521
+ case '$regex':
522
+ this.getComparisonKey(ctx, entity, key, opts);
523
+ ctx.append(' REGEXP ');
524
+ ctx.addValue(val);
525
+ break;
526
+ default:
527
+ throw TypeError(`unknown operator: ${op}`);
528
+ }
529
+ }
530
+
531
+ protected addValues(ctx: QueryContext, vals: unknown[]): void {
532
+ vals.forEach((val, index) => {
533
+ if (index > 0) {
534
+ ctx.append(', ');
535
+ }
536
+ ctx.addValue(val);
537
+ });
538
+ }
539
+
540
+ getComparisonKey<E>(ctx: QueryContext, entity: Type<E>, key: FieldKey<E>, { prefix }: QueryOptions = {}): void {
541
+ const meta = getMeta(entity);
542
+ const escapedPrefix = this.escapeId(prefix, true, true);
543
+ const field = meta.fields[key];
544
+
545
+ if (field?.virtual) {
546
+ this.getRawValue(ctx, {
547
+ value: field.virtual,
548
+ prefix,
549
+ escapedPrefix,
550
+ });
551
+ return;
552
+ }
553
+
554
+ const columnName = this.resolveColumnName(key, field);
555
+ ctx.append(escapedPrefix + this.escapeId(columnName));
556
+ }
557
+
558
+ sort<E>(ctx: QueryContext, entity: Type<E>, sort: QuerySort<E>, { prefix }: QueryOptions): void {
559
+ const sortMap = buildSortMap(sort);
560
+ if (!hasKeys(sortMap)) {
561
+ return;
562
+ }
563
+ const meta = getMeta(entity);
564
+ const flattenedSort = flatObject(sortMap, prefix);
565
+ const directionMap = { 1: '', asc: '', '-1': ' DESC', desc: ' DESC' } as const;
566
+
567
+ ctx.append(' ORDER BY ');
568
+
569
+ Object.entries(flattenedSort).forEach(([key, sort], index) => {
570
+ if (index > 0) {
571
+ ctx.append(', ');
572
+ }
573
+ const field = meta.fields[key];
574
+ const name = this.resolveColumnName(key, field);
575
+ const direction = directionMap[sort as QuerySortDirection];
576
+ ctx.append(this.escapeId(name) + direction);
577
+ });
578
+ }
579
+
580
+ pager(ctx: QueryContext, opts: QueryPager): void {
581
+ if (opts.$limit) {
582
+ ctx.append(` LIMIT ${Number(opts.$limit)}`);
583
+ }
584
+ if (opts.$skip !== undefined) {
585
+ ctx.append(` OFFSET ${Number(opts.$skip)}`);
586
+ }
587
+ }
588
+
589
+ count<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void {
590
+ const search: Query<E> = { ...q };
591
+ delete search.$sort;
592
+ this.select<E>(ctx, entity, [raw('COUNT(*)', 'count')], undefined);
593
+ this.search(ctx, entity, search, opts);
594
+ }
595
+
596
+ find<E>(ctx: QueryContext, entity: Type<E>, q: Query<E> = {}, opts?: QueryOptions): void {
597
+ this.select(ctx, entity, q.$select, opts);
598
+ this.search(ctx, entity, q, opts);
599
+ }
600
+
601
+ insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void {
602
+ const meta = getMeta(entity);
603
+ const payloads = fillOnFields(meta, payload, 'onInsert');
604
+ const keys = filterFieldKeys(meta, payloads[0], 'onInsert');
605
+
606
+ const columns = keys.map((key) => {
607
+ const field = meta.fields[key];
608
+ return this.escapeId(this.resolveColumnName(key, field));
609
+ });
610
+ const tableName = this.resolveTableName(entity, meta);
611
+ ctx.append(`INSERT INTO ${this.escapeId(tableName)} (${columns.join(', ')}) VALUES (`);
612
+
613
+ payloads.forEach((it, recordIndex) => {
614
+ if (recordIndex > 0) {
615
+ ctx.append('), (');
616
+ }
617
+ keys.forEach((key, keyIndex) => {
618
+ if (keyIndex > 0) {
619
+ ctx.append(', ');
620
+ }
621
+ const field = meta.fields[key];
622
+ this.formatPersistableValue(ctx, field, it[key]);
623
+ });
624
+ });
625
+ ctx.append(')');
626
+ }
627
+
628
+ update<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, payload: E, opts?: QueryOptions): void {
629
+ const meta = getMeta(entity);
630
+ const [filledPayload] = fillOnFields(meta, payload, 'onUpdate');
631
+ const keys = filterFieldKeys(meta, filledPayload, 'onUpdate');
632
+
633
+ const tableName = this.resolveTableName(entity, meta);
634
+ ctx.append(`UPDATE ${this.escapeId(tableName)} SET `);
635
+ keys.forEach((key, index) => {
636
+ if (index > 0) {
637
+ ctx.append(', ');
638
+ }
639
+ const field = meta.fields[key];
640
+ const columnName = this.resolveColumnName(key, field);
641
+ ctx.append(`${this.escapeId(columnName)} = `);
642
+ this.formatPersistableValue(ctx, field, filledPayload[key]);
643
+ });
644
+
645
+ this.search(ctx, entity, q, opts);
646
+ }
647
+
648
+ upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): void {
649
+ const meta = getMeta(entity);
650
+ const update = this.getUpsertUpdateAssignments(ctx, meta, conflictPaths, payload, (name) => `VALUES(${name})`);
651
+
652
+ if (update) {
653
+ this.insert(ctx, entity, payload);
654
+ ctx.append(` ON DUPLICATE KEY UPDATE ${update}`);
655
+ } else {
656
+ const insertCtx = this.createContext();
657
+ this.insert(insertCtx, entity, payload);
658
+ ctx.append(insertCtx.sql.replace(/^INSERT/, 'INSERT IGNORE'));
659
+ insertCtx.values.forEach((val) => {
660
+ ctx.pushValue(val);
661
+ });
662
+ }
663
+ }
664
+
665
+ protected getUpsertUpdateAssignments<E>(
666
+ ctx: QueryContext,
667
+ meta: EntityMeta<E>,
668
+ conflictPaths: QueryConflictPaths<E>,
669
+ payload: E,
670
+ callback?: (columnName: string) => string,
671
+ ): string {
672
+ const [filledPayload] = fillOnFields(meta, payload, 'onUpdate');
673
+ const fields = filterFieldKeys(meta, filledPayload, 'onUpdate');
674
+ return fields
675
+ .filter((col) => !conflictPaths[col])
676
+ .map((col) => {
677
+ const field = meta.fields[col];
678
+ const columnName = this.resolveColumnName(col, field);
679
+ if (callback) {
680
+ return `${this.escapeId(columnName)} = ${callback(this.escapeId(columnName))}`;
681
+ }
682
+ const valCtx = this.createContext();
683
+ this.formatPersistableValue(valCtx, field, filledPayload[col]);
684
+ valCtx.values.forEach((val) => {
685
+ ctx.pushValue(val);
686
+ });
687
+ return `${this.escapeId(columnName)} = ${valCtx.sql}`;
688
+ })
689
+ .join(', ');
690
+ }
691
+
692
+ protected getUpsertConflictPathsStr<E>(meta: EntityMeta<E>, conflictPaths: QueryConflictPaths<E>): string {
693
+ return getKeys(conflictPaths)
694
+ .map((key) => {
695
+ const field = meta.fields[key];
696
+ const columnName = this.resolveColumnName(key, field);
697
+ return this.escapeId(columnName);
698
+ })
699
+ .join(', ');
700
+ }
701
+
702
+ delete<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts: QueryOptions = {}): void {
703
+ const meta = getMeta(entity);
704
+ const tableName = this.resolveTableName(entity, meta);
705
+
706
+ if (opts.softDelete || opts.softDelete === undefined) {
707
+ if (meta.softDelete) {
708
+ const field = meta.fields[meta.softDelete];
709
+ const value = getFieldCallbackValue(field.onDelete);
710
+ const columnName = this.resolveColumnName(meta.softDelete, field);
711
+ ctx.append(`UPDATE ${this.escapeId(tableName)} SET ${this.escapeId(columnName)} = `);
712
+ ctx.addValue(value);
713
+ this.search(ctx, entity, q, opts);
714
+ return;
715
+ }
716
+ if (opts.softDelete) {
717
+ throw TypeError(`'${tableName}' has not enabled 'softDelete'`);
718
+ }
719
+ }
720
+
721
+ ctx.append(`DELETE FROM ${this.escapeId(tableName)}`);
722
+ this.search(ctx, entity, q, opts);
723
+ }
724
+
725
+ escapeId(val: string, forbidQualified?: boolean, addDot?: boolean): string {
726
+ return escapeSqlId(val, this.escapeIdChar, forbidQualified, addDot);
727
+ }
728
+
729
+ protected getPersistables<E>(
730
+ ctx: QueryContext,
731
+ meta: EntityMeta<E>,
732
+ payload: E | E[],
733
+ callbackKey: CallbackKey,
734
+ ): Record<string, unknown>[] {
735
+ const payloads = fillOnFields(meta, payload, callbackKey);
736
+ return payloads.map((it) => this.getPersistable(ctx, meta, it, callbackKey));
737
+ }
738
+
739
+ protected getPersistable<E>(
740
+ ctx: QueryContext,
741
+ meta: EntityMeta<E>,
742
+ payload: E,
743
+ callbackKey: CallbackKey,
744
+ ): Record<string, unknown> {
745
+ const filledPayload = fillOnFields(meta, payload, callbackKey)[0];
746
+ const keys = filterFieldKeys(meta, filledPayload, callbackKey);
747
+ return keys.reduce(
748
+ (acc, key) => {
749
+ const field = meta.fields[key];
750
+ const valCtx = this.createContext();
751
+ this.formatPersistableValue(valCtx, field, filledPayload[key]);
752
+ valCtx.values.forEach((val) => {
753
+ ctx.pushValue(val);
754
+ });
755
+ acc[key as string] = valCtx.sql;
756
+ return acc;
757
+ },
758
+ {} as Record<string, unknown>,
759
+ );
760
+ }
761
+
762
+ protected formatPersistableValue<E>(ctx: QueryContext, field: FieldOptions, value: unknown): void {
763
+ if (value instanceof QueryRaw) {
764
+ this.getRawValue(ctx, { value });
765
+ return;
766
+ }
767
+ if (field?.type === 'json' || field?.type === 'jsonb') {
768
+ ctx.addValue(value ? JSON.stringify(value) : null);
769
+ return;
770
+ }
771
+ if (field?.type === 'vector' && Array.isArray(value)) {
772
+ ctx.addValue(`[${value.join(',')}]`);
773
+ return;
774
+ }
775
+ ctx.addValue(value);
776
+ }
777
+
778
+ getRawValue(ctx: QueryContext, opts: QueryRawFnOptions & { value: QueryRaw; autoPrefixAlias?: boolean }) {
779
+ const { value, prefix = '', escapedPrefix, autoPrefixAlias } = opts;
780
+ if (typeof value.value === 'function') {
781
+ const res = value.value({
782
+ ...opts,
783
+ ctx,
784
+ dialect: this,
785
+ prefix,
786
+ escapedPrefix: escapedPrefix ?? this.escapeId(prefix, true, true),
787
+ });
788
+ if (typeof res === 'string' || (typeof res === 'number' && !Number.isNaN(res))) {
789
+ ctx.append(String(res));
790
+ }
791
+ } else {
792
+ ctx.append(prefix + String(value.value));
793
+ }
794
+ const alias = value.alias;
795
+ if (alias) {
796
+ const fullAlias = autoPrefixAlias ? prefix + alias : alias;
797
+ // Replace dots with underscores for alias to avoid syntax errors
798
+ const safeAlias = fullAlias.replace(/\./g, '_');
799
+ const escapedFullAlias = this.escapeId(safeAlias, true);
800
+ ctx.append(' ' + escapedFullAlias);
801
+ }
802
+ }
803
+
804
+ abstract escape(value: unknown): string;
805
+ }