wok-server 0.5.0 → 0.6.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.
- package/README.en.md +61 -0
- package/README.md +44 -29
- package/dist/cache/cache.js +98 -98
- package/dist/cache/config.js +19 -19
- package/dist/cache/index.js +27 -27
- package/dist/cache/purge-task.js +46 -46
- package/dist/cache/stat.js +47 -47
- package/dist/config/convert.js +36 -36
- package/dist/config/exception.js +14 -14
- package/dist/config/index.js +81 -81
- package/dist/http-client/index.js +136 -136
- package/dist/i18n/ar.js +17 -17
- package/dist/i18n/de.js +17 -17
- package/dist/i18n/en-us.js +17 -17
- package/dist/i18n/es.js +17 -17
- package/dist/i18n/fr.js +17 -17
- package/dist/i18n/i18n.js +231 -231
- package/dist/i18n/index.js +52 -52
- package/dist/i18n/ja.js +17 -17
- package/dist/i18n/ko.js +17 -17
- package/dist/i18n/msg.js +2 -2
- package/dist/i18n/pt.js +17 -17
- package/dist/i18n/ru.js +17 -17
- package/dist/i18n/tag.js +18 -18
- package/dist/i18n/zh-HK.js +17 -17
- package/dist/i18n/zh-TW.js +17 -17
- package/dist/i18n/zh-cn.js +17 -17
- package/dist/index.js +14 -14
- package/dist/lock/index.js +114 -114
- package/dist/log/config.js +35 -35
- package/dist/log/date.js +21 -21
- package/dist/log/file.js +198 -198
- package/dist/log/index.js +135 -135
- package/dist/log/level.js +33 -33
- package/dist/log/log.js +56 -56
- package/dist/log/store.js +19 -19
- package/dist/mongodb/collection.js +2 -2
- package/dist/mongodb/config.js +34 -34
- package/dist/mongodb/doc.js +2 -2
- package/dist/mongodb/exception.js +14 -14
- package/dist/mongodb/index.js +58 -58
- package/dist/mongodb/manager/base.js +563 -563
- package/dist/mongodb/manager/index.js +63 -63
- package/dist/mongodb/manager/tx-strict.js +84 -84
- package/dist/mongodb/manager/tx.js +30 -30
- package/dist/mongodb/migration.js +52 -52
- package/dist/mvc/access-log.js +33 -33
- package/dist/mvc/config.js +27 -27
- package/dist/mvc/exchange.js +113 -113
- package/dist/mvc/handler/index.js +7 -6
- package/dist/mvc/handler/json.js +65 -65
- package/dist/mvc/handler/restful.js +35 -35
- package/dist/mvc/handler/sse.js +65 -0
- package/dist/mvc/handler/upload.js +31 -31
- package/dist/mvc/index.js +50 -50
- package/dist/mvc/interceptor.js +2 -2
- package/dist/mvc/query.js +43 -43
- package/dist/mvc/render/file.js +132 -132
- package/dist/mvc/render/html/html.js +90 -90
- package/dist/mvc/render/html/index.js +18 -18
- package/dist/mvc/render/html/style.js +2 -2
- package/dist/mvc/render/index.js +7 -7
- package/dist/mvc/render/json.js +26 -26
- package/dist/mvc/render/text.js +16 -16
- package/dist/mvc/router.js +2 -2
- package/dist/mvc/server.js +272 -272
- package/dist/mvc/static/header.js +67 -67
- package/dist/mvc/static/index.js +6 -6
- package/dist/mvc/static/mime-type.js +84 -84
- package/dist/mvc/static/server-cache-config.js +66 -66
- package/dist/mvc/static/server-cache.js +133 -133
- package/dist/mvc/static/static-handler.js +372 -372
- package/dist/mysql/config.js +51 -51
- package/dist/mysql/exception.js +14 -14
- package/dist/mysql/index.js +87 -87
- package/dist/mysql/manager/base.js +239 -239
- package/dist/mysql/manager/index.js +107 -107
- package/dist/mysql/manager/ops/count.js +20 -20
- package/dist/mysql/manager/ops/criteria.js +356 -356
- package/dist/mysql/manager/ops/delete.js +65 -65
- package/dist/mysql/manager/ops/exist.js +26 -26
- package/dist/mysql/manager/ops/find.js +169 -169
- package/dist/mysql/manager/ops/index.js +14 -14
- package/dist/mysql/manager/ops/insert.js +106 -106
- package/dist/mysql/manager/ops/modify.js +10 -10
- package/dist/mysql/manager/ops/paginate.js +23 -23
- package/dist/mysql/manager/ops/query.js +9 -9
- package/dist/mysql/manager/ops/update.js +216 -216
- package/dist/mysql/manager/ops/utils.js +24 -24
- package/dist/mysql/manager/tx-strict.js +103 -103
- package/dist/mysql/manager/tx.js +30 -30
- package/dist/mysql/manager/utils.js +56 -56
- package/dist/mysql/migration.js +136 -136
- package/dist/mysql/table-info.js +8 -8
- package/dist/task/daily.js +59 -59
- package/dist/task/fixed-delay.js +38 -38
- package/dist/task/fixed-rate.js +42 -42
- package/dist/task/index.js +9 -9
- package/dist/task/task.js +56 -56
- package/dist/validation/exception.js +36 -36
- package/dist/validation/index.js +40 -40
- package/dist/validation/validator/array.js +34 -34
- package/dist/validation/validator/enum.js +28 -28
- package/dist/validation/validator/index.js +14 -14
- package/dist/validation/validator/length.js +40 -40
- package/dist/validation/validator/max-length.js +35 -35
- package/dist/validation/validator/max.js +29 -29
- package/dist/validation/validator/min-length.js +33 -33
- package/dist/validation/validator/min.js +29 -29
- package/dist/validation/validator/not-blank.js +33 -33
- package/dist/validation/validator/not-null.js +21 -21
- package/dist/validation/validator/plain-obj.js +32 -32
- package/dist/validation/validator/regexp.js +34 -34
- package/documentation/en/cache.md +56 -0
- package/documentation/en/config.md +96 -0
- package/documentation/en/engineering.md +256 -0
- package/documentation/en/http-client.md +32 -0
- package/documentation/en/i18n.md +143 -0
- package/documentation/en/index.md +24 -0
- package/documentation/en/lock.md +51 -0
- package/documentation/en/log.md +109 -0
- package/documentation/en/mongodb.md +256 -0
- package/documentation/en/mvc.md +688 -0
- package/documentation/en/mysql.md +552 -0
- package/documentation/en/task.md +45 -0
- package/documentation/en/test.md +56 -0
- package/documentation/en/validate.md +130 -0
- package/documentation/zh-cn/mvc.md +66 -24
- package/package.json +3 -1
- package/skills/wok-server-api-rules/SKILL.md +350 -0
- package/skills/wok-server-cache/SKILL.md +216 -0
- package/skills/wok-server-config/SKILL.md +200 -0
- package/skills/wok-server-getting-started/SKILL.md +123 -0
- package/skills/wok-server-getting-started/references/engineering.md +169 -0
- package/skills/wok-server-http-client/SKILL.md +164 -0
- package/skills/wok-server-i18n/SKILL.md +214 -0
- package/skills/wok-server-lock/SKILL.md +144 -0
- package/skills/wok-server-log/SKILL.md +218 -0
- package/skills/wok-server-mongodb/SKILL.md +235 -0
- package/skills/wok-server-mvc/SKILL.md +251 -0
- package/skills/wok-server-mvc/references/respond-html.md +157 -0
- package/skills/wok-server-mvc/references/sse.md +121 -0
- package/skills/wok-server-mvc/references/static-files.md +47 -0
- package/skills/wok-server-mvc/references/upload.md +62 -0
- package/skills/wok-server-mvc/references/websocket.md +30 -0
- package/skills/wok-server-mysql/SKILL.md +315 -0
- package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
- package/skills/wok-server-mysql/references/version-control.md +22 -0
- package/skills/wok-server-task/SKILL.md +158 -0
- package/skills/wok-server-validate/SKILL.md +167 -0
- package/src/cache/cache.ts +118 -0
- package/src/cache/config.ts +53 -0
- package/src/cache/index.ts +27 -0
- package/src/cache/purge-task.ts +53 -0
- package/src/cache/stat.ts +47 -0
- package/src/config/convert.ts +27 -0
- package/src/config/exception.ts +8 -0
- package/src/config/index.ts +92 -0
- package/src/http-client/index.ts +202 -0
- package/src/i18n/ar.ts +16 -0
- package/src/i18n/de.ts +16 -0
- package/src/i18n/en-us.ts +16 -0
- package/src/i18n/es.ts +16 -0
- package/src/i18n/fr.ts +16 -0
- package/src/i18n/i18n.ts +230 -0
- package/src/i18n/index.ts +50 -0
- package/src/i18n/ja.ts +16 -0
- package/src/i18n/ko.ts +16 -0
- package/src/i18n/msg.ts +50 -0
- package/src/i18n/pt.ts +16 -0
- package/src/i18n/ru.ts +16 -0
- package/src/i18n/tag.ts +18 -0
- package/src/i18n/zh-HK.ts +16 -0
- package/src/i18n/zh-TW.ts +16 -0
- package/src/i18n/zh-cn.ts +16 -0
- package/src/index.ts +11 -0
- package/src/lock/index.ts +164 -0
- package/src/log/config.ts +71 -0
- package/src/log/date.ts +19 -0
- package/src/log/file.ts +215 -0
- package/src/log/index.ts +136 -0
- package/src/log/level.ts +29 -0
- package/src/log/log.ts +77 -0
- package/src/log/store.ts +31 -0
- package/src/mongodb/collection.ts +25 -0
- package/src/mongodb/config.ts +69 -0
- package/src/mongodb/doc.ts +12 -0
- package/src/mongodb/exception.ts +8 -0
- package/src/mongodb/index.ts +71 -0
- package/src/mongodb/manager/base.ts +674 -0
- package/src/mongodb/manager/index.ts +80 -0
- package/src/mongodb/manager/tx-strict.ts +153 -0
- package/src/mongodb/manager/tx.ts +34 -0
- package/src/mongodb/migration.ts +66 -0
- package/src/mvc/access-log.ts +33 -0
- package/src/mvc/config.ts +70 -0
- package/src/mvc/exchange.ts +126 -0
- package/src/mvc/handler/index.ts +4 -0
- package/src/mvc/handler/json.ts +96 -0
- package/src/mvc/handler/restful.ts +39 -0
- package/src/mvc/handler/sse.ts +90 -0
- package/src/mvc/handler/upload.ts +54 -0
- package/src/mvc/index.ts +48 -0
- package/src/mvc/interceptor.ts +12 -0
- package/src/mvc/query.ts +36 -0
- package/src/mvc/render/file.ts +148 -0
- package/src/mvc/render/html/html.ts +187 -0
- package/src/mvc/render/html/index.ts +16 -0
- package/src/mvc/render/html/style.ts +1201 -0
- package/src/mvc/render/index.ts +4 -0
- package/src/mvc/render/json.ts +24 -0
- package/src/mvc/render/text.ts +14 -0
- package/src/mvc/router.ts +13 -0
- package/src/mvc/server.ts +315 -0
- package/src/mvc/static/header.ts +86 -0
- package/src/mvc/static/index.ts +3 -0
- package/src/mvc/static/mime-type.ts +81 -0
- package/src/mvc/static/server-cache-config.ts +92 -0
- package/src/mvc/static/server-cache.ts +171 -0
- package/src/mvc/static/static-handler.ts +445 -0
- package/src/mysql/config.ts +130 -0
- package/src/mysql/exception.ts +8 -0
- package/src/mysql/index.ts +88 -0
- package/src/mysql/manager/base.ts +285 -0
- package/src/mysql/manager/index.ts +112 -0
- package/src/mysql/manager/ops/count.ts +30 -0
- package/src/mysql/manager/ops/criteria.ts +412 -0
- package/src/mysql/manager/ops/delete.ts +96 -0
- package/src/mysql/manager/ops/exist.ts +41 -0
- package/src/mysql/manager/ops/find.ts +226 -0
- package/src/mysql/manager/ops/index.ts +11 -0
- package/src/mysql/manager/ops/insert.ts +120 -0
- package/src/mysql/manager/ops/modify.ts +14 -0
- package/src/mysql/manager/ops/paginate.ts +60 -0
- package/src/mysql/manager/ops/query.ts +13 -0
- package/src/mysql/manager/ops/update.ts +294 -0
- package/src/mysql/manager/ops/utils.ts +20 -0
- package/src/mysql/manager/tx-strict.ts +138 -0
- package/src/mysql/manager/tx.ts +31 -0
- package/src/mysql/manager/utils.ts +75 -0
- package/src/mysql/migration.ts +149 -0
- package/src/mysql/table-info.ts +41 -0
- package/src/task/daily.ts +70 -0
- package/src/task/fixed-delay.ts +45 -0
- package/src/task/fixed-rate.ts +49 -0
- package/src/task/index.ts +4 -0
- package/src/task/task.ts +70 -0
- package/src/validation/exception.ts +27 -0
- package/src/validation/index.ts +61 -0
- package/src/validation/validator/array.ts +32 -0
- package/src/validation/validator/enum.ts +25 -0
- package/src/validation/validator/index.ts +11 -0
- package/src/validation/validator/length.ts +42 -0
- package/src/validation/validator/max-length.ts +33 -0
- package/src/validation/validator/max.ts +26 -0
- package/src/validation/validator/min-length.ts +31 -0
- package/src/validation/validator/min.ts +26 -0
- package/src/validation/validator/not-blank.ts +31 -0
- package/src/validation/validator/not-null.ts +19 -0
- package/src/validation/validator/plain-obj.ts +30 -0
- package/src/validation/validator/regexp.ts +32 -0
- package/types/cache/cache.d.ts +52 -52
- package/types/cache/config.d.ts +32 -32
- package/types/cache/index.d.ts +2 -2
- package/types/cache/purge-task.d.ts +11 -11
- package/types/cache/stat.d.ts +26 -26
- package/types/config/convert.d.ts +6 -6
- package/types/config/exception.d.ts +7 -7
- package/types/config/index.d.ts +25 -25
- package/types/http-client/index.d.ts +71 -71
- package/types/i18n/ar.d.ts +2 -2
- package/types/i18n/de.d.ts +2 -2
- package/types/i18n/en-us.d.ts +2 -2
- package/types/i18n/es.d.ts +2 -2
- package/types/i18n/fr.d.ts +2 -2
- package/types/i18n/i18n.d.ts +102 -102
- package/types/i18n/index.d.ts +9 -9
- package/types/i18n/ja.d.ts +2 -2
- package/types/i18n/ko.d.ts +2 -2
- package/types/i18n/msg.d.ts +50 -50
- package/types/i18n/pt.d.ts +2 -2
- package/types/i18n/ru.d.ts +2 -2
- package/types/i18n/tag.d.ts +11 -11
- package/types/i18n/zh-HK.d.ts +2 -2
- package/types/i18n/zh-TW.d.ts +2 -2
- package/types/i18n/zh-cn.d.ts +2 -2
- package/types/index.d.ts +11 -11
- package/types/lock/index.d.ts +64 -64
- package/types/log/config.d.ts +35 -35
- package/types/log/date.d.ts +2 -2
- package/types/log/file.d.ts +13 -13
- package/types/log/index.d.ts +53 -53
- package/types/log/level.d.ts +14 -14
- package/types/log/log.d.ts +40 -40
- package/types/log/store.d.ts +19 -19
- package/types/mongodb/collection.d.ts +25 -25
- package/types/mongodb/config.d.ts +45 -45
- package/types/mongodb/doc.d.ts +11 -11
- package/types/mongodb/exception.d.ts +7 -7
- package/types/mongodb/index.d.ts +29 -29
- package/types/mongodb/manager/base.d.ts +188 -188
- package/types/mongodb/manager/index.d.ts +38 -38
- package/types/mongodb/manager/tx-strict.d.ts +41 -41
- package/types/mongodb/manager/tx.d.ts +21 -21
- package/types/mongodb/migration.d.ts +12 -12
- package/types/mvc/access-log.d.ts +7 -7
- package/types/mvc/config.d.ts +42 -42
- package/types/mvc/exchange.d.ts +72 -72
- package/types/mvc/handler/index.d.ts +4 -3
- package/types/mvc/handler/json.d.ts +44 -44
- package/types/mvc/handler/restful.d.ts +11 -11
- package/types/mvc/handler/sse.d.ts +34 -0
- package/types/mvc/handler/upload.d.ts +36 -36
- package/types/mvc/index.d.ts +22 -22
- package/types/mvc/interceptor.d.ts +11 -11
- package/types/mvc/query.d.ts +13 -13
- package/types/mvc/render/file.d.ts +10 -10
- package/types/mvc/render/html/html.d.ts +98 -98
- package/types/mvc/render/html/index.d.ts +11 -11
- package/types/mvc/render/html/style.d.ts +1201 -1201
- package/types/mvc/render/index.d.ts +4 -4
- package/types/mvc/render/json.d.ts +17 -17
- package/types/mvc/render/text.d.ts +10 -10
- package/types/mvc/router.d.ts +11 -11
- package/types/mvc/server.d.ts +90 -90
- package/types/mvc/static/header.d.ts +27 -27
- package/types/mvc/static/index.d.ts +3 -3
- package/types/mvc/static/mime-type.d.ts +2 -2
- package/types/mvc/static/server-cache-config.d.ts +30 -30
- package/types/mvc/static/server-cache.d.ts +76 -76
- package/types/mvc/static/static-handler.d.ts +77 -77
- package/types/mysql/config.d.ts +90 -90
- package/types/mysql/exception.d.ts +7 -7
- package/types/mysql/index.d.ts +16 -16
- package/types/mysql/manager/base.d.ts +165 -165
- package/types/mysql/manager/index.d.ts +36 -36
- package/types/mysql/manager/ops/count.d.ts +13 -13
- package/types/mysql/manager/ops/criteria.d.ts +134 -134
- package/types/mysql/manager/ops/delete.d.ts +46 -46
- package/types/mysql/manager/ops/exist.d.ts +6 -6
- package/types/mysql/manager/ops/find.d.ts +86 -86
- package/types/mysql/manager/ops/index.d.ts +10 -10
- package/types/mysql/manager/ops/insert.d.ts +18 -18
- package/types/mysql/manager/ops/modify.d.ts +3 -3
- package/types/mysql/manager/ops/paginate.d.ts +36 -36
- package/types/mysql/manager/ops/query.d.ts +3 -3
- package/types/mysql/manager/ops/update.d.ts +76 -76
- package/types/mysql/manager/ops/utils.d.ts +5 -5
- package/types/mysql/manager/tx-strict.d.ts +36 -36
- package/types/mysql/manager/tx.d.ts +15 -15
- package/types/mysql/manager/utils.d.ts +17 -17
- package/types/mysql/migration.d.ts +8 -8
- package/types/mysql/table-info.d.ts +36 -36
- package/types/task/daily.d.ts +16 -16
- package/types/task/fixed-delay.d.ts +9 -9
- package/types/task/fixed-rate.d.ts +9 -9
- package/types/task/index.d.ts +4 -4
- package/types/task/task.d.ts +34 -34
- package/types/validation/exception.d.ts +38 -38
- package/types/validation/index.d.ts +32 -32
- package/types/validation/validator/array.d.ts +5 -5
- package/types/validation/validator/enum.d.ts +8 -8
- package/types/validation/validator/index.d.ts +11 -11
- package/types/validation/validator/length.d.ts +10 -10
- package/types/validation/validator/max-length.d.ts +8 -8
- package/types/validation/validator/max.d.ts +7 -7
- package/types/validation/validator/min-length.d.ts +6 -6
- package/types/validation/validator/min.d.ts +7 -7
- package/types/validation/validator/not-blank.d.ts +7 -7
- package/types/validation/validator/not-null.d.ts +6 -6
- package/types/validation/validator/plain-obj.d.ts +7 -7
- package/types/validation/validator/regexp.d.ts +8 -8
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MysqlStrictTxSession = void 0;
|
|
4
|
-
const tx_1 = require("./tx");
|
|
5
|
-
const exception_1 = require("../exception");
|
|
6
|
-
/**
|
|
7
|
-
* 严格 mysql 事务会话,会禁用一些操作.
|
|
8
|
-
*/
|
|
9
|
-
class MysqlStrictTxSession extends tx_1.MysqlTxSession {
|
|
10
|
-
config;
|
|
11
|
-
#opsCount = 0;
|
|
12
|
-
constructor(config, conn) {
|
|
13
|
-
super(config, conn);
|
|
14
|
-
this.config = config;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* 为操作计数,检查是否操作次数过多.
|
|
18
|
-
*/
|
|
19
|
-
#checkAndAddOpsCount() {
|
|
20
|
-
if (this.#opsCount >= this.config.maxOpsInStrictTx) {
|
|
21
|
-
throw new exception_1.MysqlException('Too many operations in a strict transaction.');
|
|
22
|
-
}
|
|
23
|
-
this.#opsCount++;
|
|
24
|
-
}
|
|
25
|
-
findById(table, id) {
|
|
26
|
-
this.#checkAndAddOpsCount();
|
|
27
|
-
return super.findById(table, id);
|
|
28
|
-
}
|
|
29
|
-
findByIdIn(table, ids) {
|
|
30
|
-
if (ids.length > 100) {
|
|
31
|
-
throw new exception_1.MysqlException(`The augument ids length(${ids.length}) passed to findByIdIn in a strict transaction is too large .`);
|
|
32
|
-
}
|
|
33
|
-
this.#checkAndAddOpsCount();
|
|
34
|
-
return super.findByIdIn(table, ids);
|
|
35
|
-
}
|
|
36
|
-
existsBy(table, criteria) {
|
|
37
|
-
this.#checkAndAddOpsCount();
|
|
38
|
-
return super.existsBy(table, criteria);
|
|
39
|
-
}
|
|
40
|
-
existsById(table, id) {
|
|
41
|
-
this.#checkAndAddOpsCount();
|
|
42
|
-
return super.existsById(table, id);
|
|
43
|
-
}
|
|
44
|
-
deleteById(table, id) {
|
|
45
|
-
this.#checkAndAddOpsCount();
|
|
46
|
-
return super.deleteById(table, id);
|
|
47
|
-
}
|
|
48
|
-
deleteOne(table, criteria) {
|
|
49
|
-
this.#checkAndAddOpsCount();
|
|
50
|
-
return super.deleteOne(table, criteria);
|
|
51
|
-
}
|
|
52
|
-
deleteMany(opts) {
|
|
53
|
-
throw new exception_1.MysqlException('Prohibited to use deleteBy in a strict transaction.');
|
|
54
|
-
}
|
|
55
|
-
findAll(table) {
|
|
56
|
-
throw new exception_1.MysqlException('Prohibited to use findAll in a strict transaction.');
|
|
57
|
-
}
|
|
58
|
-
findFirst(table, criteria) {
|
|
59
|
-
this.#checkAndAddOpsCount();
|
|
60
|
-
return super.findFirst(table, criteria);
|
|
61
|
-
}
|
|
62
|
-
insert(table, data) {
|
|
63
|
-
this.#checkAndAddOpsCount();
|
|
64
|
-
return super.insert(table, data);
|
|
65
|
-
}
|
|
66
|
-
insertMany(table, list) {
|
|
67
|
-
throw new exception_1.MysqlException('Prohibited to use insertMany in a strict transaction.');
|
|
68
|
-
}
|
|
69
|
-
update(table, data) {
|
|
70
|
-
this.#checkAndAddOpsCount();
|
|
71
|
-
return super.update(table, data);
|
|
72
|
-
}
|
|
73
|
-
updateMany(opts) {
|
|
74
|
-
throw new exception_1.MysqlException('Prohibited to use updateMany in a strict transaction.');
|
|
75
|
-
}
|
|
76
|
-
updateOne(table, query, updater) {
|
|
77
|
-
this.#checkAndAddOpsCount();
|
|
78
|
-
return super.updateOne(table, query, updater);
|
|
79
|
-
}
|
|
80
|
-
partialUpdate(table, data) {
|
|
81
|
-
this.#checkAndAddOpsCount();
|
|
82
|
-
return super.partialUpdate(table, data);
|
|
83
|
-
}
|
|
84
|
-
find(opts) {
|
|
85
|
-
throw new exception_1.MysqlException('Prohibited to use find in a strict transaction.');
|
|
86
|
-
}
|
|
87
|
-
findSelect(opts) {
|
|
88
|
-
throw new exception_1.MysqlException('Prohibited to use findSelect in a strict transaction.');
|
|
89
|
-
}
|
|
90
|
-
count(table, criteria) {
|
|
91
|
-
throw new exception_1.MysqlException('Prohibited to use count in a strict transaction.');
|
|
92
|
-
}
|
|
93
|
-
paginate(opts) {
|
|
94
|
-
throw new exception_1.MysqlException('Prohibited to use paginate in a strict transaction.');
|
|
95
|
-
}
|
|
96
|
-
query(sql, values) {
|
|
97
|
-
throw new exception_1.MysqlException('Prohibited to use query in a strict transaction.');
|
|
98
|
-
}
|
|
99
|
-
modify(sql, values) {
|
|
100
|
-
throw new exception_1.MysqlException('Prohibited to use modify in a strict transaction.');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
exports.MysqlStrictTxSession = MysqlStrictTxSession;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MysqlStrictTxSession = void 0;
|
|
4
|
+
const tx_1 = require("./tx");
|
|
5
|
+
const exception_1 = require("../exception");
|
|
6
|
+
/**
|
|
7
|
+
* 严格 mysql 事务会话,会禁用一些操作.
|
|
8
|
+
*/
|
|
9
|
+
class MysqlStrictTxSession extends tx_1.MysqlTxSession {
|
|
10
|
+
config;
|
|
11
|
+
#opsCount = 0;
|
|
12
|
+
constructor(config, conn) {
|
|
13
|
+
super(config, conn);
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 为操作计数,检查是否操作次数过多.
|
|
18
|
+
*/
|
|
19
|
+
#checkAndAddOpsCount() {
|
|
20
|
+
if (this.#opsCount >= this.config.maxOpsInStrictTx) {
|
|
21
|
+
throw new exception_1.MysqlException('Too many operations in a strict transaction.');
|
|
22
|
+
}
|
|
23
|
+
this.#opsCount++;
|
|
24
|
+
}
|
|
25
|
+
findById(table, id) {
|
|
26
|
+
this.#checkAndAddOpsCount();
|
|
27
|
+
return super.findById(table, id);
|
|
28
|
+
}
|
|
29
|
+
findByIdIn(table, ids) {
|
|
30
|
+
if (ids.length > 100) {
|
|
31
|
+
throw new exception_1.MysqlException(`The augument ids length(${ids.length}) passed to findByIdIn in a strict transaction is too large .`);
|
|
32
|
+
}
|
|
33
|
+
this.#checkAndAddOpsCount();
|
|
34
|
+
return super.findByIdIn(table, ids);
|
|
35
|
+
}
|
|
36
|
+
existsBy(table, criteria) {
|
|
37
|
+
this.#checkAndAddOpsCount();
|
|
38
|
+
return super.existsBy(table, criteria);
|
|
39
|
+
}
|
|
40
|
+
existsById(table, id) {
|
|
41
|
+
this.#checkAndAddOpsCount();
|
|
42
|
+
return super.existsById(table, id);
|
|
43
|
+
}
|
|
44
|
+
deleteById(table, id) {
|
|
45
|
+
this.#checkAndAddOpsCount();
|
|
46
|
+
return super.deleteById(table, id);
|
|
47
|
+
}
|
|
48
|
+
deleteOne(table, criteria) {
|
|
49
|
+
this.#checkAndAddOpsCount();
|
|
50
|
+
return super.deleteOne(table, criteria);
|
|
51
|
+
}
|
|
52
|
+
deleteMany(opts) {
|
|
53
|
+
throw new exception_1.MysqlException('Prohibited to use deleteBy in a strict transaction.');
|
|
54
|
+
}
|
|
55
|
+
findAll(table) {
|
|
56
|
+
throw new exception_1.MysqlException('Prohibited to use findAll in a strict transaction.');
|
|
57
|
+
}
|
|
58
|
+
findFirst(table, criteria) {
|
|
59
|
+
this.#checkAndAddOpsCount();
|
|
60
|
+
return super.findFirst(table, criteria);
|
|
61
|
+
}
|
|
62
|
+
insert(table, data) {
|
|
63
|
+
this.#checkAndAddOpsCount();
|
|
64
|
+
return super.insert(table, data);
|
|
65
|
+
}
|
|
66
|
+
insertMany(table, list) {
|
|
67
|
+
throw new exception_1.MysqlException('Prohibited to use insertMany in a strict transaction.');
|
|
68
|
+
}
|
|
69
|
+
update(table, data) {
|
|
70
|
+
this.#checkAndAddOpsCount();
|
|
71
|
+
return super.update(table, data);
|
|
72
|
+
}
|
|
73
|
+
updateMany(opts) {
|
|
74
|
+
throw new exception_1.MysqlException('Prohibited to use updateMany in a strict transaction.');
|
|
75
|
+
}
|
|
76
|
+
updateOne(table, query, updater) {
|
|
77
|
+
this.#checkAndAddOpsCount();
|
|
78
|
+
return super.updateOne(table, query, updater);
|
|
79
|
+
}
|
|
80
|
+
partialUpdate(table, data) {
|
|
81
|
+
this.#checkAndAddOpsCount();
|
|
82
|
+
return super.partialUpdate(table, data);
|
|
83
|
+
}
|
|
84
|
+
find(opts) {
|
|
85
|
+
throw new exception_1.MysqlException('Prohibited to use find in a strict transaction.');
|
|
86
|
+
}
|
|
87
|
+
findSelect(opts) {
|
|
88
|
+
throw new exception_1.MysqlException('Prohibited to use findSelect in a strict transaction.');
|
|
89
|
+
}
|
|
90
|
+
count(table, criteria) {
|
|
91
|
+
throw new exception_1.MysqlException('Prohibited to use count in a strict transaction.');
|
|
92
|
+
}
|
|
93
|
+
paginate(opts) {
|
|
94
|
+
throw new exception_1.MysqlException('Prohibited to use paginate in a strict transaction.');
|
|
95
|
+
}
|
|
96
|
+
query(sql, values) {
|
|
97
|
+
throw new exception_1.MysqlException('Prohibited to use query in a strict transaction.');
|
|
98
|
+
}
|
|
99
|
+
modify(sql, values) {
|
|
100
|
+
throw new exception_1.MysqlException('Prohibited to use modify in a strict transaction.');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.MysqlStrictTxSession = MysqlStrictTxSession;
|
package/dist/mysql/manager/tx.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MysqlTxSession = void 0;
|
|
4
|
-
const base_1 = require("./base");
|
|
5
|
-
const exception_1 = require("../exception");
|
|
6
|
-
/**
|
|
7
|
-
* mysql 事务会话.
|
|
8
|
-
*/
|
|
9
|
-
class MysqlTxSession extends base_1.BaseMysqlManager {
|
|
10
|
-
/**
|
|
11
|
-
* 中止标识
|
|
12
|
-
*/
|
|
13
|
-
#aborted = false;
|
|
14
|
-
constructor(config, conn) {
|
|
15
|
-
super({ config, connection: conn });
|
|
16
|
-
}
|
|
17
|
-
queryWithConnection(queryFn) {
|
|
18
|
-
if (this.#aborted) {
|
|
19
|
-
throw new exception_1.MysqlException('Session has been aborted!');
|
|
20
|
-
}
|
|
21
|
-
return super.queryWithConnection(queryFn);
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 中止,被中止后的会话不能再进行任何操作
|
|
25
|
-
*/
|
|
26
|
-
abort() {
|
|
27
|
-
this.#aborted = true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.MysqlTxSession = MysqlTxSession;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MysqlTxSession = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
const exception_1 = require("../exception");
|
|
6
|
+
/**
|
|
7
|
+
* mysql 事务会话.
|
|
8
|
+
*/
|
|
9
|
+
class MysqlTxSession extends base_1.BaseMysqlManager {
|
|
10
|
+
/**
|
|
11
|
+
* 中止标识
|
|
12
|
+
*/
|
|
13
|
+
#aborted = false;
|
|
14
|
+
constructor(config, conn) {
|
|
15
|
+
super({ config, connection: conn });
|
|
16
|
+
}
|
|
17
|
+
queryWithConnection(queryFn) {
|
|
18
|
+
if (this.#aborted) {
|
|
19
|
+
throw new exception_1.MysqlException('Session has been aborted!');
|
|
20
|
+
}
|
|
21
|
+
return super.queryWithConnection(queryFn);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 中止,被中止后的会话不能再进行任何操作
|
|
25
|
+
*/
|
|
26
|
+
abort() {
|
|
27
|
+
this.#aborted = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.MysqlTxSession = MysqlTxSession;
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// 工具集,将一些驱动的方法进行 promise 封装,方便操作
|
|
3
|
-
// 程序中没有使用 mysql2/promise ,主要是在测试中发现 mysql2/promise 不是很可靠
|
|
4
|
-
// mysql2/promise 在查询方便处理的不是很好
|
|
5
|
-
// query 查询在没有记录的情况下仍然会返回列表,里面会包含列定义信息,不符合预期
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.promiseGetConnection = exports.promiseQuery = void 0;
|
|
8
|
-
const mysql2_1 = require("mysql2");
|
|
9
|
-
const log_1 = require("../../log");
|
|
10
|
-
/**
|
|
11
|
-
* 查询,适用于各种 sql 的执行
|
|
12
|
-
* @param config
|
|
13
|
-
* @param conn
|
|
14
|
-
* @param sql
|
|
15
|
-
* @param values
|
|
16
|
-
* @returns
|
|
17
|
-
*/
|
|
18
|
-
function promiseQuery(config, conn, sql, values = []) {
|
|
19
|
-
return new Promise((res, rej) => {
|
|
20
|
-
const start = new Date().getTime();
|
|
21
|
-
conn.query(sql, values, (err, result) => {
|
|
22
|
-
if (config.slowSqlWarn) {
|
|
23
|
-
const cost = new Date().getTime() - start;
|
|
24
|
-
// 慢 sql 警告
|
|
25
|
-
if (cost > config.slowSqlMs) {
|
|
26
|
-
(0, log_1.getLogger)().warn(`[mysql slow sql] ${cost}ms ${(0, mysql2_1.format)(sql, values)}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
if (err) {
|
|
30
|
-
rej(err);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
res(result);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
exports.promiseQuery = promiseQuery;
|
|
39
|
-
/**
|
|
40
|
-
* 获取连接
|
|
41
|
-
* @param pool
|
|
42
|
-
* @returns
|
|
43
|
-
*/
|
|
44
|
-
function promiseGetConnection(pool) {
|
|
45
|
-
return new Promise((res, rej) => {
|
|
46
|
-
pool.getConnection((err, conn) => {
|
|
47
|
-
if (err) {
|
|
48
|
-
rej(err);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
res(conn);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
exports.promiseGetConnection = promiseGetConnection;
|
|
1
|
+
"use strict";
|
|
2
|
+
// 工具集,将一些驱动的方法进行 promise 封装,方便操作
|
|
3
|
+
// 程序中没有使用 mysql2/promise ,主要是在测试中发现 mysql2/promise 不是很可靠
|
|
4
|
+
// mysql2/promise 在查询方便处理的不是很好
|
|
5
|
+
// query 查询在没有记录的情况下仍然会返回列表,里面会包含列定义信息,不符合预期
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.promiseGetConnection = exports.promiseQuery = void 0;
|
|
8
|
+
const mysql2_1 = require("mysql2");
|
|
9
|
+
const log_1 = require("../../log");
|
|
10
|
+
/**
|
|
11
|
+
* 查询,适用于各种 sql 的执行
|
|
12
|
+
* @param config
|
|
13
|
+
* @param conn
|
|
14
|
+
* @param sql
|
|
15
|
+
* @param values
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
function promiseQuery(config, conn, sql, values = []) {
|
|
19
|
+
return new Promise((res, rej) => {
|
|
20
|
+
const start = new Date().getTime();
|
|
21
|
+
conn.query(sql, values, (err, result) => {
|
|
22
|
+
if (config.slowSqlWarn) {
|
|
23
|
+
const cost = new Date().getTime() - start;
|
|
24
|
+
// 慢 sql 警告
|
|
25
|
+
if (cost > config.slowSqlMs) {
|
|
26
|
+
(0, log_1.getLogger)().warn(`[mysql slow sql] ${cost}ms ${(0, mysql2_1.format)(sql, values)}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (err) {
|
|
30
|
+
rej(err);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
res(result);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exports.promiseQuery = promiseQuery;
|
|
39
|
+
/**
|
|
40
|
+
* 获取连接
|
|
41
|
+
* @param pool
|
|
42
|
+
* @returns
|
|
43
|
+
*/
|
|
44
|
+
function promiseGetConnection(pool) {
|
|
45
|
+
return new Promise((res, rej) => {
|
|
46
|
+
pool.getConnection((err, conn) => {
|
|
47
|
+
if (err) {
|
|
48
|
+
rej(err);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
res(conn);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
exports.promiseGetConnection = promiseGetConnection;
|
package/dist/mysql/migration.js
CHANGED
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.migrate = void 0;
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
const log_1 = require("../log");
|
|
7
|
-
const exception_1 = require("./exception");
|
|
8
|
-
const utils_1 = require("./manager/utils");
|
|
9
|
-
/**
|
|
10
|
-
* 迁移.
|
|
11
|
-
* @param config
|
|
12
|
-
* @param conn
|
|
13
|
-
*/
|
|
14
|
-
async function migrate(config, conn) {
|
|
15
|
-
const versionDir = config.versionControlDir;
|
|
16
|
-
// 查找文件
|
|
17
|
-
const dir = (0, path_1.isAbsolute)(versionDir) ? versionDir : (0, path_1.resolve)(process.cwd(), versionDir);
|
|
18
|
-
if (!(0, fs_1.existsSync)(dir)) {
|
|
19
|
-
throw new Error(`Directory ${versionDir} does not exist`);
|
|
20
|
-
}
|
|
21
|
-
const versions = [];
|
|
22
|
-
// 忽略隐藏文件
|
|
23
|
-
const files = (0, fs_1.readdirSync)(dir).filter(file => !file.startsWith('.'));
|
|
24
|
-
for (const file of files) {
|
|
25
|
-
const filePath = (0, path_1.resolve)(dir, file);
|
|
26
|
-
const stat = (0, fs_1.statSync)(filePath);
|
|
27
|
-
if (!stat.isFile()) {
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (!file.endsWith('.sql')) {
|
|
31
|
-
throw new Error(`版本文件名没有以 .sql 为后缀:${file}`);
|
|
32
|
-
}
|
|
33
|
-
const version = parseInt(file.substring(0, file.length - 4));
|
|
34
|
-
if (isNaN(version)) {
|
|
35
|
-
throw new Error(`Version file is not named with a number:${file}`);
|
|
36
|
-
}
|
|
37
|
-
versions.push({ version, filePath });
|
|
38
|
-
}
|
|
39
|
-
// 排序,判定顺序
|
|
40
|
-
versions.sort((o1, o2) => o1.version - o2.version);
|
|
41
|
-
for (let i = 0; i < versions.length; i++) {
|
|
42
|
-
const version = versions[i];
|
|
43
|
-
if (version.version !== i + 1) {
|
|
44
|
-
throw new Error(`The SQL version number must start from 1 and increment one by one,error version:${version.version}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
await createVersionTableIfNotExist(config, conn);
|
|
48
|
-
// 在事务中执行版本管理,主要目的是为了通过锁来协调多个进程同时启动的情况
|
|
49
|
-
// 事务不能保存一个版本处理成功就完整回退,如有错误,仍然需要手动调整后再操作
|
|
50
|
-
await (0, utils_1.promiseQuery)(config, conn, `SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED`);
|
|
51
|
-
await new Promise((resolve, reject) => {
|
|
52
|
-
conn.beginTransaction(err => {
|
|
53
|
-
if (err) {
|
|
54
|
-
reject(err);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
resolve();
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
try {
|
|
62
|
-
// 执行 sql, 判定当前版本
|
|
63
|
-
let currentVersion = await getCurrentVersion(config, conn);
|
|
64
|
-
if (typeof currentVersion !== 'number') {
|
|
65
|
-
// 插入初始版本号
|
|
66
|
-
await (0, utils_1.promiseQuery)(config, conn, 'insert `db_version`(`version`) values (0)');
|
|
67
|
-
}
|
|
68
|
-
const filnalCurrentVersion = currentVersion || 0;
|
|
69
|
-
const pendingVersions = versions.filter(ver => ver.version > filnalCurrentVersion);
|
|
70
|
-
if (!pendingVersions.length) {
|
|
71
|
-
(0, log_1.getLogger)().info('The SQL version is already the latest.');
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const nextVersion = filnalCurrentVersion + 1;
|
|
75
|
-
if (pendingVersions[0].version !== nextVersion) {
|
|
76
|
-
throw new exception_1.MysqlException(`MySQL migration error, the next version should be ${nextVersion},but current is ${pendingVersions[0].version}`);
|
|
77
|
-
}
|
|
78
|
-
for (const verion of pendingVersions) {
|
|
79
|
-
(0, log_1.getLogger)().info(`Mysql migrating, version: ${verion.version}`);
|
|
80
|
-
let sql = (0, fs_1.readFileSync)(verion.filePath, { encoding: 'utf-8' });
|
|
81
|
-
await (0, utils_1.promiseQuery)(config, conn, sql);
|
|
82
|
-
// 版本号
|
|
83
|
-
await (0, utils_1.promiseQuery)(config, conn, `UPDATE db_version SET version=${verion.version};`);
|
|
84
|
-
}
|
|
85
|
-
// 提交
|
|
86
|
-
await new Promise((resolve, reject) => {
|
|
87
|
-
conn.commit(err => {
|
|
88
|
-
if (err) {
|
|
89
|
-
reject(err);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
resolve();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
(0, log_1.getLogger)().info('Mysql migration finished.');
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
// 异常回退,仅能回退 dml 操作,对 ddl 无效
|
|
100
|
-
await new Promise((resolve, reject) => {
|
|
101
|
-
conn.rollback(err => {
|
|
102
|
-
if (err) {
|
|
103
|
-
reject(err);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
resolve();
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
throw e;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
exports.migrate = migrate;
|
|
114
|
-
async function createVersionTableIfNotExist(config, conn) {
|
|
115
|
-
await (0, utils_1.promiseQuery)(config, conn, 'CREATE TABLE IF NOT EXISTS `db_version` (' +
|
|
116
|
-
' `version` int NOT NULL,' +
|
|
117
|
-
' PRIMARY KEY (`version`)' +
|
|
118
|
-
') ENGINE = innodb DEFAULT CHARACTER SET = "utf8mb4" ' +
|
|
119
|
-
'COLLATE = "utf8mb4_unicode_ci";');
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* 获取当前版本,使用 for update 加锁,用于协调多进程并发场景
|
|
123
|
-
* @param config
|
|
124
|
-
* @param conn
|
|
125
|
-
* @returns
|
|
126
|
-
*/
|
|
127
|
-
async function getCurrentVersion(config, conn) {
|
|
128
|
-
const res = await (0, utils_1.promiseQuery)(config, conn, 'select version from `db_version` for update');
|
|
129
|
-
const rows = res;
|
|
130
|
-
if (rows.length >= 1) {
|
|
131
|
-
return rows[0].version;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrate = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const log_1 = require("../log");
|
|
7
|
+
const exception_1 = require("./exception");
|
|
8
|
+
const utils_1 = require("./manager/utils");
|
|
9
|
+
/**
|
|
10
|
+
* 迁移.
|
|
11
|
+
* @param config
|
|
12
|
+
* @param conn
|
|
13
|
+
*/
|
|
14
|
+
async function migrate(config, conn) {
|
|
15
|
+
const versionDir = config.versionControlDir;
|
|
16
|
+
// 查找文件
|
|
17
|
+
const dir = (0, path_1.isAbsolute)(versionDir) ? versionDir : (0, path_1.resolve)(process.cwd(), versionDir);
|
|
18
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
19
|
+
throw new Error(`Directory ${versionDir} does not exist`);
|
|
20
|
+
}
|
|
21
|
+
const versions = [];
|
|
22
|
+
// 忽略隐藏文件
|
|
23
|
+
const files = (0, fs_1.readdirSync)(dir).filter(file => !file.startsWith('.'));
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
const filePath = (0, path_1.resolve)(dir, file);
|
|
26
|
+
const stat = (0, fs_1.statSync)(filePath);
|
|
27
|
+
if (!stat.isFile()) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (!file.endsWith('.sql')) {
|
|
31
|
+
throw new Error(`版本文件名没有以 .sql 为后缀:${file}`);
|
|
32
|
+
}
|
|
33
|
+
const version = parseInt(file.substring(0, file.length - 4));
|
|
34
|
+
if (isNaN(version)) {
|
|
35
|
+
throw new Error(`Version file is not named with a number:${file}`);
|
|
36
|
+
}
|
|
37
|
+
versions.push({ version, filePath });
|
|
38
|
+
}
|
|
39
|
+
// 排序,判定顺序
|
|
40
|
+
versions.sort((o1, o2) => o1.version - o2.version);
|
|
41
|
+
for (let i = 0; i < versions.length; i++) {
|
|
42
|
+
const version = versions[i];
|
|
43
|
+
if (version.version !== i + 1) {
|
|
44
|
+
throw new Error(`The SQL version number must start from 1 and increment one by one,error version:${version.version}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
await createVersionTableIfNotExist(config, conn);
|
|
48
|
+
// 在事务中执行版本管理,主要目的是为了通过锁来协调多个进程同时启动的情况
|
|
49
|
+
// 事务不能保存一个版本处理成功就完整回退,如有错误,仍然需要手动调整后再操作
|
|
50
|
+
await (0, utils_1.promiseQuery)(config, conn, `SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED`);
|
|
51
|
+
await new Promise((resolve, reject) => {
|
|
52
|
+
conn.beginTransaction(err => {
|
|
53
|
+
if (err) {
|
|
54
|
+
reject(err);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
resolve();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
// 执行 sql, 判定当前版本
|
|
63
|
+
let currentVersion = await getCurrentVersion(config, conn);
|
|
64
|
+
if (typeof currentVersion !== 'number') {
|
|
65
|
+
// 插入初始版本号
|
|
66
|
+
await (0, utils_1.promiseQuery)(config, conn, 'insert `db_version`(`version`) values (0)');
|
|
67
|
+
}
|
|
68
|
+
const filnalCurrentVersion = currentVersion || 0;
|
|
69
|
+
const pendingVersions = versions.filter(ver => ver.version > filnalCurrentVersion);
|
|
70
|
+
if (!pendingVersions.length) {
|
|
71
|
+
(0, log_1.getLogger)().info('The SQL version is already the latest.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const nextVersion = filnalCurrentVersion + 1;
|
|
75
|
+
if (pendingVersions[0].version !== nextVersion) {
|
|
76
|
+
throw new exception_1.MysqlException(`MySQL migration error, the next version should be ${nextVersion},but current is ${pendingVersions[0].version}`);
|
|
77
|
+
}
|
|
78
|
+
for (const verion of pendingVersions) {
|
|
79
|
+
(0, log_1.getLogger)().info(`Mysql migrating, version: ${verion.version}`);
|
|
80
|
+
let sql = (0, fs_1.readFileSync)(verion.filePath, { encoding: 'utf-8' });
|
|
81
|
+
await (0, utils_1.promiseQuery)(config, conn, sql);
|
|
82
|
+
// 版本号
|
|
83
|
+
await (0, utils_1.promiseQuery)(config, conn, `UPDATE db_version SET version=${verion.version};`);
|
|
84
|
+
}
|
|
85
|
+
// 提交
|
|
86
|
+
await new Promise((resolve, reject) => {
|
|
87
|
+
conn.commit(err => {
|
|
88
|
+
if (err) {
|
|
89
|
+
reject(err);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
resolve();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
(0, log_1.getLogger)().info('Mysql migration finished.');
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
// 异常回退,仅能回退 dml 操作,对 ddl 无效
|
|
100
|
+
await new Promise((resolve, reject) => {
|
|
101
|
+
conn.rollback(err => {
|
|
102
|
+
if (err) {
|
|
103
|
+
reject(err);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
resolve();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
throw e;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.migrate = migrate;
|
|
114
|
+
async function createVersionTableIfNotExist(config, conn) {
|
|
115
|
+
await (0, utils_1.promiseQuery)(config, conn, 'CREATE TABLE IF NOT EXISTS `db_version` (' +
|
|
116
|
+
' `version` int NOT NULL,' +
|
|
117
|
+
' PRIMARY KEY (`version`)' +
|
|
118
|
+
') ENGINE = innodb DEFAULT CHARACTER SET = "utf8mb4" ' +
|
|
119
|
+
'COLLATE = "utf8mb4_unicode_ci";');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 获取当前版本,使用 for update 加锁,用于协调多进程并发场景
|
|
123
|
+
* @param config
|
|
124
|
+
* @param conn
|
|
125
|
+
* @returns
|
|
126
|
+
*/
|
|
127
|
+
async function getCurrentVersion(config, conn) {
|
|
128
|
+
const res = await (0, utils_1.promiseQuery)(config, conn, 'select version from `db_version` for update');
|
|
129
|
+
const rows = res;
|
|
130
|
+
if (rows.length >= 1) {
|
|
131
|
+
return rows[0].version;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|