mm_sqlite 1.5.6 → 1.5.8
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/lib/query_error.js +22 -0
- package/lib/sql.js +15 -11
- package/lib/sqlite.js +7 -4
- package/package.json +56 -56
- package/test_db/test.db +0 -0
- package/test_db/test_basic.db +0 -0
- package/test_db/test_core_methods.db +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 构造带上下文的数据层错误
|
|
5
|
+
*
|
|
6
|
+
* 独立函数而非实例方法:DB 包装层以 `super(sqlite.run, sqlite.exec)` 传递未绑定的方法引用,
|
|
7
|
+
* 调用时 this 指向 DB 实例而不是 SQLite 实例,任何 this.xxx 辅助方法都会失效。
|
|
8
|
+
* 用模块级函数可同时覆盖「SQLite 直接被调用」与「经 DB 包装调用」两条路径。
|
|
9
|
+
*
|
|
10
|
+
* @param {Error} cause 驱动抛出的原始异常
|
|
11
|
+
* @param {string} sql 出错的 SQL
|
|
12
|
+
* @param {Array} params 绑定参数
|
|
13
|
+
* @returns {Error} 携带 code / sql / params / cause 的错误对象
|
|
14
|
+
*/
|
|
15
|
+
module.exports = function makeQueryError(cause, sql, params) {
|
|
16
|
+
const error = new Error(`SQL执行失败: ${cause.message || cause}`);
|
|
17
|
+
error.code = cause.code || cause.errno;
|
|
18
|
+
error.sql = sql;
|
|
19
|
+
error.params = params;
|
|
20
|
+
error.cause = cause;
|
|
21
|
+
return error;
|
|
22
|
+
};
|
package/lib/sql.js
CHANGED
|
@@ -1382,25 +1382,29 @@ Sql.prototype.tplQuery = function (param_dt, sql_dt) {
|
|
|
1382
1382
|
* @returns {string} 返回拼接的查询参数
|
|
1383
1383
|
*/
|
|
1384
1384
|
Sql.prototype.tplBody = function (param_dt, sql_dt) {
|
|
1385
|
-
|
|
1386
|
-
|
|
1385
|
+
if (!param_dt) {
|
|
1386
|
+
return '';
|
|
1387
|
+
}
|
|
1388
|
+
var parts = [];
|
|
1389
|
+
if (!sql_dt || Object.keys(sql_dt).length === 0) {
|
|
1387
1390
|
for (var key in param_dt) {
|
|
1388
|
-
|
|
1391
|
+
parts.push(this.escapeId(key) + ' = ' + this.escape(param_dt[key]));
|
|
1389
1392
|
}
|
|
1390
1393
|
} else {
|
|
1391
|
-
for (var
|
|
1392
|
-
var value = this.escape(param_dt[
|
|
1393
|
-
|
|
1394
|
-
|
|
1394
|
+
for (var k in param_dt) {
|
|
1395
|
+
var value = this.escape(param_dt[k]);
|
|
1396
|
+
// 不能再用 sql 作局部变量名,否则会遮蔽累加结果,SET 子句恒为空
|
|
1397
|
+
var tpl = sql_dt[k];
|
|
1398
|
+
if (tpl) {
|
|
1395
1399
|
// 使用直接替换方式,避免模板替换错误
|
|
1396
|
-
|
|
1397
|
-
|
|
1400
|
+
var replaced = tpl.replaceAll('{0}', value.trim("'"));
|
|
1401
|
+
parts.push(replaced.replace(/\+ -/g, '- ').replace(/- -/g, '+ '));
|
|
1398
1402
|
} else {
|
|
1399
|
-
|
|
1403
|
+
parts.push(this.escapeId(k) + ' = ' + value);
|
|
1400
1404
|
}
|
|
1401
1405
|
}
|
|
1402
1406
|
}
|
|
1403
|
-
return
|
|
1407
|
+
return parts.join(', ');
|
|
1404
1408
|
};
|
|
1405
1409
|
|
|
1406
1410
|
/**
|
package/lib/sqlite.js
CHANGED
|
@@ -4,6 +4,7 @@ const {
|
|
|
4
4
|
const { Base } = require('mm_mod');
|
|
5
5
|
const { fullname, addDir } = require('mm_helper');
|
|
6
6
|
const SQLitePool = require('./pool');
|
|
7
|
+
const makeQueryError = require('./query_error');
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -189,13 +190,15 @@ SQLite.prototype.run = async function (sql, params = [], timeout = 30000) {
|
|
|
189
190
|
const stmt = conn.prepare(sql);
|
|
190
191
|
ret = params.length > 0 ? stmt.all(...params) : stmt.all();
|
|
191
192
|
} catch (error) {
|
|
192
|
-
|
|
193
|
+
// D-12:查询失败必须与「查到 0 条」区分。历史实现把异常吞成 [],
|
|
194
|
+
// 上层拿到空结果继续跑,最终以 TypeError / 空页面呈现,根因彻底丢失。
|
|
195
|
+
// 这里补齐上下文后抛出,由调用方决定降级或失败;同时不再直接 console.error(D-15)
|
|
193
196
|
this.sql = sql;
|
|
194
197
|
this.error = {
|
|
195
198
|
code: error.code || error.errno,
|
|
196
199
|
message: error.message
|
|
197
200
|
};
|
|
198
|
-
|
|
201
|
+
throw makeQueryError(error, sql, params);
|
|
199
202
|
} finally {
|
|
200
203
|
await releaseConn(conn);
|
|
201
204
|
}
|
|
@@ -250,13 +253,13 @@ SQLite.prototype.exec = async function (sql, params = [], timeout) {
|
|
|
250
253
|
}
|
|
251
254
|
ret = info.lastInsertRowid || info.changes || 1;
|
|
252
255
|
} catch (error) {
|
|
253
|
-
|
|
256
|
+
// 写操作失败同样不能伪装成「影响 0 行」:上层会把「没更新」当成正常结果
|
|
254
257
|
this.sql = sql;
|
|
255
258
|
this.error = {
|
|
256
259
|
code: error.code || error.errno,
|
|
257
260
|
message: error.message
|
|
258
261
|
};
|
|
259
|
-
|
|
262
|
+
throw makeQueryError(error, sql, params);
|
|
260
263
|
} finally {
|
|
261
264
|
await releaseConn(conn);
|
|
262
265
|
}
|
package/package.json
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mm_sqlite",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "高性能SQLite数据库操作模块,提供与mm_mysql完全兼容的API接口,支持异步操作、事务处理和批量操作",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "node test.js",
|
|
8
|
-
"dev": "nodemon test.js",
|
|
9
|
-
"lint": "eslint . --config eslint.config.js",
|
|
10
|
-
"lint:fix": "eslint . --config eslint.config.js --fix"
|
|
11
|
-
},
|
|
12
|
-
"repository": {
|
|
13
|
-
"type": "git",
|
|
14
|
-
"url": "git+https://gitee.com/qiuwenwu91/mm_sqlite.git"
|
|
15
|
-
},
|
|
16
|
-
"keywords": [
|
|
17
|
-
"mm_mod",
|
|
18
|
-
"mm_adapter",
|
|
19
|
-
"mm_persist",
|
|
20
|
-
"sqlite",
|
|
21
|
-
"node.js",
|
|
22
|
-
"async",
|
|
23
|
-
"await",
|
|
24
|
-
"promise",
|
|
25
|
-
"database",
|
|
26
|
-
"transaction",
|
|
27
|
-
"batch",
|
|
28
|
-
"sql",
|
|
29
|
-
"mm_mysql",
|
|
30
|
-
"compatible",
|
|
31
|
-
"node-sqlite3",
|
|
32
|
-
"async-await"
|
|
33
|
-
],
|
|
34
|
-
"layer": "adapter",
|
|
35
|
-
"group": "persist",
|
|
36
|
-
"author": "邱文武",
|
|
37
|
-
"license": "MIT",
|
|
38
|
-
"bugs": {
|
|
39
|
-
"url": "https://gitee.com/qiuwenwu91/mm_sqlite/issues"
|
|
40
|
-
},
|
|
41
|
-
"homepage": "https://gitee.com/qiuwenwu91/mm_sqlite#readme",
|
|
42
|
-
"engines": {
|
|
43
|
-
"node": ">=22.13.0"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"mm_corejs": "^1.1.4",
|
|
47
|
-
"mm_mod": "^1.0.1",
|
|
48
|
-
"mm_helper": "^1.0.0",
|
|
49
|
-
"sqlstring": "^2.3.3"
|
|
50
|
-
},
|
|
51
|
-
"devDependencies": {
|
|
52
|
-
"eslint": "^10.9.1",
|
|
53
|
-
"eslint-plugin-jsdoc": "^64.2.1",
|
|
54
|
-
"mm_eslint": "^1.7.7"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "mm_sqlite",
|
|
3
|
+
"version": "1.5.8",
|
|
4
|
+
"description": "高性能SQLite数据库操作模块,提供与mm_mysql完全兼容的API接口,支持异步操作、事务处理和批量操作",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node test.js",
|
|
8
|
+
"dev": "nodemon test.js",
|
|
9
|
+
"lint": "eslint . --config eslint.config.js",
|
|
10
|
+
"lint:fix": "eslint . --config eslint.config.js --fix"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://gitee.com/qiuwenwu91/mm_sqlite.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mm_mod",
|
|
18
|
+
"mm_adapter",
|
|
19
|
+
"mm_persist",
|
|
20
|
+
"sqlite",
|
|
21
|
+
"node.js",
|
|
22
|
+
"async",
|
|
23
|
+
"await",
|
|
24
|
+
"promise",
|
|
25
|
+
"database",
|
|
26
|
+
"transaction",
|
|
27
|
+
"batch",
|
|
28
|
+
"sql",
|
|
29
|
+
"mm_mysql",
|
|
30
|
+
"compatible",
|
|
31
|
+
"node-sqlite3",
|
|
32
|
+
"async-await"
|
|
33
|
+
],
|
|
34
|
+
"layer": "adapter",
|
|
35
|
+
"group": "persist",
|
|
36
|
+
"author": "邱文武",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://gitee.com/qiuwenwu91/mm_sqlite/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://gitee.com/qiuwenwu91/mm_sqlite#readme",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.13.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"mm_corejs": "^1.1.4",
|
|
47
|
+
"mm_mod": "^1.0.1",
|
|
48
|
+
"mm_helper": "^1.0.0",
|
|
49
|
+
"sqlstring": "^2.3.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"eslint": "^10.9.1",
|
|
53
|
+
"eslint-plugin-jsdoc": "^64.2.1",
|
|
54
|
+
"mm_eslint": "^1.7.7"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/test_db/test.db
DELETED
|
Binary file
|
package/test_db/test_basic.db
DELETED
|
Binary file
|
|
Binary file
|