wok-server 0.5.0 → 0.7.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 (380) hide show
  1. package/README.en.md +61 -0
  2. package/README.md +44 -29
  3. package/dist/cache/cache.js +98 -98
  4. package/dist/cache/config.js +19 -19
  5. package/dist/cache/index.js +27 -27
  6. package/dist/cache/purge-task.js +46 -46
  7. package/dist/cache/stat.js +47 -47
  8. package/dist/config/convert.js +36 -36
  9. package/dist/config/exception.js +14 -14
  10. package/dist/config/index.js +81 -81
  11. package/dist/http-client/index.js +136 -136
  12. package/dist/i18n/ar.js +17 -17
  13. package/dist/i18n/de.js +17 -17
  14. package/dist/i18n/en-us.js +17 -17
  15. package/dist/i18n/es.js +17 -17
  16. package/dist/i18n/fr.js +17 -17
  17. package/dist/i18n/i18n.js +231 -231
  18. package/dist/i18n/index.js +52 -52
  19. package/dist/i18n/ja.js +17 -17
  20. package/dist/i18n/ko.js +17 -17
  21. package/dist/i18n/msg.js +2 -2
  22. package/dist/i18n/pt.js +17 -17
  23. package/dist/i18n/ru.js +17 -17
  24. package/dist/i18n/tag.js +18 -18
  25. package/dist/i18n/zh-HK.js +17 -17
  26. package/dist/i18n/zh-TW.js +17 -17
  27. package/dist/i18n/zh-cn.js +17 -17
  28. package/dist/index.js +14 -14
  29. package/dist/lock/index.js +114 -114
  30. package/dist/log/config.js +35 -35
  31. package/dist/log/date.js +21 -21
  32. package/dist/log/file.js +198 -198
  33. package/dist/log/index.js +135 -135
  34. package/dist/log/level.js +33 -33
  35. package/dist/log/log.js +56 -56
  36. package/dist/log/store.js +19 -19
  37. package/dist/mongodb/collection.js +2 -2
  38. package/dist/mongodb/config.js +34 -34
  39. package/dist/mongodb/doc.js +2 -2
  40. package/dist/mongodb/exception.js +14 -14
  41. package/dist/mongodb/index.js +58 -58
  42. package/dist/mongodb/manager/base.js +563 -563
  43. package/dist/mongodb/manager/index.js +63 -63
  44. package/dist/mongodb/manager/tx-strict.js +84 -84
  45. package/dist/mongodb/manager/tx.js +30 -30
  46. package/dist/mongodb/migration.js +52 -52
  47. package/dist/mvc/access-log.js +33 -33
  48. package/dist/mvc/config.js +27 -27
  49. package/dist/mvc/exchange.js +113 -113
  50. package/dist/mvc/handler/index.js +7 -6
  51. package/dist/mvc/handler/json.js +65 -65
  52. package/dist/mvc/handler/restful.js +35 -35
  53. package/dist/mvc/handler/sse.js +65 -0
  54. package/dist/mvc/handler/upload.js +31 -31
  55. package/dist/mvc/index.js +50 -50
  56. package/dist/mvc/interceptor.js +2 -2
  57. package/dist/mvc/query.js +43 -43
  58. package/dist/mvc/render/file.js +132 -132
  59. package/dist/mvc/render/html/html.js +90 -90
  60. package/dist/mvc/render/html/index.js +18 -18
  61. package/dist/mvc/render/html/style.js +2 -2
  62. package/dist/mvc/render/index.js +7 -7
  63. package/dist/mvc/render/json.js +26 -26
  64. package/dist/mvc/render/text.js +16 -16
  65. package/dist/mvc/router.js +2 -2
  66. package/dist/mvc/server.js +272 -272
  67. package/dist/mvc/static/header.js +67 -67
  68. package/dist/mvc/static/index.js +6 -6
  69. package/dist/mvc/static/mime-type.js +84 -84
  70. package/dist/mvc/static/server-cache-config.js +66 -66
  71. package/dist/mvc/static/server-cache.js +133 -133
  72. package/dist/mvc/static/static-handler.js +372 -372
  73. package/dist/mysql/config.js +51 -51
  74. package/dist/mysql/exception.js +14 -14
  75. package/dist/mysql/index.js +87 -87
  76. package/dist/mysql/manager/base.js +278 -239
  77. package/dist/mysql/manager/index.js +107 -107
  78. package/dist/mysql/manager/ops/count.js +20 -20
  79. package/dist/mysql/manager/ops/criteria.js +381 -356
  80. package/dist/mysql/manager/ops/delete.js +59 -65
  81. package/dist/mysql/manager/ops/exist.js +26 -26
  82. package/dist/mysql/manager/ops/find.js +149 -169
  83. package/dist/mysql/manager/ops/index.js +16 -14
  84. package/dist/mysql/manager/ops/insert.js +132 -106
  85. package/dist/mysql/manager/ops/modify.js +10 -10
  86. package/dist/mysql/manager/ops/order-by.js +28 -0
  87. package/dist/mysql/manager/ops/paginate.js +48 -23
  88. package/dist/mysql/manager/ops/query.js +9 -9
  89. package/dist/mysql/manager/ops/update.js +222 -216
  90. package/dist/mysql/manager/ops/upsert.js +178 -0
  91. package/dist/mysql/manager/ops/utils.js +28 -24
  92. package/dist/mysql/manager/tx-strict.js +103 -103
  93. package/dist/mysql/manager/tx.js +30 -30
  94. package/dist/mysql/manager/utils.js +56 -56
  95. package/dist/mysql/migration.js +136 -136
  96. package/dist/mysql/table-info.js +8 -8
  97. package/dist/task/daily.js +59 -59
  98. package/dist/task/fixed-delay.js +38 -38
  99. package/dist/task/fixed-rate.js +42 -42
  100. package/dist/task/index.js +9 -9
  101. package/dist/task/task.js +56 -56
  102. package/dist/validation/exception.js +36 -36
  103. package/dist/validation/index.js +40 -40
  104. package/dist/validation/validator/array.js +34 -34
  105. package/dist/validation/validator/enum.js +28 -28
  106. package/dist/validation/validator/index.js +14 -14
  107. package/dist/validation/validator/length.js +40 -40
  108. package/dist/validation/validator/max-length.js +35 -35
  109. package/dist/validation/validator/max.js +29 -29
  110. package/dist/validation/validator/min-length.js +33 -33
  111. package/dist/validation/validator/min.js +29 -29
  112. package/dist/validation/validator/not-blank.js +33 -33
  113. package/dist/validation/validator/not-null.js +21 -21
  114. package/dist/validation/validator/plain-obj.js +32 -32
  115. package/dist/validation/validator/regexp.js +34 -34
  116. package/documentation/en/cache.md +56 -0
  117. package/documentation/en/config.md +96 -0
  118. package/documentation/en/engineering.md +256 -0
  119. package/documentation/en/http-client.md +32 -0
  120. package/documentation/en/i18n.md +143 -0
  121. package/documentation/en/index.md +24 -0
  122. package/documentation/en/lock.md +51 -0
  123. package/documentation/en/log.md +109 -0
  124. package/documentation/en/mongodb.md +256 -0
  125. package/documentation/en/mvc.md +688 -0
  126. package/documentation/en/mysql.md +682 -0
  127. package/documentation/en/task.md +45 -0
  128. package/documentation/en/test.md +56 -0
  129. package/documentation/en/validate.md +130 -0
  130. package/documentation/zh-cn/mvc.md +66 -24
  131. package/documentation/zh-cn/mysql.md +146 -17
  132. package/package.json +4 -1
  133. package/skills/wok-server-api-rules/SKILL.md +350 -0
  134. package/skills/wok-server-cache/SKILL.md +216 -0
  135. package/skills/wok-server-code-navigation/SKILL.md +153 -0
  136. package/skills/wok-server-config/SKILL.md +200 -0
  137. package/skills/wok-server-getting-started/SKILL.md +123 -0
  138. package/skills/wok-server-getting-started/references/engineering.md +169 -0
  139. package/skills/wok-server-http-client/SKILL.md +164 -0
  140. package/skills/wok-server-i18n/SKILL.md +214 -0
  141. package/skills/wok-server-lock/SKILL.md +144 -0
  142. package/skills/wok-server-log/SKILL.md +218 -0
  143. package/skills/wok-server-mongodb/SKILL.md +235 -0
  144. package/skills/wok-server-mvc/SKILL.md +251 -0
  145. package/skills/wok-server-mvc/references/respond-html.md +157 -0
  146. package/skills/wok-server-mvc/references/sse.md +121 -0
  147. package/skills/wok-server-mvc/references/static-files.md +47 -0
  148. package/skills/wok-server-mvc/references/upload.md +62 -0
  149. package/skills/wok-server-mvc/references/websocket.md +30 -0
  150. package/skills/wok-server-mysql/SKILL.md +388 -0
  151. package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
  152. package/skills/wok-server-mysql/references/version-control.md +22 -0
  153. package/skills/wok-server-task/SKILL.md +158 -0
  154. package/skills/wok-server-validate/SKILL.md +167 -0
  155. package/src/cache/cache.ts +118 -0
  156. package/src/cache/config.ts +53 -0
  157. package/src/cache/index.ts +27 -0
  158. package/src/cache/purge-task.ts +53 -0
  159. package/src/cache/stat.ts +47 -0
  160. package/src/config/convert.ts +27 -0
  161. package/src/config/exception.ts +8 -0
  162. package/src/config/index.ts +92 -0
  163. package/src/http-client/index.ts +202 -0
  164. package/src/i18n/ar.ts +16 -0
  165. package/src/i18n/de.ts +16 -0
  166. package/src/i18n/en-us.ts +16 -0
  167. package/src/i18n/es.ts +16 -0
  168. package/src/i18n/fr.ts +16 -0
  169. package/src/i18n/i18n.ts +230 -0
  170. package/src/i18n/index.ts +50 -0
  171. package/src/i18n/ja.ts +16 -0
  172. package/src/i18n/ko.ts +16 -0
  173. package/src/i18n/msg.ts +50 -0
  174. package/src/i18n/pt.ts +16 -0
  175. package/src/i18n/ru.ts +16 -0
  176. package/src/i18n/tag.ts +18 -0
  177. package/src/i18n/zh-HK.ts +16 -0
  178. package/src/i18n/zh-TW.ts +16 -0
  179. package/src/i18n/zh-cn.ts +16 -0
  180. package/src/index.ts +11 -0
  181. package/src/lock/index.ts +164 -0
  182. package/src/log/config.ts +71 -0
  183. package/src/log/date.ts +19 -0
  184. package/src/log/file.ts +215 -0
  185. package/src/log/index.ts +136 -0
  186. package/src/log/level.ts +29 -0
  187. package/src/log/log.ts +77 -0
  188. package/src/log/store.ts +31 -0
  189. package/src/mongodb/collection.ts +25 -0
  190. package/src/mongodb/config.ts +69 -0
  191. package/src/mongodb/doc.ts +12 -0
  192. package/src/mongodb/exception.ts +8 -0
  193. package/src/mongodb/index.ts +71 -0
  194. package/src/mongodb/manager/base.ts +674 -0
  195. package/src/mongodb/manager/index.ts +80 -0
  196. package/src/mongodb/manager/tx-strict.ts +153 -0
  197. package/src/mongodb/manager/tx.ts +34 -0
  198. package/src/mongodb/migration.ts +66 -0
  199. package/src/mvc/access-log.ts +33 -0
  200. package/src/mvc/config.ts +70 -0
  201. package/src/mvc/exchange.ts +126 -0
  202. package/src/mvc/handler/index.ts +4 -0
  203. package/src/mvc/handler/json.ts +96 -0
  204. package/src/mvc/handler/restful.ts +39 -0
  205. package/src/mvc/handler/sse.ts +90 -0
  206. package/src/mvc/handler/upload.ts +54 -0
  207. package/src/mvc/index.ts +48 -0
  208. package/src/mvc/interceptor.ts +12 -0
  209. package/src/mvc/query.ts +36 -0
  210. package/src/mvc/render/file.ts +148 -0
  211. package/src/mvc/render/html/html.ts +187 -0
  212. package/src/mvc/render/html/index.ts +16 -0
  213. package/src/mvc/render/html/style.ts +1201 -0
  214. package/src/mvc/render/index.ts +4 -0
  215. package/src/mvc/render/json.ts +24 -0
  216. package/src/mvc/render/text.ts +14 -0
  217. package/src/mvc/router.ts +13 -0
  218. package/src/mvc/server.ts +315 -0
  219. package/src/mvc/static/header.ts +86 -0
  220. package/src/mvc/static/index.ts +3 -0
  221. package/src/mvc/static/mime-type.ts +81 -0
  222. package/src/mvc/static/server-cache-config.ts +92 -0
  223. package/src/mvc/static/server-cache.ts +171 -0
  224. package/src/mvc/static/static-handler.ts +445 -0
  225. package/src/mysql/config.ts +130 -0
  226. package/src/mysql/exception.ts +8 -0
  227. package/src/mysql/index.ts +88 -0
  228. package/src/mysql/manager/base.ts +332 -0
  229. package/src/mysql/manager/index.ts +112 -0
  230. package/src/mysql/manager/ops/count.ts +30 -0
  231. package/src/mysql/manager/ops/criteria.ts +446 -0
  232. package/src/mysql/manager/ops/delete.ts +91 -0
  233. package/src/mysql/manager/ops/exist.ts +41 -0
  234. package/src/mysql/manager/ops/find.ts +209 -0
  235. package/src/mysql/manager/ops/index.ts +13 -0
  236. package/src/mysql/manager/ops/insert.ts +158 -0
  237. package/src/mysql/manager/ops/modify.ts +14 -0
  238. package/src/mysql/manager/ops/order-by.ts +58 -0
  239. package/src/mysql/manager/ops/paginate.ts +100 -0
  240. package/src/mysql/manager/ops/query.ts +13 -0
  241. package/src/mysql/manager/ops/update.ts +318 -0
  242. package/src/mysql/manager/ops/upsert.ts +224 -0
  243. package/src/mysql/manager/ops/utils.ts +24 -0
  244. package/src/mysql/manager/tx-strict.ts +138 -0
  245. package/src/mysql/manager/tx.ts +31 -0
  246. package/src/mysql/manager/utils.ts +75 -0
  247. package/src/mysql/migration.ts +149 -0
  248. package/src/mysql/table-info.ts +41 -0
  249. package/src/task/daily.ts +70 -0
  250. package/src/task/fixed-delay.ts +45 -0
  251. package/src/task/fixed-rate.ts +49 -0
  252. package/src/task/index.ts +4 -0
  253. package/src/task/task.ts +70 -0
  254. package/src/validation/exception.ts +27 -0
  255. package/src/validation/index.ts +61 -0
  256. package/src/validation/validator/array.ts +32 -0
  257. package/src/validation/validator/enum.ts +25 -0
  258. package/src/validation/validator/index.ts +11 -0
  259. package/src/validation/validator/length.ts +42 -0
  260. package/src/validation/validator/max-length.ts +33 -0
  261. package/src/validation/validator/max.ts +26 -0
  262. package/src/validation/validator/min-length.ts +31 -0
  263. package/src/validation/validator/min.ts +26 -0
  264. package/src/validation/validator/not-blank.ts +31 -0
  265. package/src/validation/validator/not-null.ts +19 -0
  266. package/src/validation/validator/plain-obj.ts +30 -0
  267. package/src/validation/validator/regexp.ts +32 -0
  268. package/types/cache/cache.d.ts +52 -52
  269. package/types/cache/config.d.ts +32 -32
  270. package/types/cache/index.d.ts +2 -2
  271. package/types/cache/purge-task.d.ts +11 -11
  272. package/types/cache/stat.d.ts +26 -26
  273. package/types/config/convert.d.ts +6 -6
  274. package/types/config/exception.d.ts +7 -7
  275. package/types/config/index.d.ts +25 -25
  276. package/types/http-client/index.d.ts +71 -71
  277. package/types/i18n/ar.d.ts +2 -2
  278. package/types/i18n/de.d.ts +2 -2
  279. package/types/i18n/en-us.d.ts +2 -2
  280. package/types/i18n/es.d.ts +2 -2
  281. package/types/i18n/fr.d.ts +2 -2
  282. package/types/i18n/i18n.d.ts +102 -102
  283. package/types/i18n/index.d.ts +9 -9
  284. package/types/i18n/ja.d.ts +2 -2
  285. package/types/i18n/ko.d.ts +2 -2
  286. package/types/i18n/msg.d.ts +50 -50
  287. package/types/i18n/pt.d.ts +2 -2
  288. package/types/i18n/ru.d.ts +2 -2
  289. package/types/i18n/tag.d.ts +11 -11
  290. package/types/i18n/zh-HK.d.ts +2 -2
  291. package/types/i18n/zh-TW.d.ts +2 -2
  292. package/types/i18n/zh-cn.d.ts +2 -2
  293. package/types/index.d.ts +11 -11
  294. package/types/lock/index.d.ts +64 -64
  295. package/types/log/config.d.ts +35 -35
  296. package/types/log/date.d.ts +2 -2
  297. package/types/log/file.d.ts +13 -13
  298. package/types/log/index.d.ts +53 -53
  299. package/types/log/level.d.ts +14 -14
  300. package/types/log/log.d.ts +40 -40
  301. package/types/log/store.d.ts +19 -19
  302. package/types/mongodb/collection.d.ts +25 -25
  303. package/types/mongodb/config.d.ts +45 -45
  304. package/types/mongodb/doc.d.ts +11 -11
  305. package/types/mongodb/exception.d.ts +7 -7
  306. package/types/mongodb/index.d.ts +29 -29
  307. package/types/mongodb/manager/base.d.ts +188 -188
  308. package/types/mongodb/manager/index.d.ts +38 -38
  309. package/types/mongodb/manager/tx-strict.d.ts +41 -41
  310. package/types/mongodb/manager/tx.d.ts +21 -21
  311. package/types/mongodb/migration.d.ts +12 -12
  312. package/types/mvc/access-log.d.ts +7 -7
  313. package/types/mvc/config.d.ts +42 -42
  314. package/types/mvc/exchange.d.ts +72 -72
  315. package/types/mvc/handler/index.d.ts +4 -3
  316. package/types/mvc/handler/json.d.ts +44 -44
  317. package/types/mvc/handler/restful.d.ts +11 -11
  318. package/types/mvc/handler/sse.d.ts +34 -0
  319. package/types/mvc/handler/upload.d.ts +36 -36
  320. package/types/mvc/index.d.ts +22 -22
  321. package/types/mvc/interceptor.d.ts +11 -11
  322. package/types/mvc/query.d.ts +13 -13
  323. package/types/mvc/render/file.d.ts +10 -10
  324. package/types/mvc/render/html/html.d.ts +98 -98
  325. package/types/mvc/render/html/index.d.ts +11 -11
  326. package/types/mvc/render/html/style.d.ts +1201 -1201
  327. package/types/mvc/render/index.d.ts +4 -4
  328. package/types/mvc/render/json.d.ts +17 -17
  329. package/types/mvc/render/text.d.ts +10 -10
  330. package/types/mvc/router.d.ts +11 -11
  331. package/types/mvc/server.d.ts +90 -90
  332. package/types/mvc/static/header.d.ts +27 -27
  333. package/types/mvc/static/index.d.ts +3 -3
  334. package/types/mvc/static/mime-type.d.ts +2 -2
  335. package/types/mvc/static/server-cache-config.d.ts +30 -30
  336. package/types/mvc/static/server-cache.d.ts +76 -76
  337. package/types/mvc/static/static-handler.d.ts +77 -77
  338. package/types/mysql/config.d.ts +90 -90
  339. package/types/mysql/exception.d.ts +7 -7
  340. package/types/mysql/index.d.ts +16 -16
  341. package/types/mysql/manager/base.d.ts +196 -165
  342. package/types/mysql/manager/index.d.ts +36 -36
  343. package/types/mysql/manager/ops/count.d.ts +13 -13
  344. package/types/mysql/manager/ops/criteria.d.ts +144 -134
  345. package/types/mysql/manager/ops/delete.d.ts +47 -46
  346. package/types/mysql/manager/ops/exist.d.ts +6 -6
  347. package/types/mysql/manager/ops/find.d.ts +87 -86
  348. package/types/mysql/manager/ops/index.d.ts +12 -10
  349. package/types/mysql/manager/ops/insert.d.ts +32 -18
  350. package/types/mysql/manager/ops/modify.d.ts +3 -3
  351. package/types/mysql/manager/ops/order-by.d.ts +38 -0
  352. package/types/mysql/manager/ops/paginate.d.ts +53 -36
  353. package/types/mysql/manager/ops/query.d.ts +3 -3
  354. package/types/mysql/manager/ops/update.d.ts +99 -76
  355. package/types/mysql/manager/ops/upsert.d.ts +36 -0
  356. package/types/mysql/manager/ops/utils.d.ts +5 -5
  357. package/types/mysql/manager/tx-strict.d.ts +36 -36
  358. package/types/mysql/manager/tx.d.ts +15 -15
  359. package/types/mysql/manager/utils.d.ts +17 -17
  360. package/types/mysql/migration.d.ts +8 -8
  361. package/types/mysql/table-info.d.ts +36 -36
  362. package/types/task/daily.d.ts +16 -16
  363. package/types/task/fixed-delay.d.ts +9 -9
  364. package/types/task/fixed-rate.d.ts +9 -9
  365. package/types/task/index.d.ts +4 -4
  366. package/types/task/task.d.ts +34 -34
  367. package/types/validation/exception.d.ts +38 -38
  368. package/types/validation/index.d.ts +32 -32
  369. package/types/validation/validator/array.d.ts +5 -5
  370. package/types/validation/validator/enum.d.ts +8 -8
  371. package/types/validation/validator/index.d.ts +11 -11
  372. package/types/validation/validator/length.d.ts +10 -10
  373. package/types/validation/validator/max-length.d.ts +8 -8
  374. package/types/validation/validator/max.d.ts +7 -7
  375. package/types/validation/validator/min-length.d.ts +6 -6
  376. package/types/validation/validator/min.d.ts +7 -7
  377. package/types/validation/validator/not-blank.d.ts +7 -7
  378. package/types/validation/validator/not-null.d.ts +6 -6
  379. package/types/validation/validator/plain-obj.d.ts +7 -7
  380. package/types/validation/validator/regexp.d.ts +8 -8
