midway-fatcms 0.0.8 → 0.0.9
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/02-crud-quick.md +38 -0
- package/.qoder/skills/midway-fatcms/03-crud-sharding.md +37 -36
- package/.qoder/skills/midway-fatcms/07-examples.md +4 -0
- package/dist/configuration.d.ts +10 -0
- package/dist/configuration.js +26 -0
- package/dist/controller/helpers.controller.d.ts +6 -0
- package/dist/controller/helpers.controller.js +19 -0
- package/dist/libs/crud-pro/CrudPro.d.ts +29 -2
- package/dist/libs/crud-pro/CrudPro.js +58 -2
- package/dist/libs/crud-pro/exceptions.d.ts +7 -0
- package/dist/libs/crud-pro/exceptions.js +7 -0
- package/dist/libs/crud-pro/interfaces.d.ts +1 -0
- package/dist/libs/crud-pro/models/CrudResult.d.ts +3 -2
- package/dist/libs/crud-pro/models/CrudResult.js +1 -1
- package/dist/libs/crud-pro/models/ServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.d.ts +70 -2
- package/dist/libs/crud-pro/services/CrudProDataTypeConvertService.js +205 -13
- package/dist/libs/crud-pro/services/CrudProTableMetaService.d.ts +36 -0
- package/dist/libs/crud-pro/services/CrudProTableMetaService.js +97 -3
- package/dist/libs/crud-pro/services/CurdProServiceHub.d.ts +2 -0
- package/dist/libs/crud-pro/services/CurdProServiceHub.js +6 -0
- package/dist/libs/crud-pro-quick/CrudProQuick.d.ts +93 -6
- package/dist/libs/crud-pro-quick/CrudProQuick.js +192 -32
- package/dist/libs/crud-sharding/ShardingBase.d.ts +78 -0
- package/dist/libs/crud-sharding/ShardingBase.js +179 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.d.ts +35 -0
- package/dist/libs/crud-sharding/ShardingByCustomCrud.js +297 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.d.ts +38 -0
- package/dist/libs/crud-sharding/ShardingByHashCrud.js +86 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.d.ts +39 -0
- package/dist/libs/crud-sharding/ShardingByKeyCrud.js +74 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.d.ts +66 -0
- package/dist/libs/crud-sharding/ShardingByTimeCrud.js +524 -0
- package/dist/libs/crud-sharding/ShardingConfig.d.ts +10 -8
- package/dist/libs/crud-sharding/ShardingConfig.js +3 -3
- package/dist/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +1 -1
- package/dist/libs/crud-sharding/index.d.ts +10 -13
- package/dist/libs/crud-sharding/index.js +21 -17
- package/dist/models/RedisKeys.d.ts +1 -0
- package/dist/models/RedisKeys.js +1 -0
- package/dist/service/TableMetaCacheRedisSubscriber.d.ts +31 -0
- package/dist/service/TableMetaCacheRedisSubscriber.js +98 -0
- package/dist/service/curd/CurdMixService.d.ts +2 -2
- package/dist/service/curd/CurdProService.d.ts +109 -5
- package/dist/service/curd/CurdProService.js +127 -7
- package/package.json +1 -1
- package/src/configuration.ts +27 -0
- package/src/controller/helpers.controller.ts +15 -0
- package/src/libs/crud-pro/CrudPro.ts +73 -4
- package/src/libs/crud-pro/exceptions.ts +8 -0
- package/src/libs/crud-pro/interfaces.ts +1 -0
- package/src/libs/crud-pro/models/CrudResult.ts +5 -5
- package/src/libs/crud-pro/models/ServiceHub.ts +4 -0
- package/src/libs/crud-pro/services/CrudProDataTypeConvertService.ts +238 -15
- package/src/libs/crud-pro/services/CrudProTableMetaService.ts +110 -2
- package/src/libs/crud-pro/services/CurdProServiceHub.ts +8 -0
- package/src/libs/crud-pro-quick/CrudProQuick.ts +234 -46
- package/src/libs/crud-sharding/ShardingBase.ts +256 -0
- package/src/libs/crud-sharding/ShardingByCustomCrud.ts +329 -0
- package/src/libs/crud-sharding/ShardingByHashCrud.ts +111 -0
- package/src/libs/crud-sharding/ShardingByKeyCrud.ts +97 -0
- package/src/libs/crud-sharding/ShardingByTimeCrud.ts +628 -0
- package/src/libs/crud-sharding/ShardingConfig.ts +10 -8
- package/src/libs/crud-sharding/TIME_COLUMN_CLEAN_SPEC.md +1 -1
- package/src/libs/crud-sharding/index.ts +17 -14
- package/src/models/RedisKeys.ts +1 -0
- package/src/service/TableMetaCacheRedisSubscriber.ts +105 -0
- package/src/service/curd/CurdMixService.ts +2 -2
- package/src/service/curd/CurdProService.ts +131 -9
- package/dist/libs/crud-sharding/ShardingCrudPro.d.ts +0 -208
- package/dist/libs/crud-sharding/ShardingCrudPro.js +0 -879
- package/dist/libs/crud-sharding/ShardingRouter.d.ts +0 -70
- package/dist/libs/crud-sharding/ShardingRouter.js +0 -396
- package/src/libs/crud-sharding/ShardingCrudPro.ts +0 -1105
- package/src/libs/crud-sharding/ShardingRouter.ts +0 -533
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CrudPro } from '../../libs/crud-pro/CrudPro';
|
|
2
|
+
import { KeysOfSimpleSQL } from '../crud-pro/models/keys';
|
|
2
3
|
/**
|
|
3
4
|
* CrudPro 工厂函数类型
|
|
4
5
|
* 每次调用返回新的 CrudPro 实例,避免状态污染
|
|
@@ -11,8 +12,8 @@ export declare type CrudProFactory = () => CrudPro;
|
|
|
11
12
|
* - YEAR: 按年分表,如 order_2024, order_2025
|
|
12
13
|
* - MONTH: 按月分表,如 order_202401, order_202402
|
|
13
14
|
* - DAY: 按日分表,如 order_20240101
|
|
14
|
-
* - RANGE: 按范围分表,如 user_0 ~ user_99
|
|
15
15
|
* - HASH: 按哈希分表,如 order_01 ~ order_16
|
|
16
|
+
* - KEY: 按键值分表,字段原值=表后缀,如 order_east, order_west
|
|
16
17
|
* - CUSTOM: 自定义分表规则
|
|
17
18
|
*/
|
|
18
19
|
/**
|
|
@@ -25,10 +26,10 @@ export declare enum ShardingType {
|
|
|
25
26
|
MONTH = "month",
|
|
26
27
|
/** 按日分表:table_20240101 */
|
|
27
28
|
DAY = "day",
|
|
28
|
-
/** 按范围分表:table_0 ~ table_99 */
|
|
29
|
-
RANGE = "range",
|
|
30
29
|
/** 按哈希分表:table_01 ~ table_16 */
|
|
31
30
|
HASH = "hash",
|
|
31
|
+
/** 按键值分表:字段原值=表后缀,如 table_east, table_west */
|
|
32
|
+
KEY = "key",
|
|
32
33
|
/** 自定义分表规则 */
|
|
33
34
|
CUSTOM = "custom"
|
|
34
35
|
}
|
|
@@ -47,14 +48,15 @@ export interface IShardingConfig {
|
|
|
47
48
|
baseTable: string;
|
|
48
49
|
/**
|
|
49
50
|
* 分表数量
|
|
50
|
-
* 用于
|
|
51
|
-
* 默认值:RANGE 为 10,HASH 为 16
|
|
51
|
+
* 用于 HASH 类型,指定哈希取模的分表总数
|
|
52
52
|
*/
|
|
53
53
|
tableCount?: number;
|
|
54
54
|
/**
|
|
55
55
|
* 分表字段
|
|
56
|
-
* 用于
|
|
57
|
-
*
|
|
56
|
+
* 用于 HASH 和 KEY 类型,根据字段值计算分表
|
|
57
|
+
* - HASH: hash(shardingColumn) % tableCount
|
|
58
|
+
* - KEY: 字段原值直接作为表后缀
|
|
59
|
+
* 例如:user_id, region
|
|
58
60
|
*/
|
|
59
61
|
shardingColumn?: string;
|
|
60
62
|
/**
|
|
@@ -220,7 +222,7 @@ export interface IShardingRouterContext {
|
|
|
220
222
|
* SQL 简单名称
|
|
221
223
|
* 用于判断具体的查询类型
|
|
222
224
|
*/
|
|
223
|
-
sqlSimpleName
|
|
225
|
+
sqlSimpleName: KeysOfSimpleSQL;
|
|
224
226
|
}
|
|
225
227
|
/**
|
|
226
228
|
* 时间范围
|
|
@@ -8,8 +8,8 @@ exports.ShardingType = void 0;
|
|
|
8
8
|
* - YEAR: 按年分表,如 order_2024, order_2025
|
|
9
9
|
* - MONTH: 按月分表,如 order_202401, order_202402
|
|
10
10
|
* - DAY: 按日分表,如 order_20240101
|
|
11
|
-
* - RANGE: 按范围分表,如 user_0 ~ user_99
|
|
12
11
|
* - HASH: 按哈希分表,如 order_01 ~ order_16
|
|
12
|
+
* - KEY: 按键值分表,字段原值=表后缀,如 order_east, order_west
|
|
13
13
|
* - CUSTOM: 自定义分表规则
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
@@ -23,10 +23,10 @@ var ShardingType;
|
|
|
23
23
|
ShardingType["MONTH"] = "month";
|
|
24
24
|
/** 按日分表:table_20240101 */
|
|
25
25
|
ShardingType["DAY"] = "day";
|
|
26
|
-
/** 按范围分表:table_0 ~ table_99 */
|
|
27
|
-
ShardingType["RANGE"] = "range";
|
|
28
26
|
/** 按哈希分表:table_01 ~ table_16 */
|
|
29
27
|
ShardingType["HASH"] = "hash";
|
|
28
|
+
/** 按键值分表:字段原值=表后缀,如 table_east, table_west */
|
|
29
|
+
ShardingType["KEY"] = "key";
|
|
30
30
|
/** 自定义分表规则 */
|
|
31
31
|
ShardingType["CUSTOM"] = "custom";
|
|
32
32
|
})(ShardingType = exports.ShardingType || (exports.ShardingType = {}));
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
* - YEAR: 按年分表,如 order_2024, order_2025
|
|
8
8
|
* - MONTH: 按月分表,如 order_202401, order_202402
|
|
9
9
|
* - DAY: 按日分表,如 order_20240101
|
|
10
|
-
* - RANGE: 按范围分表,如 user_0 ~ user_99
|
|
11
10
|
* - HASH: 按哈希分表,如 order_01 ~ order_16
|
|
11
|
+
* - KEY: 按键值分表,字段原值=表后缀,如 order_east, order_west
|
|
12
12
|
* - CUSTOM: 自定义分表规则
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
|
-
* import {
|
|
15
|
+
* import { ShardingByTimeCrud, ShardingType } from '../../libs/crud-sharding';
|
|
16
16
|
*
|
|
17
|
-
* //
|
|
18
|
-
* const sharding = new
|
|
17
|
+
* // 创建时间分表操作器
|
|
18
|
+
* const sharding = new ShardingByTimeCrud(crudProFactory, {
|
|
19
19
|
* type: ShardingType.MONTH,
|
|
20
20
|
* baseTable: 't_order',
|
|
21
21
|
* timeColumn: 'created_at',
|
|
@@ -25,16 +25,13 @@
|
|
|
25
25
|
* await sharding.insert({
|
|
26
26
|
* data: { order_id: '001', amount: 100, created_at: '2024-03-15' },
|
|
27
27
|
* });
|
|
28
|
-
*
|
|
29
|
-
* // 分页查询(自动合并多表结果)
|
|
30
|
-
* const result = await sharding.findPage({
|
|
31
|
-
* condition: { created_at: { $gte: '2024-01-01', $lte: '2024-03-31' } },
|
|
32
|
-
* pageNo: 1,
|
|
33
|
-
* pageSize: 10,
|
|
34
|
-
* });
|
|
35
28
|
*/
|
|
36
|
-
export {
|
|
37
|
-
export {
|
|
29
|
+
export { ShardingBase } from './ShardingBase';
|
|
30
|
+
export { ShardingByTimeCrud } from './ShardingByTimeCrud';
|
|
31
|
+
export { ShardingByHashCrud } from './ShardingByHashCrud';
|
|
32
|
+
export { ShardingByKeyCrud } from './ShardingByKeyCrud';
|
|
33
|
+
export { ShardingByCustomCrud } from './ShardingByCustomCrud';
|
|
34
|
+
export { ShardingBase as ShardingCrudPro } from './ShardingBase';
|
|
38
35
|
export { ShardingMerger } from './ShardingMerger';
|
|
39
36
|
export { ShardingType } from './ShardingConfig';
|
|
40
37
|
export type { IShardingConfig, IShardingRouterContext, IShardingRouterFunc, IShardingTimeRange, IShardingTableCreateOptions, IShardingTableCreateResult, IShardingCountCacheConfig, } from './ShardingConfig';
|
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
* - YEAR: 按年分表,如 order_2024, order_2025
|
|
9
9
|
* - MONTH: 按月分表,如 order_202401, order_202402
|
|
10
10
|
* - DAY: 按日分表,如 order_20240101
|
|
11
|
-
* - RANGE: 按范围分表,如 user_0 ~ user_99
|
|
12
11
|
* - HASH: 按哈希分表,如 order_01 ~ order_16
|
|
12
|
+
* - KEY: 按键值分表,字段原值=表后缀,如 order_east, order_west
|
|
13
13
|
* - CUSTOM: 自定义分表规则
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
* import {
|
|
16
|
+
* import { ShardingByTimeCrud, ShardingType } from '../../libs/crud-sharding';
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
19
|
-
* const sharding = new
|
|
18
|
+
* // 创建时间分表操作器
|
|
19
|
+
* const sharding = new ShardingByTimeCrud(crudProFactory, {
|
|
20
20
|
* type: ShardingType.MONTH,
|
|
21
21
|
* baseTable: 't_order',
|
|
22
22
|
* timeColumn: 'created_at',
|
|
@@ -26,21 +26,25 @@
|
|
|
26
26
|
* await sharding.insert({
|
|
27
27
|
* data: { order_id: '001', amount: 100, created_at: '2024-03-15' },
|
|
28
28
|
* });
|
|
29
|
-
*
|
|
30
|
-
* // 分页查询(自动合并多表结果)
|
|
31
|
-
* const result = await sharding.findPage({
|
|
32
|
-
* condition: { created_at: { $gte: '2024-01-01', $lte: '2024-03-31' } },
|
|
33
|
-
* pageNo: 1,
|
|
34
|
-
* pageSize: 10,
|
|
35
|
-
* });
|
|
36
29
|
*/
|
|
37
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.shardingHashCondition = exports.ShardingCountCache = exports.ShardingTableCreator = exports.CrudUpsertResult = exports.CrudCountResult = exports.CrudExistResult = exports.CrudQueryPageResult = exports.CrudQueryListResult = exports.CrudQueryOneResult = exports.CrudWriteResult = exports.ShardingBatchInsertResult = exports.ShardingType = exports.ShardingMerger = exports.
|
|
39
|
-
//
|
|
40
|
-
var
|
|
41
|
-
Object.defineProperty(exports, "
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
exports.shardingHashCondition = exports.ShardingCountCache = exports.ShardingTableCreator = exports.CrudUpsertResult = exports.CrudCountResult = exports.CrudExistResult = exports.CrudQueryPageResult = exports.CrudQueryListResult = exports.CrudQueryOneResult = exports.CrudWriteResult = exports.ShardingBatchInsertResult = exports.ShardingType = exports.ShardingMerger = exports.ShardingCrudPro = exports.ShardingByCustomCrud = exports.ShardingByKeyCrud = exports.ShardingByHashCrud = exports.ShardingByTimeCrud = exports.ShardingBase = void 0;
|
|
32
|
+
// 基类
|
|
33
|
+
var ShardingBase_1 = require("./ShardingBase");
|
|
34
|
+
Object.defineProperty(exports, "ShardingBase", { enumerable: true, get: function () { return ShardingBase_1.ShardingBase; } });
|
|
35
|
+
// 四个子类
|
|
36
|
+
var ShardingByTimeCrud_1 = require("./ShardingByTimeCrud");
|
|
37
|
+
Object.defineProperty(exports, "ShardingByTimeCrud", { enumerable: true, get: function () { return ShardingByTimeCrud_1.ShardingByTimeCrud; } });
|
|
38
|
+
var ShardingByHashCrud_1 = require("./ShardingByHashCrud");
|
|
39
|
+
Object.defineProperty(exports, "ShardingByHashCrud", { enumerable: true, get: function () { return ShardingByHashCrud_1.ShardingByHashCrud; } });
|
|
40
|
+
var ShardingByKeyCrud_1 = require("./ShardingByKeyCrud");
|
|
41
|
+
Object.defineProperty(exports, "ShardingByKeyCrud", { enumerable: true, get: function () { return ShardingByKeyCrud_1.ShardingByKeyCrud; } });
|
|
42
|
+
var ShardingByCustomCrud_1 = require("./ShardingByCustomCrud");
|
|
43
|
+
Object.defineProperty(exports, "ShardingByCustomCrud", { enumerable: true, get: function () { return ShardingByCustomCrud_1.ShardingByCustomCrud; } });
|
|
44
|
+
// 兼容旧代码:ShardingCrudPro → ShardingBase
|
|
45
|
+
var ShardingBase_2 = require("./ShardingBase");
|
|
46
|
+
Object.defineProperty(exports, "ShardingCrudPro", { enumerable: true, get: function () { return ShardingBase_2.ShardingBase; } });
|
|
47
|
+
// 合并器(仅 Time 使用)
|
|
44
48
|
var ShardingMerger_1 = require("./ShardingMerger");
|
|
45
49
|
Object.defineProperty(exports, "ShardingMerger", { enumerable: true, get: function () { return ShardingMerger_1.ShardingMerger; } });
|
|
46
50
|
// 配置和类型
|
package/dist/models/RedisKeys.js
CHANGED
|
@@ -14,5 +14,6 @@ const RedisKeys = {
|
|
|
14
14
|
CURD_MIX_BY_DICT_PREFIX: 'FatCurdMixByDict@@',
|
|
15
15
|
QUERY_ENUM_INFO_PREFIX: 'FatQueryEnum@@',
|
|
16
16
|
REDIS_LOCK_MIDDILEWARE: 'FatRedisLock@@',
|
|
17
|
+
TABLE_META_CACHE_INVALIDATE_CHANNEL: 'FatTableMetaCacheInvalidate',
|
|
17
18
|
};
|
|
18
19
|
exports.RedisKeys = RedisKeys;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RedisService } from '@midwayjs/redis';
|
|
2
|
+
/**
|
|
3
|
+
* 初始化发布客户端
|
|
4
|
+
*
|
|
5
|
+
* 在 Midway 容器初始化完成后调用,注入已有的 RedisService 实例
|
|
6
|
+
* @param client RedisService 实例
|
|
7
|
+
*/
|
|
8
|
+
export declare function initTableMetaCachePublishClient(client: RedisService): void;
|
|
9
|
+
/**
|
|
10
|
+
* 初始化 Redis 订阅,监听缓存失效广播
|
|
11
|
+
*
|
|
12
|
+
* 使用 RedisService.duplicate() 创建独立的订阅连接。
|
|
13
|
+
* 收到广播后自动清空本节点的本地缓存。
|
|
14
|
+
*
|
|
15
|
+
* @param mainClient 已有的 RedisService 实例,用于 duplicate 出订阅连接
|
|
16
|
+
*/
|
|
17
|
+
export declare function initTableMetaCacheSubscriber(mainClient: RedisService): void;
|
|
18
|
+
/**
|
|
19
|
+
* 清空本节点缓存并广播通知集群中其他节点
|
|
20
|
+
*
|
|
21
|
+
* 调用流程:
|
|
22
|
+
* 1. 清空本节点本地缓存
|
|
23
|
+
* 2. 通过 Redis PUBLISH 广播消息
|
|
24
|
+
* 3. 其他节点收到消息后清空各自的本地缓存
|
|
25
|
+
*
|
|
26
|
+
* @returns 清空前的缓存统计
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearTableMetaCacheWithBroadcast(): {
|
|
29
|
+
metaCacheCount: number;
|
|
30
|
+
tableInfoCacheCount: number;
|
|
31
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearTableMetaCacheWithBroadcast = exports.initTableMetaCacheSubscriber = exports.initTableMetaCachePublishClient = void 0;
|
|
4
|
+
const CrudProTableMetaService_1 = require("../libs/crud-pro/services/CrudProTableMetaService");
|
|
5
|
+
const RedisKeys_1 = require("../models/RedisKeys");
|
|
6
|
+
const CHANNEL = RedisKeys_1.RedisKeys.TABLE_META_CACHE_INVALIDATE_CHANNEL;
|
|
7
|
+
/**
|
|
8
|
+
* 本节点唯一标识,用于区分是自己发出的广播还是其他节点发出的
|
|
9
|
+
* 避免重复清空(本节点已在发布前清空过)
|
|
10
|
+
*/
|
|
11
|
+
const NODE_ID = `node_${process.pid}_${Date.now()}`;
|
|
12
|
+
/**
|
|
13
|
+
* 用于发布消息的 Redis 客户端(复用 @midwayjs/redis 注入的实例)
|
|
14
|
+
*/
|
|
15
|
+
let publishClient = null;
|
|
16
|
+
/**
|
|
17
|
+
* 用于订阅的 Redis 客户端(独立连接,ioredis 规定订阅连接不能执行普通命令)
|
|
18
|
+
*/
|
|
19
|
+
let subscribeClient = null;
|
|
20
|
+
/**
|
|
21
|
+
* 初始化发布客户端
|
|
22
|
+
*
|
|
23
|
+
* 在 Midway 容器初始化完成后调用,注入已有的 RedisService 实例
|
|
24
|
+
* @param client RedisService 实例
|
|
25
|
+
*/
|
|
26
|
+
function initTableMetaCachePublishClient(client) {
|
|
27
|
+
publishClient = client;
|
|
28
|
+
}
|
|
29
|
+
exports.initTableMetaCachePublishClient = initTableMetaCachePublishClient;
|
|
30
|
+
/**
|
|
31
|
+
* 初始化 Redis 订阅,监听缓存失效广播
|
|
32
|
+
*
|
|
33
|
+
* 使用 RedisService.duplicate() 创建独立的订阅连接。
|
|
34
|
+
* 收到广播后自动清空本节点的本地缓存。
|
|
35
|
+
*
|
|
36
|
+
* @param mainClient 已有的 RedisService 实例,用于 duplicate 出订阅连接
|
|
37
|
+
*/
|
|
38
|
+
function initTableMetaCacheSubscriber(mainClient) {
|
|
39
|
+
if (subscribeClient) {
|
|
40
|
+
return; // 防止重复初始化
|
|
41
|
+
}
|
|
42
|
+
// duplicate() 创建一个同配置的独立连接
|
|
43
|
+
subscribeClient = mainClient.duplicate();
|
|
44
|
+
subscribeClient.subscribe(CHANNEL).catch((err) => {
|
|
45
|
+
console.error('[TableMetaCacheRedis] subscribe failed:', err.message);
|
|
46
|
+
});
|
|
47
|
+
subscribeClient.on('message', (channel, message) => {
|
|
48
|
+
if (channel !== CHANNEL)
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
const data = JSON.parse(message);
|
|
52
|
+
// 跳过自己发出的广播(本节点已在发布前清空过)
|
|
53
|
+
if (data.nodeId === NODE_ID)
|
|
54
|
+
return;
|
|
55
|
+
const stats = (0, CrudProTableMetaService_1.clearTableMetaCache)();
|
|
56
|
+
console.info(`[TableMetaCacheRedis] 收到其他节点(${data.nodeId})的缓存清空广播,已清空本地缓存:`, stats);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.error('[TableMetaCacheRedis] 处理缓存失效广播异常:', e);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
subscribeClient.on('error', (err) => {
|
|
63
|
+
console.error('[TableMetaCacheRedis] subscriber connection error:', err.message);
|
|
64
|
+
});
|
|
65
|
+
console.info('[TableMetaCacheRedis] 订阅已启动,监听频道:', CHANNEL);
|
|
66
|
+
}
|
|
67
|
+
exports.initTableMetaCacheSubscriber = initTableMetaCacheSubscriber;
|
|
68
|
+
/**
|
|
69
|
+
* 清空本节点缓存并广播通知集群中其他节点
|
|
70
|
+
*
|
|
71
|
+
* 调用流程:
|
|
72
|
+
* 1. 清空本节点本地缓存
|
|
73
|
+
* 2. 通过 Redis PUBLISH 广播消息
|
|
74
|
+
* 3. 其他节点收到消息后清空各自的本地缓存
|
|
75
|
+
*
|
|
76
|
+
* @returns 清空前的缓存统计
|
|
77
|
+
*/
|
|
78
|
+
function clearTableMetaCacheWithBroadcast() {
|
|
79
|
+
// 1. 清空本节点缓存
|
|
80
|
+
const stats = (0, CrudProTableMetaService_1.clearTableMetaCache)();
|
|
81
|
+
// 2. 广播通知其他节点
|
|
82
|
+
if (publishClient && typeof publishClient.publish === 'function') {
|
|
83
|
+
const message = JSON.stringify({
|
|
84
|
+
nodeId: NODE_ID,
|
|
85
|
+
timestamp: Date.now(),
|
|
86
|
+
beforeClear: stats,
|
|
87
|
+
});
|
|
88
|
+
publishClient.publish(CHANNEL, message).catch((err) => {
|
|
89
|
+
console.error('[TableMetaCacheRedis] publish failed:', err.message);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// 没有 Redis 连接时仅清空本地(单节点部署降级)
|
|
94
|
+
console.info('[TableMetaCacheRedis] 无 Redis 发布客户端,仅清空本节点缓存');
|
|
95
|
+
}
|
|
96
|
+
return stats;
|
|
97
|
+
}
|
|
98
|
+
exports.clearTableMetaCacheWithBroadcast = clearTableMetaCacheWithBroadcast;
|
|
@@ -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 {
|
|
4
|
+
import { ShardingBase } from "../../libs/crud-sharding";
|
|
5
5
|
import { IGetQuickCrudParam, IGetShardingCrudParam } from './CurdProService';
|
|
6
6
|
export interface ILinkColumnRelationParam {
|
|
7
7
|
columnsRelations: ColumnRelation[];
|
|
@@ -16,7 +16,7 @@ export declare class CurdMixService {
|
|
|
16
16
|
private prepare;
|
|
17
17
|
executeCrudByCfg(reqJson: IRequestModel, cfgModel: IRequestCfgModel2): Promise<ExecuteContext>;
|
|
18
18
|
getQuickCrud(param: IGetQuickCrudParam): import("../..").CrudProQuick;
|
|
19
|
-
getShardingCrud(param: IGetShardingCrudParam):
|
|
19
|
+
getShardingCrud(param: IGetShardingCrudParam): ShardingBase;
|
|
20
20
|
executeSQL(sqlCfgModel: ISqlCfgModel): Promise<ExecuteSQLResult>;
|
|
21
21
|
executeCrud(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
22
22
|
getCachedCfgByMethod(method: string): Promise<IRequestCfgModel>;
|
|
@@ -6,7 +6,7 @@ import { RelatedType } from './CurdMixUtils';
|
|
|
6
6
|
import { BaseService } from '../base/BaseService';
|
|
7
7
|
import { IRequestCfgModel2 } from '../../models/bizmodels';
|
|
8
8
|
import { CrudProQuick } from '../../libs/crud-pro-quick';
|
|
9
|
-
import {
|
|
9
|
+
import { ShardingBase, IShardingConfig } from '../../libs/crud-sharding';
|
|
10
10
|
/**
|
|
11
11
|
* getQuickCrud 参数接口
|
|
12
12
|
*/
|
|
@@ -36,7 +36,37 @@ export declare class CurdProService extends BaseService {
|
|
|
36
36
|
private sqlserver2Config;
|
|
37
37
|
private crudProCfg;
|
|
38
38
|
private responseCfgHandlers;
|
|
39
|
+
/**
|
|
40
|
+
* 注册“响应配置处理器”(response cfg handler)。
|
|
41
|
+
*
|
|
42
|
+
* 这些处理器会在一次 CRUD/SQL 执行完成后被调用,用于对 `ExecuteContext` 做统一的二次加工,
|
|
43
|
+
* 例如:追加扩展数据、做字段脱敏、统一包装返回结构等。
|
|
44
|
+
*
|
|
45
|
+
* @param key 处理器类型标识(业务自定义枚举/常量)
|
|
46
|
+
* @param handler 处理器实现
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* curdProService.setResponseCfgHandlers(RelatedType.USER, {
|
|
50
|
+
* async handleExecuteContextPrepare(ctx) {
|
|
51
|
+
* // 可在执行结果处理前做准备
|
|
52
|
+
* },
|
|
53
|
+
* async handleExecuteContext(ctx) {
|
|
54
|
+
* // 对 ctx.result / ctx.data 等进行二次加工
|
|
55
|
+
* },
|
|
56
|
+
* });
|
|
57
|
+
*/
|
|
39
58
|
setResponseCfgHandlers(key: RelatedType, handler: IExecuteContextHandler): void;
|
|
59
|
+
/**
|
|
60
|
+
* 获取当前已注册的“响应配置处理器”集合。
|
|
61
|
+
*
|
|
62
|
+
* 一般用于调试或在外层框架中统一检查/复用已有 handler。
|
|
63
|
+
*
|
|
64
|
+
* @returns 以 `RelatedType` 为 key 的处理器映射表
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* const handlers = curdProService.getResponseCfgHandlers();
|
|
68
|
+
* const userHandler = handlers[RelatedType.USER];
|
|
69
|
+
*/
|
|
40
70
|
getResponseCfgHandlers(): Record<RelatedType, IExecuteContextHandler>;
|
|
41
71
|
/**
|
|
42
72
|
* Execute级别:每次调用都会产生新的
|
|
@@ -44,11 +74,59 @@ export declare class CurdProService extends BaseService {
|
|
|
44
74
|
*/
|
|
45
75
|
private getCrudPro;
|
|
46
76
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
77
|
+
* 通过 `method` 走配置化 CRUD 执行(从缓存/加载的配置中解析)。
|
|
78
|
+
*
|
|
79
|
+
* 适用于:前端/调用方只传 `method` + 入参,由服务端根据 `method` 找到对应的 CRUD 配置并执行。
|
|
80
|
+
* 在非调试模式下会启用配置缓存(调试模式关闭缓存,便于开发即时生效)。
|
|
81
|
+
*
|
|
82
|
+
* @param reqJson 请求模型,必须包含 `method`
|
|
83
|
+
* @returns `ExecuteContext`(包含执行过程与结果数据)
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const ctx = await curdProService.executeCrud({
|
|
87
|
+
* method: 'user.list',
|
|
88
|
+
* pageNo: 1,
|
|
89
|
+
* pageSize: 20,
|
|
90
|
+
* });
|
|
91
|
+
* console.log(ctx.result);
|
|
49
92
|
*/
|
|
50
93
|
executeCrud(reqJson: IRequestModel): Promise<ExecuteContext>;
|
|
94
|
+
/**
|
|
95
|
+
* 直接执行一段 SQL(不依赖 `method` 配置)。
|
|
96
|
+
*
|
|
97
|
+
* 适用于:后台管理/运维脚本/内部工具需要直接跑 SQL 的场景(仍会复用本服务的连接池、日志、visitor、事务等上下文)。
|
|
98
|
+
*
|
|
99
|
+
* @param sqlCfgModel SQL 执行配置(数据库、类型、SQL、参数等)
|
|
100
|
+
* @returns SQL 执行结果
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const res = await curdProService.executeSQL({
|
|
104
|
+
* sqlDbType: SqlDbType.mysql,
|
|
105
|
+
* sqlDatabase: 'mydb',
|
|
106
|
+
* executeSql: 'select * from t_user where id = ?',
|
|
107
|
+
* executeSqlArgs: [1],
|
|
108
|
+
* });
|
|
109
|
+
*/
|
|
51
110
|
executeSQL(sqlCfgModel: ISqlCfgModel): Promise<ExecuteSQLResult>;
|
|
111
|
+
/**
|
|
112
|
+
* 直接按指定配置执行一次 CRUD(不走缓存查找)。
|
|
113
|
+
*
|
|
114
|
+
* 适用于:调用方已经拿到了/动态生成了本次要执行的 CRUD 配置,想直接执行并得到结果。
|
|
115
|
+
* 该方法会对 `cfgModel` 做两类标准化处理:
|
|
116
|
+
* - 统一修正/补全配置(`fixCfgModel`)
|
|
117
|
+
* - 应用软删除规则(`fixSoftDelete`)
|
|
118
|
+
*
|
|
119
|
+
* @param reqJson 本次请求入参
|
|
120
|
+
* @param cfgModel 本次请求对应的 CRUD 配置
|
|
121
|
+
* @returns `ExecuteContext`
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const cfg = await curdProService.getCachedCfgByMethod('user.list');
|
|
125
|
+
* const ctx = await curdProService.executeCrudByCfg(
|
|
126
|
+
* { method: 'user.list', pageNo: 1, pageSize: 20 },
|
|
127
|
+
* cfg as any
|
|
128
|
+
* );
|
|
129
|
+
*/
|
|
52
130
|
executeCrudByCfg(reqJson: IRequestModel, cfgModel: IRequestCfgModel2): Promise<ExecuteContext>;
|
|
53
131
|
/**
|
|
54
132
|
* 获取 CrudProQuick 工具类
|
|
@@ -71,7 +149,7 @@ export declare class CurdProService extends BaseService {
|
|
|
71
149
|
* 获取分表 CRUD 操作器
|
|
72
150
|
*
|
|
73
151
|
* @param param 参数对象
|
|
74
|
-
* @returns
|
|
152
|
+
* @returns ShardingBase 实例(实际类型根据 shardingConfig.type 决定)
|
|
75
153
|
*
|
|
76
154
|
* @example
|
|
77
155
|
* const sharding = curdProService.getShardingCrud({
|
|
@@ -84,7 +162,33 @@ export declare class CurdProService extends BaseService {
|
|
|
84
162
|
* },
|
|
85
163
|
* });
|
|
86
164
|
*/
|
|
87
|
-
getShardingCrud(param: IGetShardingCrudParam):
|
|
165
|
+
getShardingCrud(param: IGetShardingCrudParam): ShardingBase;
|
|
166
|
+
/**
|
|
167
|
+
* 根据 `method` 获取(可能来自缓存的)CRUD 配置。
|
|
168
|
+
*
|
|
169
|
+
* 适用于:你只想先拿到配置做检查/二次加工/审计,再决定是否执行。
|
|
170
|
+
* 非调试模式会启用缓存(调试模式关闭缓存)。
|
|
171
|
+
*
|
|
172
|
+
* @param method 配置方法名,例如:`user.list`
|
|
173
|
+
* @returns CRUD 配置模型
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* const cfg = await curdProService.getCachedCfgByMethod('user.list');
|
|
177
|
+
* console.log(cfg.sqlSimpleName);
|
|
178
|
+
*/
|
|
88
179
|
getCachedCfgByMethod(method: string): Promise<IRequestCfgModel>;
|
|
180
|
+
/**
|
|
181
|
+
* 获取数据库的表/视图等结构信息列表(用于数据源探测、表选择器、代码生成等场景)。
|
|
182
|
+
*
|
|
183
|
+
* @param query 查询条件(例如:指定数据库、关键字过滤、分页等)
|
|
184
|
+
* @param options 可选项(例如:是否包含视图/系统表、大小写处理等,具体以接口定义为准)
|
|
185
|
+
* @returns 表信息列表结果
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* const tables = await curdProService.getAllTableInfos(
|
|
189
|
+
* { sqlDbType: SqlDbType.mysql, sqlDatabase: 'mydb' },
|
|
190
|
+
* { skipCache: true }
|
|
191
|
+
* );
|
|
192
|
+
*/
|
|
89
193
|
getAllTableInfos(query: ITableNamesQuery, options?: ITableNamesOptions): Promise<ITableListResult>;
|
|
90
194
|
}
|