mm_dbs 1.0.0 → 1.0.2
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 +50 -0
- package/index.js +2 -2
- package/lib/{drive.js → db.js} +122 -169
- package/lib/manager.js +17 -30
- package/package.json +6 -1
package/example/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mm_dbs 数据库框架示例
|
|
3
|
+
* 演示 dbAdmin() 获取管理器、manager.add() 注册驱动(不连接真实数据库),
|
|
4
|
+
* 以及 Db.model() 字段模型生成与字段 SQL 模板生成。
|
|
5
|
+
* 运行:node example/index.js
|
|
6
|
+
*/
|
|
7
|
+
const { Db, Manager, dbAdmin } = require('../index.js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 主流程
|
|
11
|
+
*/
|
|
12
|
+
function main() {
|
|
13
|
+
// 方式1:通过工厂函数获取数据库管理器实例
|
|
14
|
+
const manager = dbAdmin('example');
|
|
15
|
+
console.log('工厂实例是 Manager 类型:', manager instanceof Manager);
|
|
16
|
+
console.log('admin 缓存同作用域实例:', dbAdmin('example') === manager);
|
|
17
|
+
|
|
18
|
+
// 方式2:注册一个数据库驱动(仅注册配置,不建立连接)
|
|
19
|
+
const drive = manager.add({
|
|
20
|
+
name: 'user',
|
|
21
|
+
title: '用户表',
|
|
22
|
+
table: 'user'
|
|
23
|
+
});
|
|
24
|
+
console.log('驱动是 Db 类型:', drive instanceof Db);
|
|
25
|
+
console.log('驱动表名:', drive.config.table);
|
|
26
|
+
|
|
27
|
+
// 通过字段描述生成字段模型
|
|
28
|
+
const idModel = drive.model({
|
|
29
|
+
name: 'id',
|
|
30
|
+
type: 'int(11)',
|
|
31
|
+
note: '编号:唯一标识',
|
|
32
|
+
pk: true,
|
|
33
|
+
auto: true,
|
|
34
|
+
notnull: true
|
|
35
|
+
});
|
|
36
|
+
const nameModel = drive.model({
|
|
37
|
+
name: 'name',
|
|
38
|
+
type: 'varchar(50)',
|
|
39
|
+
note: '姓名:长度[2,50]',
|
|
40
|
+
notnull: true
|
|
41
|
+
});
|
|
42
|
+
console.log('主键字段模型:', JSON.stringify(idModel, null, 2));
|
|
43
|
+
console.log('姓名字段模型:', JSON.stringify(nameModel, null, 2));
|
|
44
|
+
|
|
45
|
+
// 生成字段 SQL 模板(纯逻辑,无需数据库连接)
|
|
46
|
+
console.log('主键字段 SQL:', drive._generateFieldSql(idModel));
|
|
47
|
+
console.log('姓名字段 SQL:', drive._generateFieldSql(nameModel));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
main();
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const admin = new Admin();
|
|
|
5
5
|
admin.setClass(Manager);
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
|
-
|
|
8
|
+
Db: require('./lib/db'),
|
|
9
9
|
Manager,
|
|
10
10
|
admin,
|
|
11
11
|
/**
|
|
@@ -19,6 +19,6 @@ module.exports = {
|
|
|
19
19
|
if (!scope) {
|
|
20
20
|
scope = 'os';
|
|
21
21
|
}
|
|
22
|
-
return admin.get(scope,
|
|
22
|
+
return admin.get(scope, config, os);
|
|
23
23
|
}
|
|
24
24
|
};
|
package/lib/{drive.js → db.js}
RENAMED
|
@@ -1,82 +1,15 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const Item = require('
|
|
4
|
-
const { string, array, file } = require('mm_helper');
|
|
3
|
+
const Item = require('mm_mod').Base;
|
|
4
|
+
const { string, array, object, file } = require('mm_helper');
|
|
5
5
|
|
|
6
6
|
/** 关键词搜索默认SQL模板(用户表关联查询) */
|
|
7
7
|
const KEYWORD_DEFAULT =
|
|
8
|
-
"`user_id` in (SELECT `user_id` FROM `
|
|
8
|
+
"`user_id` in (SELECT `user_id` FROM `sys_user` WHERE `nickname` LIKE '%{0}%' OR `phone` LIKE '%{0}%' OR `wallet_address` LIKE '%{0}%')";
|
|
9
9
|
|
|
10
10
|
/** 关键词搜索默认提示 */
|
|
11
11
|
const KEYWORD_DEFAULT_TIP = '昵称、手机号、钱包地址';
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
* 按目标类型转换源值(复刻 mm_expand 对象合并的类型转换规则)
|
|
15
|
-
* @param {*} target_val 目标值
|
|
16
|
-
* @param {*} source_val 源值
|
|
17
|
-
* @returns {*} 转换后的值
|
|
18
|
-
*/
|
|
19
|
-
function _convertValue(target_val, source_val) {
|
|
20
|
-
var target_type = typeof target_val;
|
|
21
|
-
if (target_type === 'number') {
|
|
22
|
-
var num = Number(source_val);
|
|
23
|
-
return isNaN(num) ? 0 : num;
|
|
24
|
-
} else if (target_type === 'boolean') {
|
|
25
|
-
if (source_val === '0' || source_val === 'false' || source_val === 'False') {
|
|
26
|
-
return false;
|
|
27
|
-
} else if (source_val === '1' || source_val === 'true' || source_val === 'True') {
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
return Boolean(source_val);
|
|
31
|
-
} else if (target_type === 'string') {
|
|
32
|
-
return String(source_val);
|
|
33
|
-
}
|
|
34
|
-
return source_val;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 深度合并对象属性(替代原全局 push 深合并)
|
|
39
|
-
* @param {object} target 被添加的对象
|
|
40
|
-
* @param {object} source 用作添加的对象
|
|
41
|
-
* @param {boolean} supplement 是否补充目标没有的属性
|
|
42
|
-
* @returns {object} 修改后的目标对象
|
|
43
|
-
*/
|
|
44
|
-
function _push(target, source, supplement) {
|
|
45
|
-
if (!target || !source || typeof target !== 'object' || typeof source !== 'object') {
|
|
46
|
-
return target;
|
|
47
|
-
}
|
|
48
|
-
for (var key in source) {
|
|
49
|
-
if (target.hasOwnProperty(key)) {
|
|
50
|
-
var target_val = target[key];
|
|
51
|
-
var source_val = source[key];
|
|
52
|
-
if (typeof target_val === 'object' && typeof source_val === 'object') {
|
|
53
|
-
_push(target_val, source_val, supplement);
|
|
54
|
-
} else if (typeof target_val === typeof source_val) {
|
|
55
|
-
target[key] = _convertValue(target_val, source_val);
|
|
56
|
-
}
|
|
57
|
-
} else if (supplement) {
|
|
58
|
-
target[key] = source[key];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return target;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 补全文件路径(相对路径基于当前工作目录或指定基准目录)
|
|
66
|
-
* @param {string} file 文件路径
|
|
67
|
-
* @param {string} dir 基准目录(可选)
|
|
68
|
-
* @returns {string} 完整路径
|
|
69
|
-
*/
|
|
70
|
-
function _resolvePath(file, dir) {
|
|
71
|
-
if (!file || typeof file !== 'string') {
|
|
72
|
-
return process.cwd();
|
|
73
|
-
}
|
|
74
|
-
if (path.isAbsolute(file)) {
|
|
75
|
-
return file;
|
|
76
|
-
}
|
|
77
|
-
return path.resolve(dir || process.cwd(), file);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
13
|
/**
|
|
81
14
|
* 对LIKE查询中的关键词进行转义, 防止通配符注入和性能攻击
|
|
82
15
|
* @param {string} keyword 原始关键词
|
|
@@ -97,7 +30,7 @@ var escapeLikeKeyword = function (keyword) {
|
|
|
97
30
|
* @augments {Item}
|
|
98
31
|
* @class
|
|
99
32
|
*/
|
|
100
|
-
class
|
|
33
|
+
class Db extends Item {
|
|
101
34
|
static config = {
|
|
102
35
|
// 库表名称(唯一标识)
|
|
103
36
|
name: '',
|
|
@@ -127,7 +60,7 @@ class Drive extends Item {
|
|
|
127
60
|
* @class
|
|
128
61
|
*/
|
|
129
62
|
constructor(config, parent) {
|
|
130
|
-
super({ ...
|
|
63
|
+
super({ ...Db.config, ...config });
|
|
131
64
|
|
|
132
65
|
// 父级管理器引用(用于配置回退与插件查找)
|
|
133
66
|
this.parent = parent || null;
|
|
@@ -149,7 +82,7 @@ class Drive extends Item {
|
|
|
149
82
|
/**
|
|
150
83
|
* 重置配置参数
|
|
151
84
|
*/
|
|
152
|
-
|
|
85
|
+
Db.prototype._preset = function () {
|
|
153
86
|
this.query_string = [
|
|
154
87
|
'name',
|
|
155
88
|
'title',
|
|
@@ -180,7 +113,7 @@ Drive.prototype._preset = function () {
|
|
|
180
113
|
* @param {string} type 字段类型
|
|
181
114
|
* @returns {object} 解析结果
|
|
182
115
|
*/
|
|
183
|
-
|
|
116
|
+
Db.prototype._parseFieldType = function (type) {
|
|
184
117
|
var tp = string.left(type, '(', true);
|
|
185
118
|
var len = string.between(type, '(', ')');
|
|
186
119
|
var max = 0;
|
|
@@ -202,7 +135,7 @@ Drive.prototype._parseFieldType = function (type) {
|
|
|
202
135
|
* @param {number} max_length 最大长度
|
|
203
136
|
* @returns {object} 解析结果
|
|
204
137
|
*/
|
|
205
|
-
|
|
138
|
+
Db.prototype._parseFieldNote = function (note, tp, max_length) {
|
|
206
139
|
var proc_note = note.replace(':', ':').replace('(', '(').replace(')', ')');
|
|
207
140
|
var title = string.left(proc_note, ':', true).trim();
|
|
208
141
|
var desc = string.right(proc_note, ':');
|
|
@@ -256,7 +189,7 @@ Drive.prototype._parseFieldNote = function (note, tp, max_length) {
|
|
|
256
189
|
* @param {number} max_length 最大长度
|
|
257
190
|
* @returns {number} 计算后的最大值
|
|
258
191
|
*/
|
|
259
|
-
|
|
192
|
+
Db.prototype._calcMaxValue = function (tp, max, max_length) {
|
|
260
193
|
var local_max = max;
|
|
261
194
|
if (local_max === 0) {
|
|
262
195
|
switch (tp) {
|
|
@@ -295,7 +228,7 @@ Drive.prototype._calcMaxValue = function (tp, max, max_length) {
|
|
|
295
228
|
* @param {*} default_val 默认值
|
|
296
229
|
* @returns {*} 处理后的默认值
|
|
297
230
|
*/
|
|
298
|
-
|
|
231
|
+
Db.prototype._handleDefaultValue = function (tp, not_null, default_val) {
|
|
299
232
|
if (not_null && !default_val) {
|
|
300
233
|
if (tp === 'varchar' || tp === 'text') {
|
|
301
234
|
return '';
|
|
@@ -327,7 +260,7 @@ Drive.prototype._handleDefaultValue = function (tp, not_null, default_val) {
|
|
|
327
260
|
* @returns {object} 字段模型对象
|
|
328
261
|
* @private
|
|
329
262
|
*/
|
|
330
|
-
|
|
263
|
+
Db.prototype._createFieldModel = function (
|
|
331
264
|
name,
|
|
332
265
|
title,
|
|
333
266
|
description,
|
|
@@ -391,7 +324,7 @@ Drive.prototype._createFieldModel = function (
|
|
|
391
324
|
* @param {object} fields.note 字段备注
|
|
392
325
|
* @returns {object} 返回字段模型
|
|
393
326
|
*/
|
|
394
|
-
|
|
327
|
+
Db.prototype.model = function (fields) {
|
|
395
328
|
var { name, notnull, type, pk, note, auto } = fields;
|
|
396
329
|
|
|
397
330
|
var { tp, max: max_length, decimal } = this._parseFieldType(type);
|
|
@@ -447,7 +380,7 @@ Drive.prototype.model = function (fields) {
|
|
|
447
380
|
* @property {string} o.Manager_comment 索引备注
|
|
448
381
|
* @returns {object} 返回索引模型
|
|
449
382
|
*/
|
|
450
|
-
|
|
383
|
+
Db.prototype.newIndexModel = function (o) {
|
|
451
384
|
return {
|
|
452
385
|
name: o.Key_name,
|
|
453
386
|
type: o.Non_unique ? 'unique' : 'index',
|
|
@@ -461,7 +394,7 @@ Drive.prototype.newIndexModel = function (o) {
|
|
|
461
394
|
* @param {object} db 数据库管理器
|
|
462
395
|
* @returns {Array} 索引列表
|
|
463
396
|
*/
|
|
464
|
-
|
|
397
|
+
Db.prototype._updateFile = async function (db) {
|
|
465
398
|
var sql = 'SHOW INDEX FROM `' + this.config.table + '`';
|
|
466
399
|
var rows = await db.run(sql);
|
|
467
400
|
var dict = {};
|
|
@@ -490,7 +423,7 @@ Drive.prototype._updateFile = async function (db) {
|
|
|
490
423
|
* @param {object} db 数据库管理器
|
|
491
424
|
* @param {boolean} cover 是否覆盖文件
|
|
492
425
|
*/
|
|
493
|
-
|
|
426
|
+
Db.prototype.updateFile = async function (db, cover) {
|
|
494
427
|
var cg = this.config;
|
|
495
428
|
var list = [];
|
|
496
429
|
|
|
@@ -534,7 +467,7 @@ Drive.prototype.updateFile = async function (db, cover) {
|
|
|
534
467
|
* 更新索引
|
|
535
468
|
* @param {object} db 数据库管理器
|
|
536
469
|
*/
|
|
537
|
-
|
|
470
|
+
Db.prototype._updateDb = async function (db) {
|
|
538
471
|
var cg = this.config;
|
|
539
472
|
let index = cg.index || [];
|
|
540
473
|
// 更新索引
|
|
@@ -562,7 +495,7 @@ Drive.prototype._updateDb = async function (db) {
|
|
|
562
495
|
* @param {Array} list 字段列表
|
|
563
496
|
* @returns {Array} 字段列表
|
|
564
497
|
*/
|
|
565
|
-
|
|
498
|
+
Db.prototype._initTable = async function (db, cg, list) {
|
|
566
499
|
var fields = await db.fields();
|
|
567
500
|
if (fields.length === 0) {
|
|
568
501
|
var k = cg.key;
|
|
@@ -599,7 +532,7 @@ Drive.prototype._initTable = async function (db, cg, list) {
|
|
|
599
532
|
* @param {Array} fields 数据库字段列表
|
|
600
533
|
* @param {Array} list 配置字段列表
|
|
601
534
|
*/
|
|
602
|
-
|
|
535
|
+
Db.prototype._deleteUnusedFields = async function (db, fields, list) {
|
|
603
536
|
for (var i = 0; i < fields.length; i++) {
|
|
604
537
|
var o = fields[i];
|
|
605
538
|
var obj = array.getObj(list, {
|
|
@@ -617,7 +550,7 @@ Drive.prototype._deleteUnusedFields = async function (db, fields, list) {
|
|
|
617
550
|
* @param {object} o 字段对象
|
|
618
551
|
* @returns {string} 字段SQL
|
|
619
552
|
*/
|
|
620
|
-
|
|
553
|
+
Db.prototype._generateFieldSql = function (o) {
|
|
621
554
|
var type = this._getTypeSql(o);
|
|
622
555
|
var notnull = this._getNotNullSql(o);
|
|
623
556
|
var value = this._getValueSql(o);
|
|
@@ -631,7 +564,7 @@ Drive.prototype._generateFieldSql = function (o) {
|
|
|
631
564
|
* @returns {string} 类型SQL
|
|
632
565
|
* @private
|
|
633
566
|
*/
|
|
634
|
-
|
|
567
|
+
Db.prototype._getTypeSql = function (o) {
|
|
635
568
|
var type = o.type;
|
|
636
569
|
var max_len = o.max_length || 0;
|
|
637
570
|
|
|
@@ -672,7 +605,7 @@ Drive.prototype._getTypeSql = function (o) {
|
|
|
672
605
|
* @returns {string} NOT NULL SQL
|
|
673
606
|
* @private
|
|
674
607
|
*/
|
|
675
|
-
|
|
608
|
+
Db.prototype._getNotNullSql = function (o) {
|
|
676
609
|
var notnull = '';
|
|
677
610
|
|
|
678
611
|
if (this._isNotNullRequired(o)) {
|
|
@@ -692,7 +625,7 @@ Drive.prototype._getNotNullSql = function (o) {
|
|
|
692
625
|
* @returns {boolean} 是否需要NOT NULL
|
|
693
626
|
* @private
|
|
694
627
|
*/
|
|
695
|
-
|
|
628
|
+
Db.prototype._isNotNullRequired = function (o) {
|
|
696
629
|
return (
|
|
697
630
|
o.not_null || this._isDateTimeType(o.type) || this._isNumericType(o.type)
|
|
698
631
|
);
|
|
@@ -704,7 +637,7 @@ Drive.prototype._isNotNullRequired = function (o) {
|
|
|
704
637
|
* @returns {boolean} 是否为日期时间类型
|
|
705
638
|
* @private
|
|
706
639
|
*/
|
|
707
|
-
|
|
640
|
+
Db.prototype._isDateTimeType = function (type) {
|
|
708
641
|
return (
|
|
709
642
|
type === 'date' ||
|
|
710
643
|
type === 'time' ||
|
|
@@ -719,7 +652,7 @@ Drive.prototype._isDateTimeType = function (type) {
|
|
|
719
652
|
* @returns {boolean} 是否为数字类型
|
|
720
653
|
* @private
|
|
721
654
|
*/
|
|
722
|
-
|
|
655
|
+
Db.prototype._isNumericType = function (type) {
|
|
723
656
|
return (
|
|
724
657
|
type !== 'varchar' &&
|
|
725
658
|
type !== 'longtext' &&
|
|
@@ -734,7 +667,7 @@ Drive.prototype._isNumericType = function (type) {
|
|
|
734
667
|
* @returns {boolean} 是否需要AUTO_INCREMENT
|
|
735
668
|
* @private
|
|
736
669
|
*/
|
|
737
|
-
|
|
670
|
+
Db.prototype._isAutoInc = function (o) {
|
|
738
671
|
return !!o.auto && !this._isDateTimeType(o.type);
|
|
739
672
|
};
|
|
740
673
|
|
|
@@ -744,7 +677,7 @@ Drive.prototype._isAutoInc = function (o) {
|
|
|
744
677
|
* @returns {string} 默认值SQL
|
|
745
678
|
* @private
|
|
746
679
|
*/
|
|
747
|
-
|
|
680
|
+
Db.prototype._getValueSql = function (o) {
|
|
748
681
|
if (this._isAutoTime(o)) {
|
|
749
682
|
return 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
|
|
750
683
|
}
|
|
@@ -771,7 +704,7 @@ Drive.prototype._getValueSql = function (o) {
|
|
|
771
704
|
* @returns {boolean} 是否为自动时间
|
|
772
705
|
* @private
|
|
773
706
|
*/
|
|
774
|
-
|
|
707
|
+
Db.prototype._isAutoTime = function (o) {
|
|
775
708
|
return !!o.auto && this._isDateTimeType(o.type);
|
|
776
709
|
};
|
|
777
710
|
|
|
@@ -781,7 +714,7 @@ Drive.prototype._isAutoTime = function (o) {
|
|
|
781
714
|
* @returns {string} 默认值SQL
|
|
782
715
|
* @private
|
|
783
716
|
*/
|
|
784
|
-
|
|
717
|
+
Db.prototype._getDefaultValueSql = function (o) {
|
|
785
718
|
if (this._isCurrentDefault(o)) {
|
|
786
719
|
return 'DEFAULT ' + o.default;
|
|
787
720
|
} else if (this._isQuotableType(o.type)) {
|
|
@@ -797,7 +730,7 @@ Drive.prototype._getDefaultValueSql = function (o) {
|
|
|
797
730
|
* @returns {boolean} 是否为当前时间默认值
|
|
798
731
|
* @private
|
|
799
732
|
*/
|
|
800
|
-
|
|
733
|
+
Db.prototype._isCurrentDefault = function (o) {
|
|
801
734
|
return (
|
|
802
735
|
this._isDateTimeType(o.type) &&
|
|
803
736
|
o.default &&
|
|
@@ -811,7 +744,7 @@ Drive.prototype._isCurrentDefault = function (o) {
|
|
|
811
744
|
* @returns {boolean} 需要引号返回true,否则返回false
|
|
812
745
|
* @private
|
|
813
746
|
*/
|
|
814
|
-
|
|
747
|
+
Db.prototype._isQuotableType = function (type) {
|
|
815
748
|
return (
|
|
816
749
|
type === 'varchar' ||
|
|
817
750
|
type === 'longtext' ||
|
|
@@ -829,7 +762,7 @@ Drive.prototype._isQuotableType = function (type) {
|
|
|
829
762
|
* @returns {string} 空默认值SQL
|
|
830
763
|
* @private
|
|
831
764
|
*/
|
|
832
|
-
|
|
765
|
+
Db.prototype._getDefaultEmptySql = function (o) {
|
|
833
766
|
if (this._isStringType(o.type)) {
|
|
834
767
|
return "DEFAULT ''";
|
|
835
768
|
} else {
|
|
@@ -843,7 +776,7 @@ Drive.prototype._getDefaultEmptySql = function (o) {
|
|
|
843
776
|
* @returns {string} 注释SQL
|
|
844
777
|
* @private
|
|
845
778
|
*/
|
|
846
|
-
|
|
779
|
+
Db.prototype._getNoteSql = function (o) {
|
|
847
780
|
var note = (o.title || '') + ':';
|
|
848
781
|
|
|
849
782
|
if (o.type === 'varchar' || o.type === 'text' || o.type === 'longtext') {
|
|
@@ -878,7 +811,7 @@ Drive.prototype._getNoteSql = function (o) {
|
|
|
878
811
|
* @returns {string} 字段SQL
|
|
879
812
|
* @private
|
|
880
813
|
*/
|
|
881
|
-
|
|
814
|
+
Db.prototype._buildFieldSql = function (name, type, notnull, value, note) {
|
|
882
815
|
var sql = "`{1}` {2} {3} {4} COMMENT '{5}'";
|
|
883
816
|
return sql
|
|
884
817
|
.replace('{1}', name)
|
|
@@ -895,7 +828,7 @@ Drive.prototype._buildFieldSql = function (name, type, notnull, value, note) {
|
|
|
895
828
|
* @param {object} o 字段对象
|
|
896
829
|
* @param {Array} fields 数据库字段列表
|
|
897
830
|
*/
|
|
898
|
-
|
|
831
|
+
Db.prototype._addOrUpdateField = async function (db, table, o, fields) {
|
|
899
832
|
var arr = fields.filter((f) => {
|
|
900
833
|
return f.name === o.name;
|
|
901
834
|
});
|
|
@@ -919,7 +852,7 @@ Drive.prototype._addOrUpdateField = async function (db, table, o, fields) {
|
|
|
919
852
|
* @param {object} db 数据库管理器
|
|
920
853
|
* @returns {string} 更新成功返回空,否则返回错误提示
|
|
921
854
|
*/
|
|
922
|
-
|
|
855
|
+
Db.prototype.updateDb = async function (db) {
|
|
923
856
|
var cg = this.config;
|
|
924
857
|
var table = cg.table + '';
|
|
925
858
|
var list = cg.fields;
|
|
@@ -947,14 +880,14 @@ Drive.prototype.updateDb = async function (db) {
|
|
|
947
880
|
* @returns {object} 目录信息
|
|
948
881
|
* @private
|
|
949
882
|
*/
|
|
950
|
-
|
|
883
|
+
Db.prototype._deteDir = function (cg) {
|
|
951
884
|
var arr = cg.table.split('_');
|
|
952
885
|
var scope = arr[0];
|
|
953
|
-
var p =
|
|
954
|
-
var dir =
|
|
955
|
-
var dir_api =
|
|
956
|
-
var db_dir =
|
|
957
|
-
var config_file =
|
|
886
|
+
var p = file.fullname('./app/');
|
|
887
|
+
var dir = file.fullname('./' + scope, p);
|
|
888
|
+
var dir_api = file.fullname('./plugin/server', dir);
|
|
889
|
+
var db_dir = file.fullname('./db', dir_api);
|
|
890
|
+
var config_file = file.fullname(
|
|
958
891
|
'./' + cg.table.replace(scope + '_', '') + '.db.json',
|
|
959
892
|
db_dir,
|
|
960
893
|
);
|
|
@@ -973,7 +906,7 @@ Drive.prototype._deteDir = function (cg) {
|
|
|
973
906
|
* @param {string} dir 目录路径
|
|
974
907
|
* @private
|
|
975
908
|
*/
|
|
976
|
-
|
|
909
|
+
Db.prototype._ensureDir = function (dir) {
|
|
977
910
|
if (!fs.existsSync(dir)) {
|
|
978
911
|
fs.mkdirSync(dir);
|
|
979
912
|
}
|
|
@@ -983,7 +916,7 @@ Drive.prototype._ensureDir = function (dir) {
|
|
|
983
916
|
* 保存当前配置到配置文件(替代旧基类 save)
|
|
984
917
|
* @returns {void}
|
|
985
918
|
*/
|
|
986
|
-
|
|
919
|
+
Db.prototype.save = function () {
|
|
987
920
|
if (!this.config_file) {
|
|
988
921
|
return;
|
|
989
922
|
}
|
|
@@ -1014,7 +947,7 @@ Drive.prototype.save = function () {
|
|
|
1014
947
|
* 获取当前驱动目录(替代旧基类 getDir)
|
|
1015
948
|
* @returns {string} 目录路径
|
|
1016
949
|
*/
|
|
1017
|
-
|
|
950
|
+
Db.prototype.getDir = function () {
|
|
1018
951
|
if (this._dir) {
|
|
1019
952
|
return this._dir;
|
|
1020
953
|
}
|
|
@@ -1029,7 +962,7 @@ Drive.prototype.getDir = function () {
|
|
|
1029
962
|
* @returns {object|null} 事件接口管理器实例,未配置返回null
|
|
1030
963
|
* @private
|
|
1031
964
|
*/
|
|
1032
|
-
|
|
965
|
+
Db.prototype._getEventApi = function () {
|
|
1033
966
|
var getter = this.config.get_event_api;
|
|
1034
967
|
if (typeof getter !== 'function' && this.parent) {
|
|
1035
968
|
getter = this.parent.config.get_event_api;
|
|
@@ -1037,20 +970,40 @@ Drive.prototype._getEventApi = function () {
|
|
|
1037
970
|
if (typeof getter === 'function') {
|
|
1038
971
|
return getter();
|
|
1039
972
|
}
|
|
973
|
+
var admin = this._getHostApiAdmin();
|
|
974
|
+
if (admin) {
|
|
975
|
+
return admin;
|
|
976
|
+
}
|
|
1040
977
|
if (!this._event_api_warned) {
|
|
1041
978
|
this._event_api_warned = true;
|
|
1042
|
-
this.log('warn', '未配置 get_event_api
|
|
979
|
+
this.log('warn', '未配置 get_event_api 且宿主API管理器不可用,API目录判断使用默认路径');
|
|
1043
980
|
}
|
|
1044
981
|
return null;
|
|
1045
982
|
};
|
|
1046
983
|
|
|
984
|
+
/**
|
|
985
|
+
* 获取宿主API管理器工厂(未注入 get_event_api 时的回退)
|
|
986
|
+
* @returns {object|null} 支持按作用域取管理器的工厂;宿主不可用时返回null
|
|
987
|
+
* @private
|
|
988
|
+
*/
|
|
989
|
+
Db.prototype._getHostApiAdmin = function () {
|
|
990
|
+
var manager = this.parent;
|
|
991
|
+
var server = manager && typeof manager.getServer === 'function' ? manager.getServer() : null;
|
|
992
|
+
var container = server && server.container;
|
|
993
|
+
if (!container) {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
var factory = container.get('api_admin');
|
|
997
|
+
return factory && typeof factory.get === 'function' ? factory : null;
|
|
998
|
+
};
|
|
999
|
+
|
|
1047
1000
|
/**
|
|
1048
1001
|
* 处理配置文件
|
|
1049
1002
|
* @param {string} f 文件路径
|
|
1050
1003
|
* @param {boolean} cover 是否覆盖文件
|
|
1051
1004
|
* @private
|
|
1052
1005
|
*/
|
|
1053
|
-
|
|
1006
|
+
Db.prototype._handleConfigFile = function (f, cover) {
|
|
1054
1007
|
if (!file.hasFile(f)) {
|
|
1055
1008
|
this.save();
|
|
1056
1009
|
} else if (cover) {
|
|
@@ -1062,7 +1015,7 @@ Drive.prototype._handleConfigFile = function (f, cover) {
|
|
|
1062
1015
|
if (!o.description) {
|
|
1063
1016
|
delete o.description;
|
|
1064
1017
|
}
|
|
1065
|
-
|
|
1018
|
+
object.push(jobj, o, true);
|
|
1066
1019
|
file.saveText(f, JSON.stringify(jobj, null, 2));
|
|
1067
1020
|
}
|
|
1068
1021
|
};
|
|
@@ -1071,7 +1024,7 @@ Drive.prototype._handleConfigFile = function (f, cover) {
|
|
|
1071
1024
|
* 更新应用,根据表生成目录结构和文件
|
|
1072
1025
|
* @param {boolean} cover 是否覆盖文件
|
|
1073
1026
|
*/
|
|
1074
|
-
|
|
1027
|
+
Db.prototype.updateApp = async function (cover) {
|
|
1075
1028
|
var cg = this.config;
|
|
1076
1029
|
var f;
|
|
1077
1030
|
var dir_api;
|
|
@@ -1111,7 +1064,7 @@ Drive.prototype.updateApp = async function (cover) {
|
|
|
1111
1064
|
* @param {string} dir 目录路径
|
|
1112
1065
|
* @private
|
|
1113
1066
|
*/
|
|
1114
|
-
|
|
1067
|
+
Db.prototype._ensureApiDir = function (dir) {
|
|
1115
1068
|
if (!fs.existsSync(dir)) {
|
|
1116
1069
|
fs.mkdirSync(dir);
|
|
1117
1070
|
}
|
|
@@ -1126,7 +1079,7 @@ Drive.prototype._ensureApiDir = function (dir) {
|
|
|
1126
1079
|
* @returns {string} 完整目录路径
|
|
1127
1080
|
* @private
|
|
1128
1081
|
*/
|
|
1129
|
-
|
|
1082
|
+
Db.prototype._getApiDir = function (dir, app, type, name) {
|
|
1130
1083
|
var l = path.sep;
|
|
1131
1084
|
var event_api = this._getEventApi();
|
|
1132
1085
|
var o =
|
|
@@ -1153,7 +1106,7 @@ Drive.prototype._getApiDir = function (dir, app, type, name) {
|
|
|
1153
1106
|
* @param {string} dir API存放目录
|
|
1154
1107
|
* @param {boolean} cover 是否覆盖文件
|
|
1155
1108
|
*/
|
|
1156
|
-
|
|
1109
|
+
Db.prototype.updateApi = async function (dir, cover) {
|
|
1157
1110
|
var cg = this.config;
|
|
1158
1111
|
var arr = cg.table.split('_');
|
|
1159
1112
|
|
|
@@ -1177,7 +1130,7 @@ Drive.prototype.updateApi = async function (dir, cover) {
|
|
|
1177
1130
|
* @param {string} path 检索路径
|
|
1178
1131
|
* @param {string} scope 接口域
|
|
1179
1132
|
*/
|
|
1180
|
-
|
|
1133
|
+
Db.prototype.newEvent = async function (dir, path, scope) {
|
|
1181
1134
|
var f = dir + '/main.js';
|
|
1182
1135
|
if (!file.hasFile(f)) {
|
|
1183
1136
|
var code = file.loadText(__dirname + '/event_script.js');
|
|
@@ -1192,7 +1145,7 @@ Drive.prototype.newEvent = async function (dir, path, scope) {
|
|
|
1192
1145
|
* @returns {Array} 处理后的列表
|
|
1193
1146
|
* @private
|
|
1194
1147
|
*/
|
|
1195
|
-
|
|
1148
|
+
Db.prototype._handleCommaList = function (list) {
|
|
1196
1149
|
return list.map((o) => {
|
|
1197
1150
|
var arr = o.split(',');
|
|
1198
1151
|
var value = arr[0];
|
|
@@ -1217,7 +1170,7 @@ Drive.prototype._handleCommaList = function (list) {
|
|
|
1217
1170
|
* @returns {Array} 处理后的列表
|
|
1218
1171
|
* @private
|
|
1219
1172
|
*/
|
|
1220
|
-
|
|
1173
|
+
Db.prototype._handleNumberList = function (list, map) {
|
|
1221
1174
|
if (map.indexOf('0') !== 0) {
|
|
1222
1175
|
list.unshift('');
|
|
1223
1176
|
}
|
|
@@ -1232,7 +1185,7 @@ Drive.prototype._handleNumberList = function (list, map) {
|
|
|
1232
1185
|
* @returns {Array} 处理后的列表
|
|
1233
1186
|
* @private
|
|
1234
1187
|
*/
|
|
1235
|
-
|
|
1188
|
+
Db.prototype._handleSimpleList = function (list) {
|
|
1236
1189
|
return list.map((value) => {
|
|
1237
1190
|
return {
|
|
1238
1191
|
name: value,
|
|
@@ -1248,7 +1201,7 @@ Drive.prototype._handleSimpleList = function (list) {
|
|
|
1248
1201
|
* @returns {object} 处理后的格式对象
|
|
1249
1202
|
* @private
|
|
1250
1203
|
*/
|
|
1251
|
-
|
|
1204
|
+
Db.prototype._handleDotMap = function (obj, map) {
|
|
1252
1205
|
var arr = map.split('.');
|
|
1253
1206
|
var format = {
|
|
1254
1207
|
table: arr[0],
|
|
@@ -1269,7 +1222,7 @@ Drive.prototype._handleDotMap = function (obj, map) {
|
|
|
1269
1222
|
* @returns {object} 处理后的格式对象
|
|
1270
1223
|
* @private
|
|
1271
1224
|
*/
|
|
1272
|
-
|
|
1225
|
+
Db.prototype._handleSimpleMap = function (obj, map) {
|
|
1273
1226
|
return {
|
|
1274
1227
|
table: map,
|
|
1275
1228
|
id: obj.name,
|
|
@@ -1282,7 +1235,7 @@ Drive.prototype._handleSimpleMap = function (obj, map) {
|
|
|
1282
1235
|
* @param {object} obj 字段对象
|
|
1283
1236
|
* @returns {object} 返回格式
|
|
1284
1237
|
*/
|
|
1285
|
-
|
|
1238
|
+
Db.prototype.getFormat = async function (obj) {
|
|
1286
1239
|
var map = obj.map;
|
|
1287
1240
|
var format = {
|
|
1288
1241
|
key: obj.name,
|
|
@@ -1316,7 +1269,7 @@ Drive.prototype.getFormat = async function (obj) {
|
|
|
1316
1269
|
* @returns {object} 处理结果
|
|
1317
1270
|
* @private
|
|
1318
1271
|
*/
|
|
1319
|
-
|
|
1272
|
+
Db.prototype._procFieldSel = function (field_name, field_type) {
|
|
1320
1273
|
var res = {
|
|
1321
1274
|
field: '',
|
|
1322
1275
|
field_obj: '',
|
|
@@ -1339,7 +1292,7 @@ Drive.prototype._procFieldSel = function (field_name, field_type) {
|
|
|
1339
1292
|
* @returns {string} 更新后的关键词
|
|
1340
1293
|
* @private
|
|
1341
1294
|
*/
|
|
1342
|
-
|
|
1295
|
+
Db.prototype._procStringQuery = function (query, field_name, keyword) {
|
|
1343
1296
|
var new_keyword = keyword;
|
|
1344
1297
|
query[field_name] = '`' + field_name + "` like '%{0}%'";
|
|
1345
1298
|
if (this.isSet(field_name, this.query_keyword)) {
|
|
@@ -1354,7 +1307,7 @@ Drive.prototype._procStringQuery = function (query, field_name, keyword) {
|
|
|
1354
1307
|
* @param {string} field_name 字段名
|
|
1355
1308
|
* @private
|
|
1356
1309
|
*/
|
|
1357
|
-
|
|
1310
|
+
Db.prototype._procDateTimeQuery = function (query, field_name) {
|
|
1358
1311
|
query[field_name + '_min'] = '`' + field_name + "` >= '{0}'";
|
|
1359
1312
|
query[field_name + '_max'] = '`' + field_name + "` <= '{0}'";
|
|
1360
1313
|
};
|
|
@@ -1370,7 +1323,7 @@ Drive.prototype._procDateTimeQuery = function (query, field_name) {
|
|
|
1370
1323
|
* @returns {object} 处理结果
|
|
1371
1324
|
* @private
|
|
1372
1325
|
*/
|
|
1373
|
-
|
|
1326
|
+
Db.prototype._procNumberQuery = function (
|
|
1374
1327
|
query,
|
|
1375
1328
|
update_obj,
|
|
1376
1329
|
field_name,
|
|
@@ -1418,7 +1371,7 @@ Drive.prototype._procNumberQuery = function (
|
|
|
1418
1371
|
* @returns {object} 处理结果
|
|
1419
1372
|
* @private
|
|
1420
1373
|
*/
|
|
1421
|
-
|
|
1374
|
+
Db.prototype._procFieldType = function (
|
|
1422
1375
|
type,
|
|
1423
1376
|
field_name,
|
|
1424
1377
|
query,
|
|
@@ -1475,7 +1428,7 @@ Drive.prototype._procFieldType = function (
|
|
|
1475
1428
|
* @returns {object} 处理结果
|
|
1476
1429
|
* @private
|
|
1477
1430
|
*/
|
|
1478
|
-
|
|
1431
|
+
Db.prototype._procSingleField = async function (
|
|
1479
1432
|
o,
|
|
1480
1433
|
query,
|
|
1481
1434
|
update_obj,
|
|
@@ -1531,7 +1484,7 @@ Drive.prototype._procSingleField = async function (
|
|
|
1531
1484
|
* @returns {object} 处理结果
|
|
1532
1485
|
* @private
|
|
1533
1486
|
*/
|
|
1534
|
-
|
|
1487
|
+
Db.prototype._procFields = async function (fields, table) {
|
|
1535
1488
|
var query = {};
|
|
1536
1489
|
var update_obj = {};
|
|
1537
1490
|
var field = '';
|
|
@@ -1588,7 +1541,7 @@ Drive.prototype._procFields = async function (fields, table) {
|
|
|
1588
1541
|
* @returns {object} 处理后的查询对象
|
|
1589
1542
|
* @private
|
|
1590
1543
|
*/
|
|
1591
|
-
|
|
1544
|
+
Db.prototype._procKeyword = function (keyword, table) {
|
|
1592
1545
|
var safe_keyword = escapeLikeKeyword(keyword);
|
|
1593
1546
|
var new_keyword = safe_keyword;
|
|
1594
1547
|
if (table.indexOf('user_') !== -1) {
|
|
@@ -1611,7 +1564,7 @@ Drive.prototype._procKeyword = function (keyword, table) {
|
|
|
1611
1564
|
* @returns {object} 基础模型
|
|
1612
1565
|
* @private
|
|
1613
1566
|
*/
|
|
1614
|
-
|
|
1567
|
+
Db.prototype._createSqlConfig = function (cg, processed, keyword_query) {
|
|
1615
1568
|
return {
|
|
1616
1569
|
name: cg.table,
|
|
1617
1570
|
title: cg.title,
|
|
@@ -1638,7 +1591,7 @@ Drive.prototype._createSqlConfig = function (cg, processed, keyword_query) {
|
|
|
1638
1591
|
* @param {string} table 表名
|
|
1639
1592
|
* @private
|
|
1640
1593
|
*/
|
|
1641
|
-
|
|
1594
|
+
Db.prototype._saveClientConfig = function (
|
|
1642
1595
|
client,
|
|
1643
1596
|
base_model,
|
|
1644
1597
|
cover,
|
|
@@ -1676,7 +1629,7 @@ Drive.prototype._saveClientConfig = function (
|
|
|
1676
1629
|
* @param {boolean} cover 是否覆盖文件
|
|
1677
1630
|
* @private
|
|
1678
1631
|
*/
|
|
1679
|
-
|
|
1632
|
+
Db.prototype._saveManageConfig = function (manage, base_model, cover) {
|
|
1680
1633
|
var m = { ...base_model };
|
|
1681
1634
|
delete m.method;
|
|
1682
1635
|
m.field_hide = [];
|
|
@@ -1696,7 +1649,7 @@ Drive.prototype._saveManageConfig = function (manage, base_model, cover) {
|
|
|
1696
1649
|
* @param {string} manage 管理端配置保存路径
|
|
1697
1650
|
* @param {boolean} cover 是否覆盖文件
|
|
1698
1651
|
*/
|
|
1699
|
-
|
|
1652
|
+
Db.prototype.newSql = async function (client, manage, cover) {
|
|
1700
1653
|
var cg = this.config;
|
|
1701
1654
|
var uid = this.config.user_id;
|
|
1702
1655
|
|
|
@@ -1726,7 +1679,7 @@ Drive.prototype.newSql = async function (client, manage, cover) {
|
|
|
1726
1679
|
* @param {object} model 配置模型
|
|
1727
1680
|
* @param {boolean} cover 是否覆盖文件
|
|
1728
1681
|
*/
|
|
1729
|
-
|
|
1682
|
+
Db.prototype.saveFile = function (file, model, cover) {
|
|
1730
1683
|
if (!file.hasFile(file)) {
|
|
1731
1684
|
file.saveText(file, JSON.stringify(model, null, 2));
|
|
1732
1685
|
} else if (cover) {
|
|
@@ -1737,7 +1690,7 @@ Drive.prototype.saveFile = function (file, model, cover) {
|
|
|
1737
1690
|
model[k] = jobj[k];
|
|
1738
1691
|
}
|
|
1739
1692
|
}
|
|
1740
|
-
|
|
1693
|
+
object.push(jobj, model, true);
|
|
1741
1694
|
file.saveText(file, JSON.stringify(jobj, null, 2));
|
|
1742
1695
|
}
|
|
1743
1696
|
};
|
|
@@ -1748,7 +1701,7 @@ Drive.prototype.saveFile = function (file, model, cover) {
|
|
|
1748
1701
|
* @param {string} manage 管理端配置保存路径
|
|
1749
1702
|
* @param {boolean} cover 是否覆盖文件
|
|
1750
1703
|
*/
|
|
1751
|
-
|
|
1704
|
+
Db.prototype.newParam = async function (client, manage, cover) {
|
|
1752
1705
|
var cg = this.config;
|
|
1753
1706
|
var lt = cg.fields;
|
|
1754
1707
|
var cm = this._initParamConfig(cg);
|
|
@@ -1779,7 +1732,7 @@ Drive.prototype.newParam = async function (client, manage, cover) {
|
|
|
1779
1732
|
* @returns {object} 参数配置对象
|
|
1780
1733
|
* @private
|
|
1781
1734
|
*/
|
|
1782
|
-
|
|
1735
|
+
Db.prototype._initParamConfig = function (cg) {
|
|
1783
1736
|
return {
|
|
1784
1737
|
name: cg.table,
|
|
1785
1738
|
title: cg.title,
|
|
@@ -1817,7 +1770,7 @@ Drive.prototype._initParamConfig = function (cg) {
|
|
|
1817
1770
|
* @returns {object} 参数模型对象
|
|
1818
1771
|
* @private
|
|
1819
1772
|
*/
|
|
1820
|
-
|
|
1773
|
+
Db.prototype._createParamModel = function (field, type, name) {
|
|
1821
1774
|
return {
|
|
1822
1775
|
name: name,
|
|
1823
1776
|
title: field.title,
|
|
@@ -1834,7 +1787,7 @@ Drive.prototype._createParamModel = function (field, type, name) {
|
|
|
1834
1787
|
* @returns {boolean} 是否为字符串类型
|
|
1835
1788
|
* @private
|
|
1836
1789
|
*/
|
|
1837
|
-
|
|
1790
|
+
Db.prototype._isStringType = function (type) {
|
|
1838
1791
|
return type === 'varchar' || type === 'text' || type === 'longtext';
|
|
1839
1792
|
};
|
|
1840
1793
|
|
|
@@ -1848,7 +1801,7 @@ Drive.prototype._isStringType = function (type) {
|
|
|
1848
1801
|
* @returns {string} 更新后的关键词
|
|
1849
1802
|
* @private
|
|
1850
1803
|
*/
|
|
1851
|
-
|
|
1804
|
+
Db.prototype._processStringField = function (cm, m, o, n, keyword) {
|
|
1852
1805
|
var new_keyword = keyword;
|
|
1853
1806
|
m.type = 'string';
|
|
1854
1807
|
m.default = o.default;
|
|
@@ -1881,7 +1834,7 @@ Drive.prototype._processStringField = function (cm, m, o, n, keyword) {
|
|
|
1881
1834
|
* @param {object} o 字段对象
|
|
1882
1835
|
* @private
|
|
1883
1836
|
*/
|
|
1884
|
-
|
|
1837
|
+
Db.prototype._addStringRange = function (m, o) {
|
|
1885
1838
|
var range = o.min_length && o.max_length ? [o.min_length, o.max_length] : [];
|
|
1886
1839
|
if (range.length > 0) {
|
|
1887
1840
|
m.string.range = range;
|
|
@@ -1899,7 +1852,7 @@ Drive.prototype._addStringRange = function (m, o) {
|
|
|
1899
1852
|
* @returns {boolean} 是否包含
|
|
1900
1853
|
* @private
|
|
1901
1854
|
*/
|
|
1902
|
-
|
|
1855
|
+
Db.prototype._hasKeyword = function (field_name, keyword) {
|
|
1903
1856
|
return string.has(field_name, keyword);
|
|
1904
1857
|
};
|
|
1905
1858
|
|
|
@@ -1910,7 +1863,7 @@ Drive.prototype._hasKeyword = function (field_name, keyword) {
|
|
|
1910
1863
|
* @returns {boolean} 是否等于
|
|
1911
1864
|
* @private
|
|
1912
1865
|
*/
|
|
1913
|
-
|
|
1866
|
+
Db.prototype._isEqual = function (field_name, values) {
|
|
1914
1867
|
return values.includes(field_name);
|
|
1915
1868
|
};
|
|
1916
1869
|
|
|
@@ -1920,7 +1873,7 @@ Drive.prototype._isEqual = function (field_name, values) {
|
|
|
1920
1873
|
* @param {string} n 字段名
|
|
1921
1874
|
* @private
|
|
1922
1875
|
*/
|
|
1923
|
-
|
|
1876
|
+
Db.prototype._addStringFormat = function (m, n) {
|
|
1924
1877
|
if (this._hasKeyword(n, 'phone') || this._isEqual(n, ['tel'])) {
|
|
1925
1878
|
m.string.format = 'phone';
|
|
1926
1879
|
} else if (
|
|
@@ -1947,7 +1900,7 @@ Drive.prototype._addStringFormat = function (m, n) {
|
|
|
1947
1900
|
* @param {string} n 字段名
|
|
1948
1901
|
* @private
|
|
1949
1902
|
*/
|
|
1950
|
-
|
|
1903
|
+
Db.prototype._processDateTimeField = function (cm, m, o, n) {
|
|
1951
1904
|
var format = o.type === 'timestamp' ? 'datetime' : o.type;
|
|
1952
1905
|
m.type = 'string';
|
|
1953
1906
|
m.default = '';
|
|
@@ -1975,7 +1928,7 @@ Drive.prototype._processDateTimeField = function (cm, m, o, n) {
|
|
|
1975
1928
|
* @param {string} n 字段名
|
|
1976
1929
|
* @private
|
|
1977
1930
|
*/
|
|
1978
|
-
|
|
1931
|
+
Db.prototype._addDateTimeRange = function (cm, m, n) {
|
|
1979
1932
|
var m_min = { ...m };
|
|
1980
1933
|
m_min.name = n + '_min';
|
|
1981
1934
|
m_min.title += '——开始时间';
|
|
@@ -1996,7 +1949,7 @@ Drive.prototype._addDateTimeRange = function (cm, m, n) {
|
|
|
1996
1949
|
* @param {object} cg 配置对象
|
|
1997
1950
|
* @private
|
|
1998
1951
|
*/
|
|
1999
|
-
|
|
1952
|
+
Db.prototype._processNumberField = function (cm, m, o, n, cg) {
|
|
2000
1953
|
m.type = 'number';
|
|
2001
1954
|
m.default = Number(o.default) + '';
|
|
2002
1955
|
m.number = {};
|
|
@@ -2016,7 +1969,7 @@ Drive.prototype._processNumberField = function (cm, m, o, n, cg) {
|
|
|
2016
1969
|
* @param {object} o 字段对象
|
|
2017
1970
|
* @private
|
|
2018
1971
|
*/
|
|
2019
|
-
|
|
1972
|
+
Db.prototype._addNumberRange = function (m, o) {
|
|
2020
1973
|
var range = o.min && o.max ? [o.min, o.max] : [];
|
|
2021
1974
|
if (range.length > 0) {
|
|
2022
1975
|
m.number.range = range;
|
|
@@ -2034,7 +1987,7 @@ Drive.prototype._addNumberRange = function (m, o) {
|
|
|
2034
1987
|
* @param {string} n 字段名
|
|
2035
1988
|
* @private
|
|
2036
1989
|
*/
|
|
2037
|
-
|
|
1990
|
+
Db.prototype._processPrimaryKey = function (cm, m, n) {
|
|
2038
1991
|
cm.del.query_required.push(n);
|
|
2039
1992
|
cm.set.query.push(n);
|
|
2040
1993
|
cm.get.query.push(n);
|
|
@@ -2049,7 +2002,7 @@ Drive.prototype._processPrimaryKey = function (cm, m, n) {
|
|
|
2049
2002
|
* @param {string} n 字段名
|
|
2050
2003
|
* @private
|
|
2051
2004
|
*/
|
|
2052
|
-
|
|
2005
|
+
Db.prototype._processNonPrimaryKey = function (cm, m, n) {
|
|
2053
2006
|
cm.add.body.push(n);
|
|
2054
2007
|
cm.set.body.push(n);
|
|
2055
2008
|
cm.list.push(m);
|
|
@@ -2069,7 +2022,7 @@ Drive.prototype._processNonPrimaryKey = function (cm, m, n) {
|
|
|
2069
2022
|
* @param {string} n 字段名
|
|
2070
2023
|
* @private
|
|
2071
2024
|
*/
|
|
2072
|
-
|
|
2025
|
+
Db.prototype._processNonTinyInt = function (cm, m, n) {
|
|
2073
2026
|
var ne = n;
|
|
2074
2027
|
if (!ne.endsWith('id')) {
|
|
2075
2028
|
this._addNumberRangeFields(cm, m, n);
|
|
@@ -2088,7 +2041,7 @@ Drive.prototype._processNonTinyInt = function (cm, m, n) {
|
|
|
2088
2041
|
* @param {string} n 字段名
|
|
2089
2042
|
* @private
|
|
2090
2043
|
*/
|
|
2091
|
-
|
|
2044
|
+
Db.prototype._addNumberRangeFields = function (cm, m, n) {
|
|
2092
2045
|
cm.get.query.push(n + '_min');
|
|
2093
2046
|
cm.get.query.push(n + '_max');
|
|
2094
2047
|
cm.set.query.push(n + '_min');
|
|
@@ -2113,7 +2066,7 @@ Drive.prototype._addNumberRangeFields = function (cm, m, n) {
|
|
|
2113
2066
|
* @param {object} cg 配置对象
|
|
2114
2067
|
* @private
|
|
2115
2068
|
*/
|
|
2116
|
-
|
|
2069
|
+
Db.prototype._addKeywordConfig = function (cm, keyword, cg) {
|
|
2117
2070
|
if (keyword) {
|
|
2118
2071
|
cm.get.query.push('keyword');
|
|
2119
2072
|
cm.set.query.push('keyword');
|
|
@@ -2140,7 +2093,7 @@ Drive.prototype._addKeywordConfig = function (cm, keyword, cg) {
|
|
|
2140
2093
|
* @param {boolean} cover 是否覆盖文件
|
|
2141
2094
|
* @private
|
|
2142
2095
|
*/
|
|
2143
|
-
|
|
2096
|
+
Db.prototype._saveParamFiles = function (cm, client, manage, cover) {
|
|
2144
2097
|
if (client) {
|
|
2145
2098
|
this.saveFile(client + '/param.json', cm, cover);
|
|
2146
2099
|
}
|
|
@@ -2158,7 +2111,7 @@ Drive.prototype._saveParamFiles = function (cm, client, manage, cover) {
|
|
|
2158
2111
|
* @param {Array} arr 匹配的对象
|
|
2159
2112
|
* @returns {boolean} 是否设置
|
|
2160
2113
|
*/
|
|
2161
|
-
|
|
2114
|
+
Db.prototype.isSet = function (name, arr) {
|
|
2162
2115
|
if (!arr) {
|
|
2163
2116
|
return false;
|
|
2164
2117
|
}
|
|
@@ -2179,7 +2132,7 @@ Drive.prototype.isSet = function (name, arr) {
|
|
|
2179
2132
|
* @param {string} type 数据类型
|
|
2180
2133
|
* @returns {boolean} 是否可以
|
|
2181
2134
|
*/
|
|
2182
|
-
|
|
2135
|
+
Db.prototype.isCan = function (name, arr, type) {
|
|
2183
2136
|
if (type === 'longtext') {
|
|
2184
2137
|
return false;
|
|
2185
2138
|
}
|
|
@@ -2202,7 +2155,7 @@ Drive.prototype.isCan = function (name, arr, type) {
|
|
|
2202
2155
|
* @returns {string} API路径
|
|
2203
2156
|
* @private
|
|
2204
2157
|
*/
|
|
2205
|
-
|
|
2158
|
+
Db.prototype._deteApiPath = function (cg) {
|
|
2206
2159
|
var arr = cg.table.split('_');
|
|
2207
2160
|
var p = '/api/';
|
|
2208
2161
|
if (arr.length > 1) {
|
|
@@ -2220,7 +2173,7 @@ Drive.prototype._deteApiPath = function (cg) {
|
|
|
2220
2173
|
* @returns {object} API配置
|
|
2221
2174
|
* @private
|
|
2222
2175
|
*/
|
|
2223
|
-
|
|
2176
|
+
Db.prototype._createApiConfig = function (cg, path) {
|
|
2224
2177
|
return {
|
|
2225
2178
|
name: cg.table,
|
|
2226
2179
|
title: cg.title,
|
|
@@ -2241,7 +2194,7 @@ Drive.prototype._createApiConfig = function (cg, path) {
|
|
|
2241
2194
|
* @returns {boolean} 是否包含用户ID字段
|
|
2242
2195
|
* @private
|
|
2243
2196
|
*/
|
|
2244
|
-
|
|
2197
|
+
Db.prototype._hasUserIdField = function (fields) {
|
|
2245
2198
|
for (var i = 0, item; (item = fields[i++]);) {
|
|
2246
2199
|
var name = item.name;
|
|
2247
2200
|
if (
|
|
@@ -2264,7 +2217,7 @@ Drive.prototype._hasUserIdField = function (fields) {
|
|
|
2264
2217
|
* @param {boolean} cover 是否覆盖文件
|
|
2265
2218
|
* @private
|
|
2266
2219
|
*/
|
|
2267
|
-
|
|
2220
|
+
Db.prototype._saveClientApiConfig = function (
|
|
2268
2221
|
client,
|
|
2269
2222
|
base_config,
|
|
2270
2223
|
cg,
|
|
@@ -2293,7 +2246,7 @@ Drive.prototype._saveClientApiConfig = function (
|
|
|
2293
2246
|
* @param {boolean} cover 是否覆盖文件
|
|
2294
2247
|
* @private
|
|
2295
2248
|
*/
|
|
2296
|
-
|
|
2249
|
+
Db.prototype._saveManageApiConfig = function (manage, base_config, cover) {
|
|
2297
2250
|
var o = { ...base_config };
|
|
2298
2251
|
o.oauth = {
|
|
2299
2252
|
scope: true,
|
|
@@ -2312,7 +2265,7 @@ Drive.prototype._saveManageApiConfig = function (manage, base_config, cover) {
|
|
|
2312
2265
|
* @param {string} manage 管理端配置保存路径
|
|
2313
2266
|
* @param {boolean} cover 是否覆盖文件
|
|
2314
2267
|
*/
|
|
2315
|
-
|
|
2268
|
+
Db.prototype.newApi = async function (client, manage, cover) {
|
|
2316
2269
|
var cg = this.config;
|
|
2317
2270
|
var path = this._deteApiPath(cg);
|
|
2318
2271
|
var base_config = this._createApiConfig(cg, path);
|
|
@@ -2331,7 +2284,7 @@ Drive.prototype.newApi = async function (client, manage, cover) {
|
|
|
2331
2284
|
* @param {string} type 模型类型
|
|
2332
2285
|
* @returns {object} 返回获取到的模型
|
|
2333
2286
|
*/
|
|
2334
|
-
|
|
2287
|
+
Db.prototype.getModel = function (type) {
|
|
2335
2288
|
let model = { ...this.config };
|
|
2336
2289
|
let dir = this.getDir();
|
|
2337
2290
|
let l = path.sep;
|
|
@@ -2344,4 +2297,4 @@ Drive.prototype.getModel = function (type) {
|
|
|
2344
2297
|
return model;
|
|
2345
2298
|
};
|
|
2346
2299
|
|
|
2347
|
-
module.exports =
|
|
2300
|
+
module.exports = Db;
|
package/lib/manager.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const Manager = require("
|
|
2
|
-
const
|
|
1
|
+
const Manager = require("mm_mod").Manager;
|
|
2
|
+
const Db = require("./db");
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* 数据库帮助类
|
|
6
6
|
* @augments {Manager}
|
|
7
7
|
* @class
|
|
8
8
|
*/
|
|
9
|
-
class
|
|
9
|
+
class DbManager extends Manager {
|
|
10
10
|
/**
|
|
11
11
|
* 配置参数
|
|
12
12
|
* @type {object}
|
|
@@ -45,9 +45,7 @@ class Db extends Manager {
|
|
|
45
45
|
* @param {object} parent 父级模块
|
|
46
46
|
*/
|
|
47
47
|
constructor(config, parent) {
|
|
48
|
-
super({ ...
|
|
49
|
-
// 插件注册表(方案B:手动注册,供驱动 plugin() 查找)
|
|
50
|
-
this.plugins = {};
|
|
48
|
+
super({ ...DbManager.config, ...config }, parent);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
|
|
@@ -55,15 +53,15 @@ class Db extends Manager {
|
|
|
55
53
|
* 数据库驱动类
|
|
56
54
|
* @type {Drive}
|
|
57
55
|
*/
|
|
58
|
-
|
|
56
|
+
DbManager.prototype.Drive = Db;
|
|
59
57
|
|
|
60
58
|
/**
|
|
61
59
|
* 注册一个数据库驱动(方案B:手动注册,不扫描目录)
|
|
62
60
|
* @param {object} config 驱动配置(必须包含 name)
|
|
63
61
|
* @returns {object} 驱动实例
|
|
64
62
|
*/
|
|
65
|
-
|
|
66
|
-
var drive = new Drive({ host: this.config.host, ...config }, this);
|
|
63
|
+
DbManager.prototype.add = function (config) {
|
|
64
|
+
var drive = new this.Drive({ host: this.config.host, ...config }, this);
|
|
67
65
|
this.set(drive.config.name, drive);
|
|
68
66
|
return drive;
|
|
69
67
|
};
|
|
@@ -73,7 +71,7 @@ Db.prototype.add = function (config) {
|
|
|
73
71
|
* @param {string} name 驱动名称
|
|
74
72
|
* @returns {Promise<boolean>} 是否删除成功
|
|
75
73
|
*/
|
|
76
|
-
|
|
74
|
+
DbManager.prototype.del = async function (name) {
|
|
77
75
|
return await Manager.prototype.del.call(this, name);
|
|
78
76
|
};
|
|
79
77
|
|
|
@@ -82,7 +80,7 @@ Db.prototype.del = async function (name) {
|
|
|
82
80
|
* @param {string} name 驱动名称
|
|
83
81
|
* @returns {Promise<boolean>} 是否执行成功
|
|
84
82
|
*/
|
|
85
|
-
|
|
83
|
+
DbManager.prototype.reload = async function (name) {
|
|
86
84
|
var drive = this.get(name);
|
|
87
85
|
if (!drive) {
|
|
88
86
|
this.log("warn", "驱动不存在,无法重载", name);
|
|
@@ -94,23 +92,12 @@ Db.prototype.reload = async function (name) {
|
|
|
94
92
|
return true;
|
|
95
93
|
};
|
|
96
94
|
|
|
97
|
-
/**
|
|
98
|
-
* 注册插件集合(供驱动 plugin() 查找,替代原全局插件池)
|
|
99
|
-
* @param {string} name 插件作用域名称(app 名)
|
|
100
|
-
* @param {object} obj 插件集合对象(需含 get 方法)
|
|
101
|
-
* @returns {object} 当前管理器实例
|
|
102
|
-
*/
|
|
103
|
-
Db.prototype.usePlugin = function (name, obj) {
|
|
104
|
-
this.plugins[name] = obj;
|
|
105
|
-
return this;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
95
|
/**
|
|
109
96
|
* 获取所有驱动配置列表(方案B:来自注册表,替代旧基类 getInfos)
|
|
110
97
|
* @returns {Array} 驱动配置数组
|
|
111
98
|
* @private
|
|
112
99
|
*/
|
|
113
|
-
|
|
100
|
+
DbManager.prototype._getInfos = function () {
|
|
114
101
|
return this.values().map((d) => d.config);
|
|
115
102
|
};
|
|
116
103
|
|
|
@@ -119,7 +106,7 @@ Db.prototype._getInfos = function () {
|
|
|
119
106
|
* @param {string} table 表
|
|
120
107
|
* @returns {object} 返回驱动项
|
|
121
108
|
*/
|
|
122
|
-
|
|
109
|
+
DbManager.prototype.getObj = function (table) {
|
|
123
110
|
var obj;
|
|
124
111
|
var mods = this.values();
|
|
125
112
|
for (var i = 0; i < mods.length; i++) {
|
|
@@ -140,7 +127,7 @@ Db.prototype.getObj = function (table) {
|
|
|
140
127
|
* @param {boolean} cover 是否覆盖文件
|
|
141
128
|
* @returns {string} 更新成功返回null, 失败返回错误提示
|
|
142
129
|
*/
|
|
143
|
-
|
|
130
|
+
DbManager.prototype.updateFile = async function (db, name, table, cover = true) {
|
|
144
131
|
if (name) {
|
|
145
132
|
var o = this.get(name);
|
|
146
133
|
if (o) {
|
|
@@ -179,12 +166,12 @@ Db.prototype.updateFile = async function (db, name, table, cover = true) {
|
|
|
179
166
|
* @param {boolean} all 是否更新全部表,true为是,false为否
|
|
180
167
|
* @returns {string} 更新成功返回null, 失败返回错误提示
|
|
181
168
|
*/
|
|
182
|
-
|
|
169
|
+
DbManager.prototype.updateDbManager = async function (db, name, table, all) {
|
|
183
170
|
var ret;
|
|
184
171
|
if (name) {
|
|
185
172
|
var o = this.get(name);
|
|
186
173
|
if (o) {
|
|
187
|
-
ret = await o.
|
|
174
|
+
ret = await o.updateDbManager(db);
|
|
188
175
|
} else {
|
|
189
176
|
ret = "该配置不存在";
|
|
190
177
|
}
|
|
@@ -194,13 +181,13 @@ Db.prototype.updateDb = async function (db, name, table, all) {
|
|
|
194
181
|
for (var i = 0; i < mods.length; i++) {
|
|
195
182
|
var m = mods[i];
|
|
196
183
|
if (m.config.table === table) {
|
|
197
|
-
ret = await m.
|
|
184
|
+
ret = await m.updateDbManager(db);
|
|
198
185
|
break;
|
|
199
186
|
}
|
|
200
187
|
}
|
|
201
188
|
} else if (all) {
|
|
202
189
|
for (var j = 0; j < mods.length; j++) {
|
|
203
|
-
await mods[j].
|
|
190
|
+
await mods[j].updateDbManager(db);
|
|
204
191
|
}
|
|
205
192
|
}
|
|
206
193
|
}
|
|
@@ -210,4 +197,4 @@ Db.prototype.updateDb = async function (db, name, table, all) {
|
|
|
210
197
|
/**
|
|
211
198
|
* @module 导出数据库管理器类
|
|
212
199
|
*/
|
|
213
|
-
module.exports =
|
|
200
|
+
module.exports = DbManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_dbs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "数据库框架,通过设计数据库生成sql模板,或通过db.json配置文件生成mysql数据表(基于 mm_corejs,内置管理器池,无全局/原型扩展依赖)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -16,8 +16,13 @@
|
|
|
16
16
|
"group": "data",
|
|
17
17
|
"author": "邱文武",
|
|
18
18
|
"license": "ISC",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://gitee.com/qiuwenwu91/mm_dbs.git"
|
|
22
|
+
},
|
|
19
23
|
"dependencies": {
|
|
20
24
|
"mm_corejs": "^1.1.4",
|
|
25
|
+
"mm_mod": "^1.0.1",
|
|
21
26
|
"mm_helper": "^1.0.0"
|
|
22
27
|
},
|
|
23
28
|
"scripts": {
|