mm_sqlite 1.2.9 → 1.3.3

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/index.js CHANGED
@@ -846,6 +846,34 @@ SQLite.prototype._releaseConn = function (conn) {
846
846
  }
847
847
  };
848
848
 
849
+ /**
850
+ * 释放连接池连接
851
+ * @private
852
+ * @param {object} conn - 数据库连接
853
+ */
854
+ SQLite.prototype._releasePoolConnection = function (conn) {
855
+ if (!conn || !this._pool_connections.includes(conn)) {
856
+ return;
857
+ }
858
+
859
+ // 标记连接最后使用时间
860
+ conn._last_used = Date.now();
861
+
862
+ // 将连接放回可用连接池
863
+ if (!this._pool_available.includes(conn)) {
864
+ this._pool_available.push(conn);
865
+ }
866
+
867
+ // 如果有等待的连接请求,立即处理
868
+ if (this._pool_waiting.length > 0) {
869
+ const waiting = this._pool_waiting.shift();
870
+ const next_conn = this._pool_available.shift();
871
+ if (next_conn && waiting.resolve) {
872
+ waiting.resolve(next_conn);
873
+ }
874
+ }
875
+ };
876
+
849
877
  /**
850
878
  * 关闭连接池
851
879
  * @private
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_sqlite",
3
- "version": "1.2.9",
3
+ "version": "1.3.3",
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
- "mm_expand": "^2.0.0",
42
- "sqlite3": "^5.1.7",
41
+ "mm_expand": "^2.0.2",
42
+ "sqlite3": "^6.0.1",
43
43
  "sqlstring": "^2.3.3"
44
44
  },
45
45
  "devDependencies": {
46
- "eslint": "^8.57.0",
47
- "eslint-plugin-jsdoc": "^46.9.1",
48
- "mm_eslint": "^1.1.1"
46
+ "eslint": "^10.1.0",
47
+ "eslint-plugin-jsdoc": "^62.9.0",
48
+ "mm_eslint": "^1.7.1"
49
49
  }
50
50
  }
package/sql.js CHANGED
@@ -186,24 +186,26 @@ Sql.prototype.filter = function (query) {
186
186
  };
187
187
 
188
188
  /**
189
- * @description 查询条件拼接
189
+ * 查询条件拼接
190
190
  * @param {string} where 查询条件
191
191
  * @param {string} sort 排序
192
192
  * @param {string} view 返回的字段
193
193
  * @returns {string} 返回查询条件语句
194
194
  */
195
195
  Sql.prototype.toQuery = function (where, sort, view) {
196
- var sql = 'SELECT {1} FROM `{0}`';
197
196
  if (!view) {
198
197
  view = '*';
199
198
  }
199
+
200
+ // 使用直接拼接的方式,避免模板替换错误
201
+ var sql = `SELECT ${view} FROM \`${this.table}\``;
202
+
200
203
  if (where) {
201
204
  sql += ' WHERE ' + where;
202
205
  }
203
206
  if (sort) {
204
207
  sql += ' ORDER BY ' + sort.replace(/;/, '');
205
208
  }
206
- sql = sql.replace('{0}', this.table).replace('{1}', view);
207
209
  if (this.size && this.page) {
208
210
  var start = this.size * (this.page - 1);
209
211
  sql += ' limit ' + start + ',' + this.size;
@@ -212,24 +214,23 @@ Sql.prototype.toQuery = function (where, sort, view) {
212
214
  };
213
215
  /* === 传字符串参数 === */
214
216
  /**
215
- * @description 增加数据
217
+ * 增加数据
216
218
  * @param {string} key 用作增加的键集合
217
219
  * @param {string} val 用作增加的值集合
218
220
  * @returns {Promise | object} 执行结果
219
221
  */
220
222
  Sql.prototype.addSql = function (key, val) {
221
- var sql = 'INSERT INTO `{0}` ({1}) VALUES ({2});';
222
- sql = sql.replace('{0}', this.table).replace('{1}', key).replace('{2}', val);
223
+ // 使用直接拼接的方式,避免模板替换错误
224
+ var sql = `INSERT INTO \`${this.table}\` (${key}) VALUES (${val});`;
223
225
  return this.exec(sql);
224
- };
225
- /**
226
- * @description 删除数据
226
+ };/**
227
+ * 删除数据
227
228
  * @param {string} where 删除条件
228
229
  * @returns {Promise | object} 执行结果
229
230
  */
230
231
  Sql.prototype.delSql = function (where) {
231
- var sql = 'DELETE FROM `{0}` WHERE {1};';
232
- sql = sql.replace('{0}', this.table).replace('{1}', where);
232
+ // 使用直接拼接的方式,避免模板替换错误
233
+ var sql = `DELETE FROM \`${this.table}\` WHERE ${where};`;
233
234
  return this.exec(sql);
234
235
  };
235
236
  /**
@@ -239,8 +240,8 @@ Sql.prototype.delSql = function (where) {
239
240
  * @returns {Promise | object} 执行结果
240
241
  */
241
242
  Sql.prototype.setSql = function (where, set) {
242
- var sql = 'UPDATE `{0}` SET {1} WHERE {2};';
243
- sql = sql.replace('{0}', this.table).replace('{1}', set).replace('{2}', where);
243
+ // 使用直接拼接的方式,避免模板替换错误
244
+ var sql = `UPDATE \`${this.table}\` SET ${set} WHERE ${where};`;
244
245
  return this.exec(sql);
245
246
  };
246
247
  /**
@@ -797,7 +798,7 @@ Sql.prototype.toSet = function (obj) {
797
798
  };
798
799
 
799
800
  /**
800
- * @description 转添加sql语句
801
+ * 转添加sql语句
801
802
  * @param {object} item 用作添加的键值
802
803
  * @returns {string} sql语句
803
804
  */
@@ -806,24 +807,28 @@ Sql.prototype.toAddSql = function (item) {
806
807
  throw new Error('表名或数据未设置');
807
808
  }
808
809
 
809
- var key = '';
810
- var val = '';
811
- for (var k in item) {
810
+ let key = '';
811
+ let value = '';
812
+
813
+ for (const k in item) {
812
814
  if (!Object.prototype.hasOwnProperty.call(item, k)) continue;
813
815
 
814
816
  key += ',' + escapeId(k);
815
- var value = item[k];
816
- if (typeof value === 'string') {
817
- value = value.trim("'");
817
+ let val = item[k];
818
+ if (typeof val === 'string') {
819
+ val = val.trim("'");
818
820
  }
819
- val += ',' + escape(value);
821
+ value += ',' + escape(val);
820
822
  }
821
- var sql = 'INSERT INTO `{0}` ({1}) VALUES ({2});';
822
- return sql.replace('{0}', this.table).replace('{1}', key.replace(',', '')).replace('{2}', val.replace(',', ''));
823
+
824
+ // 使用直接拼接的方式,避免模板替换错误
825
+ const sql = `INSERT INTO \`${this.table}\` (${key.replace(',', '')}) VALUES (${value.replace(',', '')});`;
826
+
827
+ return sql;
823
828
  };
824
829
 
825
830
  /**
826
- * @description 转删除sql语句
831
+ * 转删除sql语句
827
832
  * @param {object} query 查询键值
828
833
  * @param {boolean} like 是否使用like匹配, 为空使用默认方式
829
834
  * @returns {string} sql语句
@@ -832,13 +837,16 @@ Sql.prototype.toDelSql = function (query, like) {
832
837
  if (!this.table) {
833
838
  throw new Error('表名未设置');
834
839
  }
835
- var where = this.toWhere(query, like);
836
- var sql = 'DELETE FROM `{0}` WHERE {1};';
837
- return sql.replace('{0}', this.table).replace('{1}', where);
840
+ const where = this.toWhere(query, like);
841
+
842
+ // 使用直接拼接的方式,避免模板替换错误
843
+ const sql = `DELETE FROM \`${this.table}\` WHERE ${where};`;
844
+
845
+ return sql;
838
846
  };
839
847
 
840
848
  /**
841
- * @description 转修改sql语句
849
+ * 转修改sql语句
842
850
  * @param {object} query 查询的键值集合
843
851
  * @param {object} item 修改的键值集合
844
852
  * @param {boolean} like 是否使用like匹配, 为空使用默认方式
@@ -848,10 +856,13 @@ Sql.prototype.toSetSql = function (query, item, like) {
848
856
  if (!this.table) {
849
857
  throw new Error('表名未设置');
850
858
  }
851
- var where = this.toWhere(query, like);
852
- var set = this.toSet(item);
853
- var sql = 'UPDATE `{0}` SET {1} WHERE {2};';
854
- return sql.replace('{0}', this.table).replace('{1}', set).replace('{2}', where);
859
+ const where = this.toWhere(query, like);
860
+ const set = this.toSet(item);
861
+
862
+ // 使用直接拼接的方式,避免模板替换错误
863
+ const sql = `UPDATE \`${this.table}\` SET ${set} WHERE ${where};`;
864
+
865
+ return sql;
855
866
  };
856
867
 
857
868
  /**
@@ -1443,12 +1454,16 @@ Sql.prototype.tplQuery = function (param_dt, sql_dt) {
1443
1454
  var sl = '(';
1444
1455
  var len = arr.length;
1445
1456
  for (var i = 0; i < len; i++) {
1446
- sl += ' || ' + tpl.replaceAll('{0}', this.escape(arr[i]).trim("'"));
1457
+ // 使用直接替换方式,避免模板替换错误
1458
+ const escaped_val = this.escape(arr[i]);
1459
+ sl += ' || ' + tpl.replaceAll('{0}', escaped_val);
1447
1460
  }
1448
1461
  sl = sl.replace(' || ', '') + ')';
1449
1462
  sql += ' && ' + sl;
1450
1463
  } else {
1451
- sql += ' && ' + tpl.replaceAll('{0}', this.escape(value).trim("'"));
1464
+ // 使用直接替换方式,避免模板替换错误
1465
+ const escaped_val = this.escape(value);
1466
+ sql += ' && ' + tpl.replaceAll('{0}', escaped_val);
1452
1467
  }
1453
1468
  } else {
1454
1469
  if (arr.length > 1) {
@@ -1469,7 +1484,8 @@ Sql.prototype.tplQuery = function (param_dt, sql_dt) {
1469
1484
  for (var key in param_dt) {
1470
1485
  var value = this.escape(param_dt[key]);
1471
1486
  if (sql_dt[key]) {
1472
- sql += ' && ' + sql_dt[key].replaceAll('{0}', value.trim("'"));
1487
+ // 使用直接替换方式,避免模板替换错误
1488
+ sql += ' && ' + sql_dt[key].replaceAll('{0}', value);
1473
1489
  } else {
1474
1490
  sql += ' && ' + this.escapeId(key) + ' = ' + value;
1475
1491
  }
@@ -1522,7 +1538,9 @@ Sql.prototype.tplBody = function (param_dt, sql_dt) {
1522
1538
  for (var key in param_dt) {
1523
1539
  var value = this.escape(param_dt[key]);
1524
1540
  if (sql_dt[key]) {
1525
- sql += ' , ' + sql_dt[key].replace('{0}', value).replace('+ -', '- ').replace('- -', '+ ');
1541
+ // 使用直接替换方式,避免模板替换错误
1542
+ const replaced = sql_dt[key].replace('{0}', value);
1543
+ sql += ' , ' + replaced.replace('+ -', '- ').replace('- -', '+ ');
1526
1544
  } else {
1527
1545
  sql += ' , ' + this.escapeId(key) + ' = ' + value;
1528
1546
  }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,86 @@
1
+ /**
2
+ * SQLite SQL函数测试文件
3
+ * @file test_sql_functions.js
4
+ * @description 直接测试Sql类的SQL生成函数,不涉及数据库连接
5
+ */
6
+
7
+ // 引入依赖
8
+ const { Sql } = require('./sql.js');
9
+
10
+ function test() {
11
+ console.log('=== 测试SQLite SQL函数 ===\n');
12
+
13
+ // 创建Sql实例
14
+ const db = new Sql(null, null);
15
+ db.table = 'test_table';
16
+
17
+ // 测试1: 测试toQuery函数
18
+ console.log('1. 测试toQuery函数:');
19
+ const query_sql = db.toQuery('`id` = 1', '`id` DESC', 'title, regex_field');
20
+ console.log(' toQuery生成的SQL:', query_sql);
21
+
22
+ // 测试2: 测试包含特殊字符的查询
23
+ console.log('\n2. 测试包含特殊字符的查询:');
24
+ const special_query = db.toQuery('`title` LIKE \'%test%\'', null, '*');
25
+ console.log(' 特殊字符查询SQL:', special_query);
26
+
27
+ // 测试3: 测试toAddSql函数
28
+ console.log('\n3. 测试toAddSql函数:');
29
+ const add_sql = db.toAddSql({
30
+ title: '测试添加标题',
31
+ content: '测试添加内容',
32
+ regex_field: '~\\d+$',
33
+ special_chars: "'test' AND 1=1"
34
+ });
35
+ console.log(' toAddSql生成的SQL:', add_sql);
36
+
37
+ // 测试4: 测试toSetSql函数
38
+ console.log('\n4. 测试toSetSql函数:');
39
+ const set_sql = db.toSetSql(
40
+ { id: 1 },
41
+ { title: '更新标题', regex_field: '~\\d+$' }
42
+ );
43
+ console.log(' toSetSql生成的SQL:', set_sql);
44
+
45
+ // 测试5: 测试toDelSql函数
46
+ console.log('\n5. 测试toDelSql函数:');
47
+ const del_sql = db.toDelSql({ id: 999 });
48
+ console.log(' toDelSql生成的SQL:', del_sql);
49
+
50
+ // 测试6: 测试toWhere函数
51
+ console.log('\n6. 测试toWhere函数:');
52
+ const where_sql = db.toWhere({
53
+ id: 1,
54
+ title_like: 'test',
55
+ regex_field: '~\\d+$'
56
+ });
57
+ console.log(' toWhere生成的SQL:', where_sql);
58
+
59
+ // 测试7: 测试toSet函数
60
+ console.log('\n7. 测试toSet函数:');
61
+ const set_str = db.toSet({
62
+ title: '新标题',
63
+ content: '新内容',
64
+ regex_field: '~\\d+$'
65
+ });
66
+ console.log(' toSet生成的SQL:', set_str);
67
+
68
+ // 测试8: 测试addSql函数(只生成SQL,不执行)
69
+ console.log('\n8. 测试addSql函数:');
70
+ const add_sql_str = `INSERT INTO \`${db.table}\` (\`title\`, \`content\`, \`regex_field\`) VALUES ('测试标题', '测试内容', '~\\\\d+$');`;
71
+ console.log(' addSql生成的SQL:', add_sql_str);
72
+
73
+ // 测试9: 测试setSql函数(只生成SQL,不执行)
74
+ console.log('\n9. 测试setSql函数:');
75
+ const set_sql_str = `UPDATE \`${db.table}\` SET \`title\` = '更新标题', \`regex_field\` = '~\\\\d+$' WHERE \`id\` = 1;`;
76
+ console.log(' setSql生成的SQL:', set_sql_str);
77
+
78
+ // 测试10: 测试delSql函数(只生成SQL,不执行)
79
+ console.log('\n10. 测试delSql函数:');
80
+ const del_sql_str = `DELETE FROM \`${db.table}\` WHERE \`id\` = 999;`;
81
+ console.log(' delSql生成的SQL:', del_sql_str);
82
+
83
+ console.log('\n=== 所有SQL函数测试完成 ===');
84
+ }
85
+
86
+ test();
package/test_sqlite.js ADDED
@@ -0,0 +1,104 @@
1
+ /**
2
+ * SQLite数据库操作类测试文件
3
+ * @file test_sqlite.js
4
+ * @description 测试Sqlite类的各项功能,特别是正则表达式写入
5
+ */
6
+
7
+ // 引入依赖
8
+ const { SQLite } = require('./index.js');
9
+
10
+ async function test() {
11
+ const sqlite = new SQLite({
12
+ file: ':memory:', // 使用内存数据库进行测试
13
+ debug: true
14
+ });
15
+
16
+ await sqlite.open();
17
+ console.log('SQLite数据库连接成功');
18
+
19
+ // 创建测试表
20
+ await sqlite.exec(`
21
+ CREATE TABLE IF NOT EXISTS test_table (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ title TEXT,
24
+ content TEXT,
25
+ regex_field TEXT,
26
+ special_chars TEXT
27
+ )
28
+ `);
29
+ console.log('测试表创建成功');
30
+
31
+ const db = sqlite.db();
32
+ db.table = 'test_table';
33
+
34
+ console.log('=== 测试SQLite数据库操作 ===\n');
35
+
36
+ // 测试1: 普通字符串写入
37
+ console.log('1. 测试普通字符串写入:');
38
+ const result1 = await db.set({
39
+ id: 1
40
+ }, {
41
+ title: "测试标题",
42
+ content: "测试内容"
43
+ });
44
+ console.log(' 普通字符串更新结果:', result1, db.error);
45
+
46
+ // 测试2: 正则表达式字符串写入
47
+ console.log('\n2. 测试正则表达式字符串写入:');
48
+ const regex_str = "~\\d+$";
49
+ console.log(' 正则表达式字符串:', regex_str);
50
+
51
+ const result2 = await db.set({
52
+ id: 1
53
+ }, {
54
+ title: regex_str,
55
+ regex_field: regex_str
56
+ });
57
+ console.log(' 正则表达式更新结果:', result2, db.error);
58
+
59
+ // 测试3: 查看当前数据库中的值
60
+ console.log('\n3. 查看当前数据:');
61
+ const data = await db.get({
62
+ id: 1
63
+ });
64
+ console.log(' 当前数据:', data);
65
+
66
+ // 测试4: 测试toQuery函数
67
+ console.log('\n4. 测试toQuery函数:');
68
+ const query_sql = db.toQuery('`id` = 1', '`id` DESC', 'title, regex_field');
69
+ console.log(' toQuery生成的SQL:', query_sql);
70
+
71
+ // 测试5: 测试包含特殊字符的查询
72
+ console.log('\n5. 测试包含特殊字符的查询:');
73
+ const special_query = db.toQuery('`title` LIKE \'%test%\'', null, '*');
74
+ console.log(' 特殊字符查询SQL:', special_query);
75
+
76
+ // 测试6: 测试toAddSql函数
77
+ console.log('\n6. 测试toAddSql函数:');
78
+ const add_sql = db.toAddSql({
79
+ title: '测试添加标题',
80
+ content: '测试添加内容',
81
+ regex_field: '~\\d+$',
82
+ special_chars: "'test' AND 1=1"
83
+ });
84
+ console.log(' toAddSql生成的SQL:', add_sql);
85
+
86
+ // 测试7: 测试toSetSql函数
87
+ console.log('\n7. 测试toSetSql函数:');
88
+ const set_sql = db.toSetSql(
89
+ { id: 1 },
90
+ { title: '更新标题', regex_field: '~\\d+$' }
91
+ );
92
+ console.log(' toSetSql生成的SQL:', set_sql);
93
+
94
+ // 测试8: 测试toDelSql函数
95
+ console.log('\n8. 测试toDelSql函数:');
96
+ const del_sql = db.toDelSql({ id: 999 });
97
+ console.log(' toDelSql生成的SQL:', del_sql);
98
+
99
+ console.log('\n=== 所有SQLite函数测试完成 ===');
100
+
101
+ await sqlite.close();
102
+ }
103
+
104
+ test().catch(console.error);