midway-fatcms 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.qoder/skills/midway-fatcms/01-quick-start.md +231 -0
- package/.qoder/skills/midway-fatcms/02-crud-quick.md +337 -0
- package/.qoder/skills/midway-fatcms/03-crud-sharding.md +488 -0
- package/.qoder/skills/midway-fatcms/04-condition-operators.md +93 -0
- package/.qoder/skills/midway-fatcms/05-configuration.md +290 -0
- package/.qoder/skills/midway-fatcms/06-builtin-functions.md +241 -0
- package/.qoder/skills/midway-fatcms/07-examples.md +500 -0
- package/.qoder/skills/midway-fatcms/SKILL.md +96 -0
- package/README.md +9 -9
- package/dist/controller/base/BaseApiController.d.ts +1 -2
- package/dist/controller/base/BaseApiController.js +0 -4
- package/dist/controller/gateway/DocGatewayController.js +1 -1
- package/dist/controller/manage/FlowConfigManageApi.js +4 -2
- package/dist/controller/manage/SysConfigMangeApi.js +6 -1
- package/dist/controller/manage/UserAccountManageApi.js +7 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/libs/crud-pro/CrudPro.d.ts +23 -2
- package/dist/libs/crud-pro/CrudPro.js +53 -2
- package/dist/libs/crud-pro/interfaces.d.ts +82 -12
- package/dist/libs/crud-pro/models/CrudResult.d.ts +115 -0
- package/dist/libs/crud-pro/models/CrudResult.js +126 -0
- package/dist/libs/crud-pro/models/RequestModel.d.ts +2 -2
- package/dist/libs/crud-pro/services/CrudProExecuteSqlService.js +36 -2
- package/dist/libs/crud-pro/services/CrudProGenSqlCondition.js +8 -4
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +1 -2
- package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +295 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.js +529 -0
- package/dist/libs/crud-pro-quick/fixSoftDelete.d.ts +30 -0
- package/dist/{service/curd → libs/crud-pro-quick}/fixSoftDelete.js +3 -6
- package/dist/libs/crud-pro-quick/index.d.ts +36 -0
- package/dist/libs/crud-pro-quick/index.js +49 -0
- package/dist/libs/crud-pro-quick/models.d.ts +33 -0
- package/dist/libs/crud-pro-quick/models.js +2 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +15 -2
- package/dist/libs/crud-sharding/ShardingConfig.js +2 -2
- package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +119 -274
- package/dist/libs/crud-sharding/ShardingCrudPro.js +544 -340
- package/dist/libs/crud-sharding/ShardingMerger.d.ts +10 -18
- package/dist/libs/crud-sharding/ShardingMerger.js +27 -44
- package/dist/libs/crud-sharding/ShardingResult.d.ts +33 -0
- package/dist/libs/crud-sharding/ShardingResult.js +16 -0
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +1 -0
- package/dist/libs/crud-sharding/ShardingRouter.js +25 -6
- package/dist/libs/crud-sharding/ShardingTableCreator.d.ts +21 -4
- package/dist/libs/crud-sharding/ShardingTableCreator.js +193 -59
- package/dist/libs/crud-sharding/ShardingUtils.d.ts +48 -0
- package/dist/libs/crud-sharding/ShardingUtils.js +122 -1
- package/dist/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/dist/libs/crud-sharding/index.d.ts +4 -3
- package/dist/libs/crud-sharding/index.js +14 -2
- package/dist/models/bizmodels.d.ts +2 -6
- package/dist/service/SysAppService.d.ts +2 -2
- package/dist/service/SysAppService.js +16 -5
- package/dist/service/SysConfigService.d.ts +1 -1
- package/dist/service/SysConfigService.js +7 -2
- package/dist/service/SysDictDataService.js +14 -4
- package/dist/service/SysMenuService.js +7 -2
- package/dist/service/curd/CurdMixService.d.ts +6 -4
- package/dist/service/curd/CurdMixService.js +16 -2
- package/dist/service/curd/CurdProService.d.ts +43 -27
- package/dist/service/curd/CurdProService.js +32 -33
- package/dist/service/flow/FlowConfigService.js +7 -2
- package/dist/service/flow/FlowInstanceCrudService.js +22 -19
- package/package.json +1 -1
- package/src/controller/base/BaseApiController.ts +0 -5
- package/src/controller/gateway/DocGatewayController.ts +1 -1
- package/src/controller/manage/CrudStandardDesignApi.ts +4 -3
- package/src/controller/manage/FlowConfigManageApi.ts +4 -2
- package/src/controller/manage/SysConfigMangeApi.ts +6 -1
- package/src/controller/manage/UserAccountManageApi.ts +7 -2
- package/src/index.ts +2 -2
- package/src/libs/crud-pro/CrudPro.ts +62 -4
- package/src/libs/crud-pro/interfaces.ts +110 -15
- package/src/libs/crud-pro/models/CrudResult.ts +178 -0
- package/src/libs/crud-pro/models/RequestModel.ts +2 -2
- package/src/libs/crud-pro/services/CrudProExecuteSqlService.ts +41 -2
- package/src/libs/crud-pro/services/CrudProGenSqlCondition.ts +11 -7
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +1 -2
- package/src/libs/crud-pro-quick/CrudProQuick.ts +594 -0
- package/src/{service/curd → libs/crud-pro-quick}/fixSoftDelete.ts +23 -13
- package/src/libs/crud-pro-quick/index.ts +52 -0
- package/src/libs/crud-pro-quick/models.ts +35 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +18 -2
- package/src/libs/crud-sharding/ShardingCrudPro.ts +660 -390
- package/src/libs/crud-sharding/ShardingMerger.ts +35 -63
- package/src/libs/crud-sharding/ShardingResult.ts +29 -0
- package/src/libs/crud-sharding/ShardingRouter.ts +27 -6
- package/src/libs/crud-sharding/ShardingTableCreator.ts +214 -71
- package/src/libs/crud-sharding/ShardingUtils.ts +137 -0
- package/src/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +488 -0
- package/src/libs/crud-sharding/index.ts +14 -3
- package/src/models/bizmodels.ts +4 -7
- package/src/service/SysAppService.ts +18 -7
- package/src/service/SysConfigService.ts +8 -3
- package/src/service/SysDictDataService.ts +14 -4
- package/src/service/SysMenuService.ts +7 -2
- package/src/service/crudstd/CrudStdService.ts +2 -2
- package/src/service/curd/CurdMixService.ts +26 -5
- package/src/service/curd/CurdProService.ts +58 -39
- package/src/service/flow/FlowConfigService.ts +7 -2
- package/src/service/flow/FlowInstanceCrudService.ts +23 -20
- package/.qoder/skills/midway-fatcms-crud/SKILL.md +0 -375
- package/.qoder/skills/midway-fatcms-crud/examples.md +0 -990
- package/.qoder/skills/midway-fatcms-crud/reference.md +0 -568
- package/dist/libs/crud-pro/README.md +0 -809
- package/dist/libs/crud-pro/README_FUNC.md +0 -193
- package/dist/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/dist/models/StandardColumns.d.ts +0 -71
- package/dist/models/StandardColumns.js +0 -28
- package/dist/service/curd/CrudProQuick.d.ts +0 -190
- package/dist/service/curd/CrudProQuick.js +0 -319
- package/dist/service/curd/README.md +0 -1100
- package/dist/service/curd/fixSoftDelete.d.ts +0 -20
- package/src/libs/crud-pro/README.md +0 -809
- package/src/libs/crud-pro/README_FUNC.md +0 -193
- package/src/libs/crud-sharding/ROUTING_LOGIC.md +0 -944
- package/src/models/StandardColumns.ts +0 -76
- package/src/service/curd/CrudProQuick.ts +0 -360
- package/src/service/curd/README.md +0 -1100
|
@@ -40,7 +40,8 @@ let FlowConfigManageApi = class FlowConfigManageApi extends BaseApiController_1.
|
|
|
40
40
|
}
|
|
41
41
|
async updateFlowConfig() {
|
|
42
42
|
const body = this.ctx.request.body;
|
|
43
|
-
const
|
|
43
|
+
const flow_code = String(body.condition.flow_code);
|
|
44
|
+
const flow_version = Number(body.condition.flow_version);
|
|
44
45
|
await this.flowConfigService.remove_cache_flow_config_one(flow_code, flow_version);
|
|
45
46
|
return this.executeSysSimpleSQL(FlowModel_1.FLOW_TABLES.flow_config, keys_1.KeysOfSimpleSQL.SIMPLE_UPDATE, {
|
|
46
47
|
enableSoftDelete: true,
|
|
@@ -53,7 +54,8 @@ let FlowConfigManageApi = class FlowConfigManageApi extends BaseApiController_1.
|
|
|
53
54
|
}
|
|
54
55
|
async deleteFlowConfig() {
|
|
55
56
|
const body = this.ctx.request.body;
|
|
56
|
-
const
|
|
57
|
+
const flow_code = String(body.condition.flow_code);
|
|
58
|
+
const flow_version = Number(body.condition.flow_version);
|
|
57
59
|
await this.flowConfigService.remove_cache_flow_config_one(flow_code, flow_version);
|
|
58
60
|
return this.executeSysSimpleSQL(FlowModel_1.FLOW_TABLES.flow_config, keys_1.KeysOfSimpleSQL.SIMPLE_DELETE, {
|
|
59
61
|
enableSoftDelete: true,
|
|
@@ -55,7 +55,12 @@ let SysConfigMangeApi = class SysConfigMangeApi extends BaseApiController_1.Base
|
|
|
55
55
|
if (!id) {
|
|
56
56
|
return common_dto_1.CommonResult.errorRes('id不能为空');
|
|
57
57
|
}
|
|
58
|
-
const
|
|
58
|
+
const sysConfigRes = await this.curdMixService.getQuickCrud({
|
|
59
|
+
sqlDatabase: SystemDbName,
|
|
60
|
+
sqlDbType: SystemDbType,
|
|
61
|
+
sqlTable: SystemTables_1.SystemTables.sys_configs,
|
|
62
|
+
}).findOne({ condition: body.condition });
|
|
63
|
+
const sysConfig = sysConfigRes.row;
|
|
59
64
|
if (!sysConfig) {
|
|
60
65
|
return common_dto_1.CommonResult.errorRes('配置项不存在');
|
|
61
66
|
}
|
|
@@ -50,9 +50,14 @@ let UserAccountManageApi = class UserAccountManageApi extends BaseApiController_
|
|
|
50
50
|
if (!id) {
|
|
51
51
|
return common_dto_1.CommonResult.errorRes('id不能为空');
|
|
52
52
|
}
|
|
53
|
-
const
|
|
53
|
+
const userAccountInfoRes = await this.curdMixService.getQuickCrud({
|
|
54
|
+
sqlDatabase: SystemDbName,
|
|
55
|
+
sqlDbType: SystemDbType,
|
|
56
|
+
sqlTable: SystemTables_1.SystemTables.sys_user_account,
|
|
57
|
+
}).findUniqueOne({
|
|
54
58
|
condition: body.condition
|
|
55
|
-
}
|
|
59
|
+
});
|
|
60
|
+
const userAccountInfo = userAccountInfoRes.row;
|
|
56
61
|
if (!userAccountInfo) {
|
|
57
62
|
return common_dto_1.CommonResult.errorRes('用户信息不存在');
|
|
58
63
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export * from './service/curd/CurdMixByWorkbenchService';
|
|
|
70
70
|
export * from './service/curd/CurdMixService';
|
|
71
71
|
export * from './service/curd/CurdMixUtils';
|
|
72
72
|
export * from './service/curd/CurdProService';
|
|
73
|
-
export * from './
|
|
73
|
+
export * from './libs/crud-pro-quick';
|
|
74
74
|
export * from './service/flow/FlowConfigService';
|
|
75
75
|
export * from './service/flow/FlowInstanceService';
|
|
76
76
|
export * from './service/flow/FlowInstanceCrudService';
|
|
@@ -87,7 +87,6 @@ export * from './models/contextLogger';
|
|
|
87
87
|
export * from './models/devops';
|
|
88
88
|
export * from './models/SystemTables';
|
|
89
89
|
export * from './models/AsyncTaskModel';
|
|
90
|
-
export * from './models/StandardColumns';
|
|
91
90
|
export * from './schedule/index';
|
|
92
91
|
export * from './libs/utils/common-dto';
|
|
93
92
|
export * from './libs/utils/crypto-utils';
|
|
@@ -110,4 +109,5 @@ export * from './libs/crud-pro/models/RequestCfgModel';
|
|
|
110
109
|
export * from './libs/crud-pro/models/SqlSegArg';
|
|
111
110
|
export * from './libs/crud-pro/models/ResModel';
|
|
112
111
|
export * from './libs/crud-sharding/index';
|
|
112
|
+
export * from './libs/crud-pro-quick/index';
|
|
113
113
|
export * from './libs/global-config/global-config';
|
package/dist/index.js
CHANGED
|
@@ -88,7 +88,7 @@ __exportStar(require("./service/curd/CurdMixByWorkbenchService"), exports);
|
|
|
88
88
|
__exportStar(require("./service/curd/CurdMixService"), exports);
|
|
89
89
|
__exportStar(require("./service/curd/CurdMixUtils"), exports);
|
|
90
90
|
__exportStar(require("./service/curd/CurdProService"), exports);
|
|
91
|
-
__exportStar(require("./
|
|
91
|
+
__exportStar(require("./libs/crud-pro-quick"), exports);
|
|
92
92
|
__exportStar(require("./service/flow/FlowConfigService"), exports);
|
|
93
93
|
__exportStar(require("./service/flow/FlowInstanceService"), exports);
|
|
94
94
|
__exportStar(require("./service/flow/FlowInstanceCrudService"), exports);
|
|
@@ -105,7 +105,6 @@ __exportStar(require("./models/contextLogger"), exports);
|
|
|
105
105
|
__exportStar(require("./models/devops"), exports);
|
|
106
106
|
__exportStar(require("./models/SystemTables"), exports);
|
|
107
107
|
__exportStar(require("./models/AsyncTaskModel"), exports);
|
|
108
|
-
__exportStar(require("./models/StandardColumns"), exports);
|
|
109
108
|
__exportStar(require("./schedule/index"), exports);
|
|
110
109
|
__exportStar(require("./libs/utils/common-dto"), exports);
|
|
111
110
|
__exportStar(require("./libs/utils/crypto-utils"), exports);
|
|
@@ -128,4 +127,5 @@ __exportStar(require("./libs/crud-pro/models/RequestCfgModel"), exports);
|
|
|
128
127
|
__exportStar(require("./libs/crud-pro/models/SqlSegArg"), exports);
|
|
129
128
|
__exportStar(require("./libs/crud-pro/models/ResModel"), exports);
|
|
130
129
|
__exportStar(require("./libs/crud-sharding/index"), exports);
|
|
130
|
+
__exportStar(require("./libs/crud-pro-quick/index"), exports);
|
|
131
131
|
__exportStar(require("./libs/global-config/global-config"), exports);
|
|
@@ -1,21 +1,36 @@
|
|
|
1
|
-
import { ICrudProCfg, ILogger, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery, IVisitor } from './interfaces';
|
|
1
|
+
import { ICrudProCfg, ILogger, IRequestCfgModel, IRequestModel, ISqlCfgModel, ITableListResult, ITableNamesOptions, ITableNamesQuery, IVisitor, ExecuteSQLResult } from './interfaces';
|
|
2
2
|
import { ExecuteContext } from './models/ExecuteContext';
|
|
3
3
|
import { Transaction } from './models/Transaction';
|
|
4
4
|
import { IExecuteContextFunc } from './models/ExecuteContextFunc';
|
|
5
5
|
declare class CrudPro {
|
|
6
6
|
private readonly executeContext;
|
|
7
7
|
private readonly serviceHub;
|
|
8
|
+
/** 标记是否已被使用(防止重复使用导致状态污染) */
|
|
9
|
+
private _isUsed;
|
|
10
|
+
/** 标记是否正在执行中(防止并发调用) */
|
|
11
|
+
private _isExecuting;
|
|
8
12
|
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* 检查是否可以开始执行
|
|
15
|
+
* @throws 如果已使用或正在执行中则抛出异常
|
|
16
|
+
*/
|
|
17
|
+
private checkAndMarkExecuting;
|
|
18
|
+
/**
|
|
19
|
+
* 标记执行完成
|
|
20
|
+
*/
|
|
21
|
+
private markExecutionComplete;
|
|
9
22
|
set transaction(transaction: Transaction);
|
|
10
23
|
set logger(logger: ILogger);
|
|
11
24
|
set visitor(visitor: IVisitor);
|
|
25
|
+
getVisitor(): IVisitor;
|
|
12
26
|
set contextFunc(contextFunc: IExecuteContextFunc);
|
|
13
27
|
set contextCfg(contextCfg: ICrudProCfg);
|
|
14
28
|
/**
|
|
15
29
|
* 直接执行一个SQL
|
|
16
30
|
* @param sqlCfgModel
|
|
31
|
+
* @returns 返回未被包装的数据库原始结果(根据 resPicker 配置返回不同类型,无 {code, data, message} 包装层)
|
|
17
32
|
*/
|
|
18
|
-
executeSQL(sqlCfgModel: ISqlCfgModel): Promise<
|
|
33
|
+
executeSQL(sqlCfgModel: ISqlCfgModel): Promise<ExecuteSQLResult>;
|
|
19
34
|
/**
|
|
20
35
|
* 从DB中读取配置
|
|
21
36
|
* @param reqJson
|
|
@@ -28,6 +43,12 @@ declare class CrudPro {
|
|
|
28
43
|
* @param cfgJson
|
|
29
44
|
*/
|
|
30
45
|
executeCrudByCfg(reqJson: IRequestModel, cfgJson: IRequestCfgModel): Promise<ExecuteContext>;
|
|
46
|
+
/**
|
|
47
|
+
* 内部执行方法(不含检查逻辑,供内部调用)
|
|
48
|
+
* @param reqJson
|
|
49
|
+
* @param cfgJson
|
|
50
|
+
*/
|
|
51
|
+
private executeCrudByCfgInternal;
|
|
31
52
|
getCachedCfgByMethod(method: string, isEnableCache: boolean): Promise<IRequestCfgModel>;
|
|
32
53
|
getAllTableInfos(query: ITableNamesQuery, options?: ITableNamesOptions): Promise<ITableListResult>;
|
|
33
54
|
/**
|
|
@@ -10,9 +10,35 @@ const MixinUtils_1 = require("./utils/MixinUtils");
|
|
|
10
10
|
const keys_1 = require("./models/keys");
|
|
11
11
|
class CrudPro {
|
|
12
12
|
constructor() {
|
|
13
|
+
/** 标记是否已被使用(防止重复使用导致状态污染) */
|
|
14
|
+
this._isUsed = false;
|
|
15
|
+
/** 标记是否正在执行中(防止并发调用) */
|
|
16
|
+
this._isExecuting = false;
|
|
13
17
|
this.executeContext = new ExecuteContext_1.ExecuteContext();
|
|
14
18
|
this.serviceHub = new CurdProServiceHub_1.CurdProServiceHub(this.executeContext);
|
|
15
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 检查是否可以开始执行
|
|
22
|
+
* @throws 如果已使用或正在执行中则抛出异常
|
|
23
|
+
*/
|
|
24
|
+
checkAndMarkExecuting() {
|
|
25
|
+
if (this._isUsed) {
|
|
26
|
+
throw new Error('[CrudPro] 此实例已被使用,不能重复使用。' +
|
|
27
|
+
'每次操作请创建新的 CrudPro 实例,可通过 curdProService.getCrudPro() 或工厂函数获取。');
|
|
28
|
+
}
|
|
29
|
+
if (this._isExecuting) {
|
|
30
|
+
throw new Error('[CrudPro] 此实例正在执行中,不能并发调用。' +
|
|
31
|
+
'请等待当前操作完成后再进行下一次调用,或创建新的实例。');
|
|
32
|
+
}
|
|
33
|
+
this._isExecuting = true;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 标记执行完成
|
|
37
|
+
*/
|
|
38
|
+
markExecutionComplete() {
|
|
39
|
+
this._isExecuting = false;
|
|
40
|
+
this._isUsed = true;
|
|
41
|
+
}
|
|
16
42
|
// 必填
|
|
17
43
|
set transaction(transaction) {
|
|
18
44
|
this.executeContext.setTransaction(transaction);
|
|
@@ -25,6 +51,10 @@ class CrudPro {
|
|
|
25
51
|
set visitor(visitor) {
|
|
26
52
|
this.executeContext.setVisitor(visitor);
|
|
27
53
|
}
|
|
54
|
+
// 必填
|
|
55
|
+
getVisitor() {
|
|
56
|
+
return this.executeContext.getVisitor();
|
|
57
|
+
}
|
|
28
58
|
set contextFunc(contextFunc) {
|
|
29
59
|
contextFunc.setExecuteContext(this.executeContext);
|
|
30
60
|
this.executeContext.contextFunc = contextFunc;
|
|
@@ -35,8 +65,10 @@ class CrudPro {
|
|
|
35
65
|
/**
|
|
36
66
|
* 直接执行一个SQL
|
|
37
67
|
* @param sqlCfgModel
|
|
68
|
+
* @returns 返回未被包装的数据库原始结果(根据 resPicker 配置返回不同类型,无 {code, data, message} 包装层)
|
|
38
69
|
*/
|
|
39
70
|
async executeSQL(sqlCfgModel) {
|
|
71
|
+
this.checkAndMarkExecuting();
|
|
40
72
|
const RES_NAME = 'executeResult';
|
|
41
73
|
const sqlCfgModel2 = {
|
|
42
74
|
resName: RES_NAME,
|
|
@@ -53,8 +85,13 @@ class CrudPro {
|
|
|
53
85
|
sqlDatabase: sqlCfgModel.sqlDatabase,
|
|
54
86
|
sqlCfgList: [sqlCfgModel2],
|
|
55
87
|
};
|
|
56
|
-
|
|
57
|
-
|
|
88
|
+
try {
|
|
89
|
+
const ss = await this.executeCrudByCfgInternal({}, cfgModel);
|
|
90
|
+
return ss.getResModelItem(RES_NAME);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
this.markExecutionComplete();
|
|
94
|
+
}
|
|
58
95
|
}
|
|
59
96
|
/**
|
|
60
97
|
* 从DB中读取配置
|
|
@@ -74,6 +111,20 @@ class CrudPro {
|
|
|
74
111
|
* @param cfgJson
|
|
75
112
|
*/
|
|
76
113
|
async executeCrudByCfg(reqJson, cfgJson) {
|
|
114
|
+
this.checkAndMarkExecuting();
|
|
115
|
+
try {
|
|
116
|
+
return await this.executeCrudByCfgInternal(reqJson, cfgJson);
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
this.markExecutionComplete();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 内部执行方法(不含检查逻辑,供内部调用)
|
|
124
|
+
* @param reqJson
|
|
125
|
+
* @param cfgJson
|
|
126
|
+
*/
|
|
127
|
+
async executeCrudByCfgInternal(reqJson, cfgJson) {
|
|
77
128
|
const logger = this.executeContext.getLogger();
|
|
78
129
|
logger.info('CurdPro executeCrudByCfg', cfgJson);
|
|
79
130
|
// 在执行之前可以根据业务需要修改需要执行的内容。
|
|
@@ -45,7 +45,7 @@ export interface IPoolConnectionClient {
|
|
|
45
45
|
export interface IRequestModel {
|
|
46
46
|
method?: string;
|
|
47
47
|
columns?: string | string[];
|
|
48
|
-
condition?:
|
|
48
|
+
condition?: IRequestCondition;
|
|
49
49
|
data?: Record<string, any> | Record<string, any>[];
|
|
50
50
|
orderBy?: string | IOrderByItem[];
|
|
51
51
|
limit?: number;
|
|
@@ -54,21 +54,42 @@ export interface IRequestModel {
|
|
|
54
54
|
pageNo?: number;
|
|
55
55
|
}
|
|
56
56
|
declare type IBasicType = boolean | string | number;
|
|
57
|
+
/**
|
|
58
|
+
* 比较操作符条件
|
|
59
|
+
* 支持 MongoDB 风格的所有查询操作符
|
|
60
|
+
*/
|
|
57
61
|
export interface ICompareCondition {
|
|
58
|
-
$
|
|
59
|
-
$gte?: IBasicType;
|
|
62
|
+
$ne?: IBasicType;
|
|
60
63
|
$lt?: IBasicType;
|
|
61
64
|
$lte?: IBasicType;
|
|
62
|
-
$
|
|
63
|
-
$
|
|
64
|
-
$
|
|
65
|
-
$
|
|
66
|
-
$
|
|
67
|
-
$
|
|
68
|
-
$
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
$gt?: IBasicType;
|
|
66
|
+
$gte?: IBasicType;
|
|
67
|
+
$in?: IBasicType[];
|
|
68
|
+
$nin?: IBasicType[];
|
|
69
|
+
$range?: [number, number];
|
|
70
|
+
$like?: string;
|
|
71
|
+
$notLike?: string;
|
|
72
|
+
$likeInclude?: string;
|
|
73
|
+
$notLikeInclude?: string;
|
|
74
|
+
$match?: string;
|
|
75
|
+
$matchBool?: string | boolean;
|
|
76
|
+
$null?: boolean;
|
|
77
|
+
$notNull?: boolean;
|
|
78
|
+
$jsonArrayContains?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 逻辑操作符条件
|
|
82
|
+
*/
|
|
83
|
+
export interface ILogicalCondition {
|
|
71
84
|
$or?: IRequestCondition[];
|
|
85
|
+
$and?: IRequestCondition[];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 查询条件类型
|
|
89
|
+
* 支持字段值直接匹配或比较操作符
|
|
90
|
+
* 支持 $or, $and 逻辑组合
|
|
91
|
+
*/
|
|
92
|
+
export interface IRequestCondition extends Record<string, IBasicType | ICompareCondition | ILogicalCondition | IRequestCondition[] | undefined>, ILogicalCondition {
|
|
72
93
|
}
|
|
73
94
|
/**
|
|
74
95
|
* 用户基本信息
|
|
@@ -139,6 +160,55 @@ export interface ISqlCfgModel extends IBaseCfgModel {
|
|
|
139
160
|
executeSqlArgs?: any[];
|
|
140
161
|
crudType?: string;
|
|
141
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* executeSQL 的返回结果类型说明(未被包装的直接结果)
|
|
165
|
+
*
|
|
166
|
+
* 注意:executeSQL 返回的是数据库查询的原始结果,没有 {code, data, message} 包装层。
|
|
167
|
+
* 返回类型取决于 resPicker 配置,请根据实际 SQL 类型选择合适的类型断言。
|
|
168
|
+
*
|
|
169
|
+
* 使用示例:
|
|
170
|
+
* // 查询列表 - 返回数组
|
|
171
|
+
* const rows = await executeSQL({ executeSql: 'SELECT * FROM users', resPicker: KeysOfSqlResPicker.RESULT_ROWS }) as ExecuteSQLRowResult<User>;
|
|
172
|
+
*
|
|
173
|
+
* // 查询单行 - 返回对象或null
|
|
174
|
+
* const user = await executeSQL({ executeSql: 'SELECT * FROM users WHERE id=?', executeSqlArgs: [1], resPicker: KeysOfSqlResPicker.RESULT_FIRST_ROW }) as ExecuteSQLSingleResult<User>;
|
|
175
|
+
*
|
|
176
|
+
* // 查询总数 - 返回数字
|
|
177
|
+
* const count = await executeSQL({ executeSql: 'SELECT COUNT(*) as total_count FROM users', resPicker: KeysOfSqlResPicker.RESULT_TOTAL_COUNT }) as ExecuteSQLCountResult;
|
|
178
|
+
*
|
|
179
|
+
* // 判断存在 - 返回布尔
|
|
180
|
+
* const exists = await executeSQL({ executeSql: 'SELECT 1 as is_exist FROM users WHERE id=?', executeSqlArgs: [1], resPicker: KeysOfSqlResPicker.RESULT_IS_EXIST }) as ExecuteSQLExistResult;
|
|
181
|
+
*
|
|
182
|
+
* // 增删改操作 - 返回受影响行数信息
|
|
183
|
+
* const result = await executeSQL({ executeSql: 'INSERT INTO users(name) VALUES(?)', executeSqlArgs: ['张三'], resPicker: KeysOfSqlResPicker.UPDATE_RESULT }) as ExecuteSQLUpdateResult;
|
|
184
|
+
*/
|
|
185
|
+
/** 查询多行时的返回类型(默认情况):原始数据行数组,无包装 */
|
|
186
|
+
export declare type ExecuteSQLRowsResult<T = Record<string, any>> = T[];
|
|
187
|
+
/** 查询单行时的返回类型:首行对象或null,无包装 */
|
|
188
|
+
export declare type ExecuteSQLSingleResult<T = Record<string, any>> = T | null;
|
|
189
|
+
/** 查询数量时的返回类型:数字,无包装 */
|
|
190
|
+
export declare type ExecuteSQLCountResult = number;
|
|
191
|
+
/** 判断存在时的返回类型:布尔值,无包装 */
|
|
192
|
+
export declare type ExecuteSQLExistResult = boolean;
|
|
193
|
+
/** 增删改操作时的返回类型:包含 insertId 和 affectedRows,无包装 */
|
|
194
|
+
export interface ExecuteSQLUpdateResult {
|
|
195
|
+
/** 插入记录的自增ID(仅INSERT操作有效) */
|
|
196
|
+
insertId: any;
|
|
197
|
+
/** 受影响的行数 */
|
|
198
|
+
affectedRows: number;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* executeSQL 的通用返回类型(未被包装的直接结果)
|
|
202
|
+
* 根据 resPicker 的不同配置,实际返回类型可能是:
|
|
203
|
+
* - ExecuteSQLRowResult<T> : 多行数据(默认)
|
|
204
|
+
* - ExecuteSQLSingleResult<T> : 单行数据或null
|
|
205
|
+
* - ExecuteSQLCountResult : 数字
|
|
206
|
+
* - ExecuteSQLExistResult : 布尔值
|
|
207
|
+
* - ExecuteSQLUpdateResult : 增删改结果
|
|
208
|
+
*
|
|
209
|
+
* 警告:此类型为联合类型,使用时建议根据实际 resPicker 进行类型断言以获得精确类型提示
|
|
210
|
+
*/
|
|
211
|
+
export declare type ExecuteSQLResult<T = Record<string, any>> = ExecuteSQLRowsResult<T> | ExecuteSQLSingleResult<T> | ExecuteSQLCountResult | ExecuteSQLExistResult | ExecuteSQLUpdateResult;
|
|
142
212
|
/**
|
|
143
213
|
* 自定义校验函数。如果不正确请抛出异常。{code:'xxx',message:'xxx'}
|
|
144
214
|
*/
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ResModelAffected } from './ResModel';
|
|
2
|
+
import { ExecuteContext } from './ExecuteContext';
|
|
3
|
+
/**
|
|
4
|
+
* 结果基类的辅助定位信息
|
|
5
|
+
* 用于错误排查和日志记录
|
|
6
|
+
*/
|
|
7
|
+
export interface CrudResultDebugInfo {
|
|
8
|
+
/** 数据库名 */
|
|
9
|
+
sqlDatabase?: string;
|
|
10
|
+
/** 表名 */
|
|
11
|
+
sqlTable?: string;
|
|
12
|
+
/** 方法名(配置中的 method 字段) */
|
|
13
|
+
method?: string;
|
|
14
|
+
/** 查询条件(用于定位问题) */
|
|
15
|
+
condition?: Record<string, any>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 结果基类
|
|
19
|
+
*
|
|
20
|
+
* 使用 ES2022 私有字段 #rawContext 存储 ExecuteContext 引用。
|
|
21
|
+
* ES2022 私有字段特性:JSON.stringify 不会序列化 # 开头的私有字段。
|
|
22
|
+
* 因此结果对象可直接返回给 API 前端,自动过滤掉内部上下文。
|
|
23
|
+
*
|
|
24
|
+
* Node.js 兼容性:Node.js 14.6+ 完全支持 ES2022 私有字段。
|
|
25
|
+
*/
|
|
26
|
+
declare abstract class CrudResultBase {
|
|
27
|
+
#private;
|
|
28
|
+
/** 辅助定位信息,用于错误排查 */
|
|
29
|
+
readonly debugInfo: CrudResultDebugInfo;
|
|
30
|
+
constructor(rawContext: ExecuteContext, debugInfo?: CrudResultDebugInfo);
|
|
31
|
+
getRawContext(): ExecuteContext;
|
|
32
|
+
/**
|
|
33
|
+
* 生成带辅助定位信息的错误消息
|
|
34
|
+
* @param baseMessage 基础错误信息
|
|
35
|
+
* @returns 包含定位信息的完整错误消息
|
|
36
|
+
*/
|
|
37
|
+
protected buildErrorMessage(baseMessage: string): string;
|
|
38
|
+
}
|
|
39
|
+
/** 写操作结果(INSERT/UPDATE/DELETE) */
|
|
40
|
+
declare class CrudWriteResult extends CrudResultBase {
|
|
41
|
+
readonly affectedRows: number;
|
|
42
|
+
readonly insertId?: string | number;
|
|
43
|
+
constructor(data: {
|
|
44
|
+
affectedRows: number;
|
|
45
|
+
insertId?: string | number;
|
|
46
|
+
rawContext: ExecuteContext;
|
|
47
|
+
debugInfo?: CrudResultDebugInfo;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** 单条查询结果 */
|
|
51
|
+
declare class CrudQueryOneResult<T = Record<string, any>> extends CrudResultBase {
|
|
52
|
+
readonly row: T | null;
|
|
53
|
+
readonly found: boolean;
|
|
54
|
+
constructor(data: {
|
|
55
|
+
row: T | null;
|
|
56
|
+
rawContext: ExecuteContext;
|
|
57
|
+
debugInfo?: CrudResultDebugInfo;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** 列表查询结果 */
|
|
61
|
+
declare class CrudQueryListResult<T = Record<string, any>> extends CrudResultBase {
|
|
62
|
+
readonly rows: T[];
|
|
63
|
+
readonly count: number;
|
|
64
|
+
constructor(data: {
|
|
65
|
+
rows: T[];
|
|
66
|
+
rawContext: ExecuteContext;
|
|
67
|
+
debugInfo?: CrudResultDebugInfo;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/** 分页查询结果 */
|
|
71
|
+
declare class CrudQueryPageResult<T = Record<string, any>> extends CrudResultBase {
|
|
72
|
+
readonly rows: T[];
|
|
73
|
+
readonly totalCount: number;
|
|
74
|
+
readonly count: number;
|
|
75
|
+
constructor(data: {
|
|
76
|
+
rows: T[];
|
|
77
|
+
totalCount: number;
|
|
78
|
+
rawContext: ExecuteContext;
|
|
79
|
+
debugInfo?: CrudResultDebugInfo;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** 存在性判断结果 */
|
|
83
|
+
declare class CrudExistResult extends CrudResultBase {
|
|
84
|
+
readonly exists: boolean;
|
|
85
|
+
constructor(data: {
|
|
86
|
+
exists: boolean;
|
|
87
|
+
rawContext: ExecuteContext;
|
|
88
|
+
debugInfo?: CrudResultDebugInfo;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/** 计数结果 */
|
|
92
|
+
declare class CrudCountResult extends CrudResultBase {
|
|
93
|
+
readonly count: number;
|
|
94
|
+
constructor(data: {
|
|
95
|
+
count: number;
|
|
96
|
+
rawContext: ExecuteContext;
|
|
97
|
+
debugInfo?: CrudResultDebugInfo;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/** InsertOrUpdate 结果 */
|
|
101
|
+
declare class CrudUpsertResult extends CrudResultBase {
|
|
102
|
+
readonly affected?: ResModelAffected;
|
|
103
|
+
readonly insertAffected?: ResModelAffected;
|
|
104
|
+
readonly updateAffected?: ResModelAffected;
|
|
105
|
+
readonly isExist: boolean;
|
|
106
|
+
constructor(data: {
|
|
107
|
+
affected?: ResModelAffected;
|
|
108
|
+
insertAffected?: ResModelAffected;
|
|
109
|
+
updateAffected?: ResModelAffected;
|
|
110
|
+
isExist: boolean;
|
|
111
|
+
rawContext: ExecuteContext;
|
|
112
|
+
debugInfo?: CrudResultDebugInfo;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export { CrudResultBase, CrudWriteResult, CrudQueryOneResult, CrudQueryListResult, CrudQueryPageResult, CrudExistResult, CrudCountResult, CrudUpsertResult, };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _CrudResultBase_rawContext;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CrudUpsertResult = exports.CrudCountResult = exports.CrudExistResult = exports.CrudQueryPageResult = exports.CrudQueryListResult = exports.CrudQueryOneResult = exports.CrudWriteResult = exports.CrudResultBase = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* 结果基类
|
|
18
|
+
*
|
|
19
|
+
* 使用 ES2022 私有字段 #rawContext 存储 ExecuteContext 引用。
|
|
20
|
+
* ES2022 私有字段特性:JSON.stringify 不会序列化 # 开头的私有字段。
|
|
21
|
+
* 因此结果对象可直接返回给 API 前端,自动过滤掉内部上下文。
|
|
22
|
+
*
|
|
23
|
+
* Node.js 兼容性:Node.js 14.6+ 完全支持 ES2022 私有字段。
|
|
24
|
+
*/
|
|
25
|
+
class CrudResultBase {
|
|
26
|
+
constructor(rawContext, debugInfo) {
|
|
27
|
+
_CrudResultBase_rawContext.set(this, void 0);
|
|
28
|
+
__classPrivateFieldSet(this, _CrudResultBase_rawContext, rawContext, "f");
|
|
29
|
+
this.debugInfo = debugInfo || {};
|
|
30
|
+
}
|
|
31
|
+
getRawContext() {
|
|
32
|
+
return __classPrivateFieldGet(this, _CrudResultBase_rawContext, "f");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 生成带辅助定位信息的错误消息
|
|
36
|
+
* @param baseMessage 基础错误信息
|
|
37
|
+
* @returns 包含定位信息的完整错误消息
|
|
38
|
+
*/
|
|
39
|
+
buildErrorMessage(baseMessage) {
|
|
40
|
+
const parts = [baseMessage];
|
|
41
|
+
if (this.debugInfo.sqlDatabase) {
|
|
42
|
+
parts.push(`数据库: ${this.debugInfo.sqlDatabase}`);
|
|
43
|
+
}
|
|
44
|
+
if (this.debugInfo.sqlTable) {
|
|
45
|
+
parts.push(`表: ${this.debugInfo.sqlTable}`);
|
|
46
|
+
}
|
|
47
|
+
if (this.debugInfo.method) {
|
|
48
|
+
parts.push(`方法: ${this.debugInfo.method}`);
|
|
49
|
+
}
|
|
50
|
+
if (this.debugInfo.condition) {
|
|
51
|
+
try {
|
|
52
|
+
parts.push(`条件: ${JSON.stringify(this.debugInfo.condition)}`);
|
|
53
|
+
}
|
|
54
|
+
catch (_a) {
|
|
55
|
+
parts.push(`条件: [无法序列化]`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return parts.join(' | ');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.CrudResultBase = CrudResultBase;
|
|
62
|
+
_CrudResultBase_rawContext = new WeakMap();
|
|
63
|
+
/** 写操作结果(INSERT/UPDATE/DELETE) */
|
|
64
|
+
class CrudWriteResult extends CrudResultBase {
|
|
65
|
+
constructor(data) {
|
|
66
|
+
super(data.rawContext, data.debugInfo);
|
|
67
|
+
this.affectedRows = data.affectedRows;
|
|
68
|
+
this.insertId = data.insertId;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.CrudWriteResult = CrudWriteResult;
|
|
72
|
+
/** 单条查询结果 */
|
|
73
|
+
class CrudQueryOneResult extends CrudResultBase {
|
|
74
|
+
constructor(data) {
|
|
75
|
+
super(data.rawContext, data.debugInfo);
|
|
76
|
+
this.row = data.row;
|
|
77
|
+
this.found = (this.row !== null && this.row !== undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.CrudQueryOneResult = CrudQueryOneResult;
|
|
81
|
+
/** 列表查询结果 */
|
|
82
|
+
class CrudQueryListResult extends CrudResultBase {
|
|
83
|
+
constructor(data) {
|
|
84
|
+
super(data.rawContext, data.debugInfo);
|
|
85
|
+
this.rows = data.rows || [];
|
|
86
|
+
this.count = this.rows.length;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.CrudQueryListResult = CrudQueryListResult;
|
|
90
|
+
/** 分页查询结果 */
|
|
91
|
+
class CrudQueryPageResult extends CrudResultBase {
|
|
92
|
+
constructor(data) {
|
|
93
|
+
super(data.rawContext, data.debugInfo);
|
|
94
|
+
this.rows = data.rows || [];
|
|
95
|
+
this.totalCount = data.totalCount;
|
|
96
|
+
this.count = this.rows.length;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.CrudQueryPageResult = CrudQueryPageResult;
|
|
100
|
+
/** 存在性判断结果 */
|
|
101
|
+
class CrudExistResult extends CrudResultBase {
|
|
102
|
+
constructor(data) {
|
|
103
|
+
super(data.rawContext, data.debugInfo);
|
|
104
|
+
this.exists = data.exists;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.CrudExistResult = CrudExistResult;
|
|
108
|
+
/** 计数结果 */
|
|
109
|
+
class CrudCountResult extends CrudResultBase {
|
|
110
|
+
constructor(data) {
|
|
111
|
+
super(data.rawContext, data.debugInfo);
|
|
112
|
+
this.count = data.count;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.CrudCountResult = CrudCountResult;
|
|
116
|
+
/** InsertOrUpdate 结果 */
|
|
117
|
+
class CrudUpsertResult extends CrudResultBase {
|
|
118
|
+
constructor(data) {
|
|
119
|
+
super(data.rawContext, data.debugInfo);
|
|
120
|
+
this.affected = data.affected;
|
|
121
|
+
this.insertAffected = data.insertAffected;
|
|
122
|
+
this.updateAffected = data.updateAffected;
|
|
123
|
+
this.isExist = data.isExist;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.CrudUpsertResult = CrudUpsertResult;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IOrderByItem, IRequestModel, IVisitor } from '../interfaces';
|
|
1
|
+
import { IOrderByItem, IRequestModel, IVisitor, IRequestCondition } from '../interfaces';
|
|
2
2
|
declare class RequestModel {
|
|
3
3
|
visitor: IVisitor;
|
|
4
4
|
method: string;
|
|
5
5
|
columns?: string[];
|
|
6
|
-
condition?:
|
|
6
|
+
condition?: IRequestCondition;
|
|
7
7
|
data?: Record<string, any> | Record<string, any>[];
|
|
8
8
|
limit: number;
|
|
9
9
|
offset: number;
|
|
@@ -16,6 +16,7 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
|
|
|
16
16
|
async executeSqlCfgModels() {
|
|
17
17
|
const exeCtx = this.getExecuteContext();
|
|
18
18
|
const sqlCfgModels = exeCtx.getSqlCfgModels();
|
|
19
|
+
console.log("CrudProExecuteSqlService===> " + JSON.stringify(sqlCfgModels));
|
|
19
20
|
for (let i = 0; i < sqlCfgModels.length; i++) {
|
|
20
21
|
const sqlCfgModel = sqlCfgModels[i];
|
|
21
22
|
const checkResult = this.executeSqlCfgModelPreCheck(sqlCfgModel);
|
|
@@ -73,9 +74,42 @@ class CrudProExecuteSqlService extends CrudProServiceBase_1.CrudProServiceBase {
|
|
|
73
74
|
// 允许空SQL,没有需要执行的正常。
|
|
74
75
|
return false;
|
|
75
76
|
}
|
|
77
|
+
const errorMsg = `禁止执行的SQL: ${sqlCfgModel.executeSql}`;
|
|
76
78
|
if (keys_1.KeyOfCrudTypes.NOT_CRUD === crudType) {
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
+
// 在 isNativeSQL 模式下,允许特定的 DDL 操作(CREATE TABLE、CREATE INDEX 等),但禁止 DROP TABLE
|
|
80
|
+
if (sqlCfgModel.isNativeSQL) {
|
|
81
|
+
// 禁止的 DDL 操作(破坏性操作)
|
|
82
|
+
const forbiddenPatterns = [
|
|
83
|
+
/^\s*DROP\s+TABLE/i,
|
|
84
|
+
/^\s*DROP\s+DATABASE/i,
|
|
85
|
+
/^\s*DROP\s+SCHEMA/i,
|
|
86
|
+
/^\s*TRUNCATE\s+TABLE/i,
|
|
87
|
+
];
|
|
88
|
+
for (const pattern of forbiddenPatterns) {
|
|
89
|
+
if (pattern.test(sqlCfgModel.executeSql)) {
|
|
90
|
+
throw new exceptions_1.CommonException(exceptions_1.Exceptions.CFG_NOT_SUPPORT_THE_SQL, errorMsg);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 允许的 DDL 操作白名单
|
|
94
|
+
const allowedPatterns = [
|
|
95
|
+
/^\s*CREATE\s+TABLE/i,
|
|
96
|
+
/^\s*CREATE\s+INDEX/i,
|
|
97
|
+
/^\s*CREATE\s+UNIQUE\s+INDEX/i,
|
|
98
|
+
/^\s*ALTER\s+TABLE/i,
|
|
99
|
+
];
|
|
100
|
+
const isAllowed = allowedPatterns.some(pattern => pattern.test(sqlCfgModel.executeSql));
|
|
101
|
+
if (isAllowed) {
|
|
102
|
+
// 允许的 DDL 操作,继续执行后续校验
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// 非允许的 DDL 操作,仍然抛出异常
|
|
106
|
+
throw new exceptions_1.CommonException(exceptions_1.Exceptions.CFG_NOT_SUPPORT_THE_SQL, errorMsg);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// 非 isNativeSQL 模式下,只支持增删改查,其他语句不支持。
|
|
111
|
+
throw new exceptions_1.CommonException(exceptions_1.Exceptions.CFG_NOT_SUPPORT_THE_SQL, errorMsg);
|
|
112
|
+
}
|
|
79
113
|
}
|
|
80
114
|
// 此SQL不需要执行
|
|
81
115
|
if (!this.isNeedExecute(sqlCfgModel)) {
|