midway-fatcms 0.0.19 → 0.0.20
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/.prettierrc.js +1 -0
- package/dist/controller/manage/ProxyApiMangeApi.js +2 -1
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +3 -19
- package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +4 -4
- package/dist/libs/crud-pro-quick/fixSoftDelete.js +2 -6
- package/dist/service/curd/CurdMixService.d.ts +1 -1
- package/dist/service/proxyapi/ProxyApiLoadService.js +2 -1
- package/dist/service/proxyapi/ProxyApiUtils.d.ts +2 -0
- package/dist/service/proxyapi/ProxyApiUtils.js +9 -1
- package/package.json +1 -1
- package/src/controller/home.controller.ts +6 -6
- package/src/controller/manage/ProxyApiMangeApi.ts +2 -1
- package/src/libs/crud-pro/interfaces.ts +71 -71
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +21 -39
- package/src/libs/crud-pro/utils/MixinUtils.ts +309 -309
- package/src/libs/crud-pro-quick/fixSoftDelete.ts +10 -50
- package/src/service/curd/CurdMixService.ts +1 -4
- package/src/service/curd/CurdProService.ts +8 -9
- package/src/service/curd/fixCfgModel.ts +145 -145
- package/src/service/proxyapi/ProxyApiLoadService.ts +3 -2
- package/src/service/proxyapi/ProxyApiUtils.ts +8 -0
package/.prettierrc.js
CHANGED
|
@@ -28,7 +28,7 @@ let ProxyApiMangeApi = class ProxyApiMangeApi extends BaseApiController_1.BaseAp
|
|
|
28
28
|
return this.executeSysSimpleSQL(SystemTables_1.SystemTables.sys_proxyapi, keys_1.KeysOfSimpleSQL.SIMPLE_INSERT, {
|
|
29
29
|
validateCfg: {
|
|
30
30
|
'data.proxy_name': [keys_1.KeysOfValidators.REQUIRED, keys_1.KeysOfValidators.STRING],
|
|
31
|
-
'data.path_prefix': [keys_1.KeysOfValidators.
|
|
31
|
+
'data.path_prefix': [keys_1.KeysOfValidators.STRING],
|
|
32
32
|
'data.upstream_code': [keys_1.KeysOfValidators.REQUIRED, keys_1.KeysOfValidators.STRING],
|
|
33
33
|
},
|
|
34
34
|
});
|
|
@@ -37,6 +37,7 @@ let ProxyApiMangeApi = class ProxyApiMangeApi extends BaseApiController_1.BaseAp
|
|
|
37
37
|
return this.executeSysSimpleSQL(SystemTables_1.SystemTables.sys_proxyapi, keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE, {
|
|
38
38
|
validateCfg: {
|
|
39
39
|
'condition.id': [keys_1.KeysOfValidators.REQUIRED, keys_1.KeysOfValidators.NUMERIC],
|
|
40
|
+
'data.path_prefix': [keys_1.KeysOfValidators.STRING],
|
|
40
41
|
},
|
|
41
42
|
});
|
|
42
43
|
}
|
|
@@ -13,23 +13,9 @@ const REGEX_STRING_TYPE = /^(varchar|char|text|longtext|mediumtext|tinytext|nvar
|
|
|
13
13
|
/** PG / MySQL 原生 boolean 列名 */
|
|
14
14
|
const REGEX_NATIVE_BOOLEAN_TYPE = /^(boolean|bool)$/;
|
|
15
15
|
/** 含 WHERE 条件的操作类型(查询/删除/更新) */
|
|
16
|
-
const CONDITION_TYPES = new Set([
|
|
17
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_QUERY,
|
|
18
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE,
|
|
19
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE,
|
|
20
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_COUNT,
|
|
21
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_EXIST,
|
|
22
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_DELETE,
|
|
23
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE,
|
|
24
|
-
]);
|
|
16
|
+
const CONDITION_TYPES = new Set([keys_1.KeysOfSimpleSQL.SIMPLE_QUERY, keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE, keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE, keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_COUNT, keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_EXIST, keys_1.KeysOfSimpleSQL.SIMPLE_DELETE, keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE]);
|
|
25
17
|
/** INSERT/UPDATE 操作类型 */
|
|
26
|
-
const INSERT_OR_UPDATE_TYPES = new Set([
|
|
27
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_INSERT,
|
|
28
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE,
|
|
29
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_INSERT_ON_DUPLICATE_UPDATE,
|
|
30
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE,
|
|
31
|
-
keys_1.KeysOfSimpleSQL.SIMPLE_BATCH_INSERT,
|
|
32
|
-
]);
|
|
18
|
+
const INSERT_OR_UPDATE_TYPES = new Set([keys_1.KeysOfSimpleSQL.SIMPLE_INSERT, keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE, keys_1.KeysOfSimpleSQL.SIMPLE_INSERT_ON_DUPLICATE_UPDATE, keys_1.KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE, keys_1.KeysOfSimpleSQL.SIMPLE_BATCH_INSERT]);
|
|
33
19
|
// ============ 工具函数 ============
|
|
34
20
|
function isIntegerType(type) {
|
|
35
21
|
return REGEX_INTEGER_TYPE.test(type);
|
|
@@ -265,9 +251,7 @@ class DataConvertHandler {
|
|
|
265
251
|
if (typeof value === 'boolean') {
|
|
266
252
|
return value ? 't' : 'f';
|
|
267
253
|
}
|
|
268
|
-
const escaped = ('' + value)
|
|
269
|
-
.replace(/\\/g, '\\\\')
|
|
270
|
-
.replace(/"/g, '\\"');
|
|
254
|
+
const escaped = ('' + value).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
271
255
|
return '"' + escaped + '"';
|
|
272
256
|
}
|
|
273
257
|
/** 对象/数组 → JSON 字符串,跳过 $sqlFunc、Date、Buffer */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { KeysOfSimpleSQL } from
|
|
2
|
-
import { IRequestModel, IVisitor } from
|
|
3
|
-
import { IRequestCfgModel2 } from
|
|
1
|
+
import { KeysOfSimpleSQL } from '../../libs/crud-pro/models/keys';
|
|
2
|
+
import { IRequestModel, IVisitor } from '../../libs/crud-pro/interfaces';
|
|
3
|
+
import { IRequestCfgModel2 } from './models';
|
|
4
4
|
/**
|
|
5
5
|
* 软删除处理函数
|
|
6
6
|
*
|
|
@@ -10,4 +10,4 @@ import { IRequestCfgModel2 } from "./models";
|
|
|
10
10
|
* @param visitor 获取当前用户信息的函数(用于软删除时记录删除人)
|
|
11
11
|
*/
|
|
12
12
|
declare function fixSoftDelete(oldSqlSimpleName: KeysOfSimpleSQL, cfgModel: IRequestCfgModel2, params: IRequestModel, visitor?: IVisitor): void;
|
|
13
|
-
export { fixSoftDelete
|
|
13
|
+
export { fixSoftDelete };
|
|
@@ -43,9 +43,7 @@ function fixSoftDelete1(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
|
43
43
|
cfgModel.sqlSimpleName = keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE;
|
|
44
44
|
}
|
|
45
45
|
// QUERY 操作:强制查询未删除的记录
|
|
46
|
-
if (keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName
|
|
47
|
-
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName
|
|
48
|
-
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
46
|
+
if (keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName || keys_1.KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName || keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
49
47
|
if (!params.condition) {
|
|
50
48
|
params.condition = {};
|
|
51
49
|
}
|
|
@@ -78,9 +76,7 @@ function fixSoftDelete2(oldSqlSimpleName, cfgModel, params, visitor) {
|
|
|
78
76
|
cfgModel.sqlSimpleName = keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE;
|
|
79
77
|
}
|
|
80
78
|
// QUERY 操作:强制查询未删除的记录
|
|
81
|
-
if (keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName
|
|
82
|
-
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName
|
|
83
|
-
|| keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
79
|
+
if (keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_ONE === oldSqlSimpleName || keys_1.KeysOfSimpleSQL.SIMPLE_QUERY === oldSqlSimpleName || keys_1.KeysOfSimpleSQL.SIMPLE_QUERY_PAGE === oldSqlSimpleName) {
|
|
84
80
|
if (!params.condition) {
|
|
85
81
|
params.condition = {};
|
|
86
82
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ColumnRelation, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery, ExecuteSQLResult } from '../../libs/crud-pro/interfaces';
|
|
2
2
|
import { IRequestCfgModel2 } from '../../models/bizmodels';
|
|
3
3
|
import { ExecuteContext } from '../../libs/crud-pro/models/ExecuteContext';
|
|
4
|
-
import { ShardingBase } from
|
|
4
|
+
import { ShardingBase } from '../../libs/crud-sharding';
|
|
5
5
|
import { IGetQuickCrudParam, IGetShardingCrudParam } from './CurdProService';
|
|
6
6
|
export interface ILinkColumnRelationParam {
|
|
7
7
|
columnsRelations: ColumnRelation[];
|
|
@@ -76,7 +76,8 @@ let ProxyApiLoadService = class ProxyApiLoadService extends BaseService_1.BaseSe
|
|
|
76
76
|
for (let i = 0; i < entities.length; i++) {
|
|
77
77
|
const entity = entities[i];
|
|
78
78
|
if (entity.status === 1) {
|
|
79
|
-
const
|
|
79
|
+
const pathPrefix = (0, ProxyApiUtils_1.normalizePathPrefix)(entity.path_prefix);
|
|
80
|
+
const path_prefix2 = '/' + entity.upstream_code + pathPrefix;
|
|
80
81
|
routeTrie.addRoute(path_prefix2, new RouteHandler_1.RouteHandler(entity));
|
|
81
82
|
}
|
|
82
83
|
}
|
|
@@ -12,4 +12,6 @@ export declare const BALANCE_STRATEGY: {
|
|
|
12
12
|
* @param str
|
|
13
13
|
* @param mod
|
|
14
14
|
*/
|
|
15
|
+
/** path_prefix 为空表示代理上游根路径;单独的 "/" 会在路由树中注册无效节点,统一归一化为空 */
|
|
16
|
+
export declare function normalizePathPrefix(path_prefix: string | null | undefined): string;
|
|
15
17
|
export declare function stringHashMod(str: string, mod: number): number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.stringHashMod = exports.BALANCE_STRATEGY = void 0;
|
|
3
|
+
exports.stringHashMod = exports.normalizePathPrefix = exports.BALANCE_STRATEGY = void 0;
|
|
4
4
|
const md5 = require("md5");
|
|
5
5
|
exports.BALANCE_STRATEGY = {
|
|
6
6
|
ROUND_ROBIN: 'ROUND_ROBIN',
|
|
@@ -16,6 +16,14 @@ exports.BALANCE_STRATEGY = {
|
|
|
16
16
|
* @param str
|
|
17
17
|
* @param mod
|
|
18
18
|
*/
|
|
19
|
+
/** path_prefix 为空表示代理上游根路径;单独的 "/" 会在路由树中注册无效节点,统一归一化为空 */
|
|
20
|
+
function normalizePathPrefix(path_prefix) {
|
|
21
|
+
if (path_prefix === '/' || path_prefix == null) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
return path_prefix;
|
|
25
|
+
}
|
|
26
|
+
exports.normalizePathPrefix = normalizePathPrefix;
|
|
19
27
|
function stringHashMod(str, mod) {
|
|
20
28
|
if (!str) {
|
|
21
29
|
throw new Error('stringHashMod str is required');
|
package/package.json
CHANGED
|
@@ -36,16 +36,17 @@ export class HomeController extends BaseApiController {
|
|
|
36
36
|
return this.ctx.render('404_workbench', infos);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
39
|
const html_content = workbenchInfo.html_content || '未配置HTML模版';
|
|
41
40
|
|
|
42
41
|
const userInfo = await this.getUserAndRefreshSessionInfo();
|
|
43
42
|
|
|
44
43
|
// 形如(不带域名):/ns/app/abc-app-path?aa=2332
|
|
45
|
-
const urlcsrftoken = await privateAES.time_encrypt_utf8_base64(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
const urlcsrftoken = await privateAES.time_encrypt_utf8_base64(
|
|
45
|
+
JSON.stringify({
|
|
46
|
+
url: this.ctx.req.url,
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
})
|
|
49
|
+
);
|
|
49
50
|
const fatcmscsrftoken = await privateAES.time_encrypt_utf8_base64('' + Date.now());
|
|
50
51
|
|
|
51
52
|
const utils = createRenderUtils({
|
|
@@ -70,7 +71,6 @@ export class HomeController extends BaseApiController {
|
|
|
70
71
|
return await this.authService.refreshSession(userSessionInfo);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
|
|
74
74
|
@Get('/robots.txt')
|
|
75
75
|
async robots(): Promise<string> {
|
|
76
76
|
return `User-agent: * \nDisallow: /ns/api/manage/`;
|
|
@@ -27,7 +27,7 @@ export class ProxyApiMangeApi extends BaseApiController {
|
|
|
27
27
|
return this.executeSysSimpleSQL(SystemTables.sys_proxyapi, KeysOfSimpleSQL.SIMPLE_INSERT, {
|
|
28
28
|
validateCfg: {
|
|
29
29
|
'data.proxy_name': [KeysOfValidators.REQUIRED, KeysOfValidators.STRING],
|
|
30
|
-
'data.path_prefix': [KeysOfValidators.
|
|
30
|
+
'data.path_prefix': [KeysOfValidators.STRING],
|
|
31
31
|
'data.upstream_code': [KeysOfValidators.REQUIRED, KeysOfValidators.STRING],
|
|
32
32
|
},
|
|
33
33
|
});
|
|
@@ -38,6 +38,7 @@ export class ProxyApiMangeApi extends BaseApiController {
|
|
|
38
38
|
return this.executeSysSimpleSQL(SystemTables.sys_proxyapi, KeysOfSimpleSQL.SIMPLE_UPDATE, {
|
|
39
39
|
validateCfg: {
|
|
40
40
|
'condition.id': [KeysOfValidators.REQUIRED, KeysOfValidators.NUMERIC],
|
|
41
|
+
'data.path_prefix': [KeysOfValidators.STRING],
|
|
41
42
|
},
|
|
42
43
|
});
|
|
43
44
|
}
|
|
@@ -10,24 +10,24 @@ export interface ICrudProCfg {
|
|
|
10
10
|
methodsCacheTime?: number; //鍐呭瓨缂撳瓨鏃堕棿榛樿 1鍒嗛挓
|
|
11
11
|
dictItemTableName?: string; // 瀛楀吀椤硅〃鍚嶇О锛岄粯璁わ細sys_data_dict_item
|
|
12
12
|
sysConfigTableName?: string; // 瀛楀吀椤硅〃鍚嶇О锛岄粯璁わ細sys_configs
|
|
13
|
-
tableMetaCacheTime?: number; // 琛ㄦ牸鍏冧俊鎭紦瀛樻椂闂?
|
|
13
|
+
tableMetaCacheTime?: number; // 琛ㄦ牸鍏冧俊鎭紦瀛樻椂闂?
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export interface ITableColumn {
|
|
17
|
-
name: string; // 瀛楁鍚?
|
|
17
|
+
name: string; // 瀛楁鍚?
|
|
18
18
|
type: string; // 鏁版嵁绫诲瀷
|
|
19
19
|
isNullable: boolean; // 鏄惁鍙┖
|
|
20
20
|
isPrimaryKey?: boolean; // 鏄惁涓婚敭
|
|
21
|
-
isIdentity?: boolean; // 鏄惁鑷鍒楋紙SQL Server锛?
|
|
22
|
-
defaultValue?: any; // 榛樿鍊?
|
|
23
|
-
maxLength?: number; // 鏈€澶ч暱搴?
|
|
21
|
+
isIdentity?: boolean; // 鏄惁鑷鍒楋紙SQL Server锛?
|
|
22
|
+
defaultValue?: any; // 榛樿鍊?
|
|
23
|
+
maxLength?: number; // 鏈€澶ч暱搴?
|
|
24
24
|
comment?: string; // 瀛楁娉ㄩ噴
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface ITableMeta {
|
|
28
28
|
expiredTime: number; // 杩囨湡鏃堕棿
|
|
29
|
-
tableColumns: string[]; // 琛ㄦ牸鎵€鏈夊瓧娈?
|
|
30
|
-
columnDetails?: ITableColumn[]; // 璇︾粏鐨勫瓧娈典俊鎭?
|
|
29
|
+
tableColumns: string[]; // 琛ㄦ牸鎵€鏈夊瓧娈?
|
|
30
|
+
columnDetails?: ITableColumn[]; // 璇︾粏鐨勫瓧娈典俊鎭?
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface IConnectionPool {
|
|
@@ -50,19 +50,19 @@ export interface IPoolConnectionClient {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* 璇锋眰妯″瀷涓?data 瀛楁鐨勫€肩被鍨?
|
|
53
|
+
* 璇锋眰妯″瀷涓?data 瀛楁鐨勫€肩被鍨?
|
|
54
54
|
*
|
|
55
|
-
* 閫氱敤绫诲瀷锛圡ySQL / PostgreSQL / SQL Server 鍧囨敮鎸侊級锛?
|
|
55
|
+
* 閫氱敤绫诲瀷锛圡ySQL / PostgreSQL / SQL Server 鍧囨敮鎸侊級锛?
|
|
56
56
|
* - string : 瀛楃涓插垪锛坴archar, char, text, nvarchar 绛夛級
|
|
57
57
|
* - number : 鏁存暟 / 娴偣鏁板垪锛坕nt, bigint, decimal, float 绛夛級
|
|
58
|
-
* - boolean : 甯冨皵鍒楋紙MySQL tinyint(1) 鏄犲皠锛汸G 鍘熺敓 boolean锛汼S bit(1)锛?
|
|
58
|
+
* - boolean : 甯冨皵鍒楋紙MySQL tinyint(1) 鏄犲皠锛汸G 鍘熺敓 boolean锛汼S bit(1)锛?
|
|
59
59
|
* - Date : 鏃ユ湡鏃堕棿鍒楋紙datetime, timestamp, date 绛夛級
|
|
60
|
-
* - null : 绌哄€?
|
|
60
|
+
* - null : 绌哄€?
|
|
61
61
|
*
|
|
62
|
-
* MySQL 涓撴湁锛?
|
|
62
|
+
* MySQL 涓撴湁锛?
|
|
63
63
|
* - Record<string, any> : MySQL JSON 鍒楋紙5.7+锛夛紝CrudProDataTypeConvertService 鑷姩 JSON.stringify()
|
|
64
64
|
*
|
|
65
|
-
* PostgreSQL 涓撴湁锛?
|
|
65
|
+
* PostgreSQL 涓撴湁锛?
|
|
66
66
|
* - any[] : PG ARRAY 鍒楋紙濡?int[], text[]锛夛紝CrudProDataTypeConvertService
|
|
67
67
|
* 浼氳嚜鍔ㄨ浆涓?PG 鏁扮粍瀛楅潰閲?{1,2,3}
|
|
68
68
|
* - Record<string, any> : PG JSONB / JSON 鍒楋紝CrudProDataTypeConvertService 鑷姩 JSON.stringify()
|
|
@@ -71,24 +71,24 @@ export interface IPoolConnectionClient {
|
|
|
71
71
|
* - any[] : longtext/varchar 绛夐潪 JSON 鍒楀瓨鏁扮粍鏃讹紝CrudProDataTypeConvertService 涔熶細鑷姩 JSON.stringify()
|
|
72
72
|
* - Record<string, any> : longtext/varchar 绛夐潪 JSON 鍒楀瓨瀵硅薄鏃讹紝鍚屼笂
|
|
73
73
|
*
|
|
74
|
-
* SQL Server 璇存槑锛?
|
|
74
|
+
* SQL Server 璇存槑锛?
|
|
75
75
|
* - 鍘熺敓 JSON 鍒楀湪 SS 涓檷绾т负 NVARCHAR(MAX)锛屼絾 longtext 瀛?JSON 瀵硅薄鐨勫満鏅悓鏍疯瑕嗙洊
|
|
76
76
|
* - XML 鍒楀悓鐞嗭紝浼?string
|
|
77
77
|
*
|
|
78
78
|
* 閫氱敤浜岃繘鍒讹紙MySQL / PostgreSQL / SQL Server锛夛細
|
|
79
|
-
* - Buffer : BLOB / LONGBLOB (MySQL)銆丅YTEA (PG)銆乂ARBINARY (SS) 绛変簩杩涘埗鍒?
|
|
79
|
+
* - Buffer : BLOB / LONGBLOB (MySQL)銆丅YTEA (PG)銆乂ARBINARY (SS) 绛変簩杩涘埗鍒?
|
|
80
80
|
* 涓夌椹卞姩锛坢ysql2 / pg / mssql锛夊師鐢熸敮鎸?Buffer 鍙傛暟锛屾棤闇€棰濆杞崲
|
|
81
81
|
*/
|
|
82
82
|
export type IRequestModelDataFieldValue =
|
|
83
|
-
| string // 閫氱敤锛氬瓧绗︿覆鍒?
|
|
83
|
+
| string // 閫氱敤锛氬瓧绗︿覆鍒?
|
|
84
84
|
| number // 閫氱敤锛氭暟鍊煎垪
|
|
85
|
-
| boolean // 閫氱敤锛氬竷灏斿垪锛圡ySQL tinyint(1) / PG boolean / SS bit(1)锛?
|
|
85
|
+
| boolean // 閫氱敤锛氬竷灏斿垪锛圡ySQL tinyint(1) / PG boolean / SS bit(1)锛?
|
|
86
86
|
| Date // 閫氱敤锛氭棩鏈熸椂闂村垪
|
|
87
|
-
| null // 閫氱敤锛氱┖鍊?
|
|
88
|
-
| any[] // PG ARRAY 列:转为 PG 数组字面量;其他列存数组:自动 JSON.stringify()
|
|
89
|
-
| Record<string, any> // json/jsonb/longtext 等列存对象:按值类型自动 JSON.stringify(),不依赖列类型
|
|
90
|
-
| Buffer // 通用二进制:MySQL BLOB / PG BYTEA / SS VARBINARY,驱动原生支持无需转换
|
|
91
|
-
| ISqlFuncArg; // 表达式:UPDATE SET / INSERT VALUES 中生成非参数化 SQL 片段(NOW/UUID/INC/DEC/MUL/FN 等)
|
|
87
|
+
| null // 閫氱敤锛氱┖鍊?
|
|
88
|
+
| any[] // PG ARRAY 列:转为 PG 数组字面量;其他列存数组:自动 JSON.stringify()
|
|
89
|
+
| Record<string, any> // json/jsonb/longtext 等列存对象:按值类型自动 JSON.stringify(),不依赖列类型
|
|
90
|
+
| Buffer // 通用二进制:MySQL BLOB / PG BYTEA / SS VARBINARY,驱动原生支持无需转换
|
|
91
|
+
| ISqlFuncArg; // 表达式:UPDATE SET / INSERT VALUES 中生成非参数化 SQL 片段(NOW/UUID/INC/DEC/MUL/FN 等)
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
export type IRequestEntity = Record<string, IRequestModelDataFieldValue>;
|
|
@@ -102,7 +102,7 @@ export interface IRequestModel {
|
|
|
102
102
|
method?: string;
|
|
103
103
|
columns?: string | string[]; // "columns": "id,name,age,sex,addr",
|
|
104
104
|
condition?: IRequestCondition; // 鎷兼帴鏌ヨ鏉′欢
|
|
105
|
-
data?: IRequestModelData, // 鍗曟潯鎴栨壒閲忔彃鍏?鏇存柊鐨勬暟鎹儴鍒?
|
|
105
|
+
data?: IRequestModelData, // 鍗曟潯鎴栨壒閲忔彃鍏?鏇存柊鐨勬暟鎹儴鍒?
|
|
106
106
|
orderBy?: string | IOrderByItem[];
|
|
107
107
|
limit?: number;
|
|
108
108
|
offset?: number;
|
|
@@ -113,53 +113,53 @@ export interface IRequestModel {
|
|
|
113
113
|
type IBasicType = boolean | string | number;
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
|
-
* 姣旇緝鎿嶄綔绗︽潯浠?
|
|
116
|
+
* 姣旇緝鎿嶄綔绗︽潯浠?
|
|
117
117
|
* 鏀寔 MongoDB 椋庢牸鐨勬墍鏈夋煡璇㈡搷浣滅
|
|
118
118
|
*/
|
|
119
119
|
export interface ICompareCondition {
|
|
120
|
-
// 姣旇緝鎿嶄綔绗?
|
|
121
|
-
$ne?: IBasicType; // 涓嶇瓑浜?
|
|
120
|
+
// 姣旇緝鎿嶄綔绗?
|
|
121
|
+
$ne?: IBasicType; // 涓嶇瓑浜?
|
|
122
122
|
$lt?: IBasicType; // 灏忎簬
|
|
123
|
-
$lte?: IBasicType; // 灏忎簬鎴栫瓑浜?
|
|
123
|
+
$lte?: IBasicType; // 灏忎簬鎴栫瓑浜?
|
|
124
124
|
$gt?: IBasicType; // 澶т簬
|
|
125
|
-
$gte?: IBasicType; // 澶т簬鎴栫瓑浜?
|
|
125
|
+
$gte?: IBasicType; // 澶т簬鎴栫瓑浜?
|
|
126
126
|
|
|
127
|
-
// 闆嗗悎鎿嶄綔绗?
|
|
127
|
+
// 闆嗗悎鎿嶄綔绗?
|
|
128
128
|
$in?: IBasicType[]; // 鍦ㄩ泦鍚堜腑
|
|
129
|
-
$nin?: IBasicType[]; // 涓嶅湪闆嗗悎涓?
|
|
129
|
+
$nin?: IBasicType[]; // 涓嶅湪闆嗗悎涓?
|
|
130
130
|
|
|
131
|
-
// 鑼冨洿鎿嶄綔绗?
|
|
131
|
+
// 鑼冨洿鎿嶄綔绗?
|
|
132
132
|
$range?: [number, number]; // 鑼冨洿鏌ヨ [min, max]
|
|
133
133
|
|
|
134
|
-
// 妯$硦鍖归厤鎿嶄綔绗?
|
|
134
|
+
// 妯$硦鍖归厤鎿嶄綔绗?
|
|
135
135
|
$like?: string; // 鍓嶇紑鍖归厤 A%
|
|
136
136
|
$notLike?: string; // 闈炲墠缂€鍖归厤
|
|
137
137
|
$likeInclude?: string; // 鍖呭惈鍖归厤 %A%
|
|
138
|
-
$notLikeInclude?: string; // 涓嶅寘鍚尮閰?
|
|
138
|
+
$notLikeInclude?: string; // 涓嶅寘鍚尮閰?
|
|
139
139
|
|
|
140
|
-
// 鍏ㄦ枃绱㈠紩鎿嶄綔绗?
|
|
140
|
+
// 鍏ㄦ枃绱㈠紩鎿嶄綔绗?
|
|
141
141
|
$match?: string; // MySQL 鍏ㄦ枃绱㈠紩
|
|
142
142
|
$matchBool?: string | boolean; // MySQL 甯冨皵鍏ㄦ枃绱㈠紩
|
|
143
143
|
|
|
144
|
-
// NULL 鍒ゆ柇鎿嶄綔绗?
|
|
144
|
+
// NULL 鍒ゆ柇鎿嶄綔绗?
|
|
145
145
|
$null?: boolean; // IS NULL
|
|
146
146
|
$notNull?: boolean; // IS NOT NULL
|
|
147
147
|
|
|
148
|
-
// JSON 鎿嶄綔绗?
|
|
148
|
+
// JSON 鎿嶄綔绗?
|
|
149
149
|
$jsonArrayContains?: string; // JSON 鏁扮粍鍖呭惈
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
|
-
* 閫昏緫鎿嶄綔绗︽潯浠?
|
|
153
|
+
* 閫昏緫鎿嶄綔绗︽潯浠?
|
|
154
154
|
*/
|
|
155
155
|
export interface ILogicalCondition {
|
|
156
|
-
$or?: IRequestCondition[]; // 閫昏緫鎴?
|
|
157
|
-
$and?: IRequestCondition[]; // 閫昏緫涓?
|
|
156
|
+
$or?: IRequestCondition[]; // 閫昏緫鎴?
|
|
157
|
+
$and?: IRequestCondition[]; // 閫昏緫涓?
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* 鏌ヨ鏉′欢绫诲瀷
|
|
162
|
-
* 鏀寔瀛楁鍊肩洿鎺ュ尮閰嶆垨姣旇緝鎿嶄綔绗?
|
|
162
|
+
* 鏀寔瀛楁鍊肩洿鎺ュ尮閰嶆垨姣旇緝鎿嶄綔绗?
|
|
163
163
|
* 鏀寔 $or, $and 閫昏緫缁勫悎
|
|
164
164
|
*/
|
|
165
165
|
export interface IRequestCondition extends Record<string, IBasicType | ICompareCondition | ILogicalCondition | IRequestCondition[] | undefined>, ILogicalCondition {
|
|
@@ -183,7 +183,7 @@ export interface IVisitor {
|
|
|
183
183
|
*/
|
|
184
184
|
export enum BasicRecordEnum {
|
|
185
185
|
dict = 'dict', // 鍏宠仈鏁版嵁瀛楀吀
|
|
186
|
-
sysCfgEnum = 'sysCfgEnum', // 閰嶇疆鏂囦欢涓紝蹇呴』鍖呭惈code涓€鍒楋紝浣滀负鍞竴閿€?
|
|
186
|
+
sysCfgEnum = 'sysCfgEnum', // 閰嶇疆鏂囦欢涓紝蹇呴』鍖呭惈code涓€鍒楋紝浣滀负鍞竴閿€?
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
export interface CopyAttr {
|
|
@@ -194,7 +194,7 @@ export interface CopyAttr {
|
|
|
194
194
|
export interface ColumnRelation {
|
|
195
195
|
relatedType: any; // 濡傦細 dict
|
|
196
196
|
relatedCode?: string; // SexEnum
|
|
197
|
-
sourceColumn: string; // 浠巖ow涓彇鍊肩殑瀛楁鍚?
|
|
197
|
+
sourceColumn: string; // 浠巖ow涓彇鍊肩殑瀛楁鍚?
|
|
198
198
|
targetColumns?: CopyAttr[]; //[{from:'label', to:'user_sex_text'}]
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -202,57 +202,57 @@ export interface ColumnRelation {
|
|
|
202
202
|
* 鍩烘湰鍝嶅簲閰嶇疆
|
|
203
203
|
*/
|
|
204
204
|
export interface IBaseCfgModel {
|
|
205
|
-
sqlTable?: string; // 鍙互涓虹┖. originSql涓笉鍖呭惈@@table鏃跺彲浠ヤ负绌?
|
|
205
|
+
sqlTable?: string; // 鍙互涓虹┖. originSql涓笉鍖呭惈@@table鏃跺彲浠ヤ负绌?
|
|
206
206
|
sqlSchema?: string; // 鍙互涓虹┖
|
|
207
207
|
sqlDatabase?: string; // 鍙互涓虹┖锛岀敤姝ゅ瓧娈佃繘琛宑onnection鐨勯€夋嫨鍜屽垏鎹€傞厤鍚坓etBizConnectionPool浣跨敤
|
|
208
208
|
sqlDbType?: SqlDbType; // 鏁版嵁搴撶被鍨嬶紝mysql(榛樿) 銆乸ostgres
|
|
209
209
|
maxLimit?: number; // 鏈€澶т竴娆℃€ц繑鍥炵殑鏁伴噺
|
|
210
210
|
columns?: string | string[]; // "columns": "id,name,age,sex,addr",
|
|
211
211
|
columnsRelation?: ColumnRelation[];
|
|
212
|
-
autoSnowflakeId?: boolean; // INSERT 鏃惰嚜鍔ㄤ负绌?id 瀛楁濉厖闆姳ID锛堥粯璁?false锛?
|
|
212
|
+
autoSnowflakeId?: boolean; // INSERT 鏃惰嚜鍔ㄤ负绌?id 瀛楁濉厖闆姳ID锛堥粯璁?false锛?
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
export type IFunctionParam = IFuncCfgModel | string | number | boolean | null;
|
|
216
216
|
export interface IFuncCfgModel extends Record<any, any> {
|
|
217
|
-
___PLAIN_OBJECT___?: boolean; // 鏈韩灏辨槸涓€涓璞?
|
|
218
|
-
functionName?: string; // 鍑芥暟鍚?
|
|
217
|
+
___PLAIN_OBJECT___?: boolean; // 鏈韩灏辨槸涓€涓璞?
|
|
218
|
+
functionName?: string; // 鍑芥暟鍚?
|
|
219
219
|
functionParams?: IFunctionParam[]; // 鍑芥暟鍙傛暟
|
|
220
220
|
|
|
221
221
|
const?: any; // 甯搁噺,浠绘剰绫诲瀷銆傚彲浠ユ槸json瀵硅薄
|
|
222
|
-
constString?: any; // 甯搁噺瀛楃涓?
|
|
223
|
-
constNumber?: number; // 甯搁噺鏁板瓧锛屼换鎰忓舰寮? int,bigDecimal,bigInteger锛屽瓧绗︿覆锛岀瓑銆?
|
|
222
|
+
constString?: any; // 甯搁噺瀛楃涓?
|
|
223
|
+
constNumber?: number; // 甯搁噺鏁板瓧锛屼换鎰忓舰寮? int,bigDecimal,bigInteger锛屽瓧绗︿覆锛岀瓑銆?
|
|
224
224
|
constBool?: boolean; // 甯搁噺bool鍊笺€備笌js鐨勫垽鏂€昏緫涓€鑷达紝false, null, 0 , "" 琚涓烘槸 false锛屽叾浠栬涓烘槸true
|
|
225
225
|
|
|
226
|
-
context?: string; // 浠巆ontext涓彇鍊?
|
|
227
|
-
contextAsString?: string; // 浠巆ontext涓彇鍊?
|
|
228
|
-
contextAsNumber?: string; // 浠巆ontext涓彇鍊?
|
|
229
|
-
contextAsBool?: string; // 浠巆ontext涓彇鍊?
|
|
226
|
+
context?: string; // 浠巆ontext涓彇鍊?
|
|
227
|
+
contextAsString?: string; // 浠巆ontext涓彇鍊?
|
|
228
|
+
contextAsNumber?: string; // 浠巆ontext涓彇鍊?
|
|
229
|
+
contextAsBool?: string; // 浠巆ontext涓彇鍊?
|
|
230
230
|
|
|
231
|
-
executeExpressReturnObject?: string; // 鎵ц琛ㄨ揪寮忥紝杩斿洖瀵硅薄銆傚彲浠ュ寘鍚玞ontext涓殑鍙橀噺銆?
|
|
232
|
-
executeExpressReturnString?: string; // 鎵ц琛ㄨ揪寮忥紝杩斿洖瀛楃涓层€傚彲浠ュ寘鍚玞ontext涓殑鍙橀噺銆?
|
|
231
|
+
executeExpressReturnObject?: string; // 鎵ц琛ㄨ揪寮忥紝杩斿洖瀵硅薄銆傚彲浠ュ寘鍚玞ontext涓殑鍙橀噺銆?
|
|
232
|
+
executeExpressReturnString?: string; // 鎵ц琛ㄨ揪寮忥紝杩斿洖瀛楃涓层€傚彲浠ュ寘鍚玞ontext涓殑鍙橀噺銆?
|
|
233
233
|
|
|
234
|
-
message?: string; // 鍦ㄦ牎楠岄樁娈垫湁鐢紝鍏朵粬闃舵娌℃湁鐢?
|
|
234
|
+
message?: string; // 鍦ㄦ牎楠岄樁娈垫湁鐢紝鍏朵粬闃舵娌℃湁鐢?
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
export interface ISqlCfgModel extends IBaseCfgModel {
|
|
238
238
|
resName?: string;
|
|
239
239
|
resPicker?: string;
|
|
240
240
|
originSql?: string; // 鏈夌壒娈婂崰浣嶇鐨凷QL, 鍘熷鐨凷QL
|
|
241
|
-
validate?: IFuncCfgModel; //鎵ц鍓嶏紝杩涜鏍¢獙锛屾牎楠屼笉閫氳繃灏辨姏鍑哄紓甯? 鏍¢獙鍑芥暟鍙互杩斿洖 boolean鎴栫洿鎺ユ姏鍑哄紓甯?
|
|
241
|
+
validate?: IFuncCfgModel; //鎵ц鍓嶏紝杩涜鏍¢獙锛屾牎楠屼笉閫氳繃灏辨姏鍑哄紓甯? 鏍¢獙鍑芥暟鍙互杩斿洖 boolean鎴栫洿鎺ユ姏鍑哄紓甯?
|
|
242
242
|
executeWhen?: IFuncCfgModel; //婊¤冻琛ㄨ揪寮忕殑缁撴灉锛屾墠鑳芥墽琛屻€?榛樿锛歵rue 鏍¢獙鍑芥暟蹇呴』杩斿洖 boolean
|
|
243
|
-
isNativeSQL?: boolean; // 鍙互杩愯鐨凷QL銆傚湪postgres/sqlserver鐜涓嬩篃鍙互浣跨敤闂彿銆?
|
|
244
|
-
executeSql?: string; // 鍙互杩愯鐨凷QL銆傚湪postgres/sqlserver鐜涓嬩篃鍙互浣跨敤闂彿銆?
|
|
245
|
-
executeSqlArgs?: any[]; //鍙互杩愯鐨凷QL鐨勫弬鏁?
|
|
243
|
+
isNativeSQL?: boolean; // 鍙互杩愯鐨凷QL銆傚湪postgres/sqlserver鐜涓嬩篃鍙互浣跨敤闂彿銆?
|
|
244
|
+
executeSql?: string; // 鍙互杩愯鐨凷QL銆傚湪postgres/sqlserver鐜涓嬩篃鍙互浣跨敤闂彿銆?
|
|
245
|
+
executeSqlArgs?: any[]; //鍙互杩愯鐨凷QL鐨勫弬鏁?
|
|
246
246
|
crudType?: string;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
/**
|
|
250
250
|
* executeSQL 鐨勮繑鍥炵粨鏋滅被鍨嬭鏄庯紙鏈鍖呰鐨勭洿鎺ョ粨鏋滐級
|
|
251
251
|
*
|
|
252
|
-
* 娉ㄦ剰锛歟xecuteSQL 杩斿洖鐨勬槸鏁版嵁搴撴煡璇㈢殑鍘熷缁撴灉锛屾病鏈?{code, data, message} 鍖呰灞傘€?
|
|
253
|
-
* 杩斿洖绫诲瀷鍙栧喅浜?resPicker 閰嶇疆锛岃鏍规嵁瀹為檯 SQL 绫诲瀷閫夋嫨鍚堥€傜殑绫诲瀷鏂█銆?
|
|
252
|
+
* 娉ㄦ剰锛歟xecuteSQL 杩斿洖鐨勬槸鏁版嵁搴撴煡璇㈢殑鍘熷缁撴灉锛屾病鏈?{code, data, message} 鍖呰灞傘€?
|
|
253
|
+
* 杩斿洖绫诲瀷鍙栧喅浜?resPicker 閰嶇疆锛岃鏍规嵁瀹為檯 SQL 绫诲瀷閫夋嫨鍚堥€傜殑绫诲瀷鏂█銆?
|
|
254
254
|
*
|
|
255
|
-
* 浣跨敤绀轰緥锛?
|
|
255
|
+
* 浣跨敤绀轰緥锛?
|
|
256
256
|
* // 鏌ヨ鍒楄〃 - 杩斿洖鏁扮粍
|
|
257
257
|
* const rows = await executeSQL({ executeSql: 'SELECT * FROM users', resPicker: KeysOfSqlResPicker.RESULT_ROWS }) as ExecuteSQLRowResult<User>;
|
|
258
258
|
*
|
|
@@ -265,7 +265,7 @@ export interface ISqlCfgModel extends IBaseCfgModel {
|
|
|
265
265
|
* // 鍒ゆ柇瀛樺湪 - 杩斿洖甯冨皵
|
|
266
266
|
* const exists = await executeSQL({ executeSql: 'SELECT 1 as is_exist FROM users WHERE id=?', executeSqlArgs: [1], resPicker: KeysOfSqlResPicker.RESULT_IS_EXIST }) as ExecuteSQLExistResult;
|
|
267
267
|
*
|
|
268
|
-
* // 澧炲垹鏀规搷浣?- 杩斿洖鍙楀奖鍝嶈鏁颁俊鎭?
|
|
268
|
+
* // 澧炲垹鏀规搷浣?- 杩斿洖鍙楀奖鍝嶈鏁颁俊鎭?
|
|
269
269
|
* const result = await executeSQL({ executeSql: 'INSERT INTO users(name) VALUES(?)', executeSqlArgs: ['寮犱笁'], resPicker: KeysOfSqlResPicker.UPDATE_RESULT }) as ExecuteSQLUpdateResult;
|
|
270
270
|
*/
|
|
271
271
|
|
|
@@ -290,15 +290,15 @@ export interface ExecuteSQLUpdateResult {
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
/**
|
|
293
|
-
* executeSQL 鐨勯€氱敤杩斿洖绫诲瀷锛堟湭琚寘瑁呯殑鐩存帴缁撴灉锛?
|
|
293
|
+
* executeSQL 鐨勯€氱敤杩斿洖绫诲瀷锛堟湭琚寘瑁呯殑鐩存帴缁撴灉锛?
|
|
294
294
|
* 鏍规嵁 resPicker 鐨勪笉鍚岄厤缃紝瀹為檯杩斿洖绫诲瀷鍙兘鏄細
|
|
295
295
|
* - ExecuteSQLRowResult<T> : 澶氳鏁版嵁锛堥粯璁わ級
|
|
296
296
|
* - ExecuteSQLSingleResult<T> : 鍗曡鏁版嵁鎴杗ull
|
|
297
297
|
* - ExecuteSQLCountResult : 鏁板瓧
|
|
298
|
-
* - ExecuteSQLExistResult : 甯冨皵鍊?
|
|
299
|
-
* - ExecuteSQLUpdateResult : 澧炲垹鏀圭粨鏋?
|
|
298
|
+
* - ExecuteSQLExistResult : 甯冨皵鍊?
|
|
299
|
+
* - ExecuteSQLUpdateResult : 澧炲垹鏀圭粨鏋?
|
|
300
300
|
*
|
|
301
|
-
* 璀﹀憡锛氭绫诲瀷涓鸿仈鍚堢被鍨嬶紝浣跨敤鏃跺缓璁牴鎹疄闄?resPicker 杩涜绫诲瀷鏂█浠ヨ幏寰楃簿纭被鍨嬫彁绀?
|
|
301
|
+
* 璀﹀憡锛氭绫诲瀷涓鸿仈鍚堢被鍨嬶紝浣跨敤鏃跺缓璁牴鎹疄闄?resPicker 杩涜绫诲瀷鏂█浠ヨ幏寰楃簿纭被鍨嬫彁绀?
|
|
302
302
|
*/
|
|
303
303
|
export type ExecuteSQLResult<T = Record<string, any>> =
|
|
304
304
|
| ExecuteSQLRowsResult<T>
|
|
@@ -389,7 +389,7 @@ export interface ITableNamesOptions {
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
/**
|
|
392
|
-
* 琛ㄤ俊鎭」锛堝寘鍚〃鍚嶅拰绫诲瀷锛?
|
|
392
|
+
* 琛ㄤ俊鎭」锛堝寘鍚〃鍚嶅拰绫诲瀷锛?
|
|
393
393
|
*/
|
|
394
394
|
export interface ITableInfo {
|
|
395
395
|
name: string; // 琛ㄥ悕
|
|
@@ -397,10 +397,10 @@ export interface ITableInfo {
|
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
/**
|
|
400
|
-
* 琛ㄤ俊鎭煡璇㈢粨鏋?
|
|
400
|
+
* 琛ㄤ俊鎭煡璇㈢粨鏋?
|
|
401
401
|
*/
|
|
402
402
|
export interface ITableListResult {
|
|
403
|
-
tables: ITableInfo[]; // 鎵€鏈夎〃鍜岃鍥?
|
|
404
|
-
tableNames: string[]; // 浠呰〃鍚嶏紙涓嶅惈瑙嗗浘锛?
|
|
403
|
+
tables: ITableInfo[]; // 鎵€鏈夎〃鍜岃鍥?
|
|
404
|
+
tableNames: string[]; // 浠呰〃鍚嶏紙涓嶅惈瑙嗗浘锛?
|
|
405
405
|
viewNames: string[]; // 浠呰鍥惧悕
|
|
406
406
|
}
|
|
@@ -19,24 +19,10 @@ const REGEX_STRING_TYPE = /^(varchar|char|text|longtext|mediumtext|tinytext|nvar
|
|
|
19
19
|
const REGEX_NATIVE_BOOLEAN_TYPE = /^(boolean|bool)$/;
|
|
20
20
|
|
|
21
21
|
/** 含 WHERE 条件的操作类型(查询/删除/更新) */
|
|
22
|
-
const CONDITION_TYPES = new Set<string>([
|
|
23
|
-
KeysOfSimpleSQL.SIMPLE_QUERY,
|
|
24
|
-
KeysOfSimpleSQL.SIMPLE_QUERY_ONE,
|
|
25
|
-
KeysOfSimpleSQL.SIMPLE_QUERY_PAGE,
|
|
26
|
-
KeysOfSimpleSQL.SIMPLE_QUERY_COUNT,
|
|
27
|
-
KeysOfSimpleSQL.SIMPLE_QUERY_EXIST,
|
|
28
|
-
KeysOfSimpleSQL.SIMPLE_DELETE,
|
|
29
|
-
KeysOfSimpleSQL.SIMPLE_UPDATE,
|
|
30
|
-
]);
|
|
22
|
+
const CONDITION_TYPES = new Set<string>([KeysOfSimpleSQL.SIMPLE_QUERY, KeysOfSimpleSQL.SIMPLE_QUERY_ONE, KeysOfSimpleSQL.SIMPLE_QUERY_PAGE, KeysOfSimpleSQL.SIMPLE_QUERY_COUNT, KeysOfSimpleSQL.SIMPLE_QUERY_EXIST, KeysOfSimpleSQL.SIMPLE_DELETE, KeysOfSimpleSQL.SIMPLE_UPDATE]);
|
|
31
23
|
|
|
32
24
|
/** INSERT/UPDATE 操作类型 */
|
|
33
|
-
const INSERT_OR_UPDATE_TYPES = new Set<string>([
|
|
34
|
-
KeysOfSimpleSQL.SIMPLE_INSERT,
|
|
35
|
-
KeysOfSimpleSQL.SIMPLE_UPDATE,
|
|
36
|
-
KeysOfSimpleSQL.SIMPLE_INSERT_ON_DUPLICATE_UPDATE,
|
|
37
|
-
KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE,
|
|
38
|
-
KeysOfSimpleSQL.SIMPLE_BATCH_INSERT,
|
|
39
|
-
]);
|
|
25
|
+
const INSERT_OR_UPDATE_TYPES = new Set<string>([KeysOfSimpleSQL.SIMPLE_INSERT, KeysOfSimpleSQL.SIMPLE_UPDATE, KeysOfSimpleSQL.SIMPLE_INSERT_ON_DUPLICATE_UPDATE, KeysOfSimpleSQL.SIMPLE_INSERT_OR_UPDATE, KeysOfSimpleSQL.SIMPLE_BATCH_INSERT]);
|
|
40
26
|
|
|
41
27
|
// ============ 工具函数 ============
|
|
42
28
|
|
|
@@ -92,9 +78,7 @@ function isInsertOrUpdateType(sqlSimpleName: string): boolean {
|
|
|
92
78
|
}
|
|
93
79
|
|
|
94
80
|
/** 获取表元数据,失败时 warn 并返回 null */
|
|
95
|
-
async function getTableMetaOrWarn(
|
|
96
|
-
serviceHub: any, logger: any, cfgModel: RequestCfgModel, actionName: string
|
|
97
|
-
) {
|
|
81
|
+
async function getTableMetaOrWarn(serviceHub: any, logger: any, cfgModel: RequestCfgModel, actionName: string) {
|
|
98
82
|
const query: ITableMetaQuery = {
|
|
99
83
|
sqlTable: cfgModel.sqlTable,
|
|
100
84
|
sqlDatabase: cfgModel.sqlDatabase,
|
|
@@ -187,8 +171,11 @@ class DataConvertHandler {
|
|
|
187
171
|
const typeMap = buildColumnTypeMap(tableMeta);
|
|
188
172
|
|
|
189
173
|
// 按列类型强转基础值(boolean 等适配实际 DB 字段)
|
|
190
|
-
if (isBatch) {
|
|
191
|
-
|
|
174
|
+
if (isBatch) {
|
|
175
|
+
for (const row of data) this.convertDataFieldsByType(row, typeMap, cfgModel.sqlDbType);
|
|
176
|
+
} else {
|
|
177
|
+
this.convertDataFieldsByType(data, typeMap, cfgModel.sqlDbType);
|
|
178
|
+
}
|
|
192
179
|
|
|
193
180
|
// PostgreSQL:ARRAY 列 JS 数组 → PG 数组字面量
|
|
194
181
|
if (cfgModel.sqlDbType === SqlDbType.postgres) {
|
|
@@ -199,23 +186,25 @@ class DataConvertHandler {
|
|
|
199
186
|
}
|
|
200
187
|
}
|
|
201
188
|
if (arrayFieldSet.size > 0) {
|
|
202
|
-
if (isBatch) {
|
|
203
|
-
|
|
189
|
+
if (isBatch) {
|
|
190
|
+
for (const row of data) this.convertPgArrayFields(row, arrayFieldSet);
|
|
191
|
+
} else {
|
|
192
|
+
this.convertPgArrayFields(data, arrayFieldSet);
|
|
193
|
+
}
|
|
204
194
|
}
|
|
205
195
|
}
|
|
206
196
|
}
|
|
207
197
|
|
|
208
198
|
// 三库通用:对象/数组 → JSON.stringify(不依赖列类型)
|
|
209
|
-
if (isBatch) {
|
|
210
|
-
|
|
199
|
+
if (isBatch) {
|
|
200
|
+
for (const row of data) this.serializeObjectValues(row);
|
|
201
|
+
} else {
|
|
202
|
+
this.serializeObjectValues(data);
|
|
203
|
+
}
|
|
211
204
|
}
|
|
212
205
|
|
|
213
206
|
/** 按表字段类型转换 data 中的基础类型值 */
|
|
214
|
-
private convertDataFieldsByType(
|
|
215
|
-
dataObj: Record<string, any>,
|
|
216
|
-
typeMap: Map<string, string>,
|
|
217
|
-
sqlDbType: SqlDbType
|
|
218
|
-
): void {
|
|
207
|
+
private convertDataFieldsByType(dataObj: Record<string, any>, typeMap: Map<string, string>, sqlDbType: SqlDbType): void {
|
|
219
208
|
for (const key of Object.keys(dataObj)) {
|
|
220
209
|
const value = dataObj[key];
|
|
221
210
|
if (value === null || value === undefined) {
|
|
@@ -291,9 +280,7 @@ class DataConvertHandler {
|
|
|
291
280
|
if (typeof value === 'boolean') {
|
|
292
281
|
return value ? 't' : 'f';
|
|
293
282
|
}
|
|
294
|
-
const escaped = ('' + value)
|
|
295
|
-
.replace(/\\/g, '\\\\')
|
|
296
|
-
.replace(/"/g, '\\"');
|
|
283
|
+
const escaped = ('' + value).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
297
284
|
return '"' + escaped + '"';
|
|
298
285
|
}
|
|
299
286
|
|
|
@@ -349,11 +336,7 @@ class ConditionConvertHandler {
|
|
|
349
336
|
}
|
|
350
337
|
|
|
351
338
|
/** 递归遍历 condition,支持 $or/$and 嵌套 */
|
|
352
|
-
private convertConditionFields(
|
|
353
|
-
condition: IRequestCondition,
|
|
354
|
-
typeMap: Map<string, string>,
|
|
355
|
-
sqlDbType: SqlDbType
|
|
356
|
-
): void {
|
|
339
|
+
private convertConditionFields(condition: IRequestCondition, typeMap: Map<string, string>, sqlDbType: SqlDbType): void {
|
|
357
340
|
if (!condition || typeof condition !== 'object') {
|
|
358
341
|
return;
|
|
359
342
|
}
|
|
@@ -410,7 +393,6 @@ class ConditionConvertHandler {
|
|
|
410
393
|
* data/condition 类型强转、PG ARRAY 字面量、对象/数组 JSON 序列化
|
|
411
394
|
*/
|
|
412
395
|
class CrudProDataTypeConvertService extends CrudProServiceBase {
|
|
413
|
-
|
|
414
396
|
async convertDataTypeByTableMeta(reqModel: RequestModel, cfgModel: RequestCfgModel): Promise<void> {
|
|
415
397
|
return new DataConvertHandler(this.serviceHub, this.logger).convertDataTypeByTableMeta(reqModel, cfgModel);
|
|
416
398
|
}
|