@@ -0,0 +1,446 @@
1
+ import { MysqlException } from '../../exception'
2
+
3
+ export interface MysqlQuery {
4
+ sql: string
5
+ values: any[]
6
+ }
7
+
8
+ /**
9
+ * mysql 查询条件中的键,左侧表达式,可以是提取信息的表达式,也可以直接是列名
10
+ *
11
+ * keyof T 列名,直接用列的值来比较
12
+ * ['json_extract', keyof T, string] 使用 json_extract 函数提取 json 信息,第二个参数是列名,最后一个参数是表达式(如:'$.name')
13
+ * ['json_length',keyof T] 使用 json_length 函数提取 json 数组的元素数量
14
+ */
15
+ export type MysqlCriteriaKey<T> =
16
+ | keyof T
17
+ | ['json_extract', keyof T, string]
18
+ | ['json_length', keyof T]
19
+
20
+ /**
21
+ * 生成条件查询中键的sql片段,包含 sql 内容和要传递的值
22
+ */
23
+ function generateMysqlCriteriaKeySqlSeg<T>(key: MysqlCriteriaKey<T>): {
24
+ sqlSeg: string
25
+ value: keyof T
26
+ } {
27
+ if (Array.isArray(key)) {
28
+ if (key[0] === 'json_extract') {
29
+ return { sqlSeg: `JSON_EXTRACT(??, ${JSON.stringify(key[2])})`, value: key[1] }
30
+ }
31
+ if (key[0] === 'json_length') {
32
+ return { sqlSeg: `JSON_LENGTH(??)`, value: key[1] }
33
+ }
34
+ throw new MysqlException(`Unsupported MysqlCriteriaKey type: ${key[0]}`)
35
+ }
36
+ return { sqlSeg: '??', value: key }
37
+ }
38
+
39
+ interface Criterion<T> {
40
+ type:
41
+ | 'eq'
42
+ | 'neq'
43
+ | 'gt'
44
+ | 'gte'
45
+ | 'lt'
46
+ | 'lte'
47
+ | 'in'
48
+ | 'notIn'
49
+ | 'or'
50
+ | 'and'
51
+ | 'like'
52
+ | 'isNull'
53
+ | 'isNotNull'
54
+ | 'notLike'
55
+ | 'between'
56
+ | 'expr'
57
+ key?: MysqlCriteriaKey<T>
58
+ value?: any
59
+ /**
60
+ * 嵌套的其它查询, or 和 and 条件下有效
61
+ */
62
+ criteria?: MysqlCriteria<T>
63
+ /**
64
+ * 自定义表达式的 SQL 片段(expr 条件下有效)
65
+ */
66
+ exprSql?: string
67
+ /**
68
+ * 自定义表达式的参数值
69
+ */
70
+ exprValues?: any[]
71
+ }
72
+
73
+ /**
74
+ * mysql 查询条件( query criterion ),默认查询条件都是并且关系(and), 部分方法会有例外,在使用的时候请注意方法说明。
75
+ *
76
+ * @param <T> 表类型
77
+ */
78
+ export class MysqlCriteria<T> {
79
+ /**
80
+ * 条件列表.
81
+ */
82
+ private criteria: Criterion<T>[] = []
83
+ /**
84
+ * 相等.
85
+ * @param column
86
+ * @param value
87
+ */
88
+ eq(column: MysqlCriteriaKey<T>, value: any) {
89
+ this.criteria.push({ type: 'eq', key: column, value })
90
+ return this
91
+ }
92
+ /**
93
+ * 不等于,注意不相等不能走索引,谨慎使用
94
+ * @param column
95
+ * @param value
96
+ */
97
+ neq(column: MysqlCriteriaKey<T>, value: any) {
98
+ this.criteria.push({ type: 'neq', key: column, value })
99
+ return this
100
+ }
101
+ /**
102
+ * like
103
+ * @param column
104
+ * @param value
105
+ * @returns
106
+ */
107
+ like(column: MysqlCriteriaKey<T>, value: string) {
108
+ this.criteria.push({ type: 'like', key: column, value })
109
+ return this
110
+ }
111
+ /**
112
+ * not like
113
+ * @param column
114
+ * @param value
115
+ * @returns
116
+ */
117
+ notLike(column: MysqlCriteriaKey<T>, value: string) {
118
+ this.criteria.push({ type: 'notLike', key: column, value })
119
+ return this
120
+ }
121
+ /**
122
+ * BETWEEN x and y
123
+ */
124
+ between(column: MysqlCriteriaKey<T>, min: number, max: number) {
125
+ this.criteria.push({ type: 'between', key: column, value: [min, max] })
126
+ return this
127
+ }
128
+ /**
129
+ * 大于
130
+ * @param column
131
+ * @param value
132
+ */
133
+ gt(column: MysqlCriteriaKey<T>, value: number | Date | string) {
134
+ this.criteria.push({ type: 'gt', key: column, value })
135
+ return this
136
+ }
137
+ /**
138
+ * 大于等于
139
+ * @param column
140
+ * @param value
141
+ */
142
+ gte(column: MysqlCriteriaKey<T>, value: number | Date | string) {
143
+ this.criteria.push({ type: 'gte', key: column, value })
144
+ return this
145
+ }
146
+ /**
147
+ * 小于
148
+ * @param column
149
+ * @param value
150
+ */
151
+ lt(column: MysqlCriteriaKey<T>, value: number | Date | string) {
152
+ this.criteria.push({ type: 'lt', key: column, value })
153
+ return this
154
+ }
155
+ /**
156
+ * 小于等于
157
+ * @param column
158
+ * @param value
159
+ */
160
+ lte(column: MysqlCriteriaKey<T>, value: number | Date | string) {
161
+ this.criteria.push({ type: 'lte', key: column, value })
162
+ return this
163
+ }
164
+ /**
165
+ * in 条件
166
+ * @param column
167
+ * @param values
168
+ */
169
+ in(column: MysqlCriteriaKey<T>, values: Array<string | number>) {
170
+ this.criteria.push({ type: 'in', key: column, value: values })
171
+ return this
172
+ }
173
+ /**
174
+ * not in 条件
175
+ * @param column
176
+ * @param values
177
+ */
178
+ notIn(column: MysqlCriteriaKey<T>, values: Array<string | number>) {
179
+ this.criteria.push({ type: 'notIn', key: column, value: values })
180
+ return this
181
+ }
182
+ /**
183
+ * 嵌入其它的查询条件,与现有的查询条件是或者关系.
184
+ * @param criteria
185
+ */
186
+ or(orCriteria: (criteria: MysqlCriteria<T>) => void) {
187
+ const criteria = new MysqlCriteria<T>()
188
+ orCriteria(criteria)
189
+ this.criteria.push({ type: 'or', criteria })
190
+ return this
191
+ }
192
+ /**
193
+ * 嵌入其它的查询条件,与现有的查询条件是并且关系.
194
+ * @param criteria
195
+ */
196
+ and(andCriteria: (criteria: MysqlCriteria<T>) => void) {
197
+ const criteria = new MysqlCriteria<T>()
198
+ andCriteria(criteria)
199
+ this.criteria.push({ type: 'and', criteria })
200
+ return this
201
+ }
202
+ /**
203
+ * 字段为空
204
+ * @param field
205
+ * @returns
206
+ */
207
+ isNull(field: MysqlCriteriaKey<T>) {
208
+ this.criteria.push({ type: 'isNull', key: field })
209
+ return this
210
+ }
211
+ /**
212
+ * 字段非空
213
+ * @param field
214
+ * @returns
215
+ */
216
+ isNotNull(field: MysqlCriteriaKey<T>) {
217
+ this.criteria.push({ type: 'isNotNull', key: field })
218
+ return this
219
+ }
220
+ /**
221
+ * 自定义表达式查询
222
+ * 如 .expr('?? * ? > ?', ['balance', 2, 50])
223
+ * 如 .expr('MATCH(??, ??) AGAINST(? IN BOOLEAN MODE)', ['title', 'content', keyword])
224
+ * 如 .expr('VECTOR_DISTANCE(??, STRING_TO_VECTOR(?)) < ?', ['content_vec', embedding, threshold])
225
+ * @param sql SQL 片段,使用 ?? 引用列名,? 引用参数值
226
+ * @param values 参数值数组,按 SQL 中占位符顺序传入
227
+ * @returns
228
+ */
229
+ expr(sql: string, values?: any[]) {
230
+ this.criteria.push({ type: 'expr', exprSql: sql, exprValues: values || [] })
231
+ return this
232
+ }
233
+ /**
234
+ * 判定是否空,未设置条件.
235
+ * @returns
236
+ */
237
+ isEmpty() {
238
+ return !this.criteria.length
239
+ }
240
+ /**
241
+ * 检查条件信息是否有效,在出错时能给予较详细的提示,以方便排查.
242
+ */
243
+ check() {
244
+ for (const criterion of this.criteria) {
245
+ if (criterion.type === 'expr') {
246
+ if (!criterion.exprSql) {
247
+ throw new MysqlException('expr clause exprSql cannot be empty')
248
+ }
249
+ continue
250
+ }
251
+ if (criterion.type === 'or' || criterion.type === 'and') {
252
+ if (!criterion.criteria) {
253
+ throw new MysqlException(`${criterion.type} clause cannot be empty`)
254
+ }
255
+ criterion.criteria.check()
256
+ continue
257
+ }
258
+ if (!criterion.key) {
259
+ throw new MysqlException('The column name of the query criteria cannot be blank.')
260
+ }
261
+ if (criterion.type === 'isNull' || criterion.type === 'isNotNull') {
262
+ continue
263
+ }
264
+ if (criterion.type === 'in' || criterion.type === 'notIn') {
265
+ if (!Array.isArray(criterion.value)) {
266
+ throw new MysqlException(
267
+ `Invalid ${
268
+ criterion.type
269
+ } condition,the condition value is not a array type,column name:${criterion.key.toString()}`
270
+ )
271
+ }
272
+ if (!criterion.value.length) {
273
+ throw new MysqlException(
274
+ `Invalid ${
275
+ criterion.type
276
+ } condition,the condition value cannot be an empty array,column name:${criterion.key.toString()}`
277
+ )
278
+ }
279
+ continue
280
+ }
281
+ if (criterion.type === 'between') {
282
+ if (!Array.isArray(criterion.value)) {
283
+ throw new MysqlException(
284
+ `Invalid between condition,the condition value is not an array type,column name:${criterion.key.toString()}, value:${
285
+ criterion.value
286
+ }`
287
+ )
288
+ }
289
+ if (criterion.value.length !== 2) {
290
+ throw new MysqlException(
291
+ `Invalid between condition,the condition value must be an array of length 2,column: ${criterion.key.toString()},value:${
292
+ criterion.value.length
293
+ }`
294
+ )
295
+ }
296
+ continue
297
+ }
298
+ if (
299
+ typeof criterion.value !== 'number' &&
300
+ typeof criterion.value !== 'string' &&
301
+ typeof criterion.value !== 'boolean' &&
302
+ !(criterion.value instanceof Date)
303
+ ) {
304
+ throw new MysqlException(
305
+ 'The value of the query criteria is invalid,only number,string,boolean and Date are supported,' +
306
+ `column name : ${criterion.key.toString()},value : ${criterion.value} .`
307
+ )
308
+ }
309
+ }
310
+ }
311
+
312
+ /**
313
+ * 生成查询数据
314
+ */
315
+ generateQuery(): MysqlQuery {
316
+ this.check()
317
+ const sqlFragments: string[] = []
318
+ const values: any[] = []
319
+ for (const criterion of this.criteria) {
320
+ // 普通的查询
321
+ if (criterion.key && criterion.value !== undefined) {
322
+ // between 特殊处理
323
+ if (criterion.type === 'between') {
324
+ sqlFragments.push('and ?? between ? and ? ')
325
+ values.push(criterion.key, criterion.value[0], criterion.value[1])
326
+ continue
327
+ }
328
+ // 符号
329
+ let sign = ''
330
+ if (criterion.type === 'eq') {
331
+ sign = '='
332
+ } else if (criterion.type === 'neq') {
333
+ sign = '!='
334
+ } else if (criterion.type === 'gt') {
335
+ sign = '>'
336
+ } else if (criterion.type === 'gte') {
337
+ sign = '>='
338
+ } else if (criterion.type === 'lt') {
339
+ sign = '<'
340
+ } else if (criterion.type === 'lte') {
341
+ sign = '<='
342
+ } else if (criterion.type === 'in') {
343
+ sign = 'in'
344
+ } else if (criterion.type === 'notIn') {
345
+ sign = 'not in'
346
+ } else if (criterion.type === 'like') {
347
+ sign = 'like'
348
+ } else if (criterion.type === 'notLike') {
349
+ sign = 'not like'
350
+ }
351
+ if (sign) {
352
+ const keySeg = generateMysqlCriteriaKeySqlSeg(criterion.key)
353
+ if (criterion.type === 'in' || criterion.type === 'notIn') {
354
+ sqlFragments.push(`and ${keySeg.sqlSeg} ${sign} (?) `)
355
+ } else {
356
+ sqlFragments.push(`and ${keySeg.sqlSeg} ${sign} ? `)
357
+ }
358
+ values.push(keySeg.value, criterion.value)
359
+ }
360
+ continue
361
+ } else if (criterion.key) {
362
+ const keySeg = generateMysqlCriteriaKeySqlSeg(criterion.key)
363
+ if (criterion.type === 'isNull') {
364
+ sqlFragments.push(`and ${keySeg.sqlSeg} is null `)
365
+ values.push(keySeg.value)
366
+ continue
367
+ }
368
+ if (criterion.type === 'isNotNull') {
369
+ sqlFragments.push(`and ${keySeg.sqlSeg} is not null `)
370
+ values.push(keySeg.value)
371
+ continue
372
+ }
373
+ }
374
+ // 特殊查询 or 和 and
375
+ else if (criterion.criteria) {
376
+ const query = criterion.criteria.generateQuery()
377
+ if (criterion.type === 'or') {
378
+ sqlFragments.push(`or (${query.sql}) `)
379
+ values.push(...query.values)
380
+ continue
381
+ }
382
+ if (criterion.type === 'and') {
383
+ sqlFragments.push(`and (${query.sql}) `)
384
+ values.push(...query.values)
385
+ continue
386
+ }
387
+ }
388
+ // 自定义表达式
389
+ else if (criterion.type === 'expr' && criterion.exprSql) {
390
+ sqlFragments.push(`and ${criterion.exprSql} `)
391
+ values.push(...(criterion.exprValues || []))
392
+ continue
393
+ }
394
+ }
395
+ if (!sqlFragments.length) {
396
+ throw new MysqlException('No valid query criteria have been set.')
397
+ }
398
+ let sql = sqlFragments.join('')
399
+ // 去除掉第一个条件的连接关键字,可能是 and 或 or
400
+ if (sql.startsWith('and')) {
401
+ sql = sql.substring(3)
402
+ } else if (sql.startsWith('or')) {
403
+ sql = sql.substring(2)
404
+ }
405
+ return { sql, values }
406
+ }
407
+ }
408
+
409
+ /**
410
+ * 混合的查询对象.
411
+ */
412
+ export type MixCriteria<T> = Partial<T> | ((criteria: MysqlCriteria<T>) => void) | MysqlCriteria<T>
413
+
414
+ function convertToCriteria<T>(example: Partial<T>): MysqlCriteria<keyof T> {
415
+ const criteria = new MysqlCriteria<keyof T>()
416
+ Object.entries(example as any).forEach(entry => {
417
+ const [key, value] = entry
418
+ criteria.eq(key as any, value)
419
+ })
420
+ return criteria
421
+ }
422
+
423
+ /**
424
+ * 将混合的查询条件转换成查询语句,如果最终构建的条件是空的,返回 undefined
425
+ * @param criteria
426
+ * @returns
427
+ */
428
+ export function buildQuery<T>(criteria: MixCriteria<T>): MysqlQuery | undefined {
429
+ if (criteria instanceof Function) {
430
+ const c = new MysqlCriteria<T>()
431
+ criteria(c)
432
+ if (!c.isEmpty()) {
433
+ return c.generateQuery()
434
+ }
435
+ } else if (criteria instanceof MysqlCriteria) {
436
+ if (!criteria.isEmpty()) {
437
+ return criteria.generateQuery()
438
+ }
439
+ } else {
440
+ const c = convertToCriteria<T>(criteria)
441
+ if (!c.isEmpty()) {
442
+ return c.generateQuery()
443
+ }
444
+ }
445
+ return undefined
446
+ }
@@ -0,0 +1,91 @@
1
+ import { PoolConnection, ResultSetHeader } from 'mysql2'
2
+ import { MysqlException } from '../../exception'
3
+ import { Table } from '../../table-info'
4
+ import { promiseQuery } from '../utils'
5
+ import { MixCriteria, buildQuery } from './criteria'
6
+ import { MysqlConfig } from '../../config'
7
+ import { OrderBy, buildOrderBy } from './order-by'
8
+
9
+ /**
10
+ * 按 id 删除.
11
+ *
12
+ * @param config
13
+ * @param connection
14
+ * @param mapping
15
+ * @param type
16
+ * @param id
17
+ */
18
+ export async function deleteById<T>(
19
+ config: MysqlConfig,
20
+ connection: PoolConnection,
21
+ table: Table<T>,
22
+ id: string | number
23
+ ): Promise<boolean> {
24
+ const res = await promiseQuery(config, connection, `delete from ?? where ?? = ?`, [
25
+ table.tableName,
26
+ table.id,
27
+ id
28
+ ])
29
+ const ok = res as ResultSetHeader
30
+ return ok.affectedRows === 1
31
+ }
32
+ /**
33
+ * 批量删除的选项
34
+ */
35
+ export interface DeleteManyOpts<T> {
36
+ /**
37
+ * 表.
38
+ */
39
+ table: Table<T>
40
+ /**
41
+ * 查询条件
42
+ * @param criteria
43
+ * @returns
44
+ */
45
+ criteria: MixCriteria<T>
46
+ /**
47
+ * 限制数量
48
+ */
49
+ limit?: number
50
+ /**
51
+ * 排序规则,按先后顺序放入,每个规则是一个元组,第一个元素是字段名称,第二个元素是顺序
52
+ */
53
+ orderBy?: OrderBy<T>
54
+ }
55
+
56
+ /**
57
+ * 按条件删除,返回被删除的记录数.
58
+ * 务必谨慎使用,大批量删除容易带来性能问题,造成线上事故.
59
+ * @param config
60
+ * @param connection
61
+ * @param table
62
+ * @param criteria
63
+ */
64
+ export async function deleteMany<T>(
65
+ config: MysqlConfig,
66
+ connection: PoolConnection,
67
+ opts: DeleteManyOpts<T>
68
+ ): Promise<number> {
69
+ let sql = 'delete from ?? '
70
+ const values: any[] = [opts.table.tableName]
71
+ let query = buildQuery(opts.criteria)
72
+ if (!query) {
73
+ throw new MysqlException('No valid criteria specified.')
74
+ }
75
+ if (query) {
76
+ sql += ` where ${query.sql} `
77
+ values.push(...query.values)
78
+ }
79
+ // 排序
80
+ if (opts.orderBy && opts.orderBy.length) {
81
+ const ob = buildOrderBy(opts.orderBy)
82
+ sql += ob.sql
83
+ values.push(...ob.values)
84
+ }
85
+ // 数量限制
86
+ if (opts.limit) {
87
+ sql += ` limit ${opts.limit} `
88
+ }
89
+ const res = await promiseQuery(config, connection, sql, values)
90
+ return (res as ResultSetHeader).affectedRows
91
+ }
@@ -0,0 +1,41 @@
1
+ import { PoolConnection, ResultSetHeader, RowDataPacket } from 'mysql2'
2
+ import { Table } from '../../table-info'
3
+ import { MixCriteria, buildQuery } from './criteria'
4
+ import { promiseQuery } from '../utils'
5
+ import { MysqlConfig } from '../../config'
6
+
7
+ export async function existsById<T>(
8
+ config: MysqlConfig,
9
+ connection: PoolConnection,
10
+ table: Table<T>,
11
+ id: string | number
12
+ ): Promise<boolean> {
13
+ const res = await promiseQuery(config, connection, `select 1 from ?? where ?? = ?`, [
14
+ table.tableName,
15
+ table.id,
16
+ id
17
+ ])
18
+ const rows = res as RowDataPacket[]
19
+ return !!rows.length
20
+ }
21
+
22
+ export async function existsBy<T>(
23
+ config: MysqlConfig,
24
+ connection: PoolConnection,
25
+ table: Table<T>,
26
+ criteria?: MixCriteria<T>
27
+ ): Promise<boolean> {
28
+ let query = criteria ? buildQuery(criteria) : undefined
29
+ let sql = `select 1 from ?? `
30
+ if (query) {
31
+ sql += ` where ${query.sql} `
32
+ }
33
+ const res = await promiseQuery(
34
+ config,
35
+ connection,
36
+ sql,
37
+ [table.tableName].concat(query ? query.values : [])
38
+ )
39
+ const rows = res as ResultSetHeader[]
40
+ return !!rows.length
41
+ }