@zhin.js/database 1.0.36 → 1.0.38
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/CHANGELOG.md +12 -0
- package/README.md +2 -5
- package/lib/dialects/sqlite.d.ts +7 -4
- package/lib/dialects/sqlite.d.ts.map +1 -1
- package/lib/dialects/sqlite.js +59 -69
- package/lib/dialects/sqlite.js.map +1 -1
- package/lib/type/document/model.d.ts.map +1 -1
- package/lib/type/document/model.js +2 -1
- package/lib/type/document/model.js.map +1 -1
- package/package.json +10 -14
- package/src/dialects/sqlite.ts +61 -73
- package/src/type/document/model.ts +2 -1
- package/tests/database.test.ts +19 -7
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -8,12 +8,9 @@ Universal database abstraction layer for Zhin.js framework with support for mult
|
|
|
8
8
|
npm install @zhin.js/database
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Install the database driver you need:
|
|
11
|
+
Install the database driver you need(SQLite 使用 Node 内置 `node:sqlite`,无需安装,需 Node.js 22.5+,推荐 24+):
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
# For SQLite
|
|
15
|
-
npm install sqlite3
|
|
16
|
-
|
|
17
14
|
# For MySQL
|
|
18
15
|
npm install mysql2
|
|
19
16
|
|
|
@@ -56,7 +53,7 @@ const user = await userModel.create({
|
|
|
56
53
|
## Supported Databases
|
|
57
54
|
|
|
58
55
|
### ✅ Relational Databases (已完整实现)
|
|
59
|
-
- **SQLite** -
|
|
56
|
+
- **SQLite** - 内置支持,使用 Node 自带 `node:sqlite`(无需安装驱动,需 Node.js 22.5+,推荐 24+)
|
|
60
57
|
- 轻量级、零配置
|
|
61
58
|
- 适合中小型应用
|
|
62
59
|
- 支持 WAL 模式
|
package/lib/dialects/sqlite.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import { Dialect } from
|
|
2
|
-
import { Database } from
|
|
3
|
-
import { Column, Transaction, TransactionOptions } from
|
|
4
|
-
import { RelatedDatabase } from
|
|
1
|
+
import { Dialect } from '../base/index.js';
|
|
2
|
+
import { Database } from '../base/index.js';
|
|
3
|
+
import { Column, Transaction, TransactionOptions } from '../types.js';
|
|
4
|
+
import { RelatedDatabase } from '../type/related/database.js';
|
|
5
5
|
export interface SQLiteDialectConfig {
|
|
6
6
|
filename: string;
|
|
7
7
|
mode?: string;
|
|
8
8
|
}
|
|
9
9
|
export declare class SQLiteDialect<S extends Record<string, object> = Record<string, object>> extends Dialect<SQLiteDialectConfig, S, string> {
|
|
10
|
+
/** Node 内置 SQLite 连接(node:sqlite),在 connect() 中动态加载 */
|
|
10
11
|
private db;
|
|
11
12
|
constructor(config: SQLiteDialectConfig);
|
|
12
13
|
isConnected(): boolean;
|
|
13
14
|
connect(): Promise<void>;
|
|
14
15
|
disconnect(): Promise<void>;
|
|
15
16
|
healthCheck(): Promise<boolean>;
|
|
17
|
+
/** node:sqlite 仅支持 number/string/bigint/buffer/null,将 Date/boolean 等转为可绑定值 */
|
|
18
|
+
private prepareBindParams;
|
|
16
19
|
query<U = any>(sql: string, params?: any[]): Promise<U>;
|
|
17
20
|
/**
|
|
18
21
|
* 处理查询结果,移除字符串字段的多余引号
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"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"}
|
package/lib/dialects/sqlite.js
CHANGED
|
@@ -1,102 +1,88 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
|
-
import { Dialect } from "../base/index.js";
|
|
3
|
-
import { Registry } from "../registry.js";
|
|
4
|
-
import { RelatedDatabase } from "../type/related/database.js";
|
|
5
2
|
import path from 'node:path';
|
|
3
|
+
import { Dialect } from '../base/index.js';
|
|
4
|
+
import { Registry } from '../registry.js';
|
|
5
|
+
import { RelatedDatabase } from '../type/related/database.js';
|
|
6
6
|
export class SQLiteDialect extends Dialect {
|
|
7
|
+
/** Node 内置 SQLite 连接(node:sqlite),在 connect() 中动态加载 */
|
|
7
8
|
db = null;
|
|
8
9
|
constructor(config) {
|
|
9
10
|
super('sqlite', config);
|
|
10
11
|
}
|
|
11
|
-
// Connection management
|
|
12
12
|
isConnected() {
|
|
13
13
|
return this.db !== null;
|
|
14
14
|
}
|
|
15
15
|
async connect() {
|
|
16
16
|
try {
|
|
17
|
-
const {
|
|
18
|
-
const
|
|
17
|
+
const { createRequire } = await import('node:module');
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
const { DatabaseSync } = require('node:sqlite');
|
|
19
20
|
const dirname = path.dirname(this.config.filename);
|
|
20
21
|
if (!fs.existsSync(dirname)) {
|
|
21
22
|
fs.mkdirSync(dirname, { recursive: true });
|
|
22
23
|
}
|
|
23
|
-
this.db = new
|
|
24
|
+
this.db = new DatabaseSync(this.config.filename);
|
|
24
25
|
}
|
|
25
26
|
catch (error) {
|
|
26
|
-
|
|
27
|
-
throw new Error(`SQLite 连接失败: ${error}`);
|
|
27
|
+
throw new Error(`SQLite 连接失败(需要 Node.js 22.5+,推荐 24+): ${error}`);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
async disconnect() {
|
|
31
31
|
if (this.db) {
|
|
32
|
-
|
|
33
|
-
this.db.close(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.db = null;
|
|
39
|
-
resolve();
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
32
|
+
try {
|
|
33
|
+
this.db.close();
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
this.db = null;
|
|
37
|
+
}
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
40
|
async healthCheck() {
|
|
46
41
|
return this.isConnected();
|
|
47
42
|
}
|
|
43
|
+
/** node:sqlite 仅支持 number/string/bigint/buffer/null,将 Date/boolean 等转为可绑定值 */
|
|
44
|
+
prepareBindParams(params) {
|
|
45
|
+
return params.map((v) => {
|
|
46
|
+
if (v == null)
|
|
47
|
+
return null;
|
|
48
|
+
if (v instanceof Date)
|
|
49
|
+
return v.toISOString();
|
|
50
|
+
if (typeof v === 'boolean')
|
|
51
|
+
return v ? 1 : 0;
|
|
52
|
+
return v;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
48
55
|
async query(sql, params) {
|
|
56
|
+
if (!this.db)
|
|
57
|
+
throw new Error('SQLite 未连接');
|
|
49
58
|
const trimmedSql = sql.trim().toLowerCase();
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
else {
|
|
60
|
-
// 对查询结果进行后处理,移除多余的引号
|
|
61
|
-
const processedRows = this.processQueryResults(rows);
|
|
62
|
-
resolve(processedRows);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
// INSERT 使用 db.run 执行,返回 { lastID, changes }
|
|
67
|
-
else if (isInsertQuery) {
|
|
68
|
-
this.db.run(sql, params, function (err) {
|
|
69
|
-
if (err) {
|
|
70
|
-
reject(err);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
resolve({ lastID: this.lastID, changes: this.changes });
|
|
74
|
-
}
|
|
75
|
-
});
|
|
59
|
+
const isSelect = trimmedSql.startsWith('select');
|
|
60
|
+
const isInsert = trimmedSql.startsWith('insert');
|
|
61
|
+
const isUpdateOrDelete = trimmedSql.startsWith('update') || trimmedSql.startsWith('delete');
|
|
62
|
+
const args = this.prepareBindParams(params ?? []);
|
|
63
|
+
try {
|
|
64
|
+
const stmt = this.db.prepare(sql);
|
|
65
|
+
if (isSelect) {
|
|
66
|
+
const rows = stmt.all(...args);
|
|
67
|
+
return this.processQueryResults(rows);
|
|
76
68
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else {
|
|
84
|
-
resolve(this.changes);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
69
|
+
if (isInsert) {
|
|
70
|
+
const result = stmt.run(...args);
|
|
71
|
+
return {
|
|
72
|
+
lastID: Number(result.lastInsertRowid),
|
|
73
|
+
changes: Number(result.changes),
|
|
74
|
+
};
|
|
87
75
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (err) {
|
|
92
|
-
reject(err);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
resolve(undefined);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
76
|
+
if (isUpdateOrDelete) {
|
|
77
|
+
const result = stmt.run(...args);
|
|
78
|
+
return Number(result.changes);
|
|
98
79
|
}
|
|
99
|
-
|
|
80
|
+
stmt.run(...args);
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
100
86
|
}
|
|
101
87
|
/**
|
|
102
88
|
* 处理查询结果,移除字符串字段的多余引号
|
|
@@ -159,8 +145,12 @@ export class SQLiteDialect extends Dialect {
|
|
|
159
145
|
}
|
|
160
146
|
async dispose() {
|
|
161
147
|
if (this.db) {
|
|
162
|
-
|
|
163
|
-
|
|
148
|
+
try {
|
|
149
|
+
this.db.close();
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
this.db = null;
|
|
153
|
+
}
|
|
164
154
|
}
|
|
165
155
|
}
|
|
166
156
|
// SQL generation methods
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/dialects/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAO9D,MAAM,OAAO,aAAyE,SAAQ,OAAuC;IACnI,uDAAuD;IAC/C,EAAE,GAAwD,IAAI,CAAC;IAEvE,YAAY,MAA2B;QACrC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC;YACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,yCAAyC,KAAK,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAED,8EAA8E;IACtE,iBAAiB,CAAC,MAAa;QACrC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,IAAI,CAAC,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC3B,IAAI,CAAC,YAAY,IAAI;gBAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9C,IAAI,OAAO,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAU,GAAW,EAAE,MAAc;QAC9C,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,gBAAgB,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAU,CAAC;gBACxC,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAM,CAAC;YAC7C,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAmE,CAAC;gBACnG,OAAO;oBACL,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;oBACtC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;iBAC3B,CAAC;YACT,CAAC;YACD,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAiC,CAAC;gBACjE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAM,CAAC;YACrC,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAClB,OAAO,SAAc,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,IAAS;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,GAAQ;QAC7B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC;QAEhD,MAAM,YAAY,GAAQ,EAAE,CAAC;QAE7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,KAAU;QAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5C,mBAAmB;QACnB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAEpC,2BAA2B;YAC3B,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzD,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,oBAAoB;oBACpB,OAAO,QAAQ,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,kDAAkD;QAClD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,aAAa,CAAC,IAAY;QACxB,MAAM,OAAO,GAA2B;YACtC,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,SAAS;YACpB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,MAAM;SACf,CAAC;QACF,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,MAAM,CAAC;IAC/C,CAAC;IAED,eAAe,CAAC,UAAkB;QAChC,OAAO,IAAI,UAAU,GAAG,CAAC;IAC3B,CAAC;IAED,uBAAuB,CAAC,KAAa;QACnC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,sBAAsB;QACpB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,aAAa,CAAC,KAAc;QAC1B,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,KAAW;QACpB,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IACpC,CAAC;IAED,UAAU,CAAC,KAAU;QACnB,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1D,CAAC;IAED,YAAY,CAAC,KAAa;QACxB,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,kBAAkB,CAAC,KAAU;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;QACzC,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACnE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,KAAK,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,WAAW,CAAC,KAAa;QACvB,OAAO,SAAS,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,OAAO,UAAU,MAAM,EAAE,CAAC;IAC5B,CAAC;IAED,iBAAiB,CAAC,KAAa,EAAE,MAAc;QAC7C,OAAO,SAAS,KAAK,WAAW,MAAM,EAAE,CAAC;IAC3C,CAAC;IAED,iBAAiB,CAAoB,SAAY,EAAE,OAAiB;QAClE,OAAO,8BAA8B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACzG,CAAC;IAED,sBAAsB,CAAC,KAAa,EAAE,MAAmB;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,KAAK,SAAS;YAC7C,CAAC,CAAC,YAAY,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YACvD,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO,GAAG,IAAI,IAAI,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,EAAE,CAAC;IAC/E,CAAC;IAED,gBAAgB,CAAoB,SAAY,EAAE,WAAqB;QACrE,OAAO,eAAe,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5F,CAAC;IAED,eAAe,CAAoB,SAAY,EAAE,QAAkB;QACjE,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO,cAAc,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;IAClF,CAAC;IAED,eAAe,CAAoB,SAAiB,EAAE,SAAY,EAAE,QAAkB;QACpF,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO,cAAc,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,+EAA+E;IAC/E,sBAAsB;IACtB,+EAA+E;IAE/E;;OAEG;IACH,oBAAoB;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAA4B;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC;QAErB,OAAO;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAEtC,OAAO;YACL,KAAK,CAAC,MAAM;gBACV,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;YAED,KAAK,CAAC,QAAQ;gBACZ,MAAM,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClC,CAAC;YAED,KAAK,CAAC,KAAK,CAAU,GAAW,EAAE,MAAc;gBAC9C,OAAO,OAAO,CAAC,KAAK,CAAI,GAAG,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;SACF,CAAC;IACJ,CAAC;CACF;AACD,MAAM,OAAO,MAAkE,SAAQ,eAAuC;IAC5H,YAAY,MAA2B,EAAE,WAAuC;QAC9E,KAAK,CAAC,IAAI,aAAa,CAAI,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;CACF;AACD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/type/document/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAa,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/type/document/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAa,MAAM,gBAAgB,CAAC;AAGhE;;;GAGG;AACH,qBAAa,aAAa,CAAC,CAAC,GAAC,GAAG,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,CAAE,SAAQ,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBAEjK,QAAQ,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC;IAKT;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAyBpE;;OAEG;IACG,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAK7G;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM;IAK3B;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpE;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC;IAMtD;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Model } from '../../base/index.js';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
2
3
|
/**
|
|
3
4
|
* 文档型模型类
|
|
4
5
|
* 继承自 Model,提供文档型数据库特有的操作
|
|
@@ -59,7 +60,7 @@ export class DocumentModel extends Model {
|
|
|
59
60
|
* 生成文档ID
|
|
60
61
|
*/
|
|
61
62
|
generateId() {
|
|
62
|
-
return
|
|
63
|
+
return randomUUID();
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
//# sourceMappingURL=model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/type/document/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/type/document/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAG3C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC;;;GAGG;AACH,MAAM,OAAO,aAA6G,SAAQ,KAAmC;IACnK,YACE,QAAgC,EAChC,IAAO;QAEP,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAOD,KAAK,CAAC,MAAM,CAAC,SAAwB;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;YAElC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CACtB;gBACE,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,EAAE;gBACV,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,IAAI,CAAC,IAAc;aAChC,EACD,CAAC,SAAS,CAAC,CACZ,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAuB,GAAG,MAAgB;QACvD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAsC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAY,CAAC,CAAC,KAAK,CAAC;YACrC,GAAG,EAAE,EAAE;SACW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAY,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAC5E,CAAC;IACD;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,MAAqB;QAChD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;YAC/B,GAAG,EAAE,EAAE;SACW,CAAC,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC;YACjB,GAAG,EAAE,EAAE;SACW,CAA6B,CAAC;IACpD,CAAC;IAED;;OAEG;IACK,UAAU;QAChB,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/database",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.38",
|
|
4
4
|
"description": "Universal database abstraction layer for Zhin.js - supports SQLite, MySQL, PostgreSQL, MongoDB, Redis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -13,19 +13,17 @@
|
|
|
13
13
|
"development": "./src/index.ts"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22.5.0"
|
|
18
|
+
},
|
|
17
19
|
"peerDependencies": {
|
|
18
|
-
"
|
|
20
|
+
"mongodb": "^3.1.13",
|
|
19
21
|
"mysql2": "^3.9.8",
|
|
20
22
|
"pg": "^7.1.2",
|
|
21
|
-
"mongodb": "^3.1.13",
|
|
22
23
|
"redis": "latest",
|
|
23
|
-
"zhin.js": "1.0.
|
|
24
|
+
"zhin.js": "1.0.51"
|
|
24
25
|
},
|
|
25
26
|
"peerDependenciesMeta": {
|
|
26
|
-
"sqlite3": {
|
|
27
|
-
"optional": true
|
|
28
|
-
},
|
|
29
27
|
"mysql2": {
|
|
30
28
|
"optional": true
|
|
31
29
|
},
|
|
@@ -40,15 +38,13 @@
|
|
|
40
38
|
}
|
|
41
39
|
},
|
|
42
40
|
"devDependencies": {
|
|
43
|
-
"
|
|
44
|
-
"
|
|
41
|
+
"@types/pg": "latest",
|
|
42
|
+
"mongodb": "latest",
|
|
45
43
|
"mysql2": "latest",
|
|
46
44
|
"pg": "latest",
|
|
47
|
-
"mongodb": "latest",
|
|
48
45
|
"redis": "latest",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"zhin.js": "1.0.49"
|
|
46
|
+
"typescript": "^5.3.0",
|
|
47
|
+
"zhin.js": "1.0.51"
|
|
52
48
|
},
|
|
53
49
|
"repository": {
|
|
54
50
|
"type": "git",
|
package/src/dialects/sqlite.ts
CHANGED
|
@@ -1,56 +1,50 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
|
-
import {Dialect} from "../base/index.js";
|
|
3
|
-
import {Registry} from "../registry.js";
|
|
4
|
-
import {Database} from "../base/index.js";
|
|
5
|
-
import {Column, Transaction, TransactionOptions} from "../types.js";
|
|
6
|
-
import {RelatedDatabase} from "../type/related/database.js";
|
|
7
2
|
import path from 'node:path';
|
|
8
|
-
|
|
3
|
+
import { Dialect } from '../base/index.js';
|
|
4
|
+
import { Registry } from '../registry.js';
|
|
5
|
+
import { Database } from '../base/index.js';
|
|
6
|
+
import { Column, Transaction, TransactionOptions } from '../types.js';
|
|
7
|
+
import { RelatedDatabase } from '../type/related/database.js';
|
|
9
8
|
|
|
10
9
|
export interface SQLiteDialectConfig {
|
|
11
10
|
filename: string;
|
|
12
|
-
mode?:string
|
|
11
|
+
mode?: string;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export class SQLiteDialect<S extends Record<string, object> = Record<string, object>> extends Dialect<SQLiteDialectConfig, S, string> {
|
|
16
|
-
|
|
15
|
+
/** Node 内置 SQLite 连接(node:sqlite),在 connect() 中动态加载 */
|
|
16
|
+
private db: { prepare(sql: string): any; close(): void } | null = null;
|
|
17
17
|
|
|
18
18
|
constructor(config: SQLiteDialectConfig) {
|
|
19
19
|
super('sqlite', config);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// Connection management
|
|
23
22
|
isConnected(): boolean {
|
|
24
23
|
return this.db !== null;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
async connect(): Promise<void> {
|
|
28
27
|
try {
|
|
29
|
-
const {
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
const { createRequire } = await import('node:module');
|
|
29
|
+
const require = createRequire(import.meta.url);
|
|
30
|
+
const { DatabaseSync } = require('node:sqlite');
|
|
31
|
+
const dirname = path.dirname(this.config.filename);
|
|
32
|
+
if (!fs.existsSync(dirname)) {
|
|
33
|
+
fs.mkdirSync(dirname, { recursive: true });
|
|
34
34
|
}
|
|
35
|
-
this.db = new
|
|
35
|
+
this.db = new DatabaseSync(this.config.filename);
|
|
36
36
|
} catch (error) {
|
|
37
|
-
|
|
38
|
-
throw new Error(`SQLite 连接失败: ${error}`);
|
|
37
|
+
throw new Error(`SQLite 连接失败(需要 Node.js 22.5+,推荐 24+): ${error}`);
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
async disconnect(): Promise<void> {
|
|
43
42
|
if (this.db) {
|
|
44
|
-
|
|
45
|
-
this.db.close(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.db = null;
|
|
50
|
-
resolve();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
});
|
|
43
|
+
try {
|
|
44
|
+
this.db.close();
|
|
45
|
+
} finally {
|
|
46
|
+
this.db = null;
|
|
47
|
+
}
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
|
|
@@ -58,55 +52,46 @@ export class SQLiteDialect<S extends Record<string, object> = Record<string, obj
|
|
|
58
52
|
return this.isConnected();
|
|
59
53
|
}
|
|
60
54
|
|
|
55
|
+
/** node:sqlite 仅支持 number/string/bigint/buffer/null,将 Date/boolean 等转为可绑定值 */
|
|
56
|
+
private prepareBindParams(params: any[]): any[] {
|
|
57
|
+
return params.map((v) => {
|
|
58
|
+
if (v == null) return null;
|
|
59
|
+
if (v instanceof Date) return v.toISOString();
|
|
60
|
+
if (typeof v === 'boolean') return v ? 1 : 0;
|
|
61
|
+
return v;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
61
65
|
async query<U = any>(sql: string, params?: any[]): Promise<U> {
|
|
66
|
+
if (!this.db) throw new Error('SQLite 未连接');
|
|
62
67
|
const trimmedSql = sql.trim().toLowerCase();
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// 对查询结果进行后处理,移除多余的引号
|
|
74
|
-
const processedRows = this.processQueryResults(rows);
|
|
75
|
-
resolve(processedRows as U);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
// INSERT 使用 db.run 执行,返回 { lastID, changes }
|
|
80
|
-
else if (isInsertQuery) {
|
|
81
|
-
this.db.run(sql, params, function(this: any, err: any) {
|
|
82
|
-
if (err) {
|
|
83
|
-
reject(err);
|
|
84
|
-
} else {
|
|
85
|
-
resolve({ lastID: this.lastID, changes: this.changes } as U);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
68
|
+
const isSelect = trimmedSql.startsWith('select');
|
|
69
|
+
const isInsert = trimmedSql.startsWith('insert');
|
|
70
|
+
const isUpdateOrDelete = trimmedSql.startsWith('update') || trimmedSql.startsWith('delete');
|
|
71
|
+
const args = this.prepareBindParams(params ?? []);
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const stmt = this.db.prepare(sql);
|
|
75
|
+
if (isSelect) {
|
|
76
|
+
const rows = stmt.all(...args) as any[];
|
|
77
|
+
return this.processQueryResults(rows) as U;
|
|
88
78
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
resolve(this.changes as U);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
79
|
+
if (isInsert) {
|
|
80
|
+
const result = stmt.run(...args) as { changes: number | bigint; lastInsertRowid: number | bigint };
|
|
81
|
+
return {
|
|
82
|
+
lastID: Number(result.lastInsertRowid),
|
|
83
|
+
changes: Number(result.changes),
|
|
84
|
+
} as U;
|
|
98
85
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (err) {
|
|
103
|
-
reject(err);
|
|
104
|
-
} else {
|
|
105
|
-
resolve(undefined as U);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
86
|
+
if (isUpdateOrDelete) {
|
|
87
|
+
const result = stmt.run(...args) as { changes: number | bigint };
|
|
88
|
+
return Number(result.changes) as U;
|
|
108
89
|
}
|
|
109
|
-
|
|
90
|
+
stmt.run(...args);
|
|
91
|
+
return undefined as U;
|
|
92
|
+
} catch (err) {
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
110
95
|
}
|
|
111
96
|
|
|
112
97
|
/**
|
|
@@ -177,8 +162,11 @@ export class SQLiteDialect<S extends Record<string, object> = Record<string, obj
|
|
|
177
162
|
|
|
178
163
|
async dispose(): Promise<void> {
|
|
179
164
|
if (this.db) {
|
|
180
|
-
|
|
181
|
-
|
|
165
|
+
try {
|
|
166
|
+
this.db.close();
|
|
167
|
+
} finally {
|
|
168
|
+
this.db = null;
|
|
169
|
+
}
|
|
182
170
|
}
|
|
183
171
|
}
|
|
184
172
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Model} from '../../base/index.js';
|
|
2
2
|
import { DocumentDatabase } from './database.js';
|
|
3
3
|
import { DocumentQueryResult, Condition } from '../../types.js';
|
|
4
|
+
import { randomUUID } from 'crypto';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 文档型模型类
|
|
@@ -81,6 +82,6 @@ export class DocumentModel<D=any, S extends Record<string, object> = Record<stri
|
|
|
81
82
|
* 生成文档ID
|
|
82
83
|
*/
|
|
83
84
|
private generateId(): string {
|
|
84
|
-
return
|
|
85
|
+
return randomUUID();
|
|
85
86
|
}
|
|
86
87
|
}
|
package/tests/database.test.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
2
3
|
import { Registry } from '../src/registry.js';
|
|
3
4
|
import { Sqlite } from '../src/dialects/sqlite.js';
|
|
4
5
|
import { MigrationRunner, defineMigration } from '../src/migration.js';
|
|
5
6
|
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
let sqliteAvailable = false;
|
|
9
|
+
try {
|
|
10
|
+
const { DatabaseSync } = require('node:sqlite');
|
|
11
|
+
const db = new DatabaseSync(':memory:');
|
|
12
|
+
db.close();
|
|
13
|
+
sqliteAvailable = true;
|
|
14
|
+
} catch {
|
|
15
|
+
// Node 内置 SQLite 需要 Node.js 22.5+(推荐 24+),版本不足时跳过 SQLite 测试
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
// 注册 SQLite dialect
|
|
7
19
|
Registry.register('sqlite', Sqlite);
|
|
8
20
|
|
|
@@ -38,7 +50,7 @@ interface TestSchema extends Record<string, object> {
|
|
|
38
50
|
};
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
describe('Database Core Features', () => {
|
|
53
|
+
describe.skipIf(!sqliteAvailable)('Database Core Features', () => {
|
|
42
54
|
let db: Sqlite<TestSchema>;
|
|
43
55
|
|
|
44
56
|
beforeAll(async () => {
|
|
@@ -91,7 +103,7 @@ describe('Database Core Features', () => {
|
|
|
91
103
|
});
|
|
92
104
|
|
|
93
105
|
afterAll(async () => {
|
|
94
|
-
await db.stop();
|
|
106
|
+
if (db) await db.stop();
|
|
95
107
|
});
|
|
96
108
|
|
|
97
109
|
beforeEach(async () => {
|
|
@@ -803,7 +815,7 @@ describe('Database Core Features', () => {
|
|
|
803
815
|
// Migration Tests (独立的 describe 块,使用独立的数据库实例)
|
|
804
816
|
// =============================================================================
|
|
805
817
|
|
|
806
|
-
describe('Migration Runner', () => {
|
|
818
|
+
describe.skipIf(!sqliteAvailable)('Migration Runner', () => {
|
|
807
819
|
let migrationDb: Sqlite<Record<string, object>>;
|
|
808
820
|
let runner: MigrationRunner;
|
|
809
821
|
|
|
@@ -1207,7 +1219,7 @@ describe('Migration Runner', () => {
|
|
|
1207
1219
|
// ============================================================================
|
|
1208
1220
|
// Lifecycle Hooks Tests
|
|
1209
1221
|
// ============================================================================
|
|
1210
|
-
describe('Lifecycle Hooks', () => {
|
|
1222
|
+
describe.skipIf(!sqliteAvailable)('Lifecycle Hooks', () => {
|
|
1211
1223
|
let db: Sqlite<TestSchema>;
|
|
1212
1224
|
let userModel: ReturnType<typeof db.model<'users'>>;
|
|
1213
1225
|
|
|
@@ -1233,8 +1245,8 @@ describe('Lifecycle Hooks', () => {
|
|
|
1233
1245
|
});
|
|
1234
1246
|
|
|
1235
1247
|
afterEach(async () => {
|
|
1236
|
-
userModel.clearHooks();
|
|
1237
|
-
await db.stop();
|
|
1248
|
+
if (userModel) userModel.clearHooks();
|
|
1249
|
+
if (db) await db.stop();
|
|
1238
1250
|
});
|
|
1239
1251
|
|
|
1240
1252
|
it('should call beforeCreate and afterCreate hooks', async () => {
|
|
@@ -1493,7 +1505,7 @@ describe('Lifecycle Hooks', () => {
|
|
|
1493
1505
|
// ============================================================================
|
|
1494
1506
|
// Many-to-Many (belongsToMany) Tests
|
|
1495
1507
|
// ============================================================================
|
|
1496
|
-
describe('Many-to-Many Relations (belongsToMany)', () => {
|
|
1508
|
+
describe.skipIf(!sqliteAvailable)('Many-to-Many Relations (belongsToMany)', () => {
|
|
1497
1509
|
let db: Sqlite<TestSchema & {
|
|
1498
1510
|
roles: { id: number; name: string };
|
|
1499
1511
|
user_roles: { user_id: number; role_id: number; assigned_at: string };
|