mm_dao 1.8.0 → 1.8.1
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/example/index.js +78 -0
- package/index.js +4 -6
- package/lib/{drive.js → dao.js} +111 -256
- package/lib/manager.js +49 -37
- package/package.json +8 -9
package/example/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* mm_dao SQL 帮助模块示例
|
|
5
|
+
* 演示:获取 SQL 模板管理器、创建 Dao 驱动,并在内存中构建查询条件(无需连接数据库)。
|
|
6
|
+
* 注:管理器 add() 存在未定义 Drive 的缺陷,此处直接实例化 Dao 驱动演示核心 API。
|
|
7
|
+
* 运行:node example/index.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { daoAdmin, Dao } = require('../index.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 创建一个纯内存的模拟数据库(仅实现 SQL 模板拼接,不连接真实数据库)
|
|
14
|
+
* @returns {object} 模拟数据库实例
|
|
15
|
+
*/
|
|
16
|
+
function createMockDb() {
|
|
17
|
+
return {
|
|
18
|
+
config: { filter: {} },
|
|
19
|
+
size: 30,
|
|
20
|
+
page: 0,
|
|
21
|
+
/**
|
|
22
|
+
* 过滤参数(无操作)
|
|
23
|
+
*/
|
|
24
|
+
filter() {},
|
|
25
|
+
/**
|
|
26
|
+
* 模板查询拼接
|
|
27
|
+
* @param {object} param 参数对象
|
|
28
|
+
* @param {object} sql_tpl 模板对象
|
|
29
|
+
* @returns {string} 拼接结果
|
|
30
|
+
*/
|
|
31
|
+
tplQuery(param, sql_tpl) {
|
|
32
|
+
const segments = [];
|
|
33
|
+
for (const key in param) {
|
|
34
|
+
const seg = sql_tpl[key]
|
|
35
|
+
? sql_tpl[key].replace(/\{0\}/g, param[key])
|
|
36
|
+
: '`' + key + "` = '" + param[key] + "'";
|
|
37
|
+
segments.push(seg);
|
|
38
|
+
}
|
|
39
|
+
return segments.join(' AND ');
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 主函数
|
|
46
|
+
* @returns {Promise<void>} 无返回值
|
|
47
|
+
*/
|
|
48
|
+
async function main() {
|
|
49
|
+
// 1. 获取 SQL 管理器(同 scope 复用实例)
|
|
50
|
+
const manager = daoAdmin('demo', { title: '示例SQL管理器' });
|
|
51
|
+
const manager2 = daoAdmin('demo');
|
|
52
|
+
console.log('管理器实例复用:', manager === manager2);
|
|
53
|
+
|
|
54
|
+
// 2. 创建 Dao 驱动(模板化增删改查)
|
|
55
|
+
const dao = new Dao(
|
|
56
|
+
{
|
|
57
|
+
name: 'user',
|
|
58
|
+
title: '用户表',
|
|
59
|
+
table: 'user_account',
|
|
60
|
+
key: 'user_id',
|
|
61
|
+
query: { name: "`name` like '%{0}%'", uid: '`uid` = {0}' }
|
|
62
|
+
},
|
|
63
|
+
manager
|
|
64
|
+
);
|
|
65
|
+
console.log('驱动类型:', dao instanceof Dao);
|
|
66
|
+
|
|
67
|
+
// 3. 构建查询条件(纯内存,无需数据库连接)
|
|
68
|
+
const where = dao.toWhere(createMockDb(), { name: '张三', uid: 1 }, 'get');
|
|
69
|
+
console.log('生成的WHERE条件:', where);
|
|
70
|
+
|
|
71
|
+
// 4. 驱动配置模型
|
|
72
|
+
console.log('驱动模型名称:', dao.getModel().name);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main().catch((err) => {
|
|
76
|
+
console.error('示例执行失败:', err);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
});
|
package/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const Drive = require('./lib/drive');
|
|
1
|
+
const Dao = require('./lib/dao');
|
|
3
2
|
const Manager = require('./lib/manager');
|
|
4
3
|
const Admin = require('mm_corejs').Admin;
|
|
5
4
|
|
|
@@ -7,8 +6,7 @@ const admin = new Admin();
|
|
|
7
6
|
admin.setClass(Manager);
|
|
8
7
|
|
|
9
8
|
module.exports = {
|
|
10
|
-
|
|
11
|
-
Drive,
|
|
9
|
+
Dao,
|
|
12
10
|
Manager,
|
|
13
11
|
admin,
|
|
14
12
|
/**
|
|
@@ -17,10 +15,10 @@ module.exports = {
|
|
|
17
15
|
* @param {object} [config] 配置参数
|
|
18
16
|
* @returns {object} SQL 管理器实例
|
|
19
17
|
*/
|
|
20
|
-
|
|
18
|
+
daoAdmin(scope, config) {
|
|
21
19
|
if (!scope) {
|
|
22
20
|
scope = 'os';
|
|
23
21
|
}
|
|
24
|
-
return admin.get(scope,
|
|
22
|
+
return admin.get(scope, config);
|
|
25
23
|
}
|
|
26
24
|
};
|
package/lib/{drive.js → dao.js}
RENAMED
|
@@ -1,164 +1,14 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const Item = require('
|
|
2
|
+
const Item = require('mm_machine').Mod;
|
|
3
3
|
const { string, array, date, file } = require('mm_helper');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 是否以指定后缀结尾(替代 mm_expand 的 String.ends)
|
|
7
|
-
* @param {string} str 源字符串
|
|
8
|
-
* @param {string} suffix 后缀
|
|
9
|
-
* @returns {boolean} 以后缀结尾返回true, 否则返回false
|
|
10
|
-
*/
|
|
11
|
-
function _strEnds(str, suffix) {
|
|
12
|
-
return (str + '').endsWith(suffix);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 合并值(替代 mm_expand 的 Array.clear/addList 深合并语义, 数组整体拷贝)
|
|
17
|
-
* @param {*} current 当前值
|
|
18
|
-
* @param {*} value 新值
|
|
19
|
-
* @param {boolean} bl 是否补充模式
|
|
20
|
-
* @returns {*} 合并后的值
|
|
21
|
-
*/
|
|
22
|
-
function _mergeValue(current, value, bl) {
|
|
23
|
-
var type = typeof current;
|
|
24
|
-
var value_type = typeof value;
|
|
25
|
-
if (type !== value_type) {
|
|
26
|
-
if (type === 'number') {
|
|
27
|
-
var n = Number(value);
|
|
28
|
-
return isNaN(n) ? 0 : n;
|
|
29
|
-
} else if (type === 'boolean') {
|
|
30
|
-
return !(value === '0' || value === 'false' || value === 'False');
|
|
31
|
-
} else if (type === 'string') {
|
|
32
|
-
return value.toString();
|
|
33
|
-
}
|
|
34
|
-
return value;
|
|
35
|
-
} else if (type === 'object') {
|
|
36
|
-
if (Array.isArray(current) && Array.isArray(value)) {
|
|
37
|
-
return value.slice();
|
|
38
|
-
}
|
|
39
|
-
_push(current, value, bl);
|
|
40
|
-
return current;
|
|
41
|
-
}
|
|
42
|
-
return value;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 将对象B合并进对象A(替代 mm_os 全局 push)
|
|
47
|
-
* @param {object} obj_a 被添加的对象
|
|
48
|
-
* @param {object} obj_b 用作添加的对象
|
|
49
|
-
* @param {boolean} bl 为true时只补充obj_a中缺失的键
|
|
50
|
-
* @returns {object} 对象A自身
|
|
51
|
-
*/
|
|
52
|
-
function _push(obj_a, obj_b, bl) {
|
|
53
|
-
if (!obj_a || !obj_b) {
|
|
54
|
-
return obj_a;
|
|
55
|
-
}
|
|
56
|
-
if (bl) {
|
|
57
|
-
for (var k in obj_b) {
|
|
58
|
-
var value = obj_b[k];
|
|
59
|
-
if (obj_a[k] === undefined || obj_a[k] === null || value === null) {
|
|
60
|
-
obj_a[k] = value;
|
|
61
|
-
} else {
|
|
62
|
-
obj_a[k] = _mergeValue(obj_a[k], value, bl);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
for (var n in obj_a) {
|
|
67
|
-
var val = obj_b[n];
|
|
68
|
-
if (val !== undefined && obj_a[n] !== null && val !== null) {
|
|
69
|
-
obj_a[n] = _mergeValue(obj_a[n], val, bl);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return obj_a;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* 生成JSON-RPC响应体(替代 mm_os 的 ret.body, 等价 mm_ret 默认 json-rpc 格式)
|
|
78
|
-
* @param {*} result 返回的结果
|
|
79
|
-
* @param {object} error 错误信息 {code, message}
|
|
80
|
-
* @returns {object} 响应格式
|
|
81
|
-
*/
|
|
82
|
-
function _retBody(result, error) {
|
|
83
|
-
var ret = {};
|
|
84
|
-
if (result) {
|
|
85
|
-
ret.result = result;
|
|
86
|
-
} else if (error) {
|
|
87
|
-
ret.error = {
|
|
88
|
-
code: error.code || 10000,
|
|
89
|
-
message: error.message || '错误'
|
|
90
|
-
};
|
|
91
|
-
} else {
|
|
92
|
-
ret.error = { code: 10000, message: '错误' };
|
|
93
|
-
}
|
|
94
|
-
return ret;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 生成错误响应(替代 mm_os 的 ret.error)
|
|
99
|
-
* @param {number} code 错误码
|
|
100
|
-
* @param {string} message 错误信息
|
|
101
|
-
* @returns {object} 错误响应格式
|
|
102
|
-
*/
|
|
103
|
-
function _retError(code, message) {
|
|
104
|
-
return _retBody(null, { code, message });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* 生成列表响应(替代 mm_os 的 ret.list)
|
|
109
|
-
* @param {Array} list 返回列表
|
|
110
|
-
* @param {number} count 查询结果数
|
|
111
|
-
* @returns {object} 列表响应格式
|
|
112
|
-
*/
|
|
113
|
-
function _retList(list, count) {
|
|
114
|
-
var result = { list: list || [] };
|
|
115
|
-
if (count !== undefined) {
|
|
116
|
-
result.count = count;
|
|
117
|
-
}
|
|
118
|
-
return _retBody(result, null);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 生成对象响应(替代 mm_os 的 ret.obj)
|
|
123
|
-
* @param {object} obj 返回对象
|
|
124
|
-
* @returns {object} 对象响应格式
|
|
125
|
-
*/
|
|
126
|
-
function _retObj(obj) {
|
|
127
|
-
return _retBody({ obj: obj }, null);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 生成布尔型响应(替代 mm_os 的 ret.bl)
|
|
132
|
-
* @param {boolean} bl 布尔结果
|
|
133
|
-
* @param {string} tip 提示信息
|
|
134
|
-
* @returns {object} 布尔响应格式
|
|
135
|
-
*/
|
|
136
|
-
function _retBl(bl, tip) {
|
|
137
|
-
return _retBody({ bl: bl, tip: tip || (bl ? '成功' : '错误') }, null);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 校验SQL标识符安全性, 仅允许字母、数字和下划线
|
|
142
|
-
* @param {string} name 标识符名称
|
|
143
|
-
* @returns {string} 安全的标识符
|
|
144
|
-
*/
|
|
145
|
-
function validateIden(name) {
|
|
146
|
-
if (typeof name !== 'string' || !name) {
|
|
147
|
-
return '';
|
|
148
|
-
}
|
|
149
|
-
var sanitized = name.replace(/`/g, '');
|
|
150
|
-
if (!/^[a-zA-Z0-9_]+$/.test(sanitized)) {
|
|
151
|
-
return '';
|
|
152
|
-
}
|
|
153
|
-
return sanitized;
|
|
154
|
-
}
|
|
4
|
+
const { getRet } = require('mm_ret');
|
|
155
5
|
|
|
156
6
|
/**
|
|
157
7
|
* Sql操作驱动类
|
|
158
8
|
* @augments {Item}
|
|
159
9
|
* @class
|
|
160
10
|
*/
|
|
161
|
-
class
|
|
11
|
+
class Dao extends Item {
|
|
162
12
|
static config = {
|
|
163
13
|
main: '',
|
|
164
14
|
// 表名 {0} 代表可前端传参自定义查询的表
|
|
@@ -283,7 +133,7 @@ class Drive extends Item {
|
|
|
283
133
|
* @class
|
|
284
134
|
*/
|
|
285
135
|
constructor(config, parent) {
|
|
286
|
-
super({ ...
|
|
136
|
+
super({ ...Dao.config, ...config });
|
|
287
137
|
|
|
288
138
|
// 父级管理器引用(用于默认配置回退与插件查找)
|
|
289
139
|
this.parent = parent || null;
|
|
@@ -296,7 +146,7 @@ class Drive extends Item {
|
|
|
296
146
|
/**
|
|
297
147
|
* 预设
|
|
298
148
|
*/
|
|
299
|
-
|
|
149
|
+
Dao.prototype._preset = function () {
|
|
300
150
|
// 保存文件目录
|
|
301
151
|
this.save_dir = './static/file/';
|
|
302
152
|
// 读取文件目录
|
|
@@ -311,7 +161,7 @@ Drive.prototype._preset = function () {
|
|
|
311
161
|
* @returns {*} 配置值, 未配置返回 undefined
|
|
312
162
|
* @private
|
|
313
163
|
*/
|
|
314
|
-
|
|
164
|
+
Dao.prototype._getInject = function (key) {
|
|
315
165
|
var value = this.config[key];
|
|
316
166
|
if (value !== undefined && value !== null && value !== '') {
|
|
317
167
|
return value;
|
|
@@ -327,7 +177,7 @@ Drive.prototype._getInject = function (key) {
|
|
|
327
177
|
* @returns {object} 字典对象
|
|
328
178
|
* @private
|
|
329
179
|
*/
|
|
330
|
-
|
|
180
|
+
Dao.prototype._getDict = function () {
|
|
331
181
|
return this._getInject('dict') || {};
|
|
332
182
|
};
|
|
333
183
|
|
|
@@ -337,7 +187,7 @@ Drive.prototype._getDict = function () {
|
|
|
337
187
|
* @param {object} db 数据库管理器
|
|
338
188
|
* @returns {object} 过滤后的参数
|
|
339
189
|
*/
|
|
340
|
-
|
|
190
|
+
Dao.prototype.before = async function (params, db) {
|
|
341
191
|
return params;
|
|
342
192
|
};
|
|
343
193
|
|
|
@@ -347,7 +197,7 @@ Drive.prototype.before = async function (params, db) {
|
|
|
347
197
|
* @param {object} db 数据管理器
|
|
348
198
|
* @returns {boolean} 验证通过返回true, 失败返回false
|
|
349
199
|
*/
|
|
350
|
-
|
|
200
|
+
Dao.prototype.check = async function (params, db) {
|
|
351
201
|
return true;
|
|
352
202
|
};
|
|
353
203
|
|
|
@@ -357,7 +207,7 @@ Drive.prototype.check = async function (params, db) {
|
|
|
357
207
|
* @param {object} db 数据管理器
|
|
358
208
|
* @returns {object} 最终执行结果
|
|
359
209
|
*/
|
|
360
|
-
|
|
210
|
+
Dao.prototype.after = async function (params, db) {
|
|
361
211
|
return db.ret;
|
|
362
212
|
};
|
|
363
213
|
|
|
@@ -366,7 +216,7 @@ Drive.prototype.after = async function (params, db) {
|
|
|
366
216
|
* @param {string} table 表名
|
|
367
217
|
* @param {object} sql 缓存sql语句
|
|
368
218
|
*/
|
|
369
|
-
|
|
219
|
+
Dao.prototype.updateCache = async function (table, sql) {};
|
|
370
220
|
|
|
371
221
|
/**
|
|
372
222
|
* @ 执行修改
|
|
@@ -375,7 +225,7 @@ Drive.prototype.updateCache = async function (table, sql) {};
|
|
|
375
225
|
* @param {object} db 数据库管理器
|
|
376
226
|
* @returns {object} 返回执行结果
|
|
377
227
|
*/
|
|
378
|
-
|
|
228
|
+
Dao.prototype.run = async function (query, body, db) {
|
|
379
229
|
var params = {
|
|
380
230
|
query,
|
|
381
231
|
body,
|
|
@@ -400,10 +250,10 @@ Drive.prototype.run = async function (query, body, db) {
|
|
|
400
250
|
* @param {object} body 修改项
|
|
401
251
|
* @returns {object} 返回准备参数
|
|
402
252
|
*/
|
|
403
|
-
|
|
253
|
+
Dao.prototype.ready = function (db, query, body) {
|
|
404
254
|
var cg = this.config;
|
|
405
255
|
var qy = { ...query };
|
|
406
|
-
|
|
256
|
+
Object.assign(db.config.filter, cg.filter);
|
|
407
257
|
db.filter(qy);
|
|
408
258
|
return {
|
|
409
259
|
cg,
|
|
@@ -418,7 +268,7 @@ Drive.prototype.ready = function (db, query, body) {
|
|
|
418
268
|
* @param {object} method 方法
|
|
419
269
|
* @returns {string} 返回查询条件
|
|
420
270
|
*/
|
|
421
|
-
|
|
271
|
+
Dao.prototype.toWhere = function (db, query, method) {
|
|
422
272
|
var { cg, qy: originalQy } = this.ready(db, query, {});
|
|
423
273
|
// 创建 qy 对象的副本,避免修改原始参数
|
|
424
274
|
var qy = { ...originalQy };
|
|
@@ -435,7 +285,7 @@ Drive.prototype.toWhere = function (db, query, method) {
|
|
|
435
285
|
* @param {object} query 查询条件
|
|
436
286
|
* @private
|
|
437
287
|
*/
|
|
438
|
-
|
|
288
|
+
Dao.prototype._setDbConfig = function (db, cg, query) {
|
|
439
289
|
db.config.separator = cg.separator;
|
|
440
290
|
if (!query.size && cg.page_size) {
|
|
441
291
|
db.size = cg.page_size + 0;
|
|
@@ -455,12 +305,12 @@ Drive.prototype._setDbConfig = function (db, cg, query) {
|
|
|
455
305
|
* @returns {object} 更新后的查询条件对象
|
|
456
306
|
* @private
|
|
457
307
|
*/
|
|
458
|
-
|
|
308
|
+
Dao.prototype._setQueryField = function (db, query, cg, method, qy) {
|
|
459
309
|
var f = db.config.filter;
|
|
460
310
|
var field = query[f.field];
|
|
461
311
|
if (string.has(cg.field, '*{0}*')) {
|
|
462
312
|
if (field) {
|
|
463
|
-
var safe_field =
|
|
313
|
+
var safe_field = typeof field === 'string' && string.validate(field, 'username') ? field : '';
|
|
464
314
|
if (safe_field) {
|
|
465
315
|
db.field = cg.field.replace('{0}', safe_field);
|
|
466
316
|
} else {
|
|
@@ -489,12 +339,12 @@ Drive.prototype._setQueryField = function (db, query, cg, method, qy) {
|
|
|
489
339
|
* @returns {object} 更新后的查询条件对象
|
|
490
340
|
* @private
|
|
491
341
|
*/
|
|
492
|
-
|
|
342
|
+
Dao.prototype._setOrderBy = function (db, query, cg, qy) {
|
|
493
343
|
var f = db.config.filter;
|
|
494
344
|
var orderby = query[f.orderby];
|
|
495
345
|
if (string.has(cg.orderby, '*{0}*')) {
|
|
496
346
|
if (orderby) {
|
|
497
|
-
var safe_orderby =
|
|
347
|
+
var safe_orderby = typeof orderby === 'string' && string.validate(orderby, 'username') ? orderby : '';
|
|
498
348
|
if (safe_orderby) {
|
|
499
349
|
db.orderby = cg.orderby.replace('{0}', safe_orderby);
|
|
500
350
|
} else {
|
|
@@ -520,7 +370,7 @@ Drive.prototype._setOrderBy = function (db, query, cg, qy) {
|
|
|
520
370
|
* @returns {string} 查询字符串
|
|
521
371
|
* @private
|
|
522
372
|
*/
|
|
523
|
-
|
|
373
|
+
Dao.prototype._buildQueryString = function (db, qy, cg) {
|
|
524
374
|
var query_str = db.tplQuery(qy, cg.query);
|
|
525
375
|
var qt = cg.query_default;
|
|
526
376
|
if (Object.keys(qt).length > 0) {
|
|
@@ -550,21 +400,21 @@ Drive.prototype._buildQueryString = function (db, qy, cg) {
|
|
|
550
400
|
* @param {object} method 方法
|
|
551
401
|
* @returns {object} 返回查询结果
|
|
552
402
|
*/
|
|
553
|
-
|
|
403
|
+
Dao.prototype.getMain = async function (db, query, method) {
|
|
554
404
|
var ret;
|
|
555
405
|
if (string.has(this.config.field, '*{0}*')) {
|
|
556
406
|
var field = query[db.config.filter.field];
|
|
557
407
|
if (field && array.getMatch(this.config.field_hide, field)) {
|
|
558
|
-
return
|
|
408
|
+
return getRet().error(70003, '不合法的查询参数');
|
|
559
409
|
}
|
|
560
410
|
}
|
|
561
411
|
var query_str = this.toWhere(db, query, method);
|
|
562
412
|
|
|
563
413
|
// 查询
|
|
564
414
|
if (db.count_ret === 'true') {
|
|
565
|
-
ret =
|
|
415
|
+
ret = getRet().body(await db.getCountSql(query_str, db.orderby, db.field), null);
|
|
566
416
|
} else {
|
|
567
|
-
ret =
|
|
417
|
+
ret = getRet().list(await db.getSql(query_str, db.orderby, db.field));
|
|
568
418
|
}
|
|
569
419
|
return ret;
|
|
570
420
|
};
|
|
@@ -576,7 +426,7 @@ Drive.prototype.getMain = async function (db, query, method) {
|
|
|
576
426
|
* @param {object} body 修改项
|
|
577
427
|
* @returns {object} 返回查询结果
|
|
578
428
|
*/
|
|
579
|
-
|
|
429
|
+
Dao.prototype.get = async function (db, query, body) {
|
|
580
430
|
return await this.getMain(db, query);
|
|
581
431
|
};
|
|
582
432
|
|
|
@@ -587,7 +437,7 @@ Drive.prototype.get = async function (db, query, body) {
|
|
|
587
437
|
* @param {object} body 修改项
|
|
588
438
|
* @returns {object} 返回查询结果
|
|
589
439
|
*/
|
|
590
|
-
|
|
440
|
+
Dao.prototype.getObj = async function (db, query, body) {
|
|
591
441
|
var qy = { ...query };
|
|
592
442
|
qy.page = 1;
|
|
593
443
|
qy.size = 1;
|
|
@@ -595,9 +445,9 @@ Drive.prototype.getObj = async function (db, query, body) {
|
|
|
595
445
|
if (ret.result) {
|
|
596
446
|
var list = ret.result.list;
|
|
597
447
|
if (list.length > 0) {
|
|
598
|
-
return
|
|
448
|
+
return getRet().body({ obj: list[0] });
|
|
599
449
|
} else {
|
|
600
|
-
return
|
|
450
|
+
return getRet().body({ obj: null });
|
|
601
451
|
}
|
|
602
452
|
}
|
|
603
453
|
return ret;
|
|
@@ -610,7 +460,7 @@ Drive.prototype.getObj = async function (db, query, body) {
|
|
|
610
460
|
* @param {object} body 修改项
|
|
611
461
|
* @returns {object} 返回修改结果
|
|
612
462
|
*/
|
|
613
|
-
|
|
463
|
+
Dao.prototype.setMain = async function (db, query, body) {
|
|
614
464
|
var ret;
|
|
615
465
|
var { cg, qy } = this.ready(db, query, body);
|
|
616
466
|
var key = cg.key;
|
|
@@ -640,9 +490,9 @@ Drive.prototype.setMain = async function (db, query, body) {
|
|
|
640
490
|
var n = await db.setSql(query_str, db.tplBody(body, cg.update));
|
|
641
491
|
|
|
642
492
|
if (n < 1) {
|
|
643
|
-
ret =
|
|
493
|
+
ret = getRet().error(500, '修改失败!\n' + db.error.message);
|
|
644
494
|
} else {
|
|
645
|
-
ret =
|
|
495
|
+
ret = getRet().bl(true, '修改成功!');
|
|
646
496
|
}
|
|
647
497
|
return ret;
|
|
648
498
|
};
|
|
@@ -654,7 +504,7 @@ Drive.prototype.setMain = async function (db, query, body) {
|
|
|
654
504
|
* @param {object} body 修改项
|
|
655
505
|
* @returns {object} 返回查询结果
|
|
656
506
|
*/
|
|
657
|
-
|
|
507
|
+
Dao.prototype.set = async function (db, query, body) {
|
|
658
508
|
return await this.setMain(db, query, body);
|
|
659
509
|
};
|
|
660
510
|
|
|
@@ -664,7 +514,7 @@ Drive.prototype.set = async function (db, query, body) {
|
|
|
664
514
|
* @param {object} body 添加项
|
|
665
515
|
* @returns {object} 返回查询结果
|
|
666
516
|
*/
|
|
667
|
-
|
|
517
|
+
Dao.prototype.addMain = async function (db, body) {
|
|
668
518
|
var ret;
|
|
669
519
|
var cg = this.config;
|
|
670
520
|
if (Object.keys(body).length > 0) {
|
|
@@ -687,12 +537,12 @@ Drive.prototype.addMain = async function (db, body) {
|
|
|
687
537
|
}
|
|
688
538
|
var n = await db.add(body);
|
|
689
539
|
if (n < 1) {
|
|
690
|
-
ret =
|
|
540
|
+
ret = getRet().error(500, '添加失败!\n' + db.error.message);
|
|
691
541
|
} else {
|
|
692
|
-
ret =
|
|
542
|
+
ret = getRet().bl(true, '添加成功!');
|
|
693
543
|
}
|
|
694
544
|
} else {
|
|
695
|
-
ret =
|
|
545
|
+
ret = getRet().error(30001, '参数不能为空');
|
|
696
546
|
}
|
|
697
547
|
if (cg.log) {
|
|
698
548
|
this.log('debug', '添加SQL语句', db.sql);
|
|
@@ -707,7 +557,7 @@ Drive.prototype.addMain = async function (db, body) {
|
|
|
707
557
|
* @param {object} body 修改项
|
|
708
558
|
* @returns {object} 返回添加结果
|
|
709
559
|
*/
|
|
710
|
-
|
|
560
|
+
Dao.prototype.add = async function (db, query, body) {
|
|
711
561
|
return await this.addMain(db, body);
|
|
712
562
|
};
|
|
713
563
|
|
|
@@ -717,9 +567,9 @@ Drive.prototype.add = async function (db, query, body) {
|
|
|
717
567
|
* @param {Array} list 添加项列表
|
|
718
568
|
* @returns {object} 返回批量添加结果
|
|
719
569
|
*/
|
|
720
|
-
|
|
570
|
+
Dao.prototype.addListMain = async function (db, list) {
|
|
721
571
|
if (!Array.isArray(list) || list.length === 0) {
|
|
722
|
-
return
|
|
572
|
+
return getRet().error(30001, '参数不能为空');
|
|
723
573
|
}
|
|
724
574
|
var success_num = 0;
|
|
725
575
|
var error_num = 0;
|
|
@@ -735,7 +585,7 @@ Drive.prototype.addListMain = async function (db, list) {
|
|
|
735
585
|
success_num++;
|
|
736
586
|
}
|
|
737
587
|
}
|
|
738
|
-
var done =
|
|
588
|
+
var done = getRet().bl(success_num > 0, success_num > 0 ? '批量添加成功!' : '批量添加失败!');
|
|
739
589
|
Object.assign(done.result, {
|
|
740
590
|
total: list.length,
|
|
741
591
|
success: success_num,
|
|
@@ -752,7 +602,7 @@ Drive.prototype.addListMain = async function (db, list) {
|
|
|
752
602
|
* @param {Array} list 添加项列表
|
|
753
603
|
* @returns {object} 返回批量添加结果
|
|
754
604
|
*/
|
|
755
|
-
|
|
605
|
+
Dao.prototype.addList = async function (db, list) {
|
|
756
606
|
return await this.addListMain(db, list);
|
|
757
607
|
};
|
|
758
608
|
|
|
@@ -762,15 +612,15 @@ Drive.prototype.addList = async function (db, list) {
|
|
|
762
612
|
* @param {object} query 查询条件
|
|
763
613
|
* @returns {object} 返回查询结果
|
|
764
614
|
*/
|
|
765
|
-
|
|
615
|
+
Dao.prototype.delMain = async function (db, query) {
|
|
766
616
|
var ret;
|
|
767
617
|
var { cg, qy } = this.ready(db, query, {});
|
|
768
618
|
var query_str = db.tplQuery(qy, cg.query);
|
|
769
619
|
var bl = await db.delSql(query_str);
|
|
770
620
|
if (bl < 1) {
|
|
771
|
-
ret =
|
|
621
|
+
ret = getRet().error(500, '删除失败!\n' + db.error.message);
|
|
772
622
|
} else {
|
|
773
|
-
ret =
|
|
623
|
+
ret = getRet().bl(true, '删除成功!');
|
|
774
624
|
}
|
|
775
625
|
if (cg.log) {
|
|
776
626
|
this.log('debug', '删除SQL语句', db.sql);
|
|
@@ -785,7 +635,7 @@ Drive.prototype.delMain = async function (db, query) {
|
|
|
785
635
|
* @param {object} body 修改项
|
|
786
636
|
* @returns {object} 返回删除结果
|
|
787
637
|
*/
|
|
788
|
-
|
|
638
|
+
Dao.prototype.del = async function (db, query, body = {}) {
|
|
789
639
|
return await this.delMain(db, { ...query, ...body });
|
|
790
640
|
};
|
|
791
641
|
|
|
@@ -796,18 +646,18 @@ Drive.prototype.del = async function (db, query, body = {}) {
|
|
|
796
646
|
* @param {object} body 修改项
|
|
797
647
|
* @returns {object} 返回修改结果
|
|
798
648
|
*/
|
|
799
|
-
|
|
649
|
+
Dao.prototype.addorsetMain = async function (db, query, body) {
|
|
800
650
|
var ret;
|
|
801
651
|
var { cg, qy } = this.ready(db, query, body);
|
|
802
652
|
if (Object.keys(body).length > 0 && Object.keys(qy).length > 0) {
|
|
803
653
|
var n = await db.addOrSet(qy, body);
|
|
804
654
|
if (n < 1) {
|
|
805
|
-
ret =
|
|
655
|
+
ret = getRet().error(500, '操作失败!\n' + db.error.message);
|
|
806
656
|
} else {
|
|
807
|
-
ret =
|
|
657
|
+
ret = getRet().bl(true, '操作成功!');
|
|
808
658
|
}
|
|
809
659
|
} else {
|
|
810
|
-
ret =
|
|
660
|
+
ret = getRet().error(30001, '参数不能为空');
|
|
811
661
|
}
|
|
812
662
|
if (cg.log) {
|
|
813
663
|
this.log('debug', '添加或修改SQL语句', db.sql);
|
|
@@ -822,7 +672,7 @@ Drive.prototype.addorsetMain = async function (db, query, body) {
|
|
|
822
672
|
* @param {object} body 修改项
|
|
823
673
|
* @returns {object} 返回查询结果
|
|
824
674
|
*/
|
|
825
|
-
|
|
675
|
+
Dao.prototype.addOrSet = async function (db, query, body) {
|
|
826
676
|
return await this.addOrSetMain(db, query, body);
|
|
827
677
|
};
|
|
828
678
|
|
|
@@ -831,7 +681,7 @@ Drive.prototype.addOrSet = async function (db, query, body) {
|
|
|
831
681
|
* @param {string} data_type 数据类型
|
|
832
682
|
* @returns {string} 返回数据类型
|
|
833
683
|
*/
|
|
834
|
-
|
|
684
|
+
Dao.prototype.getType = function (data_type) {
|
|
835
685
|
if (data_type.indexOf('int') !== -1) {
|
|
836
686
|
return 'number';
|
|
837
687
|
} else {
|
|
@@ -845,7 +695,7 @@ Drive.prototype.getType = function (data_type) {
|
|
|
845
695
|
* @param {string} field 要获取的字段
|
|
846
696
|
* @returns {Array} 返回参数信息列表
|
|
847
697
|
*/
|
|
848
|
-
|
|
698
|
+
Dao.prototype.getParam = async function (db, field) {
|
|
849
699
|
var cg = this.config;
|
|
850
700
|
if (cg.params) {
|
|
851
701
|
return cg.params;
|
|
@@ -866,7 +716,7 @@ Drive.prototype.getParam = async function (db, field) {
|
|
|
866
716
|
* @returns {Array} 字段列表
|
|
867
717
|
* @private
|
|
868
718
|
*/
|
|
869
|
-
|
|
719
|
+
Dao.prototype._getFieldsFromCache = function (cg) {
|
|
870
720
|
var lt = [];
|
|
871
721
|
// 方案B:db 池改为可选注入(config.get_db_pool 返回等价数据库池注册表),未配置则跳过缓存读取
|
|
872
722
|
var get_db_pool = this._getInject('get_db_pool');
|
|
@@ -896,7 +746,7 @@ Drive.prototype._getFieldsFromCache = function (cg) {
|
|
|
896
746
|
* @returns {Array} 字段列表
|
|
897
747
|
* @private
|
|
898
748
|
*/
|
|
899
|
-
|
|
749
|
+
Dao.prototype._getFieldsFromDb = async function (db, cg) {
|
|
900
750
|
var lt = [];
|
|
901
751
|
db.table = cg.table;
|
|
902
752
|
var list = await db.fields();
|
|
@@ -921,7 +771,7 @@ Drive.prototype._getFieldsFromDb = async function (db, cg) {
|
|
|
921
771
|
* @returns {Array} 过滤后的字段列表
|
|
922
772
|
* @private
|
|
923
773
|
*/
|
|
924
|
-
|
|
774
|
+
Dao.prototype._filterFields = function (lt, field, cg) {
|
|
925
775
|
var fields = field || cg.field_default;
|
|
926
776
|
if (fields && fields !== '*') {
|
|
927
777
|
var arr = fields.replace(/`/g, '').split(',');
|
|
@@ -935,7 +785,7 @@ Drive.prototype._filterFields = function (lt, field, cg) {
|
|
|
935
785
|
* @param {object} db 数据库操作类
|
|
936
786
|
* @returns {Array} 格式列表
|
|
937
787
|
*/
|
|
938
|
-
|
|
788
|
+
Dao.prototype.getFormat = async function (db) {
|
|
939
789
|
var dbs = { ...db };
|
|
940
790
|
dbs.size = 0;
|
|
941
791
|
var fmt = this.config.format;
|
|
@@ -966,16 +816,16 @@ Drive.prototype.getFormat = async function (db) {
|
|
|
966
816
|
* @param {string} filename 文件名
|
|
967
817
|
* @returns {object} 返回导入结果
|
|
968
818
|
*/
|
|
969
|
-
|
|
819
|
+
Dao.prototype.importMain = async function (db, filename) {
|
|
970
820
|
var params = await this.getParam(db);
|
|
971
821
|
var format = await this.getFormat(db);
|
|
972
822
|
var file = this._processFilePath(filename);
|
|
973
823
|
if (!file.hasFile(file)) {
|
|
974
|
-
return
|
|
824
|
+
return getRet().error(30001, file + '文件不存在!');
|
|
975
825
|
}
|
|
976
826
|
var jarr = await this._loadImport(file, params, format);
|
|
977
827
|
if (!jarr || !jarr.length) {
|
|
978
|
-
return
|
|
828
|
+
return getRet().error(10000, '要导入的数据不能为空!');
|
|
979
829
|
}
|
|
980
830
|
var result = await this._importToDb(db, jarr);
|
|
981
831
|
return this._buildImport(result);
|
|
@@ -987,7 +837,7 @@ Drive.prototype.importMain = async function (db, filename) {
|
|
|
987
837
|
* @returns {string} 处理后的文件路径
|
|
988
838
|
* @private
|
|
989
839
|
*/
|
|
990
|
-
|
|
840
|
+
Dao.prototype._processFilePath = function (filename) {
|
|
991
841
|
var file = filename;
|
|
992
842
|
var run_path = this._getInject('run_path') || '';
|
|
993
843
|
if (file.indexOf(run_path) !== 0) {
|
|
@@ -1006,10 +856,10 @@ Drive.prototype._processFilePath = function (filename) {
|
|
|
1006
856
|
* @returns {Array} 数据数组
|
|
1007
857
|
* @private
|
|
1008
858
|
*/
|
|
1009
|
-
|
|
1010
|
-
if (
|
|
859
|
+
Dao.prototype._loadImport = async function (file, params, format) {
|
|
860
|
+
if (file.endsWith('.json')) {
|
|
1011
861
|
return file.loadJson(file);
|
|
1012
|
-
} else if (
|
|
862
|
+
} else if (file.endsWith('.xml')) {
|
|
1013
863
|
return file.loadXml(file);
|
|
1014
864
|
} else {
|
|
1015
865
|
const Excel = require('mm_excel');
|
|
@@ -1033,7 +883,7 @@ Drive.prototype._loadImport = async function (file, params, format) {
|
|
|
1033
883
|
* @returns {object} 导入结果
|
|
1034
884
|
* @private
|
|
1035
885
|
*/
|
|
1036
|
-
|
|
886
|
+
Dao.prototype._importToDb = async function (db, jarr) {
|
|
1037
887
|
var list = [];
|
|
1038
888
|
var errors = [];
|
|
1039
889
|
var list_error = [];
|
|
@@ -1073,9 +923,9 @@ Drive.prototype._importToDb = async function (db, jarr) {
|
|
|
1073
923
|
* @returns {object} 返回结果对象
|
|
1074
924
|
* @private
|
|
1075
925
|
*/
|
|
1076
|
-
|
|
926
|
+
Dao.prototype._buildImport = function (result) {
|
|
1077
927
|
var bl = result.list.length === result.total;
|
|
1078
|
-
var body =
|
|
928
|
+
var body = getRet().bl(bl, bl ? '导入成功!' : '导入失败!');
|
|
1079
929
|
body.result.list = result.list;
|
|
1080
930
|
if (result.errors.length) {
|
|
1081
931
|
body.result.list_error = result.list_error;
|
|
@@ -1091,10 +941,10 @@ Drive.prototype._buildImport = function (result) {
|
|
|
1091
941
|
* @param {object} body 导入设置
|
|
1092
942
|
* @returns {object} 返回执行结果
|
|
1093
943
|
*/
|
|
1094
|
-
|
|
944
|
+
Dao.prototype.import = async function (db, query, body) {
|
|
1095
945
|
var params = { ...query, ...body };
|
|
1096
946
|
if (!params.file) {
|
|
1097
|
-
return
|
|
947
|
+
return getRet().error(60000, '文件名(file)参数不能为空');
|
|
1098
948
|
}
|
|
1099
949
|
return await this.importMain(db, params.file);
|
|
1100
950
|
};
|
|
@@ -1109,10 +959,10 @@ Drive.prototype.import = async function (db, query, body) {
|
|
|
1109
959
|
* @property {string} body.path 文件路径 例如: /static/download, 可不填写
|
|
1110
960
|
* @returns {object} 返回执行结果
|
|
1111
961
|
*/
|
|
1112
|
-
|
|
962
|
+
Dao.prototype.exportMain = async function (db, query, body) {
|
|
1113
963
|
var by = await this.getMain(db, query);
|
|
1114
964
|
if (db.error) {
|
|
1115
|
-
return
|
|
965
|
+
return getRet().error(10000, db.error.message);
|
|
1116
966
|
}
|
|
1117
967
|
var config = this._prepareExportConfig(query, body);
|
|
1118
968
|
var params = await this.getParam(db, config.fields);
|
|
@@ -1133,7 +983,7 @@ Drive.prototype.exportMain = async function (db, query, body) {
|
|
|
1133
983
|
* @returns {object} 导出配置
|
|
1134
984
|
* @private
|
|
1135
985
|
*/
|
|
1136
|
-
|
|
986
|
+
Dao.prototype._prepareExportConfig = function (query, body) {
|
|
1137
987
|
var path = body.path;
|
|
1138
988
|
var file = body.file;
|
|
1139
989
|
var fields = body.fields;
|
|
@@ -1158,7 +1008,7 @@ Drive.prototype._prepareExportConfig = function (query, body) {
|
|
|
1158
1008
|
* @returns {string} 导出路径
|
|
1159
1009
|
* @private
|
|
1160
1010
|
*/
|
|
1161
|
-
|
|
1011
|
+
Dao.prototype._getPath = function () {
|
|
1162
1012
|
return (
|
|
1163
1013
|
this._getInject('user_path') ||
|
|
1164
1014
|
this._getInject('static_path') ||
|
|
@@ -1175,7 +1025,7 @@ Drive.prototype._getPath = function () {
|
|
|
1175
1025
|
* @returns {string} 保存后的文件路径
|
|
1176
1026
|
* @private
|
|
1177
1027
|
*/
|
|
1178
|
-
|
|
1028
|
+
Dao.prototype._saveExportFile = async function (file, params, format, list) {
|
|
1179
1029
|
var export_path = this._getPath();
|
|
1180
1030
|
var save_file = file.fullname(file, export_path);
|
|
1181
1031
|
file.addDir(save_file);
|
|
@@ -1199,8 +1049,8 @@ Drive.prototype._saveExportFile = async function (file, params, format, list) {
|
|
|
1199
1049
|
* @returns {object} 导出结果
|
|
1200
1050
|
* @private
|
|
1201
1051
|
*/
|
|
1202
|
-
|
|
1203
|
-
var body =
|
|
1052
|
+
Dao.prototype._buildExport = function (file, name) {
|
|
1053
|
+
var body = getRet().bl(!!file, file ? '导出成功!' : '导出失败!');
|
|
1204
1054
|
body.result.file = file;
|
|
1205
1055
|
body.result.url = this.url_path + name;
|
|
1206
1056
|
return body;
|
|
@@ -1213,7 +1063,7 @@ Drive.prototype._buildExport = function (file, name) {
|
|
|
1213
1063
|
* @param {object} body 修改项
|
|
1214
1064
|
* @returns {object} 返回执行结果
|
|
1215
1065
|
*/
|
|
1216
|
-
|
|
1066
|
+
Dao.prototype.export = async function (db, query, body) {
|
|
1217
1067
|
return await this.exportMain(db, query, body);
|
|
1218
1068
|
};
|
|
1219
1069
|
|
|
@@ -1223,18 +1073,23 @@ Drive.prototype.export = async function (db, query, body) {
|
|
|
1223
1073
|
* @param {object} params 查询参数
|
|
1224
1074
|
* @returns {object} 返回执行结果
|
|
1225
1075
|
*/
|
|
1226
|
-
|
|
1076
|
+
Dao.prototype.delRepeatMain = async function (db, params) {
|
|
1227
1077
|
var pm = { ...params };
|
|
1228
1078
|
var msg = '';
|
|
1229
1079
|
var cg = this.config.del_repeat;
|
|
1230
1080
|
var order_by = pm.orderby || cg.orderby;
|
|
1231
1081
|
delete pm.orderby;
|
|
1082
|
+
var group_by_val = pm.groupby || cg.groupby;
|
|
1232
1083
|
var group_by =
|
|
1233
|
-
|
|
1084
|
+
(typeof group_by_val === 'string' && string.validate(group_by_val, 'username') ? group_by_val : '') ||
|
|
1085
|
+
cg.groupby ||
|
|
1086
|
+
'';
|
|
1234
1087
|
delete pm.groupby;
|
|
1235
1088
|
var f = db.config.filter;
|
|
1236
1089
|
// 设置查询字段
|
|
1237
|
-
var field =
|
|
1090
|
+
var field =
|
|
1091
|
+
(typeof pm[f.field] === 'string' && string.validate(pm[f.field], 'username') ? pm[f.field] : '') ||
|
|
1092
|
+
group_by;
|
|
1238
1093
|
delete pm[f.field];
|
|
1239
1094
|
db.field = field;
|
|
1240
1095
|
var sql = db
|
|
@@ -1261,7 +1116,7 @@ Drive.prototype.delRepeatMain = async function (db, params) {
|
|
|
1261
1116
|
} else {
|
|
1262
1117
|
msg = '没有重复项。';
|
|
1263
1118
|
}
|
|
1264
|
-
return
|
|
1119
|
+
return getRet().bl(!msg, msg ? '去重失败!原因:' + msg : '去重成功!');
|
|
1265
1120
|
};
|
|
1266
1121
|
|
|
1267
1122
|
/**
|
|
@@ -1271,7 +1126,7 @@ Drive.prototype.delRepeatMain = async function (db, params) {
|
|
|
1271
1126
|
* @param {object} body 正文参数
|
|
1272
1127
|
* @returns {object} 返回执行结果
|
|
1273
1128
|
*/
|
|
1274
|
-
|
|
1129
|
+
Dao.prototype.delRepeat = async function (db, query, body) {
|
|
1275
1130
|
var pm = { ...query, ...body };
|
|
1276
1131
|
return await this.delRepeatMain(db, pm);
|
|
1277
1132
|
};
|
|
@@ -1282,7 +1137,7 @@ Drive.prototype.delRepeat = async function (db, query, body) {
|
|
|
1282
1137
|
* @param {object} db 数据管理器
|
|
1283
1138
|
* @returns {object} 返回执行结果
|
|
1284
1139
|
*/
|
|
1285
|
-
|
|
1140
|
+
Dao.prototype.main = async function (params, db) {
|
|
1286
1141
|
var { query, body } = params;
|
|
1287
1142
|
|
|
1288
1143
|
var cg = this.config;
|
|
@@ -1292,7 +1147,7 @@ Drive.prototype.main = async function (params, db) {
|
|
|
1292
1147
|
method = 'get';
|
|
1293
1148
|
}
|
|
1294
1149
|
if (!string.has(cg.method, '*' + method + '*')) {
|
|
1295
|
-
return
|
|
1150
|
+
return getRet().error(50001, '不支持的操作方式');
|
|
1296
1151
|
}
|
|
1297
1152
|
method = this._getMethodName(method);
|
|
1298
1153
|
var qy = { ...query };
|
|
@@ -1303,17 +1158,17 @@ Drive.prototype.main = async function (params, db) {
|
|
|
1303
1158
|
// 过滤查询参数
|
|
1304
1159
|
var f = cg.filter;
|
|
1305
1160
|
var table = query[f.table];
|
|
1306
|
-
var safe_table =
|
|
1161
|
+
var safe_table = typeof table === 'string' && string.validate(table, 'username') ? table : '';
|
|
1307
1162
|
|
|
1308
1163
|
// 设置操作的数据表
|
|
1309
1164
|
if (string.has(cg.table, '*{0}*')) {
|
|
1310
1165
|
if (table) {
|
|
1311
1166
|
if (!safe_table) {
|
|
1312
|
-
return
|
|
1167
|
+
return getRet().error(30001, '表名包含无效字符');
|
|
1313
1168
|
}
|
|
1314
1169
|
db.table = cg.table.replace('{0}', safe_table);
|
|
1315
1170
|
} else {
|
|
1316
|
-
return
|
|
1171
|
+
return getRet().error(30001, '表名不能为空');
|
|
1317
1172
|
}
|
|
1318
1173
|
} else {
|
|
1319
1174
|
db.table = cg.table + '';
|
|
@@ -1321,7 +1176,7 @@ Drive.prototype.main = async function (params, db) {
|
|
|
1321
1176
|
|
|
1322
1177
|
return await this[method](db, qy, { ...body });
|
|
1323
1178
|
} else {
|
|
1324
|
-
return
|
|
1179
|
+
return getRet().error(50001, '不支持的操作方式');
|
|
1325
1180
|
}
|
|
1326
1181
|
};
|
|
1327
1182
|
|
|
@@ -1331,7 +1186,7 @@ Drive.prototype.main = async function (params, db) {
|
|
|
1331
1186
|
* @returns {string} 方法名
|
|
1332
1187
|
* @private
|
|
1333
1188
|
*/
|
|
1334
|
-
|
|
1189
|
+
Dao.prototype._getMethodName = function (method) {
|
|
1335
1190
|
if (!method) {
|
|
1336
1191
|
return '';
|
|
1337
1192
|
}
|
|
@@ -1354,7 +1209,7 @@ Drive.prototype._getMethodName = function (method) {
|
|
|
1354
1209
|
* @param {object} param 查询条件
|
|
1355
1210
|
* @returns {object} 返回执行结果
|
|
1356
1211
|
*/
|
|
1357
|
-
|
|
1212
|
+
Dao.prototype.sumMain = async function (db, param) {
|
|
1358
1213
|
var pm = { ...param };
|
|
1359
1214
|
var ret;
|
|
1360
1215
|
var orderby = pm.orderby || '';
|
|
@@ -1367,13 +1222,13 @@ Drive.prototype.sumMain = async function (db, param) {
|
|
|
1367
1222
|
var query_str = this.toWhere(db, pm, 'get_list');
|
|
1368
1223
|
|
|
1369
1224
|
if (!groupby || !field) {
|
|
1370
|
-
ret =
|
|
1225
|
+
ret = getRet().error(30000, '参数groupby、field是必须的,且值不能为空!');
|
|
1371
1226
|
} else {
|
|
1372
1227
|
var list = await db.groupSumSql(query_str, groupby, field, orderby);
|
|
1373
1228
|
if (!list.length && db.error) {
|
|
1374
|
-
ret =
|
|
1229
|
+
ret = getRet().body(db.error);
|
|
1375
1230
|
} else {
|
|
1376
|
-
ret =
|
|
1231
|
+
ret = getRet().list(list);
|
|
1377
1232
|
}
|
|
1378
1233
|
}
|
|
1379
1234
|
return ret;
|
|
@@ -1386,7 +1241,7 @@ Drive.prototype.sumMain = async function (db, param) {
|
|
|
1386
1241
|
* @param {object} body 正文参数
|
|
1387
1242
|
* @returns {object} 返回执行结果
|
|
1388
1243
|
*/
|
|
1389
|
-
|
|
1244
|
+
Dao.prototype.sum = async function (db, query, body) {
|
|
1390
1245
|
var pm = { ...query, ...body };
|
|
1391
1246
|
return await this.sumMain(db, pm);
|
|
1392
1247
|
};
|
|
@@ -1397,7 +1252,7 @@ Drive.prototype.sum = async function (db, query, body) {
|
|
|
1397
1252
|
* @param {object} param 查询条件
|
|
1398
1253
|
* @returns {object} 返回执行结果
|
|
1399
1254
|
*/
|
|
1400
|
-
|
|
1255
|
+
Dao.prototype.avgMain = async function (db, param) {
|
|
1401
1256
|
var pm = { ...param };
|
|
1402
1257
|
var ret;
|
|
1403
1258
|
var orderby = pm.orderby || '';
|
|
@@ -1410,13 +1265,13 @@ Drive.prototype.avgMain = async function (db, param) {
|
|
|
1410
1265
|
var query_str = this.toWhere(db, pm, 'get_list');
|
|
1411
1266
|
|
|
1412
1267
|
if (!groupby || !field) {
|
|
1413
|
-
ret =
|
|
1268
|
+
ret = getRet().error(30000, '参数groupby、field是必须的,且值不能为空!');
|
|
1414
1269
|
} else {
|
|
1415
1270
|
var list = await db.groupAvgSql(query_str, groupby, field, orderby);
|
|
1416
1271
|
if (!list.length && db.error) {
|
|
1417
|
-
ret =
|
|
1272
|
+
ret = getRet().body(db.error);
|
|
1418
1273
|
} else {
|
|
1419
|
-
ret =
|
|
1274
|
+
ret = getRet().list(list);
|
|
1420
1275
|
}
|
|
1421
1276
|
}
|
|
1422
1277
|
return ret;
|
|
@@ -1429,7 +1284,7 @@ Drive.prototype.avgMain = async function (db, param) {
|
|
|
1429
1284
|
* @param {object} body 正文参数
|
|
1430
1285
|
* @returns {object} 返回执行结果
|
|
1431
1286
|
*/
|
|
1432
|
-
|
|
1287
|
+
Dao.prototype.avg = async function (db, query, body) {
|
|
1433
1288
|
var pm = { ...query, ...body };
|
|
1434
1289
|
return await this.avgMain(db, pm);
|
|
1435
1290
|
};
|
|
@@ -1440,7 +1295,7 @@ Drive.prototype.avg = async function (db, query, body) {
|
|
|
1440
1295
|
* @param {object} param 查询条件
|
|
1441
1296
|
* @returns {object} 返回执行结果
|
|
1442
1297
|
*/
|
|
1443
|
-
|
|
1298
|
+
Dao.prototype.countMain = async function (db, param) {
|
|
1444
1299
|
var pm = { ...param };
|
|
1445
1300
|
var ret;
|
|
1446
1301
|
var orderby = pm.orderby || '';
|
|
@@ -1453,13 +1308,13 @@ Drive.prototype.countMain = async function (db, param) {
|
|
|
1453
1308
|
var query_str = this.toWhere(db, pm, 'get_list');
|
|
1454
1309
|
|
|
1455
1310
|
if (!groupby || !field) {
|
|
1456
|
-
ret =
|
|
1311
|
+
ret = getRet().error(30000, '参数groupby、field是必须的,且值不能为空!');
|
|
1457
1312
|
} else {
|
|
1458
1313
|
var list = await db.groupCountSql(query_str, groupby, field, orderby);
|
|
1459
1314
|
if (!list.length && db.error) {
|
|
1460
|
-
ret =
|
|
1315
|
+
ret = getRet().body(db.error);
|
|
1461
1316
|
} else {
|
|
1462
|
-
ret =
|
|
1317
|
+
ret = getRet().list(list);
|
|
1463
1318
|
}
|
|
1464
1319
|
}
|
|
1465
1320
|
return ret;
|
|
@@ -1472,7 +1327,7 @@ Drive.prototype.countMain = async function (db, param) {
|
|
|
1472
1327
|
* @param {object} body 正文参数
|
|
1473
1328
|
* @returns {object} 返回执行结果
|
|
1474
1329
|
*/
|
|
1475
|
-
|
|
1330
|
+
Dao.prototype.count = async function (db, query, body) {
|
|
1476
1331
|
var pm = { ...query, ...body };
|
|
1477
1332
|
return await this.countMain(db, pm);
|
|
1478
1333
|
};
|
|
@@ -1482,7 +1337,7 @@ Drive.prototype.count = async function (db, query, body) {
|
|
|
1482
1337
|
* @param {string} type 模型类型
|
|
1483
1338
|
* @returns {object} 返回获取到的模型
|
|
1484
1339
|
*/
|
|
1485
|
-
|
|
1340
|
+
Dao.prototype.getModel = function (type) {
|
|
1486
1341
|
let model = { ...this.config };
|
|
1487
1342
|
let dir = this.config.dir || '';
|
|
1488
1343
|
let l = path.sep;
|
|
@@ -1494,4 +1349,4 @@ Drive.prototype.getModel = function (type) {
|
|
|
1494
1349
|
model.name = model.name || app_name + '_' + name;
|
|
1495
1350
|
return model;
|
|
1496
1351
|
};
|
|
1497
|
-
module.exports =
|
|
1352
|
+
module.exports = Dao;
|
package/lib/manager.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
|
-
const Manager = require(
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
2
|
+
const Manager = require('mm_machine').Manager;
|
|
3
|
+
const Dao = require("./dao");
|
|
4
|
+
const { getSql } = require("mm_sql");
|
|
5
5
|
const { array } = require("mm_helper");
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -9,7 +9,7 @@ const { array } = require("mm_helper");
|
|
|
9
9
|
* @augments {Manager}
|
|
10
10
|
* @class
|
|
11
11
|
*/
|
|
12
|
-
class
|
|
12
|
+
class DaoManager extends Manager {
|
|
13
13
|
/**
|
|
14
14
|
* 配置参数
|
|
15
15
|
* @type {object}
|
|
@@ -67,11 +67,9 @@ class SqlManager extends Manager {
|
|
|
67
67
|
* @param {object} parent 父级模块
|
|
68
68
|
*/
|
|
69
69
|
constructor(config, parent) {
|
|
70
|
-
super({ ...
|
|
71
|
-
// 插件注册表(方案B:手动注册,替代原全局插件池)
|
|
72
|
-
this.plugins = {};
|
|
70
|
+
super({ ...DaoManager.config, ...config }, parent);
|
|
73
71
|
// 兼容 Sql 实例(惰性创建,供 db()/load() 等价入口委托)
|
|
74
|
-
this._sql =
|
|
72
|
+
this._sql = getSql();
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
|
|
@@ -79,15 +77,42 @@ class SqlManager extends Manager {
|
|
|
79
77
|
* sql驱动类
|
|
80
78
|
* @type {Drive}
|
|
81
79
|
*/
|
|
82
|
-
|
|
80
|
+
DaoManager.prototype.Drive = Dao;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 初始化桥接(生命周期汇聚点:init() 与 do('init') 均调用,触发 onInit)
|
|
84
|
+
* @returns {Promise<void>} 初始化完成
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
DaoManager.prototype._init = async function () {
|
|
88
|
+
await this.onInit();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 启动桥接(生命周期汇聚点,触发 onStart)
|
|
93
|
+
* @returns {Promise<void>} 启动完成
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
DaoManager.prototype._start = async function () {
|
|
97
|
+
await this.onStart();
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 停止桥接(生命周期汇聚点,触发 onStop)
|
|
102
|
+
* @returns {Promise<void>} 停止完成
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
DaoManager.prototype._stop = async function () {
|
|
106
|
+
await this.onStop();
|
|
107
|
+
};
|
|
83
108
|
|
|
84
109
|
/**
|
|
85
110
|
* 注册一个 sql 驱动(方案B:手动注册,不扫描目录)
|
|
86
111
|
* @param {object} config 驱动配置(必须包含 name)
|
|
87
112
|
* @returns {object} 驱动实例
|
|
88
113
|
*/
|
|
89
|
-
|
|
90
|
-
var drive = new Drive(
|
|
114
|
+
DaoManager.prototype.add = function (config) {
|
|
115
|
+
var drive = new this.Drive(
|
|
91
116
|
{
|
|
92
117
|
dict: this.config.dict,
|
|
93
118
|
get_db_pool: this.config.get_db_pool,
|
|
@@ -107,7 +132,7 @@ SqlManager.prototype.add = function (config) {
|
|
|
107
132
|
* @param {string} name 驱动名称
|
|
108
133
|
* @returns {Promise<boolean>} 是否删除成功
|
|
109
134
|
*/
|
|
110
|
-
|
|
135
|
+
DaoManager.prototype.del = async function (name) {
|
|
111
136
|
var drive = this.get(name);
|
|
112
137
|
if (drive) {
|
|
113
138
|
await drive.stop();
|
|
@@ -121,7 +146,7 @@ SqlManager.prototype.del = async function (name) {
|
|
|
121
146
|
* @param {string} name 驱动名称
|
|
122
147
|
* @returns {Promise<boolean>} 是否执行成功
|
|
123
148
|
*/
|
|
124
|
-
|
|
149
|
+
DaoManager.prototype.reload = async function (name) {
|
|
125
150
|
var drive = this.get(name);
|
|
126
151
|
if (!drive) {
|
|
127
152
|
this.log("warn", "驱动不存在,无法重启", name);
|
|
@@ -139,26 +164,13 @@ SqlManager.prototype.reload = async function (name) {
|
|
|
139
164
|
};
|
|
140
165
|
|
|
141
166
|
/**
|
|
142
|
-
*
|
|
143
|
-
* @param {string} name 插件作用域名称(app 名)
|
|
144
|
-
* @param {object} obj 插件集合对象(需含 get 方法)
|
|
145
|
-
* @returns {object} 当前管理器实例
|
|
146
|
-
*/
|
|
147
|
-
SqlManager.prototype.usePlugin = function (name, obj) {
|
|
148
|
-
this.plugins[name] = obj;
|
|
149
|
-
return this;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* 初始化驱动实例(仅未初始化时执行生命周期 init,重复调用安全)
|
|
167
|
+
* 初始化驱动实例(执行生命周期 init)
|
|
154
168
|
* @param {object} drive 驱动实例
|
|
155
169
|
* @returns {Promise<void>} 初始化完成
|
|
156
170
|
* @private
|
|
157
171
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
await drive.init();
|
|
161
|
-
}
|
|
172
|
+
DaoManager.prototype._initDrive = async function (drive) {
|
|
173
|
+
await drive.init();
|
|
162
174
|
};
|
|
163
175
|
|
|
164
176
|
/**
|
|
@@ -166,7 +178,7 @@ SqlManager.prototype._initDrive = async function (drive) {
|
|
|
166
178
|
* @returns {Array} 驱动配置数组
|
|
167
179
|
* @private
|
|
168
180
|
*/
|
|
169
|
-
|
|
181
|
+
DaoManager.prototype._getInfos = function () {
|
|
170
182
|
return this.values().map((d) => d.config);
|
|
171
183
|
};
|
|
172
184
|
|
|
@@ -174,8 +186,8 @@ SqlManager.prototype._getInfos = function () {
|
|
|
174
186
|
* 排序(返回按名称升序的驱动配置列表)
|
|
175
187
|
* @returns {Array} 排序后的配置列表
|
|
176
188
|
*/
|
|
177
|
-
|
|
178
|
-
var infos = this.
|
|
189
|
+
DaoManager.prototype.sort = function () {
|
|
190
|
+
var infos = this.configs;
|
|
179
191
|
return array.sortBy(infos, "asc", "name");
|
|
180
192
|
};
|
|
181
193
|
|
|
@@ -187,7 +199,7 @@ SqlManager.prototype.sort = function () {
|
|
|
187
199
|
* @param {object} db 数据库管理器 (object) 只支持可用sql语句的数据库
|
|
188
200
|
* @returns {object} 执行结果
|
|
189
201
|
*/
|
|
190
|
-
|
|
202
|
+
DaoManager.prototype.run = async function (name, query, body, db) {
|
|
191
203
|
var obj = this.get(name);
|
|
192
204
|
if (obj) {
|
|
193
205
|
return await obj.run(query, body, db);
|
|
@@ -200,7 +212,7 @@ SqlManager.prototype.run = async function (name, query, body, db) {
|
|
|
200
212
|
* @returns {Sql} 兼容 Sql 实例
|
|
201
213
|
* @private
|
|
202
214
|
*/
|
|
203
|
-
|
|
215
|
+
DaoManager.prototype._getSql = function () {
|
|
204
216
|
if (!this._sql) {
|
|
205
217
|
var SERVER = this.getServer();
|
|
206
218
|
var server_config = (SERVER && SERVER.config) || {};
|
|
@@ -223,7 +235,7 @@ SqlManager.prototype._getSql = function () {
|
|
|
223
235
|
* 获取数据库管理器(等价入口,委托内部 Sql 实例)
|
|
224
236
|
* @returns {object} 数据库管理器实例
|
|
225
237
|
*/
|
|
226
|
-
|
|
238
|
+
DaoManager.prototype.db = function () {
|
|
227
239
|
return this._getSql().db();
|
|
228
240
|
};
|
|
229
241
|
|
|
@@ -232,8 +244,8 @@ SqlManager.prototype.db = function () {
|
|
|
232
244
|
* @param {string} file SQL 文件路径
|
|
233
245
|
* @returns {Promise<object>} 执行结果统计对象
|
|
234
246
|
*/
|
|
235
|
-
|
|
247
|
+
DaoManager.prototype.load = function (file) {
|
|
236
248
|
return this._getSql().load(file);
|
|
237
249
|
};
|
|
238
250
|
|
|
239
|
-
module.exports =
|
|
251
|
+
module.exports = DaoManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_dao",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "一个通用的SQL帮助类,支持通过切换db_type实现对不同数据库的操作,包括MySQL和SQLite等;另提供 manager.js/drive.js 的SQL模板管理器(融合自 mm_os com/sql,基于 mm_corejs,内置管理器池,无全局/原型扩展依赖)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "git+https://
|
|
15
|
+
"url": "git+https://gitee.com/qiuwenwu91/mm_dao.git"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
18
|
"mm_mod",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"mm_infra",
|
|
20
|
+
"mm_runtime",
|
|
21
21
|
"sql",
|
|
22
22
|
"mysql",
|
|
23
23
|
"sql server",
|
|
@@ -42,19 +42,18 @@
|
|
|
42
42
|
"author": "邱文武",
|
|
43
43
|
"license": "ISC",
|
|
44
44
|
"bugs": {
|
|
45
|
-
"url": "https://
|
|
45
|
+
"url": "https://gitee.com/qiuwenwu91/mm_dao/issues"
|
|
46
46
|
},
|
|
47
|
-
"homepage": "https://
|
|
47
|
+
"homepage": "https://gitee.com/qiuwenwu91/mm_dao#readme",
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=12.0.0"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"mm_jsondb": "^1.0.0",
|
|
53
|
-
"mm_mysql": "^2.5.6",
|
|
54
|
-
"mm_sqlite": "^1.5.5",
|
|
55
52
|
"mm_corejs": "^1.1.4",
|
|
53
|
+
"mm_machine": "^3.5.4",
|
|
56
54
|
"mm_helper": "^1.0.0",
|
|
57
55
|
"mm_excel": "^1.2.4",
|
|
56
|
+
"mm_ret": "^1.4.8",
|
|
58
57
|
"mm_sql": "^1.8.0"
|
|
59
58
|
},
|
|
60
59
|
"devDependencies": {
|