mm_sqlite 1.4.9 → 1.5.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/db.js +0 -13
- package/index.js +81 -20
- package/link_model.js +3 -3
- package/package.json +5 -5
- package/sql.js +72 -71
- package/test_db/test_basic.db +0 -0
- package/test_db/test_core_methods.db +0 -0
package/db.js
CHANGED
|
@@ -672,19 +672,6 @@ DB.prototype.renameTable = function (table, new_table, timeout = 15000) {
|
|
|
672
672
|
return this.exec('ALTER TABLE `' + table + '` RENAME TO `' + new_table + '`;', [], timeout);
|
|
673
673
|
};
|
|
674
674
|
|
|
675
|
-
/**
|
|
676
|
-
* @description 清空数据表(保留表结构)
|
|
677
|
-
* @param {string} table 表名
|
|
678
|
-
* @param {number} timeout - 超时时间(毫秒)
|
|
679
|
-
* @returns {Promise | number} 清空成功返回1,失败返回0
|
|
680
|
-
*/
|
|
681
|
-
DB.prototype.emptyTable = function (table, timeout = 15000) {
|
|
682
|
-
if (!table) {
|
|
683
|
-
throw new TypeError('table must be specified');
|
|
684
|
-
}
|
|
685
|
-
return this.exec('DELETE FROM `' + table + '`;', [], timeout);
|
|
686
|
-
};
|
|
687
|
-
|
|
688
675
|
/**
|
|
689
676
|
* @description 检查表是否存在
|
|
690
677
|
* @param {string} table 表名
|
package/index.js
CHANGED
|
@@ -111,26 +111,24 @@ SQLite.prototype.open = async function (timeout) {
|
|
|
111
111
|
* 关闭数据库连接(统一使用连接池模式)
|
|
112
112
|
* @returns {Promise<boolean>}
|
|
113
113
|
*/
|
|
114
|
-
SQLite.prototype.close = function () {
|
|
114
|
+
SQLite.prototype.close = async function () {
|
|
115
115
|
if (this._status !== 'connected') {
|
|
116
116
|
this.log('warn', '数据库连接未建立');
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
});
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
// 统一关闭连接池
|
|
122
|
+
this._pool.close();
|
|
123
|
+
this._db = null;
|
|
124
|
+
this._open = false;
|
|
125
|
+
this._status = 'closed';
|
|
126
|
+
return true;
|
|
127
|
+
} catch (err) {
|
|
128
|
+
this.log('error', '关闭数据库连接时发生异常', err);
|
|
129
|
+
this._status = 'closed';
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
134
132
|
};
|
|
135
133
|
|
|
136
134
|
/**
|
|
@@ -209,7 +207,7 @@ SQLite.prototype.run = async function (sql, params = [], timeout = 30000) {
|
|
|
209
207
|
* @returns {Promise<object>}
|
|
210
208
|
* @throws {TypeError} 当sql参数无效时
|
|
211
209
|
*/
|
|
212
|
-
SQLite.prototype.exec = async function (sql, params, timeout) {
|
|
210
|
+
SQLite.prototype.exec = async function (sql, params = [], timeout) {
|
|
213
211
|
// 参数校验
|
|
214
212
|
if (typeof sql !== 'string' || sql.trim() === '') {
|
|
215
213
|
throw new TypeError('sql must be non-empty string');
|
|
@@ -265,7 +263,7 @@ SQLite.prototype.exec = async function (sql, params, timeout) {
|
|
|
265
263
|
* @returns {Promise<Array>}
|
|
266
264
|
* @throws {TypeError} 当table参数无效时
|
|
267
265
|
*/
|
|
268
|
-
SQLite.prototype.read = async function (table, condition, options) {
|
|
266
|
+
SQLite.prototype.read = async function (table, condition = {}, options = {}) {
|
|
269
267
|
// 参数校验
|
|
270
268
|
if (typeof table !== 'string' || table.trim() === '') {
|
|
271
269
|
throw new TypeError('table must be non-empty string');
|
|
@@ -334,6 +332,69 @@ SQLite.prototype.db = function () {
|
|
|
334
332
|
return new DB(this);
|
|
335
333
|
};
|
|
336
334
|
|
|
335
|
+
/**
|
|
336
|
+
* 初始化数据库服务(保持兼容性)
|
|
337
|
+
* @returns {Promise<void>}
|
|
338
|
+
*/
|
|
339
|
+
SQLite.prototype.init = async function () {
|
|
340
|
+
await this.open();
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* 获取连接池状态信息
|
|
345
|
+
* @returns {object} 连接池状态对象
|
|
346
|
+
*/
|
|
347
|
+
SQLite.prototype.getPoolStats = function () {
|
|
348
|
+
if (!this._pool || !this._pool._is_initialized) {
|
|
349
|
+
return {
|
|
350
|
+
status: 'not_initialized',
|
|
351
|
+
message: '连接池未初始化'
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
status: 'healthy',
|
|
357
|
+
...this._pool.getStats()
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* 健康检查
|
|
363
|
+
* @returns {Promise<object>} 健康检查结果
|
|
364
|
+
*/
|
|
365
|
+
SQLite.prototype.healthCheck = async function () {
|
|
366
|
+
try {
|
|
367
|
+
if (this._status !== 'connected') {
|
|
368
|
+
return {
|
|
369
|
+
status: 'error',
|
|
370
|
+
message: '数据库连接未初始化'
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// 执行简单的查询来检查连接状态
|
|
375
|
+
let result = await this.run('SELECT 1 as health_check');
|
|
376
|
+
|
|
377
|
+
if (result && result.length > 0 && result[0].health_check === 1) {
|
|
378
|
+
return {
|
|
379
|
+
status: 'healthy',
|
|
380
|
+
message: '数据库连接正常',
|
|
381
|
+
...this.getPoolStats()
|
|
382
|
+
};
|
|
383
|
+
} else {
|
|
384
|
+
return {
|
|
385
|
+
status: 'error',
|
|
386
|
+
message: '健康检查查询失败'
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
} catch (error) {
|
|
390
|
+
this.log('error', '健康检查失败', error);
|
|
391
|
+
return {
|
|
392
|
+
status: 'error',
|
|
393
|
+
message: `健康检查失败: ${error.message}`
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
337
398
|
// /**
|
|
338
399
|
// * 获取数据库操作实例
|
|
339
400
|
// * @param {String} database - 数据库名称
|
package/link_model.js
CHANGED
|
@@ -38,7 +38,7 @@ class LinkModel {
|
|
|
38
38
|
* @param {string} table 表名
|
|
39
39
|
* @returns {object}
|
|
40
40
|
*/
|
|
41
|
-
|
|
41
|
+
LinkModel.prototype.add = async function(table) {
|
|
42
42
|
var {
|
|
43
43
|
key,
|
|
44
44
|
value,
|
|
@@ -77,7 +77,7 @@ Link_model.prototype.add = async function(table) {
|
|
|
77
77
|
* @param {object} sql 数据管理器
|
|
78
78
|
* @returns {object} 当前对象
|
|
79
79
|
*/
|
|
80
|
-
|
|
80
|
+
LinkModel.prototype.init = function(sql) {
|
|
81
81
|
this.sql = sql;
|
|
82
82
|
return this;
|
|
83
83
|
};
|
|
@@ -88,7 +88,7 @@ Link_model.prototype.init = function(sql) {
|
|
|
88
88
|
* @param {object} value
|
|
89
89
|
* @returns {object} 当前对象
|
|
90
90
|
*/
|
|
91
|
-
|
|
91
|
+
LinkModel.prototype.update = function(key, value) {
|
|
92
92
|
var m = this.model;
|
|
93
93
|
for (var k in m) {
|
|
94
94
|
var o = m[k];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_sqlite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "高性能SQLite数据库操作模块,提供与mm_mysql完全兼容的API接口,支持异步操作、事务处理和批量操作",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"node": ">=14.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"better-sqlite3": "^13.0.
|
|
42
|
-
"mm_expand": "^2.
|
|
41
|
+
"better-sqlite3": "^13.0.3",
|
|
42
|
+
"mm_expand": "^2.5.1",
|
|
43
43
|
"sqlstring": "^2.3.3"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"eslint": "^10.8.
|
|
47
|
-
"eslint-plugin-jsdoc": "^
|
|
46
|
+
"eslint": "^10.8.1",
|
|
47
|
+
"eslint-plugin-jsdoc": "^64.0.1",
|
|
48
48
|
"mm_eslint": "^1.7.5"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/sql.js
CHANGED
|
@@ -23,6 +23,48 @@ function escapeId(value, forbidQualified) {
|
|
|
23
23
|
* @property {Function} filter 设置并过滤参数
|
|
24
24
|
*/
|
|
25
25
|
class Sql extends Base {
|
|
26
|
+
/**
|
|
27
|
+
* 过滤查询参数字典
|
|
28
|
+
*/
|
|
29
|
+
static config = {
|
|
30
|
+
/**
|
|
31
|
+
* 分隔符 用于查询时的多条件处理
|
|
32
|
+
*/
|
|
33
|
+
'separator': '|',
|
|
34
|
+
/**
|
|
35
|
+
* 过滤
|
|
36
|
+
*/
|
|
37
|
+
'filter': {
|
|
38
|
+
/**
|
|
39
|
+
* 表名
|
|
40
|
+
*/
|
|
41
|
+
'table': 'table',
|
|
42
|
+
/**
|
|
43
|
+
* 查询的页码
|
|
44
|
+
*/
|
|
45
|
+
'page': 'page',
|
|
46
|
+
/**
|
|
47
|
+
* 查询每页条数
|
|
48
|
+
*/
|
|
49
|
+
'size': 'size',
|
|
50
|
+
/**
|
|
51
|
+
* 操作方式: 传入参数method=add, 支持参数 add增、del删、set改、get查,为空则为get
|
|
52
|
+
*/
|
|
53
|
+
'method': 'method',
|
|
54
|
+
/**
|
|
55
|
+
* 排序
|
|
56
|
+
*/
|
|
57
|
+
'orderby': 'orderby',
|
|
58
|
+
/**
|
|
59
|
+
* 查询显示的字段
|
|
60
|
+
*/
|
|
61
|
+
'field': 'field',
|
|
62
|
+
/**
|
|
63
|
+
* 统计结果: 统计符合条件的结果数,只有当page等于1或0时才会统计
|
|
64
|
+
*/
|
|
65
|
+
'count_ret': 'count_ret'
|
|
66
|
+
}
|
|
67
|
+
};
|
|
26
68
|
/**
|
|
27
69
|
* @description 数据库管理器
|
|
28
70
|
* @param {Function} run 查询函数
|
|
@@ -106,49 +148,6 @@ class Sql extends Base {
|
|
|
106
148
|
*/
|
|
107
149
|
this.count_ret = 'false';
|
|
108
150
|
|
|
109
|
-
/**
|
|
110
|
-
* 过滤查询参数字典
|
|
111
|
-
*/
|
|
112
|
-
this.config = {
|
|
113
|
-
/**
|
|
114
|
-
* 分隔符 用于查询时的多条件处理
|
|
115
|
-
*/
|
|
116
|
-
'separator': '|',
|
|
117
|
-
/**
|
|
118
|
-
* 过滤
|
|
119
|
-
*/
|
|
120
|
-
'filter': {
|
|
121
|
-
/**
|
|
122
|
-
* 表名
|
|
123
|
-
*/
|
|
124
|
-
'table': 'table',
|
|
125
|
-
/**
|
|
126
|
-
* 查询的页码
|
|
127
|
-
*/
|
|
128
|
-
'page': 'page',
|
|
129
|
-
/**
|
|
130
|
-
* 查询每页条数
|
|
131
|
-
*/
|
|
132
|
-
'size': 'size',
|
|
133
|
-
/**
|
|
134
|
-
* 操作方式: 传入参数method=add, 支持参数 add增、del删、set改、get查,为空则为get
|
|
135
|
-
*/
|
|
136
|
-
'method': 'method',
|
|
137
|
-
/**
|
|
138
|
-
* 排序
|
|
139
|
-
*/
|
|
140
|
-
'orderby': 'orderby',
|
|
141
|
-
/**
|
|
142
|
-
* 查询显示的字段
|
|
143
|
-
*/
|
|
144
|
-
'field': 'field',
|
|
145
|
-
/**
|
|
146
|
-
* 统计结果: 统计符合条件的结果数,只有当page等于1或0时才会统计
|
|
147
|
-
*/
|
|
148
|
-
'count_ret': 'count_ret'
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
151
|
this.like = false;
|
|
153
152
|
}
|
|
154
153
|
}
|
|
@@ -158,20 +157,17 @@ class Sql extends Base {
|
|
|
158
157
|
* @returns {object} 返回当前对象
|
|
159
158
|
*/
|
|
160
159
|
Sql.prototype.clear = function () {
|
|
161
|
-
|
|
162
|
-
this.set = '';
|
|
163
|
-
this.order = '';
|
|
164
|
-
this.view = '';
|
|
160
|
+
// 不重置run和exec方法引用,保留构造函数中设置的函数
|
|
165
161
|
this.sql = '';
|
|
166
|
-
this.error =
|
|
167
|
-
this.
|
|
168
|
-
this.
|
|
169
|
-
this.param = {};
|
|
162
|
+
this.error = null;
|
|
163
|
+
this.results = [];
|
|
164
|
+
this.table = '';
|
|
170
165
|
this.page = 0;
|
|
171
|
-
this.size =
|
|
172
|
-
this.
|
|
173
|
-
this.
|
|
174
|
-
|
|
166
|
+
this.size = 30;
|
|
167
|
+
this.method = '';
|
|
168
|
+
this.field = '';
|
|
169
|
+
this.orderby = '';
|
|
170
|
+
this.count_ret = 'false';
|
|
175
171
|
};
|
|
176
172
|
|
|
177
173
|
/**
|
|
@@ -920,7 +916,7 @@ Sql.prototype.set = async function (query, body, like) {
|
|
|
920
916
|
* @param {number} timeout 超时时间(毫秒),默认5000ms
|
|
921
917
|
* @returns {Promise|Array} 查询结果
|
|
922
918
|
*/
|
|
923
|
-
Sql.prototype.get = async function (query, sort, view, like, timeout =
|
|
919
|
+
Sql.prototype.get = async function (query, sort, view, like, timeout = 20000) {
|
|
924
920
|
if (!this.table) {
|
|
925
921
|
throw new Error('表名未设置');
|
|
926
922
|
}
|
|
@@ -993,7 +989,7 @@ Sql.prototype.addOrSet = async function (where, set, like) {
|
|
|
993
989
|
* @param {number} timeout 超时时间(毫秒),默认30000ms
|
|
994
990
|
* @returns {Promise | number} 记录数
|
|
995
991
|
*/
|
|
996
|
-
Sql.prototype.count = async function (query, like, timeout =
|
|
992
|
+
Sql.prototype.count = async function (query, like, timeout = 20000) {
|
|
997
993
|
if (!this.table) {
|
|
998
994
|
throw new Error('表名未设置');
|
|
999
995
|
}
|
|
@@ -1082,7 +1078,7 @@ Sql.prototype.toBatchAddSql = function (list) {
|
|
|
1082
1078
|
let columns = keys.join(',');
|
|
1083
1079
|
|
|
1084
1080
|
// 构建值部分
|
|
1085
|
-
let
|
|
1081
|
+
let val_list = [];
|
|
1086
1082
|
for (let item of list) {
|
|
1087
1083
|
let values = [];
|
|
1088
1084
|
for (let k of keys) {
|
|
@@ -1090,11 +1086,11 @@ Sql.prototype.toBatchAddSql = function (list) {
|
|
|
1090
1086
|
let val = item[key];
|
|
1091
1087
|
values.push(this.escape(val));
|
|
1092
1088
|
}
|
|
1093
|
-
|
|
1089
|
+
val_list.push(`(${values.join(',')})`);
|
|
1094
1090
|
}
|
|
1095
1091
|
|
|
1096
1092
|
// 生成最终SQL
|
|
1097
|
-
let sql = `INSERT INTO \`${this.table}\` (${columns}) VALUES ${
|
|
1093
|
+
let sql = `INSERT INTO \`${this.table}\` (${columns}) VALUES ${val_list.join(',')}`;
|
|
1098
1094
|
return sql;
|
|
1099
1095
|
};
|
|
1100
1096
|
|
|
@@ -1173,7 +1169,7 @@ Sql.prototype.setList = async function (list, like = false, batch_size = 100, ti
|
|
|
1173
1169
|
if (list.length <= batch_size) {
|
|
1174
1170
|
let sql = '';
|
|
1175
1171
|
for (let item of list) {
|
|
1176
|
-
sql += this.toSetSql(item.query, item.
|
|
1172
|
+
sql += this.toSetSql(item.query, item.item, like);
|
|
1177
1173
|
}
|
|
1178
1174
|
this.sql = sql;
|
|
1179
1175
|
return await this.exec(sql, [], timeout);
|
|
@@ -1196,7 +1192,7 @@ Sql.prototype.setList = async function (list, like = false, batch_size = 100, ti
|
|
|
1196
1192
|
|
|
1197
1193
|
let batch_sql = '';
|
|
1198
1194
|
for (let item of batch) {
|
|
1199
|
-
batch_sql += this.toSetSql(item.query, item.
|
|
1195
|
+
batch_sql += this.toSetSql(item.query, item.item, like);
|
|
1200
1196
|
}
|
|
1201
1197
|
|
|
1202
1198
|
final_res = await this.exec(batch_sql, [], timeout);
|
|
@@ -1239,7 +1235,7 @@ Sql.prototype.has = function (param_dt, sql_dt) {
|
|
|
1239
1235
|
* @param {object} sql_dt sql模板集合
|
|
1240
1236
|
* @returns {string|undefined} 没有模板则返回名称,都有则返回undefined
|
|
1241
1237
|
*/
|
|
1242
|
-
Sql.prototype.
|
|
1238
|
+
Sql.prototype.not = function (param_dt, sql_dt) {
|
|
1243
1239
|
var name;
|
|
1244
1240
|
for (var key in param_dt) {
|
|
1245
1241
|
if (!sql_dt[key]) {
|
|
@@ -1256,11 +1252,14 @@ Sql.prototype.noPrm = function (param_dt, sql_dt) {
|
|
|
1256
1252
|
* @param {object} sql_dt sql模板集合
|
|
1257
1253
|
* @returns {object} 返回过滤后的参数集合
|
|
1258
1254
|
*/
|
|
1259
|
-
Sql.prototype.
|
|
1260
|
-
var dt =
|
|
1255
|
+
Sql.prototype.filterParams = function (param_dt, sql_dt) {
|
|
1256
|
+
var dt = {};
|
|
1257
|
+
if (!param_dt || !sql_dt) {
|
|
1258
|
+
return dt;
|
|
1259
|
+
}
|
|
1261
1260
|
for (var key in param_dt) {
|
|
1262
1261
|
if (!sql_dt[key]) {
|
|
1263
|
-
dt
|
|
1262
|
+
dt[key] = param_dt[key];
|
|
1264
1263
|
}
|
|
1265
1264
|
}
|
|
1266
1265
|
return dt;
|
|
@@ -1316,9 +1315,10 @@ Sql.prototype.tplQuery = function (param_dt, sql_dt) {
|
|
|
1316
1315
|
} else {
|
|
1317
1316
|
for (var key in param_dt) {
|
|
1318
1317
|
var value = this.escape(param_dt[key]);
|
|
1319
|
-
|
|
1318
|
+
let sql = sql_dt[key];
|
|
1319
|
+
if (sql) {
|
|
1320
1320
|
// 使用直接替换方式,避免模板替换错误
|
|
1321
|
-
sql += ' && ' +
|
|
1321
|
+
sql += ' && ' + sql.replaceAll('{0}', value.trim("'"));
|
|
1322
1322
|
} else {
|
|
1323
1323
|
sql += ' && ' + this.escapeId(key) + ' = ' + value;
|
|
1324
1324
|
}
|
|
@@ -1370,9 +1370,10 @@ Sql.prototype.tplBody = function (param_dt, sql_dt) {
|
|
|
1370
1370
|
} else {
|
|
1371
1371
|
for (var key in param_dt) {
|
|
1372
1372
|
var value = this.escape(param_dt[key]);
|
|
1373
|
-
|
|
1373
|
+
let sql = sql_dt[key];
|
|
1374
|
+
if (sql) {
|
|
1374
1375
|
// 使用直接替换方式,避免模板替换错误
|
|
1375
|
-
let replaced =
|
|
1376
|
+
let replaced = sql.replaceAll('{0}', value.trim("'"));
|
|
1376
1377
|
sql += ', ' + replaced.replace('+ -', '- ').replace('- -', '+ ');
|
|
1377
1378
|
} else {
|
|
1378
1379
|
sql += ', ' + this.escapeId(key) + ' = ' + value;
|
|
@@ -1427,7 +1428,7 @@ Sql.prototype.model = function (model) {
|
|
|
1427
1428
|
* @param {number} timeout 超时时间(毫秒),默认30000ms
|
|
1428
1429
|
* @returns {Promise | object | null} 查询结果
|
|
1429
1430
|
*/
|
|
1430
|
-
Sql.prototype.getObj = async function (query, sort, view, like, timeout =
|
|
1431
|
+
Sql.prototype.getObj = async function (query, sort, view, like, timeout = 20000) {
|
|
1431
1432
|
// 保存当前分页设置
|
|
1432
1433
|
let old_page = this.page;
|
|
1433
1434
|
let size = this.size;
|
package/test_db/test_basic.db
CHANGED
|
Binary file
|
|
Binary file
|