@fett/sql-translator 0.0.1-beta
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/README.md +191 -0
- package/lib/client/client.d.ts +59 -0
- package/lib/client/client.d.ts.map +1 -0
- package/lib/client/client.js +201 -0
- package/lib/client/client.js.map +1 -0
- package/lib/client/index.d.ts +15 -0
- package/lib/client/index.d.ts.map +1 -0
- package/lib/client/index.js +15 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/manager.d.ts +27 -0
- package/lib/client/manager.d.ts.map +1 -0
- package/lib/client/manager.js +73 -0
- package/lib/client/manager.js.map +1 -0
- package/lib/client/registry.d.ts +31 -0
- package/lib/client/registry.d.ts.map +1 -0
- package/lib/client/registry.js +128 -0
- package/lib/client/registry.js.map +1 -0
- package/lib/core/cache.d.ts +28 -0
- package/lib/core/cache.d.ts.map +1 -0
- package/lib/core/cache.js +58 -0
- package/lib/core/cache.js.map +1 -0
- package/lib/core/config.d.ts +16 -0
- package/lib/core/config.d.ts.map +1 -0
- package/lib/core/config.js +47 -0
- package/lib/core/config.js.map +1 -0
- package/lib/core/field-mapper/mysql.d.ts +42 -0
- package/lib/core/field-mapper/mysql.d.ts.map +1 -0
- package/lib/core/field-mapper/mysql.js +129 -0
- package/lib/core/field-mapper/mysql.js.map +1 -0
- package/lib/core/field-mapper/postgresql.d.ts +25 -0
- package/lib/core/field-mapper/postgresql.d.ts.map +1 -0
- package/lib/core/field-mapper/postgresql.js +121 -0
- package/lib/core/field-mapper/postgresql.js.map +1 -0
- package/lib/core/sql/normalize.d.ts +10 -0
- package/lib/core/sql/normalize.d.ts.map +1 -0
- package/lib/core/sql/normalize.js +121 -0
- package/lib/core/sql/normalize.js.map +1 -0
- package/lib/core/sql/pagination.d.ts +22 -0
- package/lib/core/sql/pagination.d.ts.map +1 -0
- package/lib/core/sql/pagination.js +61 -0
- package/lib/core/sql/pagination.js.map +1 -0
- package/lib/core/sql/statement.d.ts +28 -0
- package/lib/core/sql/statement.d.ts.map +1 -0
- package/lib/core/sql/statement.js +155 -0
- package/lib/core/sql/statement.js.map +1 -0
- package/lib/core/sql/table-mapper.d.ts +24 -0
- package/lib/core/sql/table-mapper.d.ts.map +1 -0
- package/lib/core/sql/table-mapper.js +113 -0
- package/lib/core/sql/table-mapper.js.map +1 -0
- package/lib/core/task-queue.d.ts +31 -0
- package/lib/core/task-queue.d.ts.map +1 -0
- package/lib/core/task-queue.js +185 -0
- package/lib/core/task-queue.js.map +1 -0
- package/lib/core/worker/bun-worker.d.ts +21 -0
- package/lib/core/worker/bun-worker.d.ts.map +1 -0
- package/lib/core/worker/bun-worker.js +93 -0
- package/lib/core/worker/bun-worker.js.map +1 -0
- package/lib/core/worker/index.d.ts +16 -0
- package/lib/core/worker/index.d.ts.map +1 -0
- package/lib/core/worker/index.js +16 -0
- package/lib/core/worker/index.js.map +1 -0
- package/lib/core/worker/node-worker.d.ts +19 -0
- package/lib/core/worker/node-worker.d.ts.map +1 -0
- package/lib/core/worker/node-worker.js +94 -0
- package/lib/core/worker/node-worker.js.map +1 -0
- package/lib/core/worker/task-runner-bun.d.ts +2 -0
- package/lib/core/worker/task-runner-bun.d.ts.map +1 -0
- package/lib/core/worker/task-runner-bun.js +18 -0
- package/lib/core/worker/task-runner-bun.js.map +1 -0
- package/lib/core/worker/task-runner.d.ts +2 -0
- package/lib/core/worker/task-runner.d.ts.map +1 -0
- package/lib/core/worker/task-runner.js +21 -0
- package/lib/core/worker/task-runner.js.map +1 -0
- package/lib/driver/index.d.ts +3 -0
- package/lib/driver/index.d.ts.map +1 -0
- package/lib/driver/index.js +16 -0
- package/lib/driver/index.js.map +1 -0
- package/lib/driver/interface.d.ts +39 -0
- package/lib/driver/interface.d.ts.map +1 -0
- package/lib/driver/interface.js +2 -0
- package/lib/driver/interface.js.map +1 -0
- package/lib/driver/mongodb/dml-translator.d.ts +21 -0
- package/lib/driver/mongodb/dml-translator.d.ts.map +1 -0
- package/lib/driver/mongodb/dml-translator.js +127 -0
- package/lib/driver/mongodb/dml-translator.js.map +1 -0
- package/lib/driver/mongodb/index.d.ts +27 -0
- package/lib/driver/mongodb/index.d.ts.map +1 -0
- package/lib/driver/mongodb/index.js +263 -0
- package/lib/driver/mongodb/index.js.map +1 -0
- package/lib/driver/mongodb/pool.d.ts +31 -0
- package/lib/driver/mongodb/pool.d.ts.map +1 -0
- package/lib/driver/mongodb/pool.js +96 -0
- package/lib/driver/mongodb/pool.js.map +1 -0
- package/lib/driver/mongodb/schema.d.ts +37 -0
- package/lib/driver/mongodb/schema.d.ts.map +1 -0
- package/lib/driver/mongodb/schema.js +238 -0
- package/lib/driver/mongodb/schema.js.map +1 -0
- package/lib/driver/mongodb/sql-translator.d.ts +19 -0
- package/lib/driver/mongodb/sql-translator.d.ts.map +1 -0
- package/lib/driver/mongodb/sql-translator.js +30 -0
- package/lib/driver/mongodb/sql-translator.js.map +1 -0
- package/lib/driver/mysql/index.d.ts +41 -0
- package/lib/driver/mysql/index.d.ts.map +1 -0
- package/lib/driver/mysql/index.js +338 -0
- package/lib/driver/mysql/index.js.map +1 -0
- package/lib/driver/mysql/pool.d.ts +46 -0
- package/lib/driver/mysql/pool.d.ts.map +1 -0
- package/lib/driver/mysql/pool.js +141 -0
- package/lib/driver/mysql/pool.js.map +1 -0
- package/lib/driver/mysql/version.d.ts +27 -0
- package/lib/driver/mysql/version.d.ts.map +1 -0
- package/lib/driver/mysql/version.js +77 -0
- package/lib/driver/mysql/version.js.map +1 -0
- package/lib/driver/postgresql/index.d.ts +34 -0
- package/lib/driver/postgresql/index.d.ts.map +1 -0
- package/lib/driver/postgresql/index.js +383 -0
- package/lib/driver/postgresql/index.js.map +1 -0
- package/lib/driver/postgresql/pool.d.ts +33 -0
- package/lib/driver/postgresql/pool.d.ts.map +1 -0
- package/lib/driver/postgresql/pool.js +104 -0
- package/lib/driver/postgresql/pool.js.map +1 -0
- package/lib/driver/registry.d.ts +16 -0
- package/lib/driver/registry.d.ts.map +1 -0
- package/lib/driver/registry.js +27 -0
- package/lib/driver/registry.js.map +1 -0
- package/lib/driver/sqlite/backend.d.ts +19 -0
- package/lib/driver/sqlite/backend.d.ts.map +1 -0
- package/lib/driver/sqlite/backend.js +5 -0
- package/lib/driver/sqlite/backend.js.map +1 -0
- package/lib/driver/sqlite/bun.d.ts +10 -0
- package/lib/driver/sqlite/bun.d.ts.map +1 -0
- package/lib/driver/sqlite/bun.js +36 -0
- package/lib/driver/sqlite/bun.js.map +1 -0
- package/lib/driver/sqlite/index.d.ts +49 -0
- package/lib/driver/sqlite/index.d.ts.map +1 -0
- package/lib/driver/sqlite/index.js +421 -0
- package/lib/driver/sqlite/index.js.map +1 -0
- package/lib/driver/sqlite/node.d.ts +10 -0
- package/lib/driver/sqlite/node.d.ts.map +1 -0
- package/lib/driver/sqlite/node.js +37 -0
- package/lib/driver/sqlite/node.js.map +1 -0
- package/lib/driver/sqlite/store.d.ts +13 -0
- package/lib/driver/sqlite/store.d.ts.map +1 -0
- package/lib/driver/sqlite/store.js +57 -0
- package/lib/driver/sqlite/store.js.map +1 -0
- package/lib/errors.d.ts +18 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +24 -0
- package/lib/errors.js.map +1 -0
- package/lib/facade/engine.d.ts +29 -0
- package/lib/facade/engine.d.ts.map +1 -0
- package/lib/facade/engine.js +107 -0
- package/lib/facade/engine.js.map +1 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +40 -0
- package/lib/index.js.map +1 -0
- package/lib/optional/static-source.d.ts +36 -0
- package/lib/optional/static-source.d.ts.map +1 -0
- package/lib/optional/static-source.js +141 -0
- package/lib/optional/static-source.js.map +1 -0
- package/lib/runtime.d.ts +12 -0
- package/lib/runtime.d.ts.map +1 -0
- package/lib/runtime.js +26 -0
- package/lib/runtime.js.map +1 -0
- package/lib/types/config.d.ts +146 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +5 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +7 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/manager.d.ts +37 -0
- package/lib/types/manager.d.ts.map +1 -0
- package/lib/types/manager.js +5 -0
- package/lib/types/manager.js.map +1 -0
- package/lib/types/queue.d.ts +45 -0
- package/lib/types/queue.d.ts.map +1 -0
- package/lib/types/queue.js +5 -0
- package/lib/types/queue.js.map +1 -0
- package/lib/types/result.d.ts +61 -0
- package/lib/types/result.d.ts.map +1 -0
- package/lib/types/result.js +16 -0
- package/lib/types/result.js.map +1 -0
- package/lib/types/schema.d.ts +51 -0
- package/lib/types/schema.d.ts.map +1 -0
- package/lib/types/schema.js +5 -0
- package/lib/types/schema.js.map +1 -0
- package/lib/types/task.d.ts +48 -0
- package/lib/types/task.d.ts.map +1 -0
- package/lib/types/task.js +136 -0
- package/lib/types/task.js.map +1 -0
- package/lib/types/transaction.d.ts +13 -0
- package/lib/types/transaction.d.ts.map +1 -0
- package/lib/types/transaction.js +2 -0
- package/lib/types/transaction.js.map +1 -0
- package/package.json +93 -0
- package/patches/bson@7.3.2.patch +105 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 标准化工具
|
|
3
|
+
*/
|
|
4
|
+
/** 去除末尾分号序列和空白字符 */
|
|
5
|
+
export declare function normalizeSql(sql: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* 剥离 SQL 中的注释和字符串常量,用于分析 SQL 结构(如查找关键词)
|
|
8
|
+
*/
|
|
9
|
+
export declare function stripSqlForSearch(sql: string): string;
|
|
10
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/core/sql/normalize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oBAAoB;AACpB,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsHrD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 标准化工具
|
|
3
|
+
*/
|
|
4
|
+
/** 去除末尾分号序列和空白字符 */
|
|
5
|
+
export function normalizeSql(sql) {
|
|
6
|
+
return String(sql ?? '')
|
|
7
|
+
.trim()
|
|
8
|
+
.replace(/(?:\s*;+\s*)+$/, '')
|
|
9
|
+
.trim();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 剥离 SQL 中的注释和字符串常量,用于分析 SQL 结构(如查找关键词)
|
|
13
|
+
*/
|
|
14
|
+
export function stripSqlForSearch(sql) {
|
|
15
|
+
let out = '';
|
|
16
|
+
let inSingle = false;
|
|
17
|
+
let inDouble = false;
|
|
18
|
+
let inBacktick = false;
|
|
19
|
+
let inLineComment = false;
|
|
20
|
+
let inBlockComment = false;
|
|
21
|
+
let escape = false;
|
|
22
|
+
let prev = '';
|
|
23
|
+
for (let i = 0; i < sql.length; i++) {
|
|
24
|
+
const ch = sql[i];
|
|
25
|
+
const next = i + 1 < sql.length ? sql[i + 1] : '';
|
|
26
|
+
if (inLineComment) {
|
|
27
|
+
if (ch === '\n') {
|
|
28
|
+
inLineComment = false;
|
|
29
|
+
out += '\n';
|
|
30
|
+
prev = '\n';
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
out += ' ';
|
|
34
|
+
prev = ch;
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (inBlockComment) {
|
|
39
|
+
if (ch === '*' && next === '/') {
|
|
40
|
+
inBlockComment = false;
|
|
41
|
+
out += ' ';
|
|
42
|
+
i++;
|
|
43
|
+
prev = '/';
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
out += ch === '\n' ? '\n' : ' ';
|
|
47
|
+
prev = ch;
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (inSingle) {
|
|
52
|
+
if (!escape && ch === "'")
|
|
53
|
+
inSingle = false;
|
|
54
|
+
escape = !escape && ch === '\\';
|
|
55
|
+
out += ch === '\n' ? '\n' : ' ';
|
|
56
|
+
prev = ch;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (inDouble) {
|
|
60
|
+
if (!escape && ch === '"')
|
|
61
|
+
inDouble = false;
|
|
62
|
+
escape = !escape && ch === '\\';
|
|
63
|
+
out += ch === '\n' ? '\n' : ' ';
|
|
64
|
+
prev = ch;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (inBacktick) {
|
|
68
|
+
if (ch === '`')
|
|
69
|
+
inBacktick = false;
|
|
70
|
+
out += ch === '\n' ? '\n' : ' ';
|
|
71
|
+
prev = ch;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
escape = false;
|
|
75
|
+
if (ch === '-' &&
|
|
76
|
+
next === '-' &&
|
|
77
|
+
(prev === '' || /\s/.test(prev)) &&
|
|
78
|
+
(i + 2 >= sql.length || /\s/.test(sql[i + 2]))) {
|
|
79
|
+
inLineComment = true;
|
|
80
|
+
out += ' ';
|
|
81
|
+
i++;
|
|
82
|
+
prev = '-';
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (ch === '#') {
|
|
86
|
+
inLineComment = true;
|
|
87
|
+
out += ' ';
|
|
88
|
+
prev = '#';
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (ch === '/' && next === '*') {
|
|
92
|
+
inBlockComment = true;
|
|
93
|
+
out += ' ';
|
|
94
|
+
i++;
|
|
95
|
+
prev = '*';
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (ch === "'") {
|
|
99
|
+
inSingle = true;
|
|
100
|
+
out += ' ';
|
|
101
|
+
prev = "'";
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (ch === '"') {
|
|
105
|
+
inDouble = true;
|
|
106
|
+
out += ' ';
|
|
107
|
+
prev = '"';
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (ch === '`') {
|
|
111
|
+
inBacktick = true;
|
|
112
|
+
out += ' ';
|
|
113
|
+
prev = '`';
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
out += ch;
|
|
117
|
+
prev = ch;
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/sql/normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 分页工具:分页子句检测、LIMIT/OFFSET 提取、分页 SQL 包装
|
|
3
|
+
*/
|
|
4
|
+
/** 从 SQL 中提取 LIMIT 和 OFFSET 的值(兼容 LIMIT a,b 与 LIMIT a OFFSET b) */
|
|
5
|
+
export declare function extractLimitOffset(sql: string): {
|
|
6
|
+
limit?: number;
|
|
7
|
+
offset?: number;
|
|
8
|
+
};
|
|
9
|
+
/** 检查 SQL 是否包含分页子句 */
|
|
10
|
+
export declare function hasPaginationClause(sql: string, extraPatterns?: RegExp[]): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* 用 whereClause 包装 SQL
|
|
13
|
+
* MySQL 5.7 无 CTE:走派生表;否则用 CTE(语义等价,CTE 可读性更好)
|
|
14
|
+
*/
|
|
15
|
+
export declare function wrapWithWhereClause(sql: string, whereClause: string, opts?: {
|
|
16
|
+
supportsCTE?: boolean;
|
|
17
|
+
}): string;
|
|
18
|
+
/** 生成分页 SQL(LIMIT/OFFSET,MySQL/PG/SQLite 通用) */
|
|
19
|
+
export declare function buildPagedSql(baseSql: string, limit: number, offset: number): string;
|
|
20
|
+
/** 生成总数 SQL */
|
|
21
|
+
export declare function buildCountSql(baseSql: string): string;
|
|
22
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../src/core/sql/pagination.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BnF;AAED,sBAAsB;AACtB,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,EAAO,GAAG,OAAO,CAItF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,MAAM,CAMR;AAED,gDAAgD;AAChD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,eAAe;AACf,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 分页工具:分页子句检测、LIMIT/OFFSET 提取、分页 SQL 包装
|
|
3
|
+
*/
|
|
4
|
+
import { stripSqlForSearch } from './normalize.js';
|
|
5
|
+
/** 从 SQL 中提取 LIMIT 和 OFFSET 的值(兼容 LIMIT a,b 与 LIMIT a OFFSET b) */
|
|
6
|
+
export function extractLimitOffset(sql) {
|
|
7
|
+
const s = stripSqlForSearch(sql);
|
|
8
|
+
let limit;
|
|
9
|
+
let offset;
|
|
10
|
+
// LIMIT a, b(MySQL 逗号语法)优先;命中后不再解析 LIMIT n OFFSET m
|
|
11
|
+
const commaMatches = Array.from(s.matchAll(/\blimit\s+(\d+)\s*,\s*(\d+)/gi));
|
|
12
|
+
if (commaMatches.length) {
|
|
13
|
+
const m = commaMatches[commaMatches.length - 1];
|
|
14
|
+
offset = Number(m[1]);
|
|
15
|
+
limit = Number(m[2]);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const offsetMatches = Array.from(s.matchAll(/\blimit\s+(\d+)(?:\s+offset\s+(\d+))?/gi));
|
|
19
|
+
if (offsetMatches.length) {
|
|
20
|
+
const m = offsetMatches[offsetMatches.length - 1];
|
|
21
|
+
const l = Number(m[1]);
|
|
22
|
+
const o = m[2] !== undefined ? Number(m[2]) : undefined;
|
|
23
|
+
if (!Number.isNaN(l))
|
|
24
|
+
limit = l;
|
|
25
|
+
if (o !== undefined && !Number.isNaN(o))
|
|
26
|
+
offset = o;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (limit !== undefined && Number.isNaN(limit))
|
|
30
|
+
limit = undefined;
|
|
31
|
+
if (offset !== undefined && Number.isNaN(offset))
|
|
32
|
+
offset = undefined;
|
|
33
|
+
return { limit, offset };
|
|
34
|
+
}
|
|
35
|
+
/** 检查 SQL 是否包含分页子句 */
|
|
36
|
+
export function hasPaginationClause(sql, extraPatterns = []) {
|
|
37
|
+
const s = stripSqlForSearch(sql);
|
|
38
|
+
const patterns = [/\blimit\b/i, /\boffset\b/i, ...extraPatterns];
|
|
39
|
+
return patterns.some((p) => p.test(s));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 用 whereClause 包装 SQL
|
|
43
|
+
* MySQL 5.7 无 CTE:走派生表;否则用 CTE(语义等价,CTE 可读性更好)
|
|
44
|
+
*/
|
|
45
|
+
export function wrapWithWhereClause(sql, whereClause, opts = {}) {
|
|
46
|
+
if (!whereClause)
|
|
47
|
+
return sql;
|
|
48
|
+
if (opts.supportsCTE === false) {
|
|
49
|
+
return `SELECT * FROM (${sql}) AS __t WHERE ${whereClause}`;
|
|
50
|
+
}
|
|
51
|
+
return `WITH __t AS (${sql}) SELECT * FROM __t WHERE ${whereClause}`;
|
|
52
|
+
}
|
|
53
|
+
/** 生成分页 SQL(LIMIT/OFFSET,MySQL/PG/SQLite 通用) */
|
|
54
|
+
export function buildPagedSql(baseSql, limit, offset) {
|
|
55
|
+
return `${baseSql} LIMIT ${Math.max(limit, 0)} OFFSET ${Math.max(offset, 0)}`;
|
|
56
|
+
}
|
|
57
|
+
/** 生成总数 SQL */
|
|
58
|
+
export function buildCountSql(baseSql) {
|
|
59
|
+
return `SELECT COUNT(1) AS total FROM (${baseSql}) AS __t2`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/core/sql/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 语句类型识别与 DML 安全检测
|
|
3
|
+
*/
|
|
4
|
+
export type StatementType = 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'DDL' | 'TRANSACTION' | 'OTHER' | 'UNKNOWN';
|
|
5
|
+
/** 识别 SQL 语句类型(基于剥离注释/字符串后的首关键字) */
|
|
6
|
+
export declare function detectStatementType(sql: string): StatementType;
|
|
7
|
+
export type DmlStatementType = 'INSERT' | 'UPDATE' | 'DELETE';
|
|
8
|
+
export declare function isDmlStatement(type: StatementType): type is DmlStatementType;
|
|
9
|
+
/**
|
|
10
|
+
* 提取 UPDATE / DELETE 语句的 WHERE 子句原文(保留字符串字面量)
|
|
11
|
+
* 在剥离版上定位 WHERE 位置,再从原始 SQL 截取到末尾(两版字符位置一致)
|
|
12
|
+
* 返回 null 表示无 WHERE(用于 DML 安全护栏)
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractDmlWhere(sql: string): string | null;
|
|
15
|
+
/** UPDATE/DELETE 是否有 WHERE 子句 */
|
|
16
|
+
export declare function hasDmlWhere(sql: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* 从 SQL 中提取引用的表名(含 schema-qualified)
|
|
19
|
+
* 注意:在原始 SQL 上做正则(不剥离字符串),与引号标识符/中文表名兼容;
|
|
20
|
+
* 字符串字面量内误匹配的风险
|
|
21
|
+
* */
|
|
22
|
+
export declare function extractTableNamesFromSql(sql: string): Set<string>;
|
|
23
|
+
/**
|
|
24
|
+
* 解析 INSERT VALUES 行数(DML 批量上限校验用)
|
|
25
|
+
* @returns 行数;无法解析(如 INSERT ... SELECT)返回 0
|
|
26
|
+
*/
|
|
27
|
+
export declare function countInsertValueRows(sql: string): number;
|
|
28
|
+
//# sourceMappingURL=statement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statement.d.ts","sourceRoot":"","sources":["../../../src/core/sql/statement.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,aAAa,GACb,OAAO,GACP,SAAS,CAAC;AAEd,oCAAoC;AACpC,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAgC9D;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,IAAI,gBAAgB,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ1D;AAED,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAOD;;;;KAIK;AACL,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiEjE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA6BxD"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 语句类型识别与 DML 安全检测
|
|
3
|
+
*/
|
|
4
|
+
import { stripSqlForSearch } from './normalize.js';
|
|
5
|
+
/** 识别 SQL 语句类型(基于剥离注释/字符串后的首关键字) */
|
|
6
|
+
export function detectStatementType(sql) {
|
|
7
|
+
const s = stripSqlForSearch(sql).trimStart();
|
|
8
|
+
if (!s)
|
|
9
|
+
return 'UNKNOWN';
|
|
10
|
+
const m = s.match(/^[a-zA-Z]+/);
|
|
11
|
+
if (!m)
|
|
12
|
+
return 'UNKNOWN';
|
|
13
|
+
const kw = m[0].toUpperCase();
|
|
14
|
+
switch (kw) {
|
|
15
|
+
case 'SELECT':
|
|
16
|
+
case 'WITH':
|
|
17
|
+
return 'SELECT';
|
|
18
|
+
case 'INSERT':
|
|
19
|
+
case 'REPLACE':
|
|
20
|
+
return 'INSERT';
|
|
21
|
+
case 'UPDATE':
|
|
22
|
+
return 'UPDATE';
|
|
23
|
+
case 'DELETE':
|
|
24
|
+
return 'DELETE';
|
|
25
|
+
case 'CREATE':
|
|
26
|
+
case 'ALTER':
|
|
27
|
+
case 'DROP':
|
|
28
|
+
case 'TRUNCATE':
|
|
29
|
+
case 'RENAME':
|
|
30
|
+
return 'DDL';
|
|
31
|
+
case 'BEGIN':
|
|
32
|
+
case 'COMMIT':
|
|
33
|
+
case 'ROLLBACK':
|
|
34
|
+
case 'START':
|
|
35
|
+
case 'SAVEPOINT':
|
|
36
|
+
return 'TRANSACTION';
|
|
37
|
+
default:
|
|
38
|
+
return 'OTHER';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function isDmlStatement(type) {
|
|
42
|
+
return type === 'INSERT' || type === 'UPDATE' || type === 'DELETE';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 提取 UPDATE / DELETE 语句的 WHERE 子句原文(保留字符串字面量)
|
|
46
|
+
* 在剥离版上定位 WHERE 位置,再从原始 SQL 截取到末尾(两版字符位置一致)
|
|
47
|
+
* 返回 null 表示无 WHERE(用于 DML 安全护栏)
|
|
48
|
+
*/
|
|
49
|
+
export function extractDmlWhere(sql) {
|
|
50
|
+
const stripped = stripSqlForSearch(sql);
|
|
51
|
+
const type = detectStatementType(sql);
|
|
52
|
+
if (type !== 'UPDATE' && type !== 'DELETE')
|
|
53
|
+
return null;
|
|
54
|
+
const m = stripped.match(/\bwhere\b/i);
|
|
55
|
+
if (!m || m.index === undefined)
|
|
56
|
+
return null;
|
|
57
|
+
return sql.slice(m.index);
|
|
58
|
+
}
|
|
59
|
+
/** UPDATE/DELETE 是否有 WHERE 子句 */
|
|
60
|
+
export function hasDmlWhere(sql) {
|
|
61
|
+
return extractDmlWhere(sql) !== null;
|
|
62
|
+
}
|
|
63
|
+
const TABLE_KEYWORDS = 'FROM|JOIN|INNER\\s+JOIN|LEFT\\s+JOIN|RIGHT\\s+JOIN|FULL\\s+JOIN|CROSS\\s+JOIN';
|
|
64
|
+
const ANY_QUOTED_IDENTIFIER = `(?:"[^"]+"|'[^']+'|\`[^\`]+\`)`;
|
|
65
|
+
const BARE_IDENTIFIER = '[a-zA-Z_\\u4e00-\\u9fff][a-zA-Z0-9_\\u4e00-\\u9fff]*';
|
|
66
|
+
const IDENTIFIER = `(?:${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`;
|
|
67
|
+
/**
|
|
68
|
+
* 从 SQL 中提取引用的表名(含 schema-qualified)
|
|
69
|
+
* 注意:在原始 SQL 上做正则(不剥离字符串),与引号标识符/中文表名兼容;
|
|
70
|
+
* 字符串字面量内误匹配的风险
|
|
71
|
+
* */
|
|
72
|
+
export function extractTableNamesFromSql(sql) {
|
|
73
|
+
const tableNames = new Set();
|
|
74
|
+
const s = sql;
|
|
75
|
+
const stripQuotes = (identifier) => {
|
|
76
|
+
if ((identifier.startsWith('"') && identifier.endsWith('"')) ||
|
|
77
|
+
(identifier.startsWith("'") && identifier.endsWith("'")) ||
|
|
78
|
+
(identifier.startsWith('`') && identifier.endsWith('`'))) {
|
|
79
|
+
return identifier.slice(1, -1);
|
|
80
|
+
}
|
|
81
|
+
return identifier;
|
|
82
|
+
};
|
|
83
|
+
// 1. "schema"."table" 复合形式 → "schema.table"
|
|
84
|
+
const compoundQuoted = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${ANY_QUOTED_IDENTIFIER})\\.(${ANY_QUOTED_IDENTIFIER})`, 'gi');
|
|
85
|
+
let match;
|
|
86
|
+
while ((match = compoundQuoted.exec(s)) !== null) {
|
|
87
|
+
tableNames.add(`${stripQuotes(match[1])}.${stripQuotes(match[2])}`);
|
|
88
|
+
}
|
|
89
|
+
// 2. schema.table 裸名复合形式
|
|
90
|
+
const compoundBare = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${BARE_IDENTIFIER})\\.(${BARE_IDENTIFIER})`, 'gi');
|
|
91
|
+
while ((match = compoundBare.exec(s)) !== null) {
|
|
92
|
+
tableNames.add(`${match[1]}.${match[2]}`);
|
|
93
|
+
}
|
|
94
|
+
// 3. 简单表名(不带 schema 前缀)
|
|
95
|
+
const simpleNamePattern = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`, 'gi');
|
|
96
|
+
while ((match = simpleNamePattern.exec(s)) !== null) {
|
|
97
|
+
const name = stripQuotes(match[1]);
|
|
98
|
+
let isCompoundPart = false;
|
|
99
|
+
tableNames.forEach((existing) => {
|
|
100
|
+
if (existing.endsWith(`.${name}`))
|
|
101
|
+
isCompoundPart = true;
|
|
102
|
+
});
|
|
103
|
+
if (!isCompoundPart)
|
|
104
|
+
tableNames.add(name);
|
|
105
|
+
}
|
|
106
|
+
// 4. INSERT INTO / UPDATE / DELETE FROM 的目标表
|
|
107
|
+
const intoPattern = new RegExp(`\\b(?:INTO|UPDATE)\\s+(${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`, 'gi');
|
|
108
|
+
while ((match = intoPattern.exec(s)) !== null) {
|
|
109
|
+
tableNames.add(stripQuotes(match[1]));
|
|
110
|
+
}
|
|
111
|
+
const deletePattern = new RegExp(`\\bDELETE\\s+FROM\\s+(${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`, 'gi');
|
|
112
|
+
while ((match = deletePattern.exec(s)) !== null) {
|
|
113
|
+
tableNames.add(stripQuotes(match[1]));
|
|
114
|
+
}
|
|
115
|
+
return tableNames;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 解析 INSERT VALUES 行数(DML 批量上限校验用)
|
|
119
|
+
* @returns 行数;无法解析(如 INSERT ... SELECT)返回 0
|
|
120
|
+
*/
|
|
121
|
+
export function countInsertValueRows(sql) {
|
|
122
|
+
const s = stripSqlForSearch(sql);
|
|
123
|
+
const m = s.match(/\bINSERT\b[\s\S]*?\bVALUES\s*/i);
|
|
124
|
+
if (!m || m.index === undefined)
|
|
125
|
+
return 0;
|
|
126
|
+
const rest = s.slice(m.index + m[0].length);
|
|
127
|
+
// 取到第一个完整的括号组(VALUES (..),(..),...)
|
|
128
|
+
let depth = 0;
|
|
129
|
+
let groups = 0;
|
|
130
|
+
let inParen = false;
|
|
131
|
+
for (let i = 0; i < rest.length; i++) {
|
|
132
|
+
const ch = rest[i];
|
|
133
|
+
if (ch === '(') {
|
|
134
|
+
if (!inParen) {
|
|
135
|
+
inParen = true;
|
|
136
|
+
groups++;
|
|
137
|
+
}
|
|
138
|
+
depth++;
|
|
139
|
+
}
|
|
140
|
+
else if (ch === ')') {
|
|
141
|
+
depth--;
|
|
142
|
+
if (depth === 0) {
|
|
143
|
+
inParen = false;
|
|
144
|
+
// 括号组结束后,若下一非空字符不是逗号,说明 VALUES 结束
|
|
145
|
+
let j = i + 1;
|
|
146
|
+
while (j < rest.length && /\s/.test(rest[j]))
|
|
147
|
+
j++;
|
|
148
|
+
if (rest[j] !== ',')
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return groups;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=statement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statement.js","sourceRoot":"","sources":["../../../src/core/sql/statement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 表名映射工具(迁移自 WizBuild sql-table-mapper.ts)
|
|
3
|
+
* 将用户 SQL 中的逻辑表名(可能带 schema 前缀)替换为物理表名(如 SQLite 表名)
|
|
4
|
+
*
|
|
5
|
+
* 支持格式:
|
|
6
|
+
* - 裸表名:FROM 表名 / FROM "表名" / FROM '表名' / FROM `表名`
|
|
7
|
+
* - Schema 限定:FROM "数据源名"."数据表名" / FROM 数据源名.数据表名
|
|
8
|
+
* - 带 alias:FROM "表名" AS t / FROM "表名" t
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 替换 SQL 中的表名为物理表名
|
|
12
|
+
* @param mapping 逻辑表名 → 物理表名;复合 key("数据源名.表名")优先于裸名
|
|
13
|
+
*/
|
|
14
|
+
export declare function replaceTableNamesInSql(sql: string, tableNameMapping: Map<string, string>): string;
|
|
15
|
+
/** 去除标识符引号 */
|
|
16
|
+
export declare function stripQuotes(identifier: string): string;
|
|
17
|
+
/** 从 SQL 中提取用户引用的表名(裸名 + schema-qualified) */
|
|
18
|
+
export declare function extractTableNamesFromSql(sql: string): Set<string>;
|
|
19
|
+
/** 验证表名替换结果,返回警告列表 */
|
|
20
|
+
export declare function validateTableNameReplacement(originalSql: string, replacedSql: string, tableNameMapping: Map<string, string>): {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
warnings: string[];
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=table-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-mapper.d.ts","sourceRoot":"","sources":["../../../src/core/sql/table-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,MAAM,CAgER;AAED,cAAc;AACd,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAStD;AAED,8CAA8C;AAC9C,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAkCjE;AAED,sBAAsB;AACtB,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAwBxC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL 表名映射工具(迁移自 WizBuild sql-table-mapper.ts)
|
|
3
|
+
* 将用户 SQL 中的逻辑表名(可能带 schema 前缀)替换为物理表名(如 SQLite 表名)
|
|
4
|
+
*
|
|
5
|
+
* 支持格式:
|
|
6
|
+
* - 裸表名:FROM 表名 / FROM "表名" / FROM '表名' / FROM `表名`
|
|
7
|
+
* - Schema 限定:FROM "数据源名"."数据表名" / FROM 数据源名.数据表名
|
|
8
|
+
* - 带 alias:FROM "表名" AS t / FROM "表名" t
|
|
9
|
+
*/
|
|
10
|
+
const TABLE_KEYWORDS = 'FROM|JOIN|INNER\\s+JOIN|LEFT\\s+JOIN|RIGHT\\s+JOIN|FULL\\s+JOIN|CROSS\\s+JOIN';
|
|
11
|
+
const ANY_QUOTED_IDENTIFIER = `(?:"[^"]+"|'[^']+'|\`[^\`]+\`)`;
|
|
12
|
+
const BARE_IDENTIFIER = '[a-zA-Z_\\u4e00-\\u9fff][a-zA-Z0-9_\\u4e00-\\u9fff]*';
|
|
13
|
+
const IDENTIFIER = `(?:${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`;
|
|
14
|
+
const SCHEMA_PREFIX = `(?:${IDENTIFIER}\\.)`;
|
|
15
|
+
const ALIAS_PATTERN = '(?:\\s+(?:AS\\s+)?(?:' + IDENTIFIER + '))?';
|
|
16
|
+
/** 将 tableNameMapping 的 entries 按 key 长度降序排序(复合 key 优先) */
|
|
17
|
+
function sortMappingEntries(mapping) {
|
|
18
|
+
return [...mapping.entries()].sort((a, b) => b[0].length - a[0].length);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 替换 SQL 中的表名为物理表名
|
|
22
|
+
* @param mapping 逻辑表名 → 物理表名;复合 key("数据源名.表名")优先于裸名
|
|
23
|
+
*/
|
|
24
|
+
export function replaceTableNamesInSql(sql, tableNameMapping) {
|
|
25
|
+
let result = sql;
|
|
26
|
+
for (const [tableName, sqliteTableName] of sortMappingEntries(tableNameMapping)) {
|
|
27
|
+
const isCompoundKey = tableName.includes('.');
|
|
28
|
+
if (isCompoundKey) {
|
|
29
|
+
const [schemaPart, tablePart] = tableName.split('.', 2);
|
|
30
|
+
const escapedSchema = escapeRegExp(schemaPart);
|
|
31
|
+
const escapedTable = escapeRegExp(tablePart);
|
|
32
|
+
const doubleQuotedCompound = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)"${escapedSchema}"\\."${escapedTable}"(${ALIAS_PATTERN})`, 'gi');
|
|
33
|
+
result = result.replace(doubleQuotedCompound, `$1"${sqliteTableName}"$2`);
|
|
34
|
+
const singleQuotedCompound = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)'${escapedSchema}'\\.'${escapedTable}'(${ALIAS_PATTERN})`, 'gi');
|
|
35
|
+
result = result.replace(singleQuotedCompound, `$1"${sqliteTableName}"$2`);
|
|
36
|
+
const backtickQuotedCompound = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)\`${escapedSchema}\`\\.\`${escapedTable}\`(${ALIAS_PATTERN})`, 'gi');
|
|
37
|
+
result = result.replace(backtickQuotedCompound, `$1"${sqliteTableName}"$2`);
|
|
38
|
+
const bareCompound = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)${escapedSchema}\\.${escapedTable}(${ALIAS_PATTERN})`, 'gi');
|
|
39
|
+
result = result.replace(bareCompound, `$1"${sqliteTableName}"$2`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const escapedName = escapeRegExp(tableName);
|
|
43
|
+
const doubleQuoted = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)(?:${SCHEMA_PREFIX})?"${escapedName}"(${ALIAS_PATTERN})`, 'gi');
|
|
44
|
+
result = result.replace(doubleQuoted, `$1"${sqliteTableName}"$2`);
|
|
45
|
+
const singleQuoted = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)(?:${SCHEMA_PREFIX})?'${escapedName}'(${ALIAS_PATTERN})`, 'gi');
|
|
46
|
+
result = result.replace(singleQuoted, `$1"${sqliteTableName}"$2`);
|
|
47
|
+
const backtickQuoted = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)(?:${SCHEMA_PREFIX})?\`${escapedName}\`(${ALIAS_PATTERN})`, 'gi');
|
|
48
|
+
result = result.replace(backtickQuoted, `$1"${sqliteTableName}"$2`);
|
|
49
|
+
const bareName = new RegExp(`(\\b(?:${TABLE_KEYWORDS})\\s+)(?:${SCHEMA_PREFIX})?${escapedName}(${ALIAS_PATTERN})`, 'gi');
|
|
50
|
+
result = result.replace(bareName, `$1"${sqliteTableName}"$2`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/** 去除标识符引号 */
|
|
56
|
+
export function stripQuotes(identifier) {
|
|
57
|
+
if ((identifier.startsWith('"') && identifier.endsWith('"')) ||
|
|
58
|
+
(identifier.startsWith("'") && identifier.endsWith("'")) ||
|
|
59
|
+
(identifier.startsWith('`') && identifier.endsWith('`'))) {
|
|
60
|
+
return identifier.slice(1, -1);
|
|
61
|
+
}
|
|
62
|
+
return identifier;
|
|
63
|
+
}
|
|
64
|
+
/** 从 SQL 中提取用户引用的表名(裸名 + schema-qualified) */
|
|
65
|
+
export function extractTableNamesFromSql(sql) {
|
|
66
|
+
const tableNames = new Set();
|
|
67
|
+
const compoundDoubleQuoted = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${ANY_QUOTED_IDENTIFIER})\\.(${ANY_QUOTED_IDENTIFIER})`, 'gi');
|
|
68
|
+
let match;
|
|
69
|
+
while ((match = compoundDoubleQuoted.exec(sql)) !== null) {
|
|
70
|
+
tableNames.add(`${stripQuotes(match[1])}.${stripQuotes(match[2])}`);
|
|
71
|
+
}
|
|
72
|
+
const compoundBare = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${BARE_IDENTIFIER})\\.(${BARE_IDENTIFIER})`, 'gi');
|
|
73
|
+
while ((match = compoundBare.exec(sql)) !== null) {
|
|
74
|
+
tableNames.add(`${match[1]}.${match[2]}`);
|
|
75
|
+
}
|
|
76
|
+
const simpleNamePattern = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(${ANY_QUOTED_IDENTIFIER}|${BARE_IDENTIFIER})`, 'gi');
|
|
77
|
+
while ((match = simpleNamePattern.exec(sql)) !== null) {
|
|
78
|
+
const name = stripQuotes(match[1]);
|
|
79
|
+
let isCompoundPart = false;
|
|
80
|
+
tableNames.forEach((existing) => {
|
|
81
|
+
if (existing.endsWith(`.${name}`))
|
|
82
|
+
isCompoundPart = true;
|
|
83
|
+
});
|
|
84
|
+
if (!isCompoundPart)
|
|
85
|
+
tableNames.add(name);
|
|
86
|
+
}
|
|
87
|
+
return tableNames;
|
|
88
|
+
}
|
|
89
|
+
/** 验证表名替换结果,返回警告列表 */
|
|
90
|
+
export function validateTableNameReplacement(originalSql, replacedSql, tableNameMapping) {
|
|
91
|
+
const warnings = [];
|
|
92
|
+
const originalTableNames = extractTableNamesFromSql(originalSql);
|
|
93
|
+
for (const name of originalTableNames) {
|
|
94
|
+
const bareName = name.includes('.') ? name.split('.').pop() : name;
|
|
95
|
+
const hasMapping = tableNameMapping.has(name) || tableNameMapping.has(bareName);
|
|
96
|
+
if (!hasMapping) {
|
|
97
|
+
warnings.push(`表 "${name}" 在映射中未找到对应的物理表名`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const [logicalName] of tableNameMapping) {
|
|
101
|
+
const bareName = logicalName.includes('.') ? logicalName.split('.').pop() : logicalName;
|
|
102
|
+
const residualPattern = new RegExp(`\\b(?:${TABLE_KEYWORDS})\\s+(?:${SCHEMA_PREFIX})?"${escapeRegExp(bareName)}"`, 'gi');
|
|
103
|
+
if (residualPattern.test(replacedSql)) {
|
|
104
|
+
warnings.push(`表 "${bareName}" 可能未被替换`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { valid: warnings.length === 0, warnings };
|
|
108
|
+
}
|
|
109
|
+
/** 正则转义 */
|
|
110
|
+
function escapeRegExp(str) {
|
|
111
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=table-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-mapper.js","sourceRoot":"","sources":["../../../src/core/sql/table-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IntrospectRunner, IntrospectTask } from '../types/task.js';
|
|
2
|
+
import type { EnqueueOptions, TaskQueue, TaskQueueOptions, WorkerTaskSpec } from '../types/queue.js';
|
|
3
|
+
export declare class TaskQueueImpl implements TaskQueue {
|
|
4
|
+
private options;
|
|
5
|
+
private queue;
|
|
6
|
+
private active;
|
|
7
|
+
private closed;
|
|
8
|
+
private seq;
|
|
9
|
+
private idleWaiters;
|
|
10
|
+
private workerBackend;
|
|
11
|
+
private workerBackendPromise;
|
|
12
|
+
constructor(options?: TaskQueueOptions);
|
|
13
|
+
/** 默认并发 = CPU 数 */
|
|
14
|
+
private get concurrency();
|
|
15
|
+
size(): number;
|
|
16
|
+
/**
|
|
17
|
+
* 入队执行
|
|
18
|
+
* - 传函数:进程内异步执行(I/O 密集任务默认方式)
|
|
19
|
+
* - 传 WorkerTaskSpec + opts.worker=true:offload 到 worker 线程(CPU 密集任务)
|
|
20
|
+
*/
|
|
21
|
+
enqueue<T>(fn: (() => T | Promise<T>) | WorkerTaskSpec, opts?: EnqueueOptions): Promise<T>;
|
|
22
|
+
/** 长任务形态:支持进度上报与取消 */
|
|
23
|
+
introspect<T>(runner: IntrospectRunner<T>): IntrospectTask<T>;
|
|
24
|
+
waitIdle(): Promise<void>;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
private pump;
|
|
27
|
+
private execute;
|
|
28
|
+
private runInWorker;
|
|
29
|
+
private getWorkerBackend;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=task-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-queue.d.ts","sourceRoot":"","sources":["../../src/core/task-queue.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAqB,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAY3B,qBAAa,aAAc,YAAW,SAAS;IASjC,OAAO,CAAC,OAAO;IAR3B,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,oBAAoB,CAAuC;gBAE/C,OAAO,GAAE,gBAAqB;IAElD,mBAAmB;IACnB,OAAO,KAAK,WAAW,GAEtB;IAED,IAAI,IAAI,MAAM;IAId;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IA8C9F,sBAAsB;IACtB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAM7D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB5B,OAAO,CAAC,IAAI;YAeE,OAAO;IA6BrB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,gBAAgB;CAqBzB"}
|