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
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { IRequestCfgModel } from '../../libs/crud-pro/interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* 常用标准表结构字段(6个字段)
|
|
4
|
+
*
|
|
5
|
+
* 用于软删除和审计跟踪:
|
|
6
|
+
* - deleted_at: 删除时间戳,0=未删除
|
|
7
|
+
* - deleted_by: 删除人ID
|
|
8
|
+
* - created_by: 创建人ID
|
|
9
|
+
* - created_at: 创建时间(毫秒时间戳)
|
|
10
|
+
* - modified_by: 修改人ID
|
|
11
|
+
* - modified_at: 修改时间(毫秒时间戳)
|
|
12
|
+
*/
|
|
13
|
+
export interface ICommonStandardColumns {
|
|
14
|
+
deleted_at?: number;
|
|
15
|
+
deleted_by?: string;
|
|
16
|
+
created_by?: string;
|
|
17
|
+
created_at?: number;
|
|
18
|
+
modified_by?: string;
|
|
19
|
+
modified_at?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 扩展的请求配置模型
|
|
23
|
+
*
|
|
24
|
+
* 在 IRequestCfgModel 基础上添加了业务层常用的配置项:
|
|
25
|
+
* - enableStandardUpdateCfg: 启用标准字段自动填充
|
|
26
|
+
* - enableStandardUpdateCfgCondition: 启用标准字段条件注入
|
|
27
|
+
* - enableSoftDelete: 启用软删除
|
|
28
|
+
*/
|
|
29
|
+
export interface IRequestCfgModel2 extends IRequestCfgModel {
|
|
30
|
+
enableStandardUpdateCfg?: boolean | string[];
|
|
31
|
+
enableStandardUpdateCfgCondition?: boolean | string[];
|
|
32
|
+
enableSoftDelete?: boolean;
|
|
33
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { CrudPro } from '../../libs/crud-pro/CrudPro';
|
|
2
|
+
/**
|
|
3
|
+
* CrudPro 工厂函数类型
|
|
4
|
+
* 每次调用返回新的 CrudPro 实例,避免状态污染
|
|
5
|
+
*/
|
|
6
|
+
export declare type CrudProFactory = () => CrudPro;
|
|
1
7
|
/**
|
|
2
8
|
* 分表配置模型
|
|
3
9
|
*
|
|
@@ -56,6 +62,13 @@ export interface IShardingConfig {
|
|
|
56
62
|
* 用于时间分表类型(YEAR/MONTH/DAY),使用时间分表时必填
|
|
57
63
|
*/
|
|
58
64
|
timeColumn?: string;
|
|
65
|
+
/**
|
|
66
|
+
* 主键字段
|
|
67
|
+
* 用于时间分表场景下,当 condition 中包含主键时,时间字段仅用于路由定位分表,
|
|
68
|
+
* 不参与具体表的查询条件(避免时间精度损失导致查询失败)
|
|
69
|
+
* 例如:id, order_id
|
|
70
|
+
*/
|
|
71
|
+
primaryKey?: string;
|
|
59
72
|
/**
|
|
60
73
|
* 自定义分表路由函数
|
|
61
74
|
* 用于 CUSTOM 类型
|
|
@@ -77,8 +90,8 @@ export interface IShardingConfig {
|
|
|
77
90
|
* 适用于时间分表类型(YEAR/MONTH/DAY)。
|
|
78
91
|
*
|
|
79
92
|
* 默认值:
|
|
80
|
-
* - YEAR:
|
|
81
|
-
* - MONTH:
|
|
93
|
+
* - YEAR: 2(最近2年)
|
|
94
|
+
* - MONTH: 3(最近3个月)
|
|
82
95
|
* - DAY: 7(最近7天)
|
|
83
96
|
*
|
|
84
97
|
* @example
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ShardingType = void 0;
|
|
2
4
|
/**
|
|
3
5
|
* 分表配置模型
|
|
4
6
|
*
|
|
@@ -10,8 +12,6 @@
|
|
|
10
12
|
* - HASH: 按哈希分表,如 order_01 ~ order_16
|
|
11
13
|
* - CUSTOM: 自定义分表规则
|
|
12
14
|
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.ShardingType = void 0;
|
|
15
15
|
/**
|
|
16
16
|
* 分表类型
|
|
17
17
|
*/
|
|
@@ -1,30 +1,7 @@
|
|
|
1
|
-
import { CrudPro } from '../../libs/crud-pro/CrudPro';
|
|
2
1
|
import { IRequestModel, IRequestCfgModel } from '../../libs/crud-pro/interfaces';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
/**
|
|
7
|
-
* 智能批量插入结果
|
|
8
|
-
*/
|
|
9
|
-
export interface IShardingSmartBatchInsertResult {
|
|
10
|
-
/** 总插入条数 */
|
|
11
|
-
totalAffected: number;
|
|
12
|
-
/** 各分表插入结果 */
|
|
13
|
-
tableResults: Array<{
|
|
14
|
-
table: string;
|
|
15
|
-
affected: number;
|
|
16
|
-
rowCount: number;
|
|
17
|
-
}>;
|
|
18
|
-
/** 涉及的分表数量 */
|
|
19
|
-
tableCount: number;
|
|
20
|
-
/** 是否全部成功 */
|
|
21
|
-
success: boolean;
|
|
22
|
-
/** 错误信息(如果有) */
|
|
23
|
-
errors: Array<{
|
|
24
|
-
table: string;
|
|
25
|
-
error: Error;
|
|
26
|
-
}>;
|
|
27
|
-
}
|
|
2
|
+
import { IShardingConfig, CrudProFactory } from './ShardingConfig';
|
|
3
|
+
import { CrudWriteResult, CrudQueryOneResult, CrudQueryListResult, CrudQueryPageResult, CrudExistResult, CrudCountResult, CrudUpsertResult } from '../../libs/crud-pro/models/CrudResult';
|
|
4
|
+
import { ShardingBatchInsertResult } from './ShardingResult';
|
|
28
5
|
/**
|
|
29
6
|
* 分表 CRUD 操作封装器
|
|
30
7
|
*
|
|
@@ -51,313 +28,181 @@ export interface IShardingSmartBatchInsertResult {
|
|
|
51
28
|
* await sharding.insert({ data: { order_id: '001', amount: 100, created_at: '2024-03-15' } });
|
|
52
29
|
*
|
|
53
30
|
* // 分页查询(自动合并多表结果)
|
|
54
|
-
* const result = await sharding.
|
|
31
|
+
* const result = await sharding.findPage({
|
|
55
32
|
* condition: { created_at: { $gte: '2024-01-01', $lte: '2024-03-31' } },
|
|
56
33
|
* pageNo: 1,
|
|
57
34
|
* pageSize: 10,
|
|
58
35
|
* });
|
|
59
36
|
*/
|
|
60
37
|
export declare class ShardingCrudPro {
|
|
61
|
-
private readonly
|
|
38
|
+
private readonly crudProFactory;
|
|
62
39
|
private readonly config;
|
|
63
40
|
private readonly router;
|
|
64
41
|
private readonly merger;
|
|
65
42
|
private readonly tableCreator;
|
|
66
43
|
private baseCfg;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* 设置基础配置(会应用到所有操作)
|
|
70
|
-
*
|
|
71
|
-
* @param cfg 配置项,如 sqlDatabase、sqlDbType 等
|
|
72
|
-
* @returns this,支持链式调用
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* sharding.setBaseCfg({
|
|
76
|
-
* sqlDatabase: 'mydb',
|
|
77
|
-
* sqlDbType: SqlDbType.mysql,
|
|
78
|
-
* });
|
|
79
|
-
*/
|
|
44
|
+
private enableSoftDelete;
|
|
45
|
+
constructor(crudProFactory: CrudProFactory, config: IShardingConfig);
|
|
80
46
|
setBaseCfg(cfg: Partial<IRequestCfgModel>): this;
|
|
81
|
-
/**
|
|
82
|
-
* 获取分表配置
|
|
83
|
-
*/
|
|
84
47
|
getConfig(): IShardingConfig;
|
|
85
48
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* 根据分表规则自动路由到目标分表。
|
|
89
|
-
* 对于时间分表,需要确保 data 中包含时间字段。
|
|
90
|
-
* 对于哈希/范围分表,需要确保 data 中包含分表字段。
|
|
91
|
-
*
|
|
92
|
-
* 如果目标分表不存在且配置了 autoCreateTable,会自动创建分表。
|
|
93
|
-
*
|
|
94
|
-
* @param reqJson 请求参数,data 为要插入的数据
|
|
95
|
-
* @returns 执行上下文
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* await sharding.insert({
|
|
99
|
-
* data: {
|
|
100
|
-
* order_id: 'ORD001',
|
|
101
|
-
* amount: 100,
|
|
102
|
-
* created_at: '2024-03-15 10:00:00',
|
|
103
|
-
* },
|
|
104
|
-
* });
|
|
105
|
-
*/
|
|
106
|
-
insert(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
107
|
-
/**
|
|
108
|
-
* 批量插入数据(支持跨分表)
|
|
109
|
-
*
|
|
110
|
-
* 自动将数据按分表分组,并行插入到对应的分表。
|
|
111
|
-
*
|
|
112
|
-
* @param reqJson 请求参数,data 为要插入的数据数组
|
|
113
|
-
* @returns 批量插入结果
|
|
114
|
-
*
|
|
115
|
-
* 执行流程:
|
|
116
|
-
* 1. 遍历所有数据,根据分表字段计算目标分表
|
|
117
|
-
* 2. 将数据按分表分组
|
|
118
|
-
* 3. 并行执行各分表的批量插入
|
|
119
|
-
* 4. 汇总结果返回
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* // 数据分布在不同月份的分表
|
|
123
|
-
* const result = await sharding.batchInsert({
|
|
124
|
-
* data: [
|
|
125
|
-
* { order_id: '001', amount: 100, created_at: '2024-01-15' }, // -> t_order_202401
|
|
126
|
-
* { order_id: '002', amount: 200, created_at: '2024-01-20' }, // -> t_order_202401
|
|
127
|
-
* { order_id: '003', amount: 150, created_at: '2024-02-10' }, // -> t_order_202402
|
|
128
|
-
* { order_id: '004', amount: 300, created_at: '2024-03-05' }, // -> t_order_202403
|
|
129
|
-
* ],
|
|
130
|
-
* });
|
|
131
|
-
*
|
|
132
|
-
* console.log(result.totalAffected); // 4
|
|
133
|
-
* console.log(result.tableCount); // 3
|
|
134
|
-
* console.log(result.tableResults);
|
|
135
|
-
* // [
|
|
136
|
-
* // { table: 't_order_202401', affected: 2, rowCount: 2 },
|
|
137
|
-
* // { table: 't_order_202402', affected: 1, rowCount: 1 },
|
|
138
|
-
* // { table: 't_order_202403', affected: 1, rowCount: 1 },
|
|
139
|
-
* // ]
|
|
49
|
+
* 设置是否启用软删除
|
|
50
|
+
* @param enable 是否启用软删除
|
|
140
51
|
*/
|
|
141
|
-
|
|
52
|
+
setEnableSoftDelete(enable: boolean): this;
|
|
53
|
+
insert(reqJson: IRequestModel): Promise<CrudWriteResult>;
|
|
54
|
+
batchInsert(reqJson: IRequestModel): Promise<ShardingBatchInsertResult>;
|
|
55
|
+
update(reqJson: IRequestModel): Promise<CrudWriteResult>;
|
|
56
|
+
delete(reqJson: IRequestModel): Promise<CrudWriteResult>;
|
|
142
57
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* 根据条件中的分表字段自动路由到目标分表。
|
|
58
|
+
* 恢复软删除的记录
|
|
59
|
+
* 将 deleted_at 字段重置为 0,deleted_by 重置为空字符串
|
|
146
60
|
*
|
|
147
|
-
* @param reqJson
|
|
148
|
-
* @returns
|
|
61
|
+
* @param reqJson 请求参数,通过 condition 指定要恢复的记录
|
|
62
|
+
* @returns CrudWriteResult 包含 affectedRows 和 getRawContext()
|
|
149
63
|
*
|
|
150
64
|
* @example
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* data: { amount: 200 },
|
|
154
|
-
* });
|
|
155
|
-
*/
|
|
156
|
-
update(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
157
|
-
/**
|
|
158
|
-
* 删除数据
|
|
65
|
+
* // 恢复指定 ID 的记录
|
|
66
|
+
* await sharding.restore({ condition: { id: 1 } });
|
|
159
67
|
*
|
|
160
|
-
*
|
|
68
|
+
* // 恢复多条记录(使用 $in 操作符)
|
|
69
|
+
* await sharding.restore({ condition: { id: { $in: [1, 2, 3] } } });
|
|
161
70
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
71
|
+
* // 按条件批量恢复记录
|
|
72
|
+
* await sharding.restore({ condition: { status: 'deleted' } });
|
|
164
73
|
*/
|
|
165
|
-
|
|
74
|
+
restore(reqJson: IRequestModel): Promise<CrudWriteResult>;
|
|
75
|
+
insertOrUpdate(reqJson: IRequestModel): Promise<CrudUpsertResult>;
|
|
76
|
+
insertOnDuplicateUpdate(reqJson: IRequestModel): Promise<CrudWriteResult>;
|
|
77
|
+
findOne<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryOneResult<T>>;
|
|
166
78
|
/**
|
|
167
|
-
*
|
|
79
|
+
* 查询唯一单条记录(期望结果为 0 条或 1 条)
|
|
168
80
|
*
|
|
169
|
-
*
|
|
81
|
+
* 与 findOne 不同,此方法会校验查询结果的唯一性:
|
|
82
|
+
* - 如果查到 0 条:返回 row = null
|
|
83
|
+
* - 如果查到 1 条:正常返回
|
|
84
|
+
* - 如果查到多条:抛出异常,包含详细的定位信息(含分表名列表)
|
|
170
85
|
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
|
|
174
|
-
insertOrUpdate(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
175
|
-
/**
|
|
176
|
-
* 插入或更新(ON DUPLICATE KEY UPDATE)
|
|
177
|
-
*
|
|
178
|
-
* 路由逻辑:根据 condition 路由(先查询是否存在)
|
|
86
|
+
* 分表场景的特殊处理:
|
|
87
|
+
* - 单分表:直接查询并校验唯一性
|
|
88
|
+
* - 多分表:顺序查询各分表,累计找到的数量,超过 1 条立即抛异常
|
|
179
89
|
*
|
|
180
90
|
* @param reqJson 请求参数
|
|
181
|
-
* @returns
|
|
182
|
-
|
|
183
|
-
insertOnDuplicateUpdate(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
184
|
-
/**
|
|
185
|
-
* 查询单条记录
|
|
186
|
-
*
|
|
187
|
-
* 如果能根据条件确定单一分表,则查询单表;
|
|
188
|
-
* 否则按顺序查询各分表,返回第一条匹配记录。
|
|
189
|
-
*
|
|
190
|
-
* @param reqJson 请求参数,condition 为查询条件
|
|
191
|
-
* @returns 单条记录,未找到返回 null
|
|
91
|
+
* @returns CrudQueryOneResult 包含 row、found 和 getRawContext()
|
|
92
|
+
* @throws Error 如果查询到多条记录
|
|
192
93
|
*
|
|
193
94
|
* @example
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
* - 必须传 orderBy 参数
|
|
206
|
-
* - orderBy 必须为 timeColumn DESC 或 timeColumn ASC(如 'created_at DESC' / 'created_at ASC')
|
|
207
|
-
*
|
|
208
|
-
* @param reqJson 请求参数
|
|
209
|
-
* @returns 数据列表
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* const orders = await sharding.query({
|
|
213
|
-
* condition: { created_at: { $gte: '2024-01-01', $lte: '2024-03-31' } },
|
|
214
|
-
* orderBy: 'created_at DESC', // 或 'created_at ASC'
|
|
215
|
-
* });
|
|
216
|
-
*/
|
|
217
|
-
query(reqJson: IRequestModel): Promise<any[]>;
|
|
218
|
-
/**
|
|
219
|
-
* 分页查询
|
|
220
|
-
*
|
|
221
|
-
* 自动处理跨分表的分页:
|
|
222
|
-
* 1. 顺序累计查询各分表
|
|
223
|
-
* 2. 截取目标数据(无需排序)
|
|
224
|
-
*
|
|
225
|
-
* 使用约束:
|
|
226
|
-
* - 必须传 orderBy 参数
|
|
227
|
-
* - orderBy 必须为 timeColumn DESC 或 timeColumn ASC(如 'created_at DESC' / 'created_at ASC')
|
|
228
|
-
*
|
|
229
|
-
* @param reqJson 请求参数,包含 pageNo、pageSize 和 orderBy
|
|
230
|
-
* @returns 分页结果,包含 rows 和 total_count
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* const result = await sharding.queryPage({
|
|
234
|
-
* condition: { created_at: { $gte: '2024-01-01', $lte: '2024-03-31' } },
|
|
235
|
-
* pageNo: 1,
|
|
236
|
-
* pageSize: 10,
|
|
237
|
-
* orderBy: 'created_at DESC', // 或 'created_at ASC'
|
|
238
|
-
* });
|
|
239
|
-
* console.log(result.rows, result.total_count);
|
|
240
|
-
*/
|
|
241
|
-
queryPage(reqJson: IRequestModel): Promise<IShardingPageQueryResult>;
|
|
242
|
-
/**
|
|
243
|
-
* 查询记录总数
|
|
244
|
-
*
|
|
245
|
-
* 如果涉及多个分表,会并行查询各分表并汇总。
|
|
246
|
-
*
|
|
247
|
-
* @param reqJson 请求参数
|
|
248
|
-
* @returns 记录总数
|
|
249
|
-
*/
|
|
250
|
-
queryCount(reqJson: IRequestModel): Promise<number>;
|
|
251
|
-
/**
|
|
252
|
-
* 判断记录是否存在
|
|
253
|
-
*
|
|
254
|
-
* 如果涉及多个分表,会并行查询,任一分表存在即返回 true。
|
|
255
|
-
*
|
|
256
|
-
* @param reqJson 请求参数
|
|
257
|
-
* @returns 是否存在
|
|
258
|
-
*/
|
|
259
|
-
isExist(reqJson: IRequestModel): Promise<boolean>;
|
|
260
|
-
/**
|
|
261
|
-
* 【batchInsert 专用】按分表对数据进行分组
|
|
262
|
-
*
|
|
263
|
-
* 仅用于 batchInsert 方法,遍历所有数据项,
|
|
264
|
-
* 根据分表规则计算每条数据的目标分表,将相同分表的数据归为一组。
|
|
265
|
-
*
|
|
266
|
-
* @param dataArray 数据数组
|
|
267
|
-
* @returns 分表 -> 数据列表 的映射
|
|
268
|
-
*/
|
|
95
|
+
* // 根据唯一索引查询单条
|
|
96
|
+
* const result = await sharding.findUniqueOne({ condition: { order_id: 'ORD001' } });
|
|
97
|
+
* if (result.found) {
|
|
98
|
+
* console.log(result.row);
|
|
99
|
+
* }
|
|
100
|
+
*/
|
|
101
|
+
findUniqueOne<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryOneResult<T>>;
|
|
102
|
+
findList<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryListResult<T>>;
|
|
103
|
+
findPage<T = Record<string, any>>(reqJson: IRequestModel): Promise<CrudQueryPageResult<T>>;
|
|
104
|
+
findCount(reqJson: IRequestModel): Promise<CrudCountResult>;
|
|
105
|
+
isExist(reqJson: IRequestModel): Promise<CrudExistResult>;
|
|
269
106
|
private batchInsertGroupDataByTable;
|
|
270
107
|
private batchInsertResolveTableForData;
|
|
271
|
-
/**
|
|
272
|
-
* 解析单个目标表
|
|
273
|
-
*
|
|
274
|
-
* 写操作必须确定单一目标表,否则抛出异常。
|
|
275
|
-
*/
|
|
276
108
|
private resolveSingleTable;
|
|
277
|
-
/**
|
|
278
|
-
* 获取分表字段提示
|
|
279
|
-
*/
|
|
280
109
|
private getShardingColumnHint;
|
|
281
|
-
/**
|
|
282
|
-
* 构建配置
|
|
283
|
-
*/
|
|
284
110
|
private buildCfg;
|
|
285
|
-
/**
|
|
286
|
-
* 在指定表上执行操作
|
|
287
|
-
*/
|
|
288
111
|
private executeOnTable;
|
|
289
|
-
|
|
290
|
-
* 从指定表查询单条
|
|
291
|
-
*/
|
|
292
|
-
private queryOneFromTable;
|
|
293
|
-
/**
|
|
294
|
-
* 从指定表查询数量
|
|
295
|
-
*/
|
|
296
|
-
private queryCountFromTable;
|
|
297
|
-
/**
|
|
298
|
-
* 判断指定表中是否存在记录
|
|
299
|
-
*/
|
|
112
|
+
private findCountFromTable;
|
|
300
113
|
private isExistInTable;
|
|
301
|
-
/**
|
|
302
|
-
* 获取数据库中真实存在的表名集合
|
|
303
|
-
*/
|
|
304
114
|
private getExistingTablesSet;
|
|
115
|
+
private isTableExists;
|
|
116
|
+
private createShardingTableIfNeeded;
|
|
305
117
|
/**
|
|
306
|
-
*
|
|
118
|
+
* 判断是否为时间分表类型
|
|
307
119
|
*/
|
|
308
|
-
private
|
|
120
|
+
private isTimeSharding;
|
|
309
121
|
/**
|
|
310
|
-
*
|
|
122
|
+
* 校验时间分表插入操作的 data 必须包含 timeColumn
|
|
311
123
|
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* - 如果分表不存在且 autoCreateTable=true,自动创建
|
|
315
|
-
* - 如果分表不存在且 autoCreateTable=false,抛出异常
|
|
124
|
+
* 时间分表需要根据时间字段路由到正确的分表,
|
|
125
|
+
* 如果 data 中缺少时间字段,将无法确定数据应插入哪个分表。
|
|
316
126
|
*
|
|
317
|
-
* @param
|
|
127
|
+
* @param reqJson 请求参数
|
|
128
|
+
* @param operation 操作名称(用于错误提示)
|
|
129
|
+
* @throws Error 如果 data 中缺少时间字段
|
|
318
130
|
*/
|
|
319
|
-
private
|
|
131
|
+
private validateTimeColumnForData;
|
|
320
132
|
/**
|
|
321
|
-
*
|
|
133
|
+
* 校验时间分表批量插入操作的每条 data 必须包含 timeColumn
|
|
322
134
|
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
135
|
+
* @param dataArray 数据数组
|
|
136
|
+
* @param operation 操作名称(用于错误提示)
|
|
137
|
+
* @throws Error 如果任一条 data 中缺少时间字段
|
|
138
|
+
*/
|
|
139
|
+
private validateTimeColumnForBatchData;
|
|
140
|
+
/**
|
|
141
|
+
* 校验时间分表写操作的 condition 必须包含路由字段(timeColumn)
|
|
326
142
|
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
* - DESC 时表顺序为 新→旧,ASC 时表顺序为 旧→新(由调用方反转)
|
|
330
|
-
* - 这样无需内存排序,直接按表顺序拼接即可
|
|
143
|
+
* 时间分表需要根据时间字段路由到正确的分表,
|
|
144
|
+
* 如果 condition 中缺少时间字段,将无法确定操作哪个分表。
|
|
331
145
|
*
|
|
332
146
|
* @param reqJson 请求参数
|
|
147
|
+
* @param operation 操作名称(用于错误提示)
|
|
148
|
+
* @throws Error 如果 condition 中缺少时间字段
|
|
333
149
|
*/
|
|
334
|
-
private
|
|
150
|
+
private validateRoutingFieldForCondition;
|
|
335
151
|
/**
|
|
336
|
-
*
|
|
152
|
+
* 智能处理时间分表场景下的时间字段
|
|
153
|
+
*
|
|
154
|
+
* **问题背景**:
|
|
155
|
+
* 在时间分表(YEAR/MONTH/DAY)场景中,timeColumn 既是路由键也是查询条件。
|
|
156
|
+
* 用户传入的时间值可能精度不一致(如传 '2024-01-15' 但数据库存的是毫秒时间戳),
|
|
157
|
+
* 直接作为 WHERE 条件可能导致匹配失败。
|
|
158
|
+
*
|
|
159
|
+
* **处理规则**(详见 TIME_COLUMN_CLEAN_SPEC.md):
|
|
160
|
+
* 1. 操作符表达式($gte/$lte/$range/$in/$null 等)→ 始终保留,不做处理
|
|
161
|
+
* 2. 精确值 + 有 primaryKey → 清理(从 WHERE 移除,仅用于路由)
|
|
162
|
+
* 3. 精确值 + 无 primaryKey + 日期粒度字符串(年/月/日)→ 转换为 $gte/$lte 范围
|
|
163
|
+
* 4. 精确值 + 无 primaryKey + 其他(时间戳/datetime/null等)→ 保留原值
|
|
164
|
+
*
|
|
165
|
+
* **示例**:
|
|
166
|
+
* ```typescript
|
|
167
|
+
* // 有主键 + 精确值 → 清理
|
|
168
|
+
* { order_id: 'ORD001', created_at: '2024-01-15' }
|
|
169
|
+
* → { order_id: 'ORD001' }
|
|
170
|
+
*
|
|
171
|
+
* // 无主键 + 日期粒度字符串 → 转换为范围
|
|
172
|
+
* { status: 'paid', created_at: '2024-01' }
|
|
173
|
+
* → { status: 'paid', created_at: { $gte: '2024-01-01 00:00:00', $lte: '2024-01-31 23:59:59' } }
|
|
337
174
|
*
|
|
338
|
-
*
|
|
175
|
+
* // 操作符表达式 → 保留
|
|
176
|
+
* { order_id: 'ORD001', created_at: { $gte: '2024-01', $lte: '2024-06' } }
|
|
177
|
+
* → 不做任何处理
|
|
178
|
+
* ```
|
|
339
179
|
*
|
|
340
180
|
* @param reqJson 请求参数
|
|
341
|
-
* @returns
|
|
181
|
+
* @returns 处理后的请求参数
|
|
342
182
|
*/
|
|
343
|
-
private
|
|
183
|
+
private cleanTimeColumnForSingleTableQuery;
|
|
344
184
|
/**
|
|
345
|
-
*
|
|
185
|
+
* 校验时间操作符的值必须精确到秒
|
|
346
186
|
*
|
|
347
|
-
*
|
|
348
|
-
* -
|
|
349
|
-
*
|
|
187
|
+
* MySQL 中 '2026-04-30' 等价于 '2026-04-30 00:00:00',
|
|
188
|
+
* 导致 $lte: '2026-04-30' 会丢失当天所有数据。
|
|
189
|
+
* 如果用户需要查整月/整天数据,应传粒度字符串由系统自动转换,而非手动写 $gte/$lte。
|
|
350
190
|
*
|
|
351
|
-
* @param
|
|
352
|
-
* @param
|
|
353
|
-
* @
|
|
191
|
+
* @param operatorValue 操作符表达式的值
|
|
192
|
+
* @param timeColumn 时间字段名
|
|
193
|
+
* @throws Error 如果操作符值缺少时间部分
|
|
354
194
|
*/
|
|
195
|
+
private validateTimeOperatorPrecision;
|
|
196
|
+
private validateFindOrderBy;
|
|
197
|
+
private isAscOrderBy;
|
|
355
198
|
private sortTablesForOrderBy;
|
|
356
199
|
/**
|
|
357
|
-
*
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
200
|
+
* 构建辅助定位信息
|
|
201
|
+
*/
|
|
202
|
+
private buildDebugInfo;
|
|
203
|
+
/**
|
|
204
|
+
* 格式化唯一性错误消息
|
|
361
205
|
*/
|
|
362
|
-
private
|
|
206
|
+
private formatUniqueError;
|
|
207
|
+
private resolveFindTables;
|
|
363
208
|
}
|