wok-server 0.4.13 → 0.5.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/dist/log/config.js +7 -1
- package/dist/log/file.js +175 -49
- package/dist/log/index.js +76 -46
- package/dist/log/log.js +56 -0
- package/dist/log/store.js +3 -0
- package/dist/mysql/manager/base.js +8 -0
- package/dist/mysql/manager/ops/find.js +40 -1
- package/dist/mysql/manager/tx-strict.js +3 -0
- package/documentation/zh-cn/engineering.md +1 -1
- package/documentation/zh-cn/log.md +81 -8
- package/documentation/zh-cn/mysql.md +24 -23
- package/documentation/zh-cn/validate.md +2 -2
- package/package.json +1 -1
- package/types/log/config.d.ts +8 -0
- package/types/log/file.d.ts +10 -2
- package/types/log/index.d.ts +25 -6
- package/types/log/log.d.ts +40 -0
- package/types/log/store.d.ts +8 -1
- package/types/mysql/manager/base.d.ts +7 -1
- package/types/mysql/manager/ops/find.d.ts +16 -0
- package/types/mysql/manager/tx-strict.d.ts +2 -1
package/dist/log/config.js
CHANGED
|
@@ -6,11 +6,15 @@ const config_1 = require("../config");
|
|
|
6
6
|
const validation_1 = require("../validation");
|
|
7
7
|
const level_1 = require("./level");
|
|
8
8
|
const envConfig = (0, config_1.registerConfig)({
|
|
9
|
+
console: true,
|
|
10
|
+
format: 'text',
|
|
9
11
|
file: false,
|
|
10
12
|
fileDir: 'logs',
|
|
11
13
|
fileMaxDays: 30,
|
|
12
14
|
level: 'INFO'
|
|
13
15
|
}, 'LOG', {
|
|
16
|
+
console: [(0, validation_1.notNull)()],
|
|
17
|
+
format: [(0, validation_1.notNull)()],
|
|
14
18
|
file: [(0, validation_1.notNull)()],
|
|
15
19
|
fileDir: [(0, validation_1.notBlank)()],
|
|
16
20
|
fileMaxDays: [(0, validation_1.min)(1)],
|
|
@@ -25,5 +29,7 @@ exports.config = Object.freeze({
|
|
|
25
29
|
file: envConfig.file,
|
|
26
30
|
fileDir,
|
|
27
31
|
fileMaxDays: envConfig.fileMaxDays,
|
|
28
|
-
level: (0, level_1.parseLogLevel)(level)
|
|
32
|
+
level: (0, level_1.parseLogLevel)(level),
|
|
33
|
+
console: envConfig.console,
|
|
34
|
+
format: envConfig.format
|
|
29
35
|
});
|
package/dist/log/file.js
CHANGED
|
@@ -1,72 +1,198 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fileStore = void 0;
|
|
3
|
+
exports.flushLogsToFile = exports.fileStore = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const promises_1 = require("fs/promises");
|
|
6
6
|
const os_1 = require("os");
|
|
7
7
|
const path_1 = require("path");
|
|
8
|
-
const task_1 = require("../task");
|
|
9
8
|
const config_1 = require("./config");
|
|
10
|
-
|
|
9
|
+
const log_1 = require("./log");
|
|
10
|
+
// 日志队列
|
|
11
|
+
let LOG_QUEUE = [];
|
|
12
|
+
// 最大缓冲数量
|
|
13
|
+
const MAX_QUEUE_SIZE = 1024;
|
|
14
|
+
// 写入定时器
|
|
15
|
+
let WRITE_TIMER = null;
|
|
16
|
+
// 延迟写入时间(毫秒)
|
|
17
|
+
const WRITE_DELAY = 100;
|
|
18
|
+
// 是否已经安排了清理任务
|
|
19
|
+
let CLEANUP_SCHEDULED = false;
|
|
20
|
+
// 清理任务定时器
|
|
21
|
+
let CLEANUP_TIMER = null;
|
|
11
22
|
/**
|
|
12
23
|
* 文件存储.
|
|
13
|
-
* @param log
|
|
24
|
+
* @param log 日志对象
|
|
25
|
+
* @param logConfig 日志配置
|
|
14
26
|
*/
|
|
15
|
-
function fileStore(log) {
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
function fileStore(log, logConfig) {
|
|
28
|
+
// 将日志添加到队列
|
|
29
|
+
LOG_QUEUE.push(log);
|
|
30
|
+
// 如果队列超过最大缓冲数量,立即写入
|
|
31
|
+
if (LOG_QUEUE.length >= MAX_QUEUE_SIZE) {
|
|
32
|
+
writeLogs(logConfig).catch(e => console.error('Writing log file failed', e));
|
|
33
|
+
// 在写入前检查是否需要安排清理任务
|
|
34
|
+
if (!CLEANUP_SCHEDULED) {
|
|
35
|
+
scheduleCleanupTask(logConfig);
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// 安排延迟写入
|
|
40
|
+
if (!WRITE_TIMER) {
|
|
41
|
+
WRITE_TIMER = setTimeout(() => {
|
|
42
|
+
WRITE_TIMER = null;
|
|
43
|
+
writeLogs(logConfig).catch(e => console.error('Writing log file failed', e));
|
|
44
|
+
}, WRITE_DELAY);
|
|
45
|
+
}
|
|
46
|
+
// 如果启用了文件存储并且还没有安排清理任务,则安排清理任务
|
|
47
|
+
if (!CLEANUP_SCHEDULED) {
|
|
48
|
+
scheduleCleanupTask(logConfig);
|
|
49
|
+
}
|
|
18
50
|
}
|
|
19
51
|
exports.fileStore = fileStore;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
52
|
+
/**
|
|
53
|
+
* 根据日期构建日志文件路径
|
|
54
|
+
* @param logConfig 日志配置
|
|
55
|
+
* @param dateKey 数字键 (格式:年*10000 + 月*100 + 日)
|
|
56
|
+
* @returns 日志文件路径
|
|
57
|
+
*/
|
|
58
|
+
function buildFilePathByDate(logConfig, dateKey) {
|
|
59
|
+
const fileName = `${dateKey}.log`;
|
|
60
|
+
// 确保目录是绝对路径
|
|
61
|
+
let fileDir = logConfig.fileDir;
|
|
62
|
+
if (!(0, path_1.isAbsolute)(fileDir)) {
|
|
63
|
+
fileDir = (0, path_1.resolve)(process.cwd(), fileDir);
|
|
64
|
+
}
|
|
65
|
+
return (0, path_1.resolve)(fileDir, fileName);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 根据日期对象计算数字键
|
|
69
|
+
* @param date 日期对象
|
|
70
|
+
* @returns 数字键 (格式:年*10000 + 月*100 + 日)
|
|
71
|
+
*/
|
|
72
|
+
function calculateDateKey(date) {
|
|
73
|
+
const year = date.getFullYear();
|
|
74
|
+
const month = date.getMonth() + 1; // 转换为1-12
|
|
26
75
|
const day = date.getDate();
|
|
27
|
-
|
|
28
|
-
fileName += '.log';
|
|
29
|
-
return (0, path_1.resolve)(config_1.config.fileDir, fileName);
|
|
76
|
+
return year * 10000 + month * 100 + day;
|
|
30
77
|
}
|
|
31
|
-
|
|
32
|
-
|
|
78
|
+
/**
|
|
79
|
+
* 写入日志到文件
|
|
80
|
+
* @param logConfig 日志配置
|
|
81
|
+
*/
|
|
82
|
+
async function writeLogs(logConfig) {
|
|
83
|
+
if (!LOG_QUEUE.length || !logConfig.file) {
|
|
33
84
|
return;
|
|
34
85
|
}
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
86
|
+
// 复制队列并清空原始队列
|
|
87
|
+
const logsToWrite = [...LOG_QUEUE];
|
|
88
|
+
LOG_QUEUE = [];
|
|
89
|
+
// 按日期对日志进行分组 - 使用数字键提升性能
|
|
90
|
+
const logsByDate = new Map();
|
|
91
|
+
logsToWrite.forEach(log => {
|
|
92
|
+
const logDate = new Date(log.time);
|
|
93
|
+
// 直接使用日期对象计算数字键
|
|
94
|
+
const dateKey = calculateDateKey(logDate);
|
|
95
|
+
const dateLogs = logsByDate.get(dateKey);
|
|
96
|
+
if (dateLogs) {
|
|
97
|
+
dateLogs.push(log);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
logsByDate.set(dateKey, [log]);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
// 为每个日期组写入对应的日志文件
|
|
104
|
+
for (const [dateKey, dateLogs] of logsByDate.entries()) {
|
|
105
|
+
// 直接使用数字键构建文件路径
|
|
106
|
+
const filePath = buildFilePathByDate(logConfig, dateKey);
|
|
107
|
+
const dir = (0, path_1.dirname)(filePath);
|
|
108
|
+
// 确保目录存在
|
|
109
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
110
|
+
await (0, promises_1.mkdir)(dir, { recursive: true });
|
|
111
|
+
}
|
|
112
|
+
// 格式化并写入该日期的所有日志
|
|
113
|
+
const lines = dateLogs
|
|
114
|
+
.map(log => (logConfig.format === 'json' ? (0, log_1.formatLogJson)(log) : (0, log_1.formatLogText)(log)))
|
|
115
|
+
.join(os_1.EOL);
|
|
116
|
+
try {
|
|
117
|
+
await (0, promises_1.appendFile)(filePath, lines);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error(`Failed to write logs for date ${dateKey}:`, error);
|
|
121
|
+
// 继续处理下一个日期的日志,不中断整个写入过程
|
|
122
|
+
}
|
|
39
123
|
}
|
|
40
|
-
const lines = QUEUE.join(os_1.EOL);
|
|
41
|
-
QUEUE = [];
|
|
42
|
-
await (0, promises_1.appendFile)(path, lines);
|
|
43
124
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
125
|
+
/**
|
|
126
|
+
* 执行日志清理任务
|
|
127
|
+
* @param logConfig 日志配置
|
|
128
|
+
*/
|
|
129
|
+
async function performCleanupTask(logConfig) {
|
|
130
|
+
try {
|
|
131
|
+
let dir = logConfig.fileDir;
|
|
132
|
+
if (!(0, path_1.isAbsolute)(dir)) {
|
|
133
|
+
dir = (0, path_1.resolve)(process.cwd(), dir);
|
|
134
|
+
}
|
|
135
|
+
// 确保目录存在
|
|
136
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const files = await (0, promises_1.readdir)(dir);
|
|
140
|
+
const now = new Date().getTime();
|
|
141
|
+
const maxAge = logConfig.fileMaxDays * 24 * 3600 * 1000;
|
|
142
|
+
for (const file of files) {
|
|
143
|
+
try {
|
|
144
|
+
// 获取文件的完整路径
|
|
145
|
+
const filePath = (0, path_1.resolve)(dir, file);
|
|
146
|
+
// 获取文件的最后修改时间
|
|
147
|
+
const fileStats = (0, fs_1.statSync)(filePath);
|
|
148
|
+
const lastModifiedTime = fileStats.mtime.getTime();
|
|
149
|
+
// 检查文件是否过期(最后修改时间早于最大保留天数)
|
|
150
|
+
if (lastModifiedTime + maxAge < now) {
|
|
66
151
|
console.warn(`Remove log file: ${file}`);
|
|
67
|
-
await (0, promises_1.rm)(
|
|
152
|
+
await (0, promises_1.rm)(filePath);
|
|
68
153
|
}
|
|
69
154
|
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
console.error(`Failed to process log file ${file}:`, error);
|
|
157
|
+
// 继续处理下一个文件,不中断清理过程
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
70
160
|
}
|
|
71
|
-
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error('Error during log cleanup:', error);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
// 清理完成后,重置清理任务安排状态
|
|
167
|
+
CLEANUP_SCHEDULED = false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 安排日志清理任务
|
|
172
|
+
* @param logConfig 日志配置
|
|
173
|
+
*/
|
|
174
|
+
function scheduleCleanupTask(logConfig) {
|
|
175
|
+
CLEANUP_SCHEDULED = true;
|
|
176
|
+
// 清除现有的清理定时器
|
|
177
|
+
if (CLEANUP_TIMER) {
|
|
178
|
+
clearTimeout(CLEANUP_TIMER);
|
|
179
|
+
}
|
|
180
|
+
// 设置清理任务在一天后执行
|
|
181
|
+
const delay = 24 * 60 * 60 * 1000;
|
|
182
|
+
CLEANUP_TIMER = setTimeout(() => {
|
|
183
|
+
CLEANUP_TIMER = null;
|
|
184
|
+
performCleanupTask(logConfig).catch(e => console.error('Cleanup task failed', e));
|
|
185
|
+
}, delay);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 确保所有日志都被写入文件
|
|
189
|
+
* 可以在应用程序关闭时调用
|
|
190
|
+
*/
|
|
191
|
+
async function flushLogsToFile() {
|
|
192
|
+
if (WRITE_TIMER) {
|
|
193
|
+
clearTimeout(WRITE_TIMER);
|
|
194
|
+
WRITE_TIMER = null;
|
|
195
|
+
}
|
|
196
|
+
await writeLogs(config_1.config);
|
|
72
197
|
}
|
|
198
|
+
exports.flushLogsToFile = flushLogsToFile;
|
package/dist/log/index.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setLogStore = exports.getLogger = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const os_1 = require("os");
|
|
6
5
|
const config_1 = require("./config");
|
|
7
|
-
const date_1 = require("./date");
|
|
8
6
|
const file_1 = require("./file");
|
|
9
7
|
const level_1 = require("./level");
|
|
8
|
+
const log_1 = require("./log");
|
|
10
9
|
const store_1 = require("./store");
|
|
11
10
|
/**
|
|
12
11
|
* 文件存储
|
|
@@ -14,92 +13,123 @@ const store_1 = require("./store");
|
|
|
14
13
|
if (config_1.config.file) {
|
|
15
14
|
(0, store_1.setLogStore)(file_1.fileStore);
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* @param error
|
|
22
|
-
*/
|
|
23
|
-
function log(level, message, error) {
|
|
24
|
-
if (level < config_1.config.level) {
|
|
25
|
-
return;
|
|
16
|
+
class Logger {
|
|
17
|
+
prefix;
|
|
18
|
+
constructor(prefix) {
|
|
19
|
+
this.prefix = prefix;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
21
|
+
/**
|
|
22
|
+
* 输出日志
|
|
23
|
+
* @param level
|
|
24
|
+
* @param message
|
|
25
|
+
* @param error
|
|
26
|
+
*/
|
|
27
|
+
log(level, message, error) {
|
|
28
|
+
if (level < config_1.config.level) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const log = {
|
|
32
|
+
level,
|
|
33
|
+
content: message,
|
|
34
|
+
time: new Date(),
|
|
35
|
+
prefix: this.prefix,
|
|
36
|
+
error
|
|
37
|
+
};
|
|
38
|
+
// 控制台输出日志
|
|
39
|
+
if (config_1.config.console) {
|
|
40
|
+
// const msg = config.format === 'text' ? formatLogText(log, true) : formatLogJson(log, true)
|
|
41
|
+
// 控制台强制使用 text 格式,json 格式只在文件中输出
|
|
42
|
+
const msg = (0, log_1.formatLogText)(log, true);
|
|
43
|
+
switch (level) {
|
|
44
|
+
case level_1.LogLevel.DEBUG:
|
|
45
|
+
console.debug(msg);
|
|
46
|
+
break;
|
|
47
|
+
case level_1.LogLevel.INFO:
|
|
48
|
+
console.info(msg);
|
|
49
|
+
break;
|
|
50
|
+
case level_1.LogLevel.WARN:
|
|
51
|
+
console.warn(msg);
|
|
52
|
+
break;
|
|
53
|
+
case level_1.LogLevel.ERROR:
|
|
54
|
+
console.error(msg);
|
|
55
|
+
break;
|
|
43
56
|
}
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
if (error) {
|
|
58
|
+
console.error(error);
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
|
-
|
|
61
|
+
// 自定义存储中输出日志
|
|
62
|
+
const store = (0, store_1.getLogStore)();
|
|
63
|
+
if (store) {
|
|
64
|
+
store(log, config_1.config);
|
|
65
|
+
}
|
|
49
66
|
}
|
|
50
|
-
}
|
|
51
|
-
const logger = Object.freeze({
|
|
52
67
|
/**
|
|
53
68
|
* debug 日志
|
|
54
69
|
*/
|
|
55
70
|
debug(message) {
|
|
56
|
-
log(level_1.LogLevel.DEBUG, message);
|
|
57
|
-
}
|
|
71
|
+
this.log(level_1.LogLevel.DEBUG, message);
|
|
72
|
+
}
|
|
58
73
|
isDebugEnabled() {
|
|
59
74
|
return level_1.LogLevel.DEBUG >= config_1.config.level;
|
|
60
|
-
}
|
|
75
|
+
}
|
|
61
76
|
/**
|
|
62
77
|
* info 日志
|
|
63
78
|
* @param message
|
|
64
79
|
*/
|
|
65
80
|
info(message) {
|
|
66
|
-
log(level_1.LogLevel.INFO, message);
|
|
67
|
-
}
|
|
81
|
+
this.log(level_1.LogLevel.INFO, message);
|
|
82
|
+
}
|
|
68
83
|
isInfoEnabled() {
|
|
69
84
|
return level_1.LogLevel.INFO >= config_1.config.level;
|
|
70
|
-
}
|
|
85
|
+
}
|
|
71
86
|
/**
|
|
72
87
|
* 警告日志
|
|
73
88
|
* @param message
|
|
74
89
|
* @param error
|
|
75
90
|
*/
|
|
76
91
|
warn(message, error) {
|
|
77
|
-
log(level_1.LogLevel.WARN, message, error);
|
|
78
|
-
}
|
|
92
|
+
this.log(level_1.LogLevel.WARN, message, error);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 等同于 warn
|
|
96
|
+
* @param message
|
|
97
|
+
* @param error
|
|
98
|
+
*/
|
|
99
|
+
warning(message, error) {
|
|
100
|
+
this.log(level_1.LogLevel.WARN, message, error);
|
|
101
|
+
}
|
|
79
102
|
isWarnEnabled() {
|
|
80
103
|
return level_1.LogLevel.WARN >= config_1.config.level;
|
|
81
|
-
}
|
|
104
|
+
}
|
|
82
105
|
/**
|
|
83
106
|
* 错误日志
|
|
84
107
|
* @param message
|
|
85
108
|
* @param error
|
|
86
109
|
*/
|
|
87
110
|
error(message, error) {
|
|
88
|
-
log(level_1.LogLevel.ERROR, message, error);
|
|
89
|
-
}
|
|
111
|
+
this.log(level_1.LogLevel.ERROR, message, error);
|
|
112
|
+
}
|
|
90
113
|
isErrorEnabled() {
|
|
91
114
|
return level_1.LogLevel.ERROR >= config_1.config.level;
|
|
92
115
|
}
|
|
93
|
-
}
|
|
116
|
+
}
|
|
117
|
+
const defaultLogger = new Logger();
|
|
94
118
|
/**
|
|
95
119
|
* 获取日志对象.
|
|
120
|
+
*
|
|
121
|
+
* @param prefix 日志前缀,如果有值,每条日志前都会加上前缀信息
|
|
96
122
|
* @returns
|
|
97
123
|
*/
|
|
98
|
-
function getLogger() {
|
|
99
|
-
|
|
124
|
+
function getLogger(prefix) {
|
|
125
|
+
if (prefix) {
|
|
126
|
+
return new Logger(prefix);
|
|
127
|
+
}
|
|
128
|
+
return defaultLogger;
|
|
100
129
|
}
|
|
101
130
|
exports.getLogger = getLogger;
|
|
102
131
|
tslib_1.__exportStar(require("./config"), exports);
|
|
103
132
|
tslib_1.__exportStar(require("./level"), exports);
|
|
133
|
+
tslib_1.__exportStar(require("./log"), exports);
|
|
104
134
|
var store_2 = require("./store");
|
|
105
135
|
Object.defineProperty(exports, "setLogStore", { enumerable: true, get: function () { return store_2.setLogStore; } });
|
package/dist/log/log.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatLogJson = exports.formatLogText = void 0;
|
|
4
|
+
const os_1 = require("os");
|
|
5
|
+
const date_1 = require("./date");
|
|
6
|
+
const level_1 = require("./level");
|
|
7
|
+
/**
|
|
8
|
+
* 将日志格式化为简单的文本
|
|
9
|
+
* @param log
|
|
10
|
+
* @param ignoreError 忽略异常信息
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
function formatLogText(log, ignoreError = false) {
|
|
14
|
+
let str = `[${(0, date_1.formatDateTime)(log.time)}][${level_1.LogLevel[log.level]}]${log.prefix ? `[${log.prefix}]` : ''}${log.content}`;
|
|
15
|
+
if (log.error && !ignoreError) {
|
|
16
|
+
if (log.error.stack) {
|
|
17
|
+
str += os_1.EOL + log.error.stack;
|
|
18
|
+
}
|
|
19
|
+
else if (log.error.message) {
|
|
20
|
+
str += os_1.EOL + log.error.message;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
str += os_1.EOL + log.error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return str;
|
|
27
|
+
}
|
|
28
|
+
exports.formatLogText = formatLogText;
|
|
29
|
+
/**
|
|
30
|
+
* 将日志格式化为 json
|
|
31
|
+
* @param log
|
|
32
|
+
* @param ignoreError 忽略异常信息
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
function formatLogJson(log, ignoreError = false) {
|
|
36
|
+
let error;
|
|
37
|
+
if (log.error && !ignoreError) {
|
|
38
|
+
error = '';
|
|
39
|
+
if (log.error.stack) {
|
|
40
|
+
error += log.error.stack;
|
|
41
|
+
}
|
|
42
|
+
else if (log.error.message) {
|
|
43
|
+
error += log.error.message;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
error += log.error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const json = { ...log };
|
|
50
|
+
delete json.error;
|
|
51
|
+
if (error) {
|
|
52
|
+
json.error = error;
|
|
53
|
+
}
|
|
54
|
+
return JSON.stringify(json);
|
|
55
|
+
}
|
|
56
|
+
exports.formatLogJson = formatLogJson;
|
package/dist/log/store.js
CHANGED
|
@@ -192,6 +192,14 @@ class BaseMysqlManager {
|
|
|
192
192
|
find(opts) {
|
|
193
193
|
return this.queryWithConnection(conn => (0, ops_1.find)(this.opts.config, conn, opts));
|
|
194
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* 指定字段条件查询
|
|
197
|
+
* @param opts
|
|
198
|
+
* @returns
|
|
199
|
+
*/
|
|
200
|
+
findSelect(opts) {
|
|
201
|
+
return this.queryWithConnection(conn => (0, ops_1.findSelect)(this.opts.config, conn, opts));
|
|
202
|
+
}
|
|
195
203
|
/**
|
|
196
204
|
* 指定条件查询数量
|
|
197
205
|
* @param table 表信息
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findFirst = exports.findByIdIn = exports.find = exports.findAll = exports.findById = void 0;
|
|
3
|
+
exports.findFirst = exports.findByIdIn = exports.findSelect = exports.find = exports.findAll = exports.findById = void 0;
|
|
4
4
|
const criteria_1 = require("./criteria");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
/**
|
|
@@ -73,6 +73,45 @@ async function find(config, conn, opts) {
|
|
|
73
73
|
return res;
|
|
74
74
|
}
|
|
75
75
|
exports.find = find;
|
|
76
|
+
/**
|
|
77
|
+
* 查询指定的字段,返回值类型与选择的字段有关
|
|
78
|
+
* @param onfig
|
|
79
|
+
* @param conn
|
|
80
|
+
* @param opts
|
|
81
|
+
*/
|
|
82
|
+
async function findSelect(config, conn, opts) {
|
|
83
|
+
let query = opts.criteria ? (0, criteria_1.buildQuery)(opts.criteria) : undefined;
|
|
84
|
+
const values = [];
|
|
85
|
+
let sql = `select ${opts.select.map(() => '??').join(',')} from ?? `;
|
|
86
|
+
values.push(...opts.select, opts.table.tableName);
|
|
87
|
+
if (query) {
|
|
88
|
+
sql += ` where ${query.sql} `;
|
|
89
|
+
values.push(...query.values);
|
|
90
|
+
}
|
|
91
|
+
// 排序
|
|
92
|
+
if (opts.orderBy && opts.orderBy.length) {
|
|
93
|
+
opts.orderBy.forEach((orderBy, idx) => {
|
|
94
|
+
const [field, sort] = orderBy;
|
|
95
|
+
if (idx == 0) {
|
|
96
|
+
sql += ` order by ?? ${sort} `;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
sql += ` , ?? ${sort} `;
|
|
100
|
+
}
|
|
101
|
+
values.push(field);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// 数量限制
|
|
105
|
+
if (opts.limit) {
|
|
106
|
+
sql += ` limit ${opts.limit} `;
|
|
107
|
+
if (opts.offset) {
|
|
108
|
+
sql += ` offset ${opts.offset}`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const res = await (0, utils_1.promiseQuery)(config, conn, sql, values);
|
|
112
|
+
return res;
|
|
113
|
+
}
|
|
114
|
+
exports.findSelect = findSelect;
|
|
76
115
|
/**
|
|
77
116
|
* 根据 id 列表查询记录
|
|
78
117
|
* @param connection
|
|
@@ -84,6 +84,9 @@ class MysqlStrictTxSession extends tx_1.MysqlTxSession {
|
|
|
84
84
|
find(opts) {
|
|
85
85
|
throw new exception_1.MysqlException('Prohibited to use find in a strict transaction.');
|
|
86
86
|
}
|
|
87
|
+
findSelect(opts) {
|
|
88
|
+
throw new exception_1.MysqlException('Prohibited to use findSelect in a strict transaction.');
|
|
89
|
+
}
|
|
87
90
|
count(table, criteria) {
|
|
88
91
|
throw new exception_1.MysqlException('Prohibited to use count in a strict transaction.');
|
|
89
92
|
}
|
|
@@ -4,12 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
## 环境变量
|
|
6
6
|
|
|
7
|
-
| 环境变量名称 | 默认值 | 说明
|
|
8
|
-
| :---------------- | :----- |
|
|
9
|
-
| LOG_LEVEL | info | 日志级别,低于设定级别的日志将不会输出,取值:DEBUG,INFO,WARN,ERROR
|
|
10
|
-
| LOG_FILE | false | 取值 true 或 false ,表示是否开启文件
|
|
11
|
-
| LOG_FILE_MAX_DAYS | 30 | 数文件的保留天数
|
|
12
|
-
| LOG_FILE_DIR | logs | 日志文件存储路径,支持相对路径和绝对路径,相对路径是相对于进程执行目录的
|
|
7
|
+
| 环境变量名称 | 默认值 | 说明 |
|
|
8
|
+
| :---------------- | :----- | :-------------------------------------------------------------------------------- |
|
|
9
|
+
| LOG_LEVEL | info | 日志级别,低于设定级别的日志将不会输出,取值:DEBUG,INFO,WARN,ERROR |
|
|
10
|
+
| LOG_FILE | false | 取值 true 或 false ,表示是否开启文件 |
|
|
11
|
+
| LOG_FILE_MAX_DAYS | 30 | 数文件的保留天数 |
|
|
12
|
+
| LOG_FILE_DIR | logs | 日志文件存储路径,支持相对路径和绝对路径,相对路径是相对于进程执行目录的 |
|
|
13
|
+
| LOG_CONSOLE | true | 是否输出日志到控制台,0.5 版本新增加 |
|
|
14
|
+
| LOG_FORMAT | text | 输出日志的格式,可设置为 json 或 text, 0.5 版本新增加,注意控制台是强制输出文本的 |
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
## 使用
|
|
15
18
|
|
|
@@ -24,17 +27,87 @@ const err = new Error('错误信息测试')
|
|
|
24
27
|
logger.error('错误日志输出信息', err)
|
|
25
28
|
|
|
26
29
|
if (logger.isDebugEnabled()) {
|
|
27
|
-
logger.debug(
|
|
30
|
+
logger.debug(`调试日志输出, args: ${JSON.stringify(args)}`)
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 判定是否支持某个日志级别
|
|
35
|
+
|
|
36
|
+
日志对象提供了 isDebugEnabled、isInfoEnabled、isWarnEnabled、isErrorEnabled 方法来判定是否支持某个日志级别。
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
if (logger.isDebugEnabled()) {
|
|
40
|
+
logger.debug('调试日志输出')
|
|
28
41
|
}
|
|
29
42
|
```
|
|
30
43
|
|
|
44
|
+
这些方法的作用是判断当前是否支持某个级别,然后再做处理,如果不支持就不构建日志内容。
|
|
45
|
+
一些情况下,可以避免构建日志信息所带来的不必要的开销。
|
|
46
|
+
|
|
47
|
+
## 给日志增加前缀
|
|
48
|
+
|
|
49
|
+
0.5 版本开始,getLogger 函数支持增加前缀,比如:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const logger = getLogger('my-module')
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
这样输出的日志会增加前缀 `[my-module]`,方便区分不同模块的日志。
|
|
56
|
+
|
|
57
|
+
例如,默认无前缀的日志是这样的:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
[2024/08/19 16:27:18.214][INFO]Mysql migration
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
增加前缀后是这样的:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
[2024/08/19 16:27:18.214][INFO][my-module]Mysql migration
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
|
31
70
|
## 自定义日志存储
|
|
32
71
|
|
|
33
72
|
通过函数 setLogStore 可以自定义日志的存储,一旦设置,将会覆盖掉文件存储,即使设置了开启文件,日志也不会输出到文件中。
|
|
34
73
|
|
|
74
|
+
从 0.5 版本开始,日志做了结构化,存储函数的参数是日志对象和配置信息,而不是一个字符串了。
|
|
75
|
+
|
|
76
|
+
|
|
35
77
|
```ts
|
|
36
|
-
setLogStore(log => {
|
|
78
|
+
setLogStore((log: Log, config: LogConfig) => {
|
|
79
|
+
// log 的类型是 Log
|
|
80
|
+
// config 的类型是 LogConfig
|
|
37
81
|
// 可以根据需要将日志内容放入消息队列或独立的文件存储系统中
|
|
38
82
|
messageQueue.push(log)
|
|
39
83
|
})
|
|
40
84
|
```
|
|
85
|
+
|
|
86
|
+
Log 的定义如下:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
export interface Log {
|
|
90
|
+
/**
|
|
91
|
+
* 日志的时间
|
|
92
|
+
*/
|
|
93
|
+
time: Date
|
|
94
|
+
/**
|
|
95
|
+
* 日志的等级
|
|
96
|
+
*/
|
|
97
|
+
level: LogLevel
|
|
98
|
+
/**
|
|
99
|
+
* 日志的内容
|
|
100
|
+
*/
|
|
101
|
+
content: string
|
|
102
|
+
/**
|
|
103
|
+
* 异常信息
|
|
104
|
+
*/
|
|
105
|
+
error?: any
|
|
106
|
+
/**
|
|
107
|
+
* 前缀信息
|
|
108
|
+
*/
|
|
109
|
+
prefix?: string
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
LogConfig 类型则是包含了前面的环境变量配置信息,用于获取配置信息来决定如何处理日志。
|
|
@@ -29,7 +29,7 @@ mysql 组件基于 [mysql2](https://www.npmjs.com/package/mysql2) 封装,提
|
|
|
29
29
|
| MYSQL_SLOW_SQL_MS | 慢 sql 毫秒数,默认 200 |
|
|
30
30
|
| MYSQL_TRANSACTION_TIMEOUT | 事务超时时间,单位毫秒,默认 5000 |
|
|
31
31
|
| MYSQL_TRANSACTION_STRICT | 事务严格模式,默认 true,设置为 false 可关闭严格模式 |
|
|
32
|
-
| MYSQL_MAX_OPS_IN_STRICT_TX | 严格事务中可以执行的操作次数,默认 10
|
|
32
|
+
| MYSQL_MAX_OPS_IN_STRICT_TX | 严格事务中可以执行的操作次数,默认 10 |
|
|
33
33
|
|
|
34
34
|
## 初始化
|
|
35
35
|
|
|
@@ -48,7 +48,7 @@ await enableMysql()
|
|
|
48
48
|
await enableMysql('d2')
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
执行上面的操作后,会自动映射以 `D2_` 为前缀的环境变量。
|
|
52
52
|
|
|
53
53
|
下面是多数据源的环境变量示例:
|
|
54
54
|
|
|
@@ -284,27 +284,28 @@ await manager.modify(`update user set nickname='无名' where nickname='佚名'`
|
|
|
284
284
|
|
|
285
285
|
### 所有操作方法
|
|
286
286
|
|
|
287
|
-
| 方法 | 功能说明
|
|
288
|
-
| :------------ |
|
|
289
|
-
| findById | 按 id 查询
|
|
290
|
-
| findByIdIn | 按 id 列表查询多条记录
|
|
291
|
-
| existsBy | 判定指定的条件是否存在记录
|
|
292
|
-
| existsById | 判定 id 是否存在
|
|
293
|
-
| deleteById | 按 id 删除
|
|
294
|
-
| deleteMany | 按指定条件删除,危险操作,建议尽可能设置 limit 参数来限制数量
|
|
295
|
-
| findAll | 查询表下所有记录,危险操作,建议只对数据量非常小的表使用
|
|
296
|
-
| findFirst | 查询符合条件的第一条记录
|
|
297
|
-
| insert | 插入记录
|
|
298
|
-
| insertMany | 一次性插入多条记录
|
|
299
|
-
| update | 更新记录,需要完整信息
|
|
300
|
-
| partialUpdate | 局部更新,只提供 id 和需要更新的字段信息
|
|
301
|
-
| updateOne | 只更新指定条件的第一条记录,必须是相等条件,不支持范围条件
|
|
302
|
-
| updateMany | 更新所有符合条件的记录,危险操作,建议对条件严加限制,控制受影响的范围
|
|
303
|
-
| find | 按条件查询所有符合条件的记录,危险操作,建议尽可能设置 limit 参数来限制数量
|
|
304
|
-
|
|
|
305
|
-
|
|
|
306
|
-
|
|
|
307
|
-
|
|
|
287
|
+
| 方法 | 功能说明 |
|
|
288
|
+
| :------------ | :---------------------------------------------------------------------------------- |
|
|
289
|
+
| findById | 按 id 查询 |
|
|
290
|
+
| findByIdIn | 按 id 列表查询多条记录 |
|
|
291
|
+
| existsBy | 判定指定的条件是否存在记录 |
|
|
292
|
+
| existsById | 判定 id 是否存在 |
|
|
293
|
+
| deleteById | 按 id 删除 |
|
|
294
|
+
| deleteMany | 按指定条件删除,危险操作,建议尽可能设置 limit 参数来限制数量 |
|
|
295
|
+
| findAll | 查询表下所有记录,危险操作,建议只对数据量非常小的表使用 |
|
|
296
|
+
| findFirst | 查询符合条件的第一条记录 |
|
|
297
|
+
| insert | 插入记录 |
|
|
298
|
+
| insertMany | 一次性插入多条记录 |
|
|
299
|
+
| update | 更新记录,需要完整信息 |
|
|
300
|
+
| partialUpdate | 局部更新,只提供 id 和需要更新的字段信息 |
|
|
301
|
+
| updateOne | 只更新指定条件的第一条记录,必须是相等条件,不支持范围条件 |
|
|
302
|
+
| updateMany | 更新所有符合条件的记录,危险操作,建议对条件严加限制,控制受影响的范围 |
|
|
303
|
+
| find | 按条件查询所有符合条件的记录,危险操作,建议尽可能设置 limit 参数来限制数量 |
|
|
304
|
+
| findSelect | 指定字段进行条件查询,与 find 唯一的不同的是多一个参数 select 可以用来指定要返回的列 |
|
|
305
|
+
| count | 统计符合条件的记录数量,危险操作,建议严格限制条件,注意索引的利用 |
|
|
306
|
+
| paginate | 分页查询 ,危险操作,基于 find 和 count |
|
|
307
|
+
| query | 自定义 sql 查询,返回记录列表,支持预编译 sql |
|
|
308
|
+
| modify | 执行自定义 sql,返回操作记录数 ,支持预编译 sql |
|
|
308
309
|
|
|
309
310
|
### json 类型
|
|
310
311
|
|
|
@@ -20,8 +20,8 @@ validate(
|
|
|
20
20
|
|
|
21
21
|
| 函数 | 作用 |
|
|
22
22
|
| :---------- | :--------------------------------------------------- |
|
|
23
|
-
| notNull | 非空校验,不能是 null 或
|
|
24
|
-
| notBlank | 字符非空校验,不能是 null 或
|
|
23
|
+
| notNull | 非空校验,不能是 null 或 undefined |
|
|
24
|
+
| notBlank | 字符非空校验,不能是 null 或 undefined 或空白字符串 |
|
|
25
25
|
| min | 校验数字最小值 |
|
|
26
26
|
| max | 校验数字最大值 |
|
|
27
27
|
| length | 校验长度,适用于字符串和数组 |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wok-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"packageManager": "pnpm@8.9.0",
|
|
5
5
|
"description": "一个基于 NodeJs 和 TypeScript 的后端框架,轻量级、克制、简洁。A lightweight, restrained, and concise backend framework based on Node.js and TypeScript.",
|
|
6
6
|
"scripts": {
|
package/types/log/config.d.ts
CHANGED
package/types/log/file.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
import { LogConfig } from './config';
|
|
2
|
+
import { Log } from './log';
|
|
1
3
|
/**
|
|
2
4
|
* 文件存储.
|
|
3
|
-
* @param log
|
|
5
|
+
* @param log 日志对象
|
|
6
|
+
* @param logConfig 日志配置
|
|
4
7
|
*/
|
|
5
|
-
export declare function fileStore(log:
|
|
8
|
+
export declare function fileStore(log: Log, logConfig: LogConfig): void;
|
|
9
|
+
/**
|
|
10
|
+
* 确保所有日志都被写入文件
|
|
11
|
+
* 可以在应用程序关闭时调用
|
|
12
|
+
*/
|
|
13
|
+
export declare function flushLogsToFile(): Promise<void>;
|
package/types/log/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
declare class Logger {
|
|
2
|
+
private prefix?;
|
|
3
|
+
constructor(prefix?: string | undefined);
|
|
4
|
+
/**
|
|
5
|
+
* 输出日志
|
|
6
|
+
* @param level
|
|
7
|
+
* @param message
|
|
8
|
+
* @param error
|
|
9
|
+
*/
|
|
10
|
+
private log;
|
|
6
11
|
/**
|
|
7
12
|
* debug 日志
|
|
8
13
|
*/
|
|
@@ -20,6 +25,12 @@ export declare function getLogger(): Readonly<{
|
|
|
20
25
|
* @param error
|
|
21
26
|
*/
|
|
22
27
|
warn(message: string, error?: any): void;
|
|
28
|
+
/**
|
|
29
|
+
* 等同于 warn
|
|
30
|
+
* @param message
|
|
31
|
+
* @param error
|
|
32
|
+
*/
|
|
33
|
+
warning(message: string, error?: any): void;
|
|
23
34
|
isWarnEnabled(): boolean;
|
|
24
35
|
/**
|
|
25
36
|
* 错误日志
|
|
@@ -28,7 +39,15 @@ export declare function getLogger(): Readonly<{
|
|
|
28
39
|
*/
|
|
29
40
|
error(message: string, error?: any): void;
|
|
30
41
|
isErrorEnabled(): boolean;
|
|
31
|
-
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 获取日志对象.
|
|
45
|
+
*
|
|
46
|
+
* @param prefix 日志前缀,如果有值,每条日志前都会加上前缀信息
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
export declare function getLogger(prefix?: string): Logger;
|
|
32
50
|
export * from './config';
|
|
33
51
|
export * from './level';
|
|
52
|
+
export * from './log';
|
|
34
53
|
export { setLogStore } from './store';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LogLevel } from './level';
|
|
2
|
+
/**
|
|
3
|
+
* 单条日志的信息
|
|
4
|
+
*/
|
|
5
|
+
export interface Log {
|
|
6
|
+
/**
|
|
7
|
+
* 日志的时间
|
|
8
|
+
*/
|
|
9
|
+
time: Date;
|
|
10
|
+
/**
|
|
11
|
+
* 日志的等级
|
|
12
|
+
*/
|
|
13
|
+
level: LogLevel;
|
|
14
|
+
/**
|
|
15
|
+
* 日志的内容
|
|
16
|
+
*/
|
|
17
|
+
content: string;
|
|
18
|
+
/**
|
|
19
|
+
* 异常信息
|
|
20
|
+
*/
|
|
21
|
+
error?: any;
|
|
22
|
+
/**
|
|
23
|
+
* 前缀信息
|
|
24
|
+
*/
|
|
25
|
+
prefix?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 将日志格式化为简单的文本
|
|
29
|
+
* @param log
|
|
30
|
+
* @param ignoreError 忽略异常信息
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatLogText(log: Log, ignoreError?: boolean): string;
|
|
34
|
+
/**
|
|
35
|
+
* 将日志格式化为 json
|
|
36
|
+
* @param log
|
|
37
|
+
* @param ignoreError 忽略异常信息
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatLogJson(log: Log, ignoreError?: boolean): string;
|
package/types/log/store.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { LogConfig } from './config';
|
|
2
|
+
import { Log } from './log';
|
|
1
3
|
/**
|
|
2
4
|
* 日志存储函数
|
|
3
5
|
*/
|
|
4
6
|
export interface LogStore {
|
|
5
|
-
|
|
7
|
+
/**
|
|
8
|
+
* 日志存储函数
|
|
9
|
+
* @param log 日志
|
|
10
|
+
* @param config 日志配置
|
|
11
|
+
*/
|
|
12
|
+
(log: Log, config: LogConfig): void;
|
|
6
13
|
}
|
|
7
14
|
/**
|
|
8
15
|
* 设置日志存储.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Pool, PoolConnection } from 'mysql2';
|
|
2
2
|
import { MysqlConfig } from '../config';
|
|
3
3
|
import { Table } from '../table-info';
|
|
4
|
-
import { DeleteManyOpts, FindOpts, MixCriteria, MysqlPage, MysqlPaginateOpts, UpdateOpts, Updater } from './ops';
|
|
4
|
+
import { DeleteManyOpts, FindOpts, MixCriteria, MysqlPage, MysqlPaginateOpts, UpdateOpts, Updater, FindSelectOpts } from './ops';
|
|
5
5
|
/**
|
|
6
6
|
* mysql 管理器基类,提供基础的操作方法.
|
|
7
7
|
*/
|
|
@@ -129,6 +129,12 @@ export declare abstract class BaseMysqlManager {
|
|
|
129
129
|
* @returns
|
|
130
130
|
*/
|
|
131
131
|
find<T>(opts: FindOpts<T>): Promise<T[]>;
|
|
132
|
+
/**
|
|
133
|
+
* 指定字段条件查询
|
|
134
|
+
* @param opts
|
|
135
|
+
* @returns
|
|
136
|
+
*/
|
|
137
|
+
findSelect<T, K extends keyof T>(opts: FindSelectOpts<T, K>): Promise<Pick<T, K>[]>;
|
|
132
138
|
/**
|
|
133
139
|
* 指定条件查询数量
|
|
134
140
|
* @param table 表信息
|
|
@@ -48,6 +48,22 @@ export interface FindOpts<T> {
|
|
|
48
48
|
* @returns
|
|
49
49
|
*/
|
|
50
50
|
export declare function find<T>(config: MysqlConfig, conn: PoolConnection, opts: FindOpts<T>): Promise<T[]>;
|
|
51
|
+
/**
|
|
52
|
+
* 指定字段条件查询选项
|
|
53
|
+
*/
|
|
54
|
+
export interface FindSelectOpts<T, K extends keyof T> extends FindOpts<T> {
|
|
55
|
+
/**
|
|
56
|
+
* 要查询的字段
|
|
57
|
+
*/
|
|
58
|
+
select: K[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 查询指定的字段,返回值类型与选择的字段有关
|
|
62
|
+
* @param onfig
|
|
63
|
+
* @param conn
|
|
64
|
+
* @param opts
|
|
65
|
+
*/
|
|
66
|
+
export declare function findSelect<T, K extends keyof T>(config: MysqlConfig, conn: PoolConnection, opts: FindSelectOpts<T, K>): Promise<Array<Pick<T, K>>>;
|
|
51
67
|
/**
|
|
52
68
|
* 根据 id 列表查询记录
|
|
53
69
|
* @param connection
|
|
@@ -2,7 +2,7 @@ import { PoolConnection } from 'mysql2';
|
|
|
2
2
|
import { MysqlConfig } from '../config';
|
|
3
3
|
import { MysqlTxSession } from './tx';
|
|
4
4
|
import { Table } from '../table-info';
|
|
5
|
-
import { DeleteManyOpts, FindOpts, MixCriteria, MysqlPage, MysqlPaginateOpts, UpdateOpts, Updater } from './ops';
|
|
5
|
+
import { DeleteManyOpts, FindOpts, FindSelectOpts, MixCriteria, MysqlPage, MysqlPaginateOpts, UpdateOpts, Updater } from './ops';
|
|
6
6
|
/**
|
|
7
7
|
* 严格 mysql 事务会话,会禁用一些操作.
|
|
8
8
|
*/
|
|
@@ -28,6 +28,7 @@ export declare class MysqlStrictTxSession extends MysqlTxSession {
|
|
|
28
28
|
}>): Promise<boolean>;
|
|
29
29
|
partialUpdate<T>(table: Table<T>, data: Updater<T>): Promise<boolean>;
|
|
30
30
|
find<T>(opts: FindOpts<T>): Promise<T[]>;
|
|
31
|
+
findSelect<T, K extends keyof T>(opts: FindSelectOpts<T, K>): Promise<Pick<T, K>[]>;
|
|
31
32
|
count<T>(table: Table<T>, criteria?: MixCriteria<T> | undefined): Promise<number>;
|
|
32
33
|
paginate<T>(opts: MysqlPaginateOpts<T>): Promise<MysqlPage<T>>;
|
|
33
34
|
query<T>(sql: string, values?: any[] | undefined): Promise<T[]>;
|