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.
- 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 +278 -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 +381 -356
- package/dist/mysql/manager/ops/delete.js +59 -65
- package/dist/mysql/manager/ops/exist.js +26 -26
- package/dist/mysql/manager/ops/find.js +149 -169
- package/dist/mysql/manager/ops/index.js +16 -14
- package/dist/mysql/manager/ops/insert.js +132 -106
- package/dist/mysql/manager/ops/modify.js +10 -10
- package/dist/mysql/manager/ops/order-by.js +28 -0
- package/dist/mysql/manager/ops/paginate.js +48 -23
- package/dist/mysql/manager/ops/query.js +9 -9
- package/dist/mysql/manager/ops/update.js +222 -216
- package/dist/mysql/manager/ops/upsert.js +178 -0
- package/dist/mysql/manager/ops/utils.js +28 -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 +682 -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/documentation/zh-cn/mysql.md +146 -17
- package/package.json +4 -1
- package/skills/wok-server-api-rules/SKILL.md +350 -0
- package/skills/wok-server-cache/SKILL.md +216 -0
- package/skills/wok-server-code-navigation/SKILL.md +153 -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 +388 -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 +332 -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 +446 -0
- package/src/mysql/manager/ops/delete.ts +91 -0
- package/src/mysql/manager/ops/exist.ts +41 -0
- package/src/mysql/manager/ops/find.ts +209 -0
- package/src/mysql/manager/ops/index.ts +13 -0
- package/src/mysql/manager/ops/insert.ts +158 -0
- package/src/mysql/manager/ops/modify.ts +14 -0
- package/src/mysql/manager/ops/order-by.ts +58 -0
- package/src/mysql/manager/ops/paginate.ts +100 -0
- package/src/mysql/manager/ops/query.ts +13 -0
- package/src/mysql/manager/ops/update.ts +318 -0
- package/src/mysql/manager/ops/upsert.ts +224 -0
- package/src/mysql/manager/ops/utils.ts +24 -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 +196 -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 +144 -134
- package/types/mysql/manager/ops/delete.d.ts +47 -46
- package/types/mysql/manager/ops/exist.d.ts +6 -6
- package/types/mysql/manager/ops/find.d.ts +87 -86
- package/types/mysql/manager/ops/index.d.ts +12 -10
- package/types/mysql/manager/ops/insert.d.ts +32 -18
- package/types/mysql/manager/ops/modify.d.ts +3 -3
- package/types/mysql/manager/ops/order-by.d.ts +38 -0
- package/types/mysql/manager/ops/paginate.d.ts +53 -36
- package/types/mysql/manager/ops/query.d.ts +3 -3
- package/types/mysql/manager/ops/update.d.ts +99 -76
- package/types/mysql/manager/ops/upsert.d.ts +36 -0
- 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,563 +1,563 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BaseMongoManager = void 0;
|
|
4
|
-
const log_1 = require("../../log");
|
|
5
|
-
const validation_1 = require("../../validation");
|
|
6
|
-
const exception_1 = require("../exception");
|
|
7
|
-
/**
|
|
8
|
-
* mongodb 管理器基类,提供基本的操作功能.
|
|
9
|
-
*/
|
|
10
|
-
class BaseMongoManager {
|
|
11
|
-
config;
|
|
12
|
-
db;
|
|
13
|
-
session;
|
|
14
|
-
/**
|
|
15
|
-
* mongodb 管理器构建
|
|
16
|
-
* @param db 库
|
|
17
|
-
* @param session 要绑定的会话,用于事务
|
|
18
|
-
*/
|
|
19
|
-
constructor(config, db, session) {
|
|
20
|
-
this.config = config;
|
|
21
|
-
this.db = db;
|
|
22
|
-
this.session = session;
|
|
23
|
-
}
|
|
24
|
-
getCollection(collInfo) {
|
|
25
|
-
return this.db.collection(collInfo.collectionName);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* 查询计时
|
|
29
|
-
* @param opts
|
|
30
|
-
*/
|
|
31
|
-
async timingQuery(opts) {
|
|
32
|
-
const start = new Date().getTime();
|
|
33
|
-
try {
|
|
34
|
-
return await opts.query();
|
|
35
|
-
}
|
|
36
|
-
finally {
|
|
37
|
-
if (this.config.slowQueryWarn) {
|
|
38
|
-
const cost = new Date().getTime() - start;
|
|
39
|
-
if (cost > this.config.slowQueryMs) {
|
|
40
|
-
(0, log_1.getLogger)().warn(`[mongodb slow query] ${cost}ms ${JSON.stringify(opts.desc())}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async findById(coll, id) {
|
|
46
|
-
return this.timingQuery({
|
|
47
|
-
query: async () => {
|
|
48
|
-
const res = await this.getCollection(coll).findOne({ _id: id }, {
|
|
49
|
-
limit: 1,
|
|
50
|
-
session: this.session
|
|
51
|
-
});
|
|
52
|
-
return res;
|
|
53
|
-
},
|
|
54
|
-
desc: () => ({
|
|
55
|
-
op: 'findById',
|
|
56
|
-
coll: coll.collectionName,
|
|
57
|
-
id
|
|
58
|
-
})
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* 根据id列表查询
|
|
63
|
-
* @param coll
|
|
64
|
-
* @param ids
|
|
65
|
-
* @returns
|
|
66
|
-
*/
|
|
67
|
-
findByIdIn(coll, ids) {
|
|
68
|
-
return this.timingQuery({
|
|
69
|
-
query: async () => {
|
|
70
|
-
const res = this.getCollection(coll).find({ _id: { $in: ids } }, { session: this.session });
|
|
71
|
-
return res.toArray();
|
|
72
|
-
},
|
|
73
|
-
desc() {
|
|
74
|
-
return {
|
|
75
|
-
op: 'findByIdIn',
|
|
76
|
-
coll: coll.collectionName,
|
|
77
|
-
ids
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* 根据id判定是否存在
|
|
84
|
-
* @param coll
|
|
85
|
-
* @param id
|
|
86
|
-
*/
|
|
87
|
-
async existsById(coll, id) {
|
|
88
|
-
const res = await this.findById(coll, id);
|
|
89
|
-
return !!res;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* 按指定的条件来判定是否存在记录
|
|
93
|
-
* @param coll
|
|
94
|
-
* @param filter
|
|
95
|
-
*/
|
|
96
|
-
async existsBy(coll, filter) {
|
|
97
|
-
return this.timingQuery({
|
|
98
|
-
query: async () => {
|
|
99
|
-
const res = await this.getCollection(coll).findOne(filter, {
|
|
100
|
-
limit: 1,
|
|
101
|
-
session: this.session
|
|
102
|
-
});
|
|
103
|
-
return !!res;
|
|
104
|
-
},
|
|
105
|
-
desc() {
|
|
106
|
-
return {
|
|
107
|
-
op: 'existsBy',
|
|
108
|
-
coll: coll.collectionName,
|
|
109
|
-
filter
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* 按id进行删除
|
|
116
|
-
* @param coll
|
|
117
|
-
* @param id
|
|
118
|
-
* @returns
|
|
119
|
-
*/
|
|
120
|
-
async deleteById(coll, id) {
|
|
121
|
-
return this.timingQuery({
|
|
122
|
-
query: async () => {
|
|
123
|
-
const res = await this.getCollection(coll).deleteOne({ _id: id }, {
|
|
124
|
-
session: this.session
|
|
125
|
-
});
|
|
126
|
-
return res.deletedCount === 1;
|
|
127
|
-
},
|
|
128
|
-
desc() {
|
|
129
|
-
return {
|
|
130
|
-
op: 'deleteById',
|
|
131
|
-
coll: coll.collectionName,
|
|
132
|
-
id
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* 仅删除一条记录
|
|
139
|
-
* @param coll
|
|
140
|
-
* @param filter
|
|
141
|
-
* @returns
|
|
142
|
-
*/
|
|
143
|
-
async deleteOne(coll, filter) {
|
|
144
|
-
if (!Object.keys(filter).length) {
|
|
145
|
-
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
146
|
-
}
|
|
147
|
-
return this.timingQuery({
|
|
148
|
-
query: async () => {
|
|
149
|
-
const res = await this.getCollection(coll).deleteOne(filter, {
|
|
150
|
-
session: this.session
|
|
151
|
-
});
|
|
152
|
-
return res.deletedCount === 1;
|
|
153
|
-
},
|
|
154
|
-
desc() {
|
|
155
|
-
return {
|
|
156
|
-
op: 'deleteMany',
|
|
157
|
-
coll: coll.collectionName,
|
|
158
|
-
filter
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* 按条件删除数据,返回删除的记录行数.
|
|
165
|
-
* 务必谨慎使用,大批量删除容易带来性能问题,造成线上事故.
|
|
166
|
-
* @param coll
|
|
167
|
-
* @param filter
|
|
168
|
-
* @returns 被删除记录的数量
|
|
169
|
-
*/
|
|
170
|
-
async deleteMany(coll, filter) {
|
|
171
|
-
if (!Object.keys(filter).length) {
|
|
172
|
-
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
173
|
-
}
|
|
174
|
-
return this.timingQuery({
|
|
175
|
-
query: async () => {
|
|
176
|
-
const res = await this.getCollection(coll).deleteMany(filter, {
|
|
177
|
-
session: this.session
|
|
178
|
-
});
|
|
179
|
-
return res.deletedCount;
|
|
180
|
-
},
|
|
181
|
-
desc() {
|
|
182
|
-
return {
|
|
183
|
-
op: 'deleteMany',
|
|
184
|
-
coll: coll.collectionName,
|
|
185
|
-
filter
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* 查询集合中所有记录.谨慎使用!
|
|
192
|
-
* @param coll
|
|
193
|
-
* @returns
|
|
194
|
-
*/
|
|
195
|
-
async findAll(coll) {
|
|
196
|
-
return this.timingQuery({
|
|
197
|
-
query: async () => {
|
|
198
|
-
const arr = await this.getCollection(coll).find({}, { session: this.session }).toArray();
|
|
199
|
-
return arr;
|
|
200
|
-
},
|
|
201
|
-
desc() {
|
|
202
|
-
return {
|
|
203
|
-
op: 'findAll',
|
|
204
|
-
coll: coll.collectionName
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* 根据给定的条件查找第一条符合条件的记录
|
|
211
|
-
* @param coll
|
|
212
|
-
* @param filter
|
|
213
|
-
* @returns
|
|
214
|
-
*/
|
|
215
|
-
async findFirst(coll, filter) {
|
|
216
|
-
return this.timingQuery({
|
|
217
|
-
query: async () => {
|
|
218
|
-
const res = await this.getCollection(coll).findOne(filter, {
|
|
219
|
-
limit: 1,
|
|
220
|
-
session: this.session
|
|
221
|
-
});
|
|
222
|
-
return res;
|
|
223
|
-
},
|
|
224
|
-
desc() {
|
|
225
|
-
return {
|
|
226
|
-
op: 'findFirst',
|
|
227
|
-
coll: coll.collectionName,
|
|
228
|
-
filter
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* 插入新记录
|
|
235
|
-
* @param coll
|
|
236
|
-
* @param data
|
|
237
|
-
* @returns
|
|
238
|
-
*/
|
|
239
|
-
async insert(coll, data) {
|
|
240
|
-
return this.timingQuery({
|
|
241
|
-
query: async () => {
|
|
242
|
-
// 创建时间和更新时间
|
|
243
|
-
if (coll.createdDate) {
|
|
244
|
-
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime();
|
|
245
|
-
data[coll.createdDate.field] = createdData;
|
|
246
|
-
}
|
|
247
|
-
if (coll.updatedDate) {
|
|
248
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
249
|
-
data[coll.updatedDate.field] = updatedDate;
|
|
250
|
-
}
|
|
251
|
-
const collection = this.getCollection(coll);
|
|
252
|
-
const res = await collection.insertOne(data, { session: this.session });
|
|
253
|
-
if (data._id) {
|
|
254
|
-
return data;
|
|
255
|
-
}
|
|
256
|
-
data._id = res.insertedId;
|
|
257
|
-
return data;
|
|
258
|
-
},
|
|
259
|
-
desc() {
|
|
260
|
-
return {
|
|
261
|
-
op: 'insert',
|
|
262
|
-
coll: coll.collectionName,
|
|
263
|
-
data
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* 插入多条,批量插入.
|
|
270
|
-
* @param coll
|
|
271
|
-
* @param list
|
|
272
|
-
*/
|
|
273
|
-
async insertMany(coll, list) {
|
|
274
|
-
return this.timingQuery({
|
|
275
|
-
query: async () => {
|
|
276
|
-
const docList = list.map(data => {
|
|
277
|
-
// 创建时间和更新时间
|
|
278
|
-
if (coll.createdDate) {
|
|
279
|
-
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime();
|
|
280
|
-
data[coll.createdDate.field] = createdData;
|
|
281
|
-
}
|
|
282
|
-
if (coll.updatedDate) {
|
|
283
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
284
|
-
data[coll.updatedDate.field] = updatedDate;
|
|
285
|
-
}
|
|
286
|
-
return data;
|
|
287
|
-
});
|
|
288
|
-
const collection = this.getCollection(coll);
|
|
289
|
-
const res = await collection.insertMany(docList, { session: this.session });
|
|
290
|
-
docList.forEach((doc, idx) => {
|
|
291
|
-
if (doc._id) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
if (res.insertedIds[idx]) {
|
|
295
|
-
doc._id = res.insertedIds[idx];
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
return docList;
|
|
299
|
-
},
|
|
300
|
-
desc() {
|
|
301
|
-
return {
|
|
302
|
-
op: 'insertMany',
|
|
303
|
-
coll: coll.collectionName,
|
|
304
|
-
list
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* 更新,更新完整的文档内容。
|
|
311
|
-
* @param coll 集合信息
|
|
312
|
-
* @param data 要更新的数据,必须包含 _id 字段,支持 mongo 更新语法 $inc 等
|
|
313
|
-
* @returns 返回最新的数据
|
|
314
|
-
* @throws MongoDBException 当无法完成更新时抛出
|
|
315
|
-
*/
|
|
316
|
-
async update(coll, data) {
|
|
317
|
-
return this.timingQuery({
|
|
318
|
-
query: async () => {
|
|
319
|
-
const id = data._id;
|
|
320
|
-
if (!id) {
|
|
321
|
-
throw new exception_1.MongoDBException(`Cannot update a document without an id,collection name:${coll.collectionName}`);
|
|
322
|
-
}
|
|
323
|
-
delete data._id;
|
|
324
|
-
let createData = undefined;
|
|
325
|
-
// 保护创建时间不被更新
|
|
326
|
-
if (coll.createdDate && data[coll.createdDate.field]) {
|
|
327
|
-
createData = data[coll.createdDate.field];
|
|
328
|
-
delete data[coll.createdDate.field];
|
|
329
|
-
}
|
|
330
|
-
// 更新时间
|
|
331
|
-
if (coll.updatedDate) {
|
|
332
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
333
|
-
data[coll.updatedDate.field] = updatedDate;
|
|
334
|
-
}
|
|
335
|
-
const res = await this.getCollection(coll).updateOne({ _id: id }, { $set: data }, {
|
|
336
|
-
session: this.session
|
|
337
|
-
});
|
|
338
|
-
if (res.modifiedCount !== 1) {
|
|
339
|
-
throw new exception_1.MongoDBException(`Failed to update record, possibly due to non-existent record,collection:${coll.collectionName},id:${id}`);
|
|
340
|
-
}
|
|
341
|
-
data._id = id;
|
|
342
|
-
if (coll.createdDate && createData) {
|
|
343
|
-
data[coll.createdDate.field] = createData;
|
|
344
|
-
}
|
|
345
|
-
return data;
|
|
346
|
-
},
|
|
347
|
-
desc() {
|
|
348
|
-
return {
|
|
349
|
-
op: 'update',
|
|
350
|
-
coll: coll.collectionName,
|
|
351
|
-
data
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* 仅更新一条记录
|
|
358
|
-
* @param coll
|
|
359
|
-
* @param filter
|
|
360
|
-
* @param updater
|
|
361
|
-
*/
|
|
362
|
-
async updateOne(coll, filter, updater) {
|
|
363
|
-
if (!Object.keys(filter).length) {
|
|
364
|
-
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
365
|
-
}
|
|
366
|
-
if (!Object.keys(updater).length) {
|
|
367
|
-
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
368
|
-
}
|
|
369
|
-
return this.timingQuery({
|
|
370
|
-
query: async () => {
|
|
371
|
-
// 更新时间处理
|
|
372
|
-
if (coll.updatedDate) {
|
|
373
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
374
|
-
if (updater.$set) {
|
|
375
|
-
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
const res = await this.getCollection(coll).updateOne(filter, updater, {
|
|
382
|
-
session: this.session
|
|
383
|
-
});
|
|
384
|
-
return res.modifiedCount === 1;
|
|
385
|
-
},
|
|
386
|
-
desc() {
|
|
387
|
-
return {
|
|
388
|
-
op: 'updateOne',
|
|
389
|
-
coll: coll.collectionName,
|
|
390
|
-
filter,
|
|
391
|
-
updator: updater
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* 局部更新,仅更新部分字段,可对字段做递增或数组元组的处理。
|
|
398
|
-
* @param coll 集合信息
|
|
399
|
-
* @param id id
|
|
400
|
-
* @param updater 更新内容
|
|
401
|
-
* @returns 更新是否成功
|
|
402
|
-
*/
|
|
403
|
-
async partialUpdate(coll, id, updater) {
|
|
404
|
-
if (!Object.keys(updater).length) {
|
|
405
|
-
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
406
|
-
}
|
|
407
|
-
return this.timingQuery({
|
|
408
|
-
query: async () => {
|
|
409
|
-
// 更新时间处理
|
|
410
|
-
if (coll.updatedDate) {
|
|
411
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
412
|
-
if (updater.$set) {
|
|
413
|
-
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
const res = await this.getCollection(coll).updateOne({ _id: id }, updater, {
|
|
420
|
-
session: this.session
|
|
421
|
-
});
|
|
422
|
-
return res.modifiedCount === 1;
|
|
423
|
-
},
|
|
424
|
-
desc() {
|
|
425
|
-
return {
|
|
426
|
-
op: 'partialUpdate',
|
|
427
|
-
coll: coll.collectionName,
|
|
428
|
-
id,
|
|
429
|
-
updator: updater
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* 根据条件更新多条记录,和 partialUpdate 区别是可以根据过滤条件来处理多条记录。
|
|
436
|
-
* @param coll 集合
|
|
437
|
-
* @param filter 过滤规则
|
|
438
|
-
* @param updater 更新内容
|
|
439
|
-
* @returns 此次更新的记录数
|
|
440
|
-
*/
|
|
441
|
-
async updateMany(coll, filter, updater) {
|
|
442
|
-
if (!Object.keys(filter).length) {
|
|
443
|
-
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
444
|
-
}
|
|
445
|
-
if (!Object.keys(updater).length) {
|
|
446
|
-
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
447
|
-
}
|
|
448
|
-
return this.timingQuery({
|
|
449
|
-
query: async () => {
|
|
450
|
-
// 更新时间处理
|
|
451
|
-
if (coll.updatedDate) {
|
|
452
|
-
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
453
|
-
if (updater.$set) {
|
|
454
|
-
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
const res = await this.getCollection(coll).updateMany(filter, updater, {
|
|
461
|
-
session: this.session
|
|
462
|
-
});
|
|
463
|
-
return res.modifiedCount;
|
|
464
|
-
},
|
|
465
|
-
desc() {
|
|
466
|
-
return {
|
|
467
|
-
op: 'updateMany',
|
|
468
|
-
coll: coll.collectionName,
|
|
469
|
-
filter,
|
|
470
|
-
updator: updater
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* 条件查询
|
|
477
|
-
* @param coll 集合信息
|
|
478
|
-
* @param filter 过滤条件
|
|
479
|
-
* @param opts 额外的选项
|
|
480
|
-
* @returns
|
|
481
|
-
*/
|
|
482
|
-
async find(coll, filter, opts) {
|
|
483
|
-
return this.timingQuery({
|
|
484
|
-
query: async () => {
|
|
485
|
-
const arr = await this.getCollection(coll)
|
|
486
|
-
.find(filter, {
|
|
487
|
-
limit: opts && opts.limit && opts.limit > 0 ? opts.limit : undefined,
|
|
488
|
-
skip: opts && opts.limit && opts.limit > 0 && opts.offset && opts.offset > 0
|
|
489
|
-
? opts.offset
|
|
490
|
-
: undefined,
|
|
491
|
-
sort: opts && opts.orderBy ? opts.orderBy : undefined,
|
|
492
|
-
session: this.session
|
|
493
|
-
})
|
|
494
|
-
.toArray();
|
|
495
|
-
return arr;
|
|
496
|
-
},
|
|
497
|
-
desc() {
|
|
498
|
-
return {
|
|
499
|
-
op: 'find',
|
|
500
|
-
coll: coll.collectionName,
|
|
501
|
-
filter,
|
|
502
|
-
opts
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* 查询符合条件的文档数量。请谨慎使用,count 是不能从索引直接读取的,只能实时计数,使用不当容易造成性能问题,引发线上事故。
|
|
509
|
-
* @param coll
|
|
510
|
-
* @param filter
|
|
511
|
-
* @returns
|
|
512
|
-
*/
|
|
513
|
-
count(coll, filter) {
|
|
514
|
-
return this.timingQuery({
|
|
515
|
-
query: async () => {
|
|
516
|
-
return this.getCollection(coll).countDocuments(filter, { session: this.session });
|
|
517
|
-
},
|
|
518
|
-
desc() {
|
|
519
|
-
return {
|
|
520
|
-
op: 'count',
|
|
521
|
-
coll: coll.collectionName,
|
|
522
|
-
filter
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* 分页查询。谨慎使用,不建议对规模较大的数据查询直接使用分页。
|
|
529
|
-
* @param coll 集合信息
|
|
530
|
-
* @param filter 过滤条件
|
|
531
|
-
* @param opts 分页参数
|
|
532
|
-
*/
|
|
533
|
-
async paginate(coll, filter, opts) {
|
|
534
|
-
(0, validation_1.validate)(opts, {
|
|
535
|
-
pn: [(0, validation_1.notNull)(), (0, validation_1.min)(1)],
|
|
536
|
-
pz: [(0, validation_1.notNull)(), (0, validation_1.min)(1)]
|
|
537
|
-
});
|
|
538
|
-
const start = new Date().getTime();
|
|
539
|
-
try {
|
|
540
|
-
const offset = (opts.pn - 1) * opts.pz;
|
|
541
|
-
const res = await Promise.all([
|
|
542
|
-
this.find(coll, filter, { offset, limit: opts.pz, orderBy: opts.orderBy }),
|
|
543
|
-
this.count(coll, filter)
|
|
544
|
-
]);
|
|
545
|
-
const [list, total] = res;
|
|
546
|
-
return { list, total };
|
|
547
|
-
}
|
|
548
|
-
finally {
|
|
549
|
-
if (this.config.slowQueryWarn) {
|
|
550
|
-
const cost = new Date().getTime() - start;
|
|
551
|
-
if (cost > this.config.slowQueryMs) {
|
|
552
|
-
(0, log_1.getLogger)().warn(`[mongodb slow query] ${cost}ms ${JSON.stringify({
|
|
553
|
-
op: 'paginate',
|
|
554
|
-
coll: coll.collectionName,
|
|
555
|
-
filter,
|
|
556
|
-
opts
|
|
557
|
-
})}`);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
exports.BaseMongoManager = BaseMongoManager;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseMongoManager = void 0;
|
|
4
|
+
const log_1 = require("../../log");
|
|
5
|
+
const validation_1 = require("../../validation");
|
|
6
|
+
const exception_1 = require("../exception");
|
|
7
|
+
/**
|
|
8
|
+
* mongodb 管理器基类,提供基本的操作功能.
|
|
9
|
+
*/
|
|
10
|
+
class BaseMongoManager {
|
|
11
|
+
config;
|
|
12
|
+
db;
|
|
13
|
+
session;
|
|
14
|
+
/**
|
|
15
|
+
* mongodb 管理器构建
|
|
16
|
+
* @param db 库
|
|
17
|
+
* @param session 要绑定的会话,用于事务
|
|
18
|
+
*/
|
|
19
|
+
constructor(config, db, session) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.db = db;
|
|
22
|
+
this.session = session;
|
|
23
|
+
}
|
|
24
|
+
getCollection(collInfo) {
|
|
25
|
+
return this.db.collection(collInfo.collectionName);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 查询计时
|
|
29
|
+
* @param opts
|
|
30
|
+
*/
|
|
31
|
+
async timingQuery(opts) {
|
|
32
|
+
const start = new Date().getTime();
|
|
33
|
+
try {
|
|
34
|
+
return await opts.query();
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
if (this.config.slowQueryWarn) {
|
|
38
|
+
const cost = new Date().getTime() - start;
|
|
39
|
+
if (cost > this.config.slowQueryMs) {
|
|
40
|
+
(0, log_1.getLogger)().warn(`[mongodb slow query] ${cost}ms ${JSON.stringify(opts.desc())}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async findById(coll, id) {
|
|
46
|
+
return this.timingQuery({
|
|
47
|
+
query: async () => {
|
|
48
|
+
const res = await this.getCollection(coll).findOne({ _id: id }, {
|
|
49
|
+
limit: 1,
|
|
50
|
+
session: this.session
|
|
51
|
+
});
|
|
52
|
+
return res;
|
|
53
|
+
},
|
|
54
|
+
desc: () => ({
|
|
55
|
+
op: 'findById',
|
|
56
|
+
coll: coll.collectionName,
|
|
57
|
+
id
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 根据id列表查询
|
|
63
|
+
* @param coll
|
|
64
|
+
* @param ids
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
findByIdIn(coll, ids) {
|
|
68
|
+
return this.timingQuery({
|
|
69
|
+
query: async () => {
|
|
70
|
+
const res = this.getCollection(coll).find({ _id: { $in: ids } }, { session: this.session });
|
|
71
|
+
return res.toArray();
|
|
72
|
+
},
|
|
73
|
+
desc() {
|
|
74
|
+
return {
|
|
75
|
+
op: 'findByIdIn',
|
|
76
|
+
coll: coll.collectionName,
|
|
77
|
+
ids
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 根据id判定是否存在
|
|
84
|
+
* @param coll
|
|
85
|
+
* @param id
|
|
86
|
+
*/
|
|
87
|
+
async existsById(coll, id) {
|
|
88
|
+
const res = await this.findById(coll, id);
|
|
89
|
+
return !!res;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 按指定的条件来判定是否存在记录
|
|
93
|
+
* @param coll
|
|
94
|
+
* @param filter
|
|
95
|
+
*/
|
|
96
|
+
async existsBy(coll, filter) {
|
|
97
|
+
return this.timingQuery({
|
|
98
|
+
query: async () => {
|
|
99
|
+
const res = await this.getCollection(coll).findOne(filter, {
|
|
100
|
+
limit: 1,
|
|
101
|
+
session: this.session
|
|
102
|
+
});
|
|
103
|
+
return !!res;
|
|
104
|
+
},
|
|
105
|
+
desc() {
|
|
106
|
+
return {
|
|
107
|
+
op: 'existsBy',
|
|
108
|
+
coll: coll.collectionName,
|
|
109
|
+
filter
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 按id进行删除
|
|
116
|
+
* @param coll
|
|
117
|
+
* @param id
|
|
118
|
+
* @returns
|
|
119
|
+
*/
|
|
120
|
+
async deleteById(coll, id) {
|
|
121
|
+
return this.timingQuery({
|
|
122
|
+
query: async () => {
|
|
123
|
+
const res = await this.getCollection(coll).deleteOne({ _id: id }, {
|
|
124
|
+
session: this.session
|
|
125
|
+
});
|
|
126
|
+
return res.deletedCount === 1;
|
|
127
|
+
},
|
|
128
|
+
desc() {
|
|
129
|
+
return {
|
|
130
|
+
op: 'deleteById',
|
|
131
|
+
coll: coll.collectionName,
|
|
132
|
+
id
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 仅删除一条记录
|
|
139
|
+
* @param coll
|
|
140
|
+
* @param filter
|
|
141
|
+
* @returns
|
|
142
|
+
*/
|
|
143
|
+
async deleteOne(coll, filter) {
|
|
144
|
+
if (!Object.keys(filter).length) {
|
|
145
|
+
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
146
|
+
}
|
|
147
|
+
return this.timingQuery({
|
|
148
|
+
query: async () => {
|
|
149
|
+
const res = await this.getCollection(coll).deleteOne(filter, {
|
|
150
|
+
session: this.session
|
|
151
|
+
});
|
|
152
|
+
return res.deletedCount === 1;
|
|
153
|
+
},
|
|
154
|
+
desc() {
|
|
155
|
+
return {
|
|
156
|
+
op: 'deleteMany',
|
|
157
|
+
coll: coll.collectionName,
|
|
158
|
+
filter
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 按条件删除数据,返回删除的记录行数.
|
|
165
|
+
* 务必谨慎使用,大批量删除容易带来性能问题,造成线上事故.
|
|
166
|
+
* @param coll
|
|
167
|
+
* @param filter
|
|
168
|
+
* @returns 被删除记录的数量
|
|
169
|
+
*/
|
|
170
|
+
async deleteMany(coll, filter) {
|
|
171
|
+
if (!Object.keys(filter).length) {
|
|
172
|
+
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
173
|
+
}
|
|
174
|
+
return this.timingQuery({
|
|
175
|
+
query: async () => {
|
|
176
|
+
const res = await this.getCollection(coll).deleteMany(filter, {
|
|
177
|
+
session: this.session
|
|
178
|
+
});
|
|
179
|
+
return res.deletedCount;
|
|
180
|
+
},
|
|
181
|
+
desc() {
|
|
182
|
+
return {
|
|
183
|
+
op: 'deleteMany',
|
|
184
|
+
coll: coll.collectionName,
|
|
185
|
+
filter
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 查询集合中所有记录.谨慎使用!
|
|
192
|
+
* @param coll
|
|
193
|
+
* @returns
|
|
194
|
+
*/
|
|
195
|
+
async findAll(coll) {
|
|
196
|
+
return this.timingQuery({
|
|
197
|
+
query: async () => {
|
|
198
|
+
const arr = await this.getCollection(coll).find({}, { session: this.session }).toArray();
|
|
199
|
+
return arr;
|
|
200
|
+
},
|
|
201
|
+
desc() {
|
|
202
|
+
return {
|
|
203
|
+
op: 'findAll',
|
|
204
|
+
coll: coll.collectionName
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 根据给定的条件查找第一条符合条件的记录
|
|
211
|
+
* @param coll
|
|
212
|
+
* @param filter
|
|
213
|
+
* @returns
|
|
214
|
+
*/
|
|
215
|
+
async findFirst(coll, filter) {
|
|
216
|
+
return this.timingQuery({
|
|
217
|
+
query: async () => {
|
|
218
|
+
const res = await this.getCollection(coll).findOne(filter, {
|
|
219
|
+
limit: 1,
|
|
220
|
+
session: this.session
|
|
221
|
+
});
|
|
222
|
+
return res;
|
|
223
|
+
},
|
|
224
|
+
desc() {
|
|
225
|
+
return {
|
|
226
|
+
op: 'findFirst',
|
|
227
|
+
coll: coll.collectionName,
|
|
228
|
+
filter
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* 插入新记录
|
|
235
|
+
* @param coll
|
|
236
|
+
* @param data
|
|
237
|
+
* @returns
|
|
238
|
+
*/
|
|
239
|
+
async insert(coll, data) {
|
|
240
|
+
return this.timingQuery({
|
|
241
|
+
query: async () => {
|
|
242
|
+
// 创建时间和更新时间
|
|
243
|
+
if (coll.createdDate) {
|
|
244
|
+
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime();
|
|
245
|
+
data[coll.createdDate.field] = createdData;
|
|
246
|
+
}
|
|
247
|
+
if (coll.updatedDate) {
|
|
248
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
249
|
+
data[coll.updatedDate.field] = updatedDate;
|
|
250
|
+
}
|
|
251
|
+
const collection = this.getCollection(coll);
|
|
252
|
+
const res = await collection.insertOne(data, { session: this.session });
|
|
253
|
+
if (data._id) {
|
|
254
|
+
return data;
|
|
255
|
+
}
|
|
256
|
+
data._id = res.insertedId;
|
|
257
|
+
return data;
|
|
258
|
+
},
|
|
259
|
+
desc() {
|
|
260
|
+
return {
|
|
261
|
+
op: 'insert',
|
|
262
|
+
coll: coll.collectionName,
|
|
263
|
+
data
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 插入多条,批量插入.
|
|
270
|
+
* @param coll
|
|
271
|
+
* @param list
|
|
272
|
+
*/
|
|
273
|
+
async insertMany(coll, list) {
|
|
274
|
+
return this.timingQuery({
|
|
275
|
+
query: async () => {
|
|
276
|
+
const docList = list.map(data => {
|
|
277
|
+
// 创建时间和更新时间
|
|
278
|
+
if (coll.createdDate) {
|
|
279
|
+
const createdData = coll.createdDate.type === 'date' ? new Date() : new Date().getTime();
|
|
280
|
+
data[coll.createdDate.field] = createdData;
|
|
281
|
+
}
|
|
282
|
+
if (coll.updatedDate) {
|
|
283
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
284
|
+
data[coll.updatedDate.field] = updatedDate;
|
|
285
|
+
}
|
|
286
|
+
return data;
|
|
287
|
+
});
|
|
288
|
+
const collection = this.getCollection(coll);
|
|
289
|
+
const res = await collection.insertMany(docList, { session: this.session });
|
|
290
|
+
docList.forEach((doc, idx) => {
|
|
291
|
+
if (doc._id) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (res.insertedIds[idx]) {
|
|
295
|
+
doc._id = res.insertedIds[idx];
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
return docList;
|
|
299
|
+
},
|
|
300
|
+
desc() {
|
|
301
|
+
return {
|
|
302
|
+
op: 'insertMany',
|
|
303
|
+
coll: coll.collectionName,
|
|
304
|
+
list
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* 更新,更新完整的文档内容。
|
|
311
|
+
* @param coll 集合信息
|
|
312
|
+
* @param data 要更新的数据,必须包含 _id 字段,支持 mongo 更新语法 $inc 等
|
|
313
|
+
* @returns 返回最新的数据
|
|
314
|
+
* @throws MongoDBException 当无法完成更新时抛出
|
|
315
|
+
*/
|
|
316
|
+
async update(coll, data) {
|
|
317
|
+
return this.timingQuery({
|
|
318
|
+
query: async () => {
|
|
319
|
+
const id = data._id;
|
|
320
|
+
if (!id) {
|
|
321
|
+
throw new exception_1.MongoDBException(`Cannot update a document without an id,collection name:${coll.collectionName}`);
|
|
322
|
+
}
|
|
323
|
+
delete data._id;
|
|
324
|
+
let createData = undefined;
|
|
325
|
+
// 保护创建时间不被更新
|
|
326
|
+
if (coll.createdDate && data[coll.createdDate.field]) {
|
|
327
|
+
createData = data[coll.createdDate.field];
|
|
328
|
+
delete data[coll.createdDate.field];
|
|
329
|
+
}
|
|
330
|
+
// 更新时间
|
|
331
|
+
if (coll.updatedDate) {
|
|
332
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
333
|
+
data[coll.updatedDate.field] = updatedDate;
|
|
334
|
+
}
|
|
335
|
+
const res = await this.getCollection(coll).updateOne({ _id: id }, { $set: data }, {
|
|
336
|
+
session: this.session
|
|
337
|
+
});
|
|
338
|
+
if (res.modifiedCount !== 1) {
|
|
339
|
+
throw new exception_1.MongoDBException(`Failed to update record, possibly due to non-existent record,collection:${coll.collectionName},id:${id}`);
|
|
340
|
+
}
|
|
341
|
+
data._id = id;
|
|
342
|
+
if (coll.createdDate && createData) {
|
|
343
|
+
data[coll.createdDate.field] = createData;
|
|
344
|
+
}
|
|
345
|
+
return data;
|
|
346
|
+
},
|
|
347
|
+
desc() {
|
|
348
|
+
return {
|
|
349
|
+
op: 'update',
|
|
350
|
+
coll: coll.collectionName,
|
|
351
|
+
data
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* 仅更新一条记录
|
|
358
|
+
* @param coll
|
|
359
|
+
* @param filter
|
|
360
|
+
* @param updater
|
|
361
|
+
*/
|
|
362
|
+
async updateOne(coll, filter, updater) {
|
|
363
|
+
if (!Object.keys(filter).length) {
|
|
364
|
+
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
365
|
+
}
|
|
366
|
+
if (!Object.keys(updater).length) {
|
|
367
|
+
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
368
|
+
}
|
|
369
|
+
return this.timingQuery({
|
|
370
|
+
query: async () => {
|
|
371
|
+
// 更新时间处理
|
|
372
|
+
if (coll.updatedDate) {
|
|
373
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
374
|
+
if (updater.$set) {
|
|
375
|
+
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const res = await this.getCollection(coll).updateOne(filter, updater, {
|
|
382
|
+
session: this.session
|
|
383
|
+
});
|
|
384
|
+
return res.modifiedCount === 1;
|
|
385
|
+
},
|
|
386
|
+
desc() {
|
|
387
|
+
return {
|
|
388
|
+
op: 'updateOne',
|
|
389
|
+
coll: coll.collectionName,
|
|
390
|
+
filter,
|
|
391
|
+
updator: updater
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* 局部更新,仅更新部分字段,可对字段做递增或数组元组的处理。
|
|
398
|
+
* @param coll 集合信息
|
|
399
|
+
* @param id id
|
|
400
|
+
* @param updater 更新内容
|
|
401
|
+
* @returns 更新是否成功
|
|
402
|
+
*/
|
|
403
|
+
async partialUpdate(coll, id, updater) {
|
|
404
|
+
if (!Object.keys(updater).length) {
|
|
405
|
+
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
406
|
+
}
|
|
407
|
+
return this.timingQuery({
|
|
408
|
+
query: async () => {
|
|
409
|
+
// 更新时间处理
|
|
410
|
+
if (coll.updatedDate) {
|
|
411
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
412
|
+
if (updater.$set) {
|
|
413
|
+
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const res = await this.getCollection(coll).updateOne({ _id: id }, updater, {
|
|
420
|
+
session: this.session
|
|
421
|
+
});
|
|
422
|
+
return res.modifiedCount === 1;
|
|
423
|
+
},
|
|
424
|
+
desc() {
|
|
425
|
+
return {
|
|
426
|
+
op: 'partialUpdate',
|
|
427
|
+
coll: coll.collectionName,
|
|
428
|
+
id,
|
|
429
|
+
updator: updater
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* 根据条件更新多条记录,和 partialUpdate 区别是可以根据过滤条件来处理多条记录。
|
|
436
|
+
* @param coll 集合
|
|
437
|
+
* @param filter 过滤规则
|
|
438
|
+
* @param updater 更新内容
|
|
439
|
+
* @returns 此次更新的记录数
|
|
440
|
+
*/
|
|
441
|
+
async updateMany(coll, filter, updater) {
|
|
442
|
+
if (!Object.keys(filter).length) {
|
|
443
|
+
throw new exception_1.MongoDBException('filter cannot be empty !');
|
|
444
|
+
}
|
|
445
|
+
if (!Object.keys(updater).length) {
|
|
446
|
+
throw new exception_1.MongoDBException('updater cannot be empty !');
|
|
447
|
+
}
|
|
448
|
+
return this.timingQuery({
|
|
449
|
+
query: async () => {
|
|
450
|
+
// 更新时间处理
|
|
451
|
+
if (coll.updatedDate) {
|
|
452
|
+
const updatedDate = coll.updatedDate.type === 'date' ? new Date() : new Date().getTime();
|
|
453
|
+
if (updater.$set) {
|
|
454
|
+
updater.$set[coll.updatedDate.field] = updatedDate;
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
updater.$set = { [coll.updatedDate.field]: updatedDate };
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const res = await this.getCollection(coll).updateMany(filter, updater, {
|
|
461
|
+
session: this.session
|
|
462
|
+
});
|
|
463
|
+
return res.modifiedCount;
|
|
464
|
+
},
|
|
465
|
+
desc() {
|
|
466
|
+
return {
|
|
467
|
+
op: 'updateMany',
|
|
468
|
+
coll: coll.collectionName,
|
|
469
|
+
filter,
|
|
470
|
+
updator: updater
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* 条件查询
|
|
477
|
+
* @param coll 集合信息
|
|
478
|
+
* @param filter 过滤条件
|
|
479
|
+
* @param opts 额外的选项
|
|
480
|
+
* @returns
|
|
481
|
+
*/
|
|
482
|
+
async find(coll, filter, opts) {
|
|
483
|
+
return this.timingQuery({
|
|
484
|
+
query: async () => {
|
|
485
|
+
const arr = await this.getCollection(coll)
|
|
486
|
+
.find(filter, {
|
|
487
|
+
limit: opts && opts.limit && opts.limit > 0 ? opts.limit : undefined,
|
|
488
|
+
skip: opts && opts.limit && opts.limit > 0 && opts.offset && opts.offset > 0
|
|
489
|
+
? opts.offset
|
|
490
|
+
: undefined,
|
|
491
|
+
sort: opts && opts.orderBy ? opts.orderBy : undefined,
|
|
492
|
+
session: this.session
|
|
493
|
+
})
|
|
494
|
+
.toArray();
|
|
495
|
+
return arr;
|
|
496
|
+
},
|
|
497
|
+
desc() {
|
|
498
|
+
return {
|
|
499
|
+
op: 'find',
|
|
500
|
+
coll: coll.collectionName,
|
|
501
|
+
filter,
|
|
502
|
+
opts
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* 查询符合条件的文档数量。请谨慎使用,count 是不能从索引直接读取的,只能实时计数,使用不当容易造成性能问题,引发线上事故。
|
|
509
|
+
* @param coll
|
|
510
|
+
* @param filter
|
|
511
|
+
* @returns
|
|
512
|
+
*/
|
|
513
|
+
count(coll, filter) {
|
|
514
|
+
return this.timingQuery({
|
|
515
|
+
query: async () => {
|
|
516
|
+
return this.getCollection(coll).countDocuments(filter, { session: this.session });
|
|
517
|
+
},
|
|
518
|
+
desc() {
|
|
519
|
+
return {
|
|
520
|
+
op: 'count',
|
|
521
|
+
coll: coll.collectionName,
|
|
522
|
+
filter
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* 分页查询。谨慎使用,不建议对规模较大的数据查询直接使用分页。
|
|
529
|
+
* @param coll 集合信息
|
|
530
|
+
* @param filter 过滤条件
|
|
531
|
+
* @param opts 分页参数
|
|
532
|
+
*/
|
|
533
|
+
async paginate(coll, filter, opts) {
|
|
534
|
+
(0, validation_1.validate)(opts, {
|
|
535
|
+
pn: [(0, validation_1.notNull)(), (0, validation_1.min)(1)],
|
|
536
|
+
pz: [(0, validation_1.notNull)(), (0, validation_1.min)(1)]
|
|
537
|
+
});
|
|
538
|
+
const start = new Date().getTime();
|
|
539
|
+
try {
|
|
540
|
+
const offset = (opts.pn - 1) * opts.pz;
|
|
541
|
+
const res = await Promise.all([
|
|
542
|
+
this.find(coll, filter, { offset, limit: opts.pz, orderBy: opts.orderBy }),
|
|
543
|
+
this.count(coll, filter)
|
|
544
|
+
]);
|
|
545
|
+
const [list, total] = res;
|
|
546
|
+
return { list, total };
|
|
547
|
+
}
|
|
548
|
+
finally {
|
|
549
|
+
if (this.config.slowQueryWarn) {
|
|
550
|
+
const cost = new Date().getTime() - start;
|
|
551
|
+
if (cost > this.config.slowQueryMs) {
|
|
552
|
+
(0, log_1.getLogger)().warn(`[mongodb slow query] ${cost}ms ${JSON.stringify({
|
|
553
|
+
op: 'paginate',
|
|
554
|
+
coll: coll.collectionName,
|
|
555
|
+
filter,
|
|
556
|
+
opts
|
|
557
|
+
})}`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
exports.BaseMongoManager = BaseMongoManager;
|