oak-backend-base 3.2.3 → 3.3.1

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.
@@ -1,158 +1,158 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const lodash_1 = require("oak-domain/lib/utils/lodash");
4
- const oak_domain_1 = require("oak-domain");
5
- class DataSubscriber {
6
- ns;
7
- contextBuilder;
8
- filterMap;
9
- idEntityMap;
10
- constructor(ns, contextBuilder) {
11
- this.ns = ns;
12
- this.contextBuilder = contextBuilder;
13
- this.startup();
14
- this.filterMap = {};
15
- this.idEntityMap = {};
16
- }
17
- formCreateRoomRoutine(def) {
18
- const { id, entity, filter } = def;
19
- return (room) => {
20
- if (room === id) {
21
- console.log('instance:', process.env.NODE_APP_INSTANCE, 'add filter', room);
22
- // 本房间不存在,说明这个filter是新出现的
23
- if (this.filterMap[entity]) {
24
- // id的唯一性由前台保证,重复则无视
25
- Object.assign(this.filterMap[entity], {
26
- [id]: filter,
27
- });
28
- }
29
- else {
30
- Object.assign(this.filterMap, {
31
- [entity]: {
32
- [id]: filter,
33
- }
34
- });
35
- }
36
- this.idEntityMap[id] = entity;
37
- }
38
- };
39
- }
40
- /**
41
- * 来自外部的socket连接,监听数据变化
42
- */
43
- startup() {
44
- this.ns.on('connection', async (socket) => {
45
- try {
46
- const { 'oak-cxt': cxtStr } = socket.handshake.headers;
47
- const context = await this.contextBuilder(cxtStr);
48
- socket.userId = context.getCurrentUserId();
49
- socket.context = context;
50
- socket.idMap = {};
51
- socket.on('sub', async (data) => {
52
- try {
53
- console.log('instance:', process.env.NODE_APP_INSTANCE, 'on sub', JSON.stringify(data));
54
- await Promise.all(data.map(async (ele) => {
55
- const { id, entity, filter } = ele;
56
- // 尝试select此filter,如果失败说明权限越界
57
- await context.select(entity, {
58
- data: {
59
- id: 1,
60
- },
61
- filter,
62
- }, {});
63
- }));
64
- }
65
- catch (err) {
66
- socket.emit('error', err.toString());
67
- return;
68
- }
69
- data.forEach((ele) => {
70
- const createRoomRoutine = this.formCreateRoomRoutine(ele);
71
- this.ns.adapter.on('create-room', createRoomRoutine);
72
- socket.join(ele.id);
73
- this.ns.adapter.off('create-room', createRoomRoutine);
74
- });
75
- });
76
- socket.on('unsub', (ids) => {
77
- // console.log('instance:', process.env.NODE_APP_INSTANCE, 'on unsub', JSON.stringify(ids));
78
- ids.forEach((id) => {
79
- socket.leave(id);
80
- });
81
- });
82
- }
83
- catch (err) {
84
- socket.emit('error', err.toString());
85
- }
86
- });
87
- this.ns.adapter.on('delete-room', (room) => {
88
- const entity = this.idEntityMap[room];
89
- if (entity) {
90
- // console.log('instance:', process.env.NODE_APP_INSTANCE, 'remove filter', room);
91
- (0, lodash_1.unset)(this.filterMap[entity], room);
92
- (0, lodash_1.unset)(this.idEntityMap, room);
93
- }
94
- });
95
- this.ns.on('sendRecord', (entity, filter, record, isCreate) => {
96
- console.log('instance:', process.env.NODE_APP_INSTANCE, 'get record from another', JSON.stringify(entity));
97
- });
98
- }
99
- sendRecord(entity, filter, record, sid, isCreate) {
100
- if (entity === 'spContractApplyment') {
101
- console.log('instance:', process.env.NODE_APP_INSTANCE, 'sendRecord', JSON.stringify(entity));
102
- }
103
- this.ns.serverSideEmit('sendRecord', entity, filter, record, isCreate);
104
- if (this.filterMap[entity]) {
105
- Object.keys(this.filterMap[entity]).forEach(async (room) => {
106
- const context = await this.contextBuilder();
107
- const filter2 = this.filterMap[entity][room];
108
- let needSend = false;
109
- if (isCreate) {
110
- // 如果是插入数据肯定是单行,使用相容性检测
111
- const contained = await (0, oak_domain_1.checkFilterContains)(entity, context, filter2, filter, true);
112
- needSend = contained;
113
- }
114
- else {
115
- const repeled = await (0, oak_domain_1.checkFilterRepel)(entity, context, filter, filter2, true);
116
- needSend = !repeled;
117
- }
118
- if (needSend) {
119
- // console.log('instance:', process.env.NODE_APP_INSTANCE, 'needSend', JSON.stringify(room));
120
- if (sid) {
121
- this.ns.to(room).except(sid).emit('data', [record], [room]);
122
- }
123
- else {
124
- this.ns.to(room).emit('data', [record], [room]);
125
- }
126
- }
127
- });
128
- }
129
- }
130
- onDataCommited(context) {
131
- const sid = context.getSubscriberId();
132
- const { opRecords } = context;
133
- opRecords.forEach((record) => {
134
- const { a } = record;
135
- switch (a) {
136
- case 'c': {
137
- const { e, d } = record;
138
- this.sendRecord(e, d, record, sid, true);
139
- break;
140
- }
141
- case 'u': {
142
- const { e, d, f } = record;
143
- this.sendRecord(e, f, record, sid);
144
- break;
145
- }
146
- case 'r': {
147
- const { e, f } = record;
148
- this.sendRecord(e, f, record, sid);
149
- break;
150
- }
151
- default: {
152
- break;
153
- }
154
- }
155
- });
156
- }
157
- }
158
- exports.default = DataSubscriber;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lodash_1 = require("oak-domain/lib/utils/lodash");
4
+ const oak_domain_1 = require("oak-domain");
5
+ class DataSubscriber {
6
+ ns;
7
+ contextBuilder;
8
+ filterMap;
9
+ idEntityMap;
10
+ constructor(ns, contextBuilder) {
11
+ this.ns = ns;
12
+ this.contextBuilder = contextBuilder;
13
+ this.startup();
14
+ this.filterMap = {};
15
+ this.idEntityMap = {};
16
+ }
17
+ formCreateRoomRoutine(def) {
18
+ const { id, entity, filter } = def;
19
+ return (room) => {
20
+ if (room === id) {
21
+ console.log('instance:', process.env.NODE_APP_INSTANCE, 'add filter', room);
22
+ // 本房间不存在,说明这个filter是新出现的
23
+ if (this.filterMap[entity]) {
24
+ // id的唯一性由前台保证,重复则无视
25
+ Object.assign(this.filterMap[entity], {
26
+ [id]: filter,
27
+ });
28
+ }
29
+ else {
30
+ Object.assign(this.filterMap, {
31
+ [entity]: {
32
+ [id]: filter,
33
+ }
34
+ });
35
+ }
36
+ this.idEntityMap[id] = entity;
37
+ }
38
+ };
39
+ }
40
+ /**
41
+ * 来自外部的socket连接,监听数据变化
42
+ */
43
+ startup() {
44
+ this.ns.on('connection', async (socket) => {
45
+ try {
46
+ const { 'oak-cxt': cxtStr } = socket.handshake.headers;
47
+ const context = await this.contextBuilder(cxtStr);
48
+ socket.userId = context.getCurrentUserId();
49
+ socket.context = context;
50
+ socket.idMap = {};
51
+ socket.on('sub', async (data) => {
52
+ try {
53
+ console.log('instance:', process.env.NODE_APP_INSTANCE, 'on sub', JSON.stringify(data));
54
+ await Promise.all(data.map(async (ele) => {
55
+ const { id, entity, filter } = ele;
56
+ // 尝试select此filter,如果失败说明权限越界
57
+ await context.select(entity, {
58
+ data: {
59
+ id: 1,
60
+ },
61
+ filter,
62
+ }, {});
63
+ }));
64
+ }
65
+ catch (err) {
66
+ socket.emit('error', err.toString());
67
+ return;
68
+ }
69
+ data.forEach((ele) => {
70
+ const createRoomRoutine = this.formCreateRoomRoutine(ele);
71
+ this.ns.adapter.on('create-room', createRoomRoutine);
72
+ socket.join(ele.id);
73
+ this.ns.adapter.off('create-room', createRoomRoutine);
74
+ });
75
+ });
76
+ socket.on('unsub', (ids) => {
77
+ // console.log('instance:', process.env.NODE_APP_INSTANCE, 'on unsub', JSON.stringify(ids));
78
+ ids.forEach((id) => {
79
+ socket.leave(id);
80
+ });
81
+ });
82
+ }
83
+ catch (err) {
84
+ socket.emit('error', err.toString());
85
+ }
86
+ });
87
+ this.ns.adapter.on('delete-room', (room) => {
88
+ const entity = this.idEntityMap[room];
89
+ if (entity) {
90
+ // console.log('instance:', process.env.NODE_APP_INSTANCE, 'remove filter', room);
91
+ (0, lodash_1.unset)(this.filterMap[entity], room);
92
+ (0, lodash_1.unset)(this.idEntityMap, room);
93
+ }
94
+ });
95
+ this.ns.on('sendRecord', (entity, filter, record, isCreate) => {
96
+ console.log('instance:', process.env.NODE_APP_INSTANCE, 'get record from another', JSON.stringify(entity));
97
+ });
98
+ }
99
+ sendRecord(entity, filter, record, sid, isCreate) {
100
+ if (entity === 'spContractApplyment') {
101
+ console.log('instance:', process.env.NODE_APP_INSTANCE, 'sendRecord', JSON.stringify(entity));
102
+ }
103
+ this.ns.serverSideEmit('sendRecord', entity, filter, record, isCreate);
104
+ if (this.filterMap[entity]) {
105
+ Object.keys(this.filterMap[entity]).forEach(async (room) => {
106
+ const context = await this.contextBuilder();
107
+ const filter2 = this.filterMap[entity][room];
108
+ let needSend = false;
109
+ if (isCreate) {
110
+ // 如果是插入数据肯定是单行,使用相容性检测
111
+ const contained = await (0, oak_domain_1.checkFilterContains)(entity, context, filter2, filter, true);
112
+ needSend = contained;
113
+ }
114
+ else {
115
+ const repeled = await (0, oak_domain_1.checkFilterRepel)(entity, context, filter, filter2, true);
116
+ needSend = !repeled;
117
+ }
118
+ if (needSend) {
119
+ // console.log('instance:', process.env.NODE_APP_INSTANCE, 'needSend', JSON.stringify(room));
120
+ if (sid) {
121
+ this.ns.to(room).except(sid).emit('data', [record], [room]);
122
+ }
123
+ else {
124
+ this.ns.to(room).emit('data', [record], [room]);
125
+ }
126
+ }
127
+ });
128
+ }
129
+ }
130
+ onDataCommited(context) {
131
+ const sid = context.getSubscriberId();
132
+ const { opRecords } = context;
133
+ opRecords.forEach((record) => {
134
+ const { a } = record;
135
+ switch (a) {
136
+ case 'c': {
137
+ const { e, d } = record;
138
+ this.sendRecord(e, d, record, sid, true);
139
+ break;
140
+ }
141
+ case 'u': {
142
+ const { e, d, f } = record;
143
+ this.sendRecord(e, f, record, sid);
144
+ break;
145
+ }
146
+ case 'r': {
147
+ const { e, f } = record;
148
+ this.sendRecord(e, f, record, sid);
149
+ break;
150
+ }
151
+ default: {
152
+ break;
153
+ }
154
+ }
155
+ });
156
+ }
157
+ }
158
+ exports.default = DataSubscriber;
package/lib/DbStore.d.ts CHANGED
@@ -1,20 +1,20 @@
1
- import { MysqlStore, MySqlSelectOption, MysqlOperateOption } from 'oak-db';
2
- import { EntityDict, StorageSchema, Trigger, Checker, SelectOption, SelectFreeEntities, UpdateFreeDict, AuthDeduceRelationMap, VolatileTrigger, OperateOption } from 'oak-domain/lib/types';
3
- import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
4
- import { MySQLConfiguration } from 'oak-db/lib/MySQL/types/Configuration';
5
- import { BackendRuntimeContext } from 'oak-frontend-base';
6
- import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
7
- export declare class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends MysqlStore<ED, Cxt> implements AsyncRowStore<ED, Cxt> {
8
- private executor;
9
- private relationAuth;
10
- constructor(storageSchema: StorageSchema<ED>, contextBuilder: (scene?: string) => Promise<Cxt>, mysqlConfiguration: MySQLConfiguration, authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities?: SelectFreeEntities<ED>, updateFreeDict?: UpdateFreeDict<ED>, onVolatileTrigger?: <T extends keyof ED>(entity: T, trigger: VolatileTrigger<ED, T, Cxt>, ids: string[], cxtStr: string, option: OperateOption) => Promise<void>);
11
- protected cascadeUpdateAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
12
- operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
13
- select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: MySqlSelectOption): Promise<Partial<ED[T]["Schema"]>[]>;
14
- count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>;
15
- registerTrigger<T extends keyof ED>(trigger: Trigger<ED, T, Cxt>): void;
16
- registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
17
- setOnVolatileTrigger(onVolatileTrigger: <T extends keyof ED>(entity: T, trigger: VolatileTrigger<ED, T, Cxt>, ids: string[], cxtStr: string, option: OperateOption) => Promise<void>): void;
18
- execVolatileTrigger<T extends keyof ED>(entity: T, name: string, ids: string[], context: Cxt, option: OperateOption): Promise<void>;
19
- checkpoint(ts: number): Promise<number>;
20
- }
1
+ import { MysqlStore, MySqlSelectOption, MysqlOperateOption } from 'oak-db';
2
+ import { EntityDict, StorageSchema, Trigger, Checker, SelectOption, SelectFreeEntities, UpdateFreeDict, AuthDeduceRelationMap, VolatileTrigger, OperateOption } from 'oak-domain/lib/types';
3
+ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
4
+ import { MySQLConfiguration } from 'oak-db/lib/MySQL/types/Configuration';
5
+ import { BackendRuntimeContext } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
6
+ import { AsyncContext, AsyncRowStore } from 'oak-domain/lib/store/AsyncRowStore';
7
+ export declare class DbStore<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends MysqlStore<ED, Cxt> implements AsyncRowStore<ED, Cxt> {
8
+ private executor;
9
+ private relationAuth;
10
+ constructor(storageSchema: StorageSchema<ED>, contextBuilder: (scene?: string) => Promise<Cxt>, mysqlConfiguration: MySQLConfiguration, authDeduceRelationMap: AuthDeduceRelationMap<ED>, selectFreeEntities?: SelectFreeEntities<ED>, updateFreeDict?: UpdateFreeDict<ED>, onVolatileTrigger?: <T extends keyof ED>(entity: T, trigger: VolatileTrigger<ED, T, Cxt>, ids: string[], cxtStr: string, option: OperateOption) => Promise<void>);
11
+ protected cascadeUpdateAsync<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: AsyncContext<ED>, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
12
+ operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: MysqlOperateOption): Promise<import("oak-domain/lib/types").OperationResult<ED>>;
13
+ select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: MySqlSelectOption): Promise<Partial<ED[T]["Schema"]>[]>;
14
+ count<T extends keyof ED>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: SelectOption): Promise<number>;
15
+ registerTrigger<T extends keyof ED>(trigger: Trigger<ED, T, Cxt>): void;
16
+ registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
17
+ setOnVolatileTrigger(onVolatileTrigger: <T extends keyof ED>(entity: T, trigger: VolatileTrigger<ED, T, Cxt>, ids: string[], cxtStr: string, option: OperateOption) => Promise<void>): void;
18
+ execVolatileTrigger<T extends keyof ED>(entity: T, name: string, ids: string[], context: Cxt, option: OperateOption): Promise<void>;
19
+ checkpoint(ts: number): Promise<number>;
20
+ }
package/lib/DbStore.js CHANGED
@@ -1,122 +1,122 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DbStore = void 0;
4
- const oak_db_1 = require("oak-db");
5
- const TriggerExecutor_1 = require("oak-domain/lib/store/TriggerExecutor");
6
- const RelationAuth_1 = require("oak-domain/lib/store/RelationAuth");
7
- class DbStore extends oak_db_1.MysqlStore {
8
- executor;
9
- relationAuth;
10
- constructor(storageSchema, contextBuilder, mysqlConfiguration, authDeduceRelationMap, selectFreeEntities = [], updateFreeDict = {}, onVolatileTrigger) {
11
- super(storageSchema, mysqlConfiguration);
12
- this.executor = new TriggerExecutor_1.TriggerExecutor((scene) => contextBuilder(scene), undefined, onVolatileTrigger);
13
- this.relationAuth = new RelationAuth_1.RelationAuth(storageSchema, authDeduceRelationMap, selectFreeEntities, updateFreeDict);
14
- }
15
- async cascadeUpdateAsync(entity, operation, context, option) {
16
- // 如果是在modi处理过程中,所有的trigger也可以延时到apply时再处理(这时候因为modi中的数据并不实际存在,处理会有问题)
17
- if (!option.blockTrigger) {
18
- await this.executor.preOperation(entity, operation, context, option);
19
- }
20
- const result = await super.cascadeUpdateAsync(entity, operation, context, option);
21
- if (!option.blockTrigger) {
22
- await this.executor.postOperation(entity, operation, context, option);
23
- }
24
- return result;
25
- }
26
- async operate(entity, operation, context, option) {
27
- const autoCommit = !context.getCurrentTxnId();
28
- let result;
29
- if (autoCommit) {
30
- await context.begin();
31
- }
32
- try {
33
- await this.relationAuth.checkRelationAsync(entity, operation, context);
34
- result = await super.operate(entity, operation, context, option);
35
- }
36
- catch (err) {
37
- await context.rollback();
38
- throw err;
39
- }
40
- if (autoCommit) {
41
- await context.commit();
42
- }
43
- return result;
44
- }
45
- async select(entity, selection, context, option) {
46
- const autoCommit = !context.getCurrentTxnId();
47
- if (autoCommit) {
48
- await context.begin();
49
- }
50
- let result;
51
- // select的trigger应加在根select之前,cascade的select不加处理
52
- Object.assign(selection, {
53
- action: 'select',
54
- });
55
- if (!option.blockTrigger) {
56
- await this.executor.preOperation(entity, selection, context, option);
57
- }
58
- if (!option.dontCollect) {
59
- await this.relationAuth.checkRelationAsync(entity, selection, context);
60
- }
61
- try {
62
- result = await super.select(entity, selection, context, option);
63
- if (!option.blockTrigger) {
64
- await this.executor.postOperation(entity, selection, context, option, result);
65
- }
66
- }
67
- catch (err) {
68
- await context.rollback();
69
- throw err;
70
- }
71
- if (autoCommit) {
72
- await context.commit();
73
- }
74
- return result;
75
- }
76
- async count(entity, selection, context, option) {
77
- const autoCommit = !context.getCurrentTxnId();
78
- let result;
79
- if (autoCommit) {
80
- await context.begin();
81
- }
82
- try {
83
- // count不用检查权限,因为检查权限中本身要用到count
84
- // const selection2 = Object.assign({
85
- // action: 'select',
86
- // }, selection) as ED[T]['Operation'];
87
- // await this.relationAuth.checkRelationAsync(entity, selection2, context);
88
- // if (!option.blockTrigger) {
89
- // await this.executor.preOperation(entity, selection2, context, option);
90
- // }
91
- result = await super.count(entity, selection, context, option);
92
- /* count应该不存在后trigger吧
93
- if (!option.blockTrigger) {
94
- await this.executor.postOperation(entity, selection2, context, option);
95
- } */
96
- }
97
- catch (err) {
98
- await context.rollback();
99
- throw err;
100
- }
101
- if (autoCommit) {
102
- await context.commit();
103
- }
104
- return result;
105
- }
106
- registerTrigger(trigger) {
107
- this.executor.registerTrigger(trigger);
108
- }
109
- registerChecker(checker) {
110
- this.executor.registerChecker(checker);
111
- }
112
- setOnVolatileTrigger(onVolatileTrigger) {
113
- this.executor.setOnVolatileTrigger(onVolatileTrigger);
114
- }
115
- async execVolatileTrigger(entity, name, ids, context, option) {
116
- return this.executor.execVolatileTrigger(entity, name, ids, context, option);
117
- }
118
- checkpoint(ts) {
119
- return this.executor.checkpoint(ts);
120
- }
121
- }
122
- exports.DbStore = DbStore;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DbStore = void 0;
4
+ const oak_db_1 = require("oak-db");
5
+ const TriggerExecutor_1 = require("oak-domain/lib/store/TriggerExecutor");
6
+ const RelationAuth_1 = require("oak-domain/lib/store/RelationAuth");
7
+ class DbStore extends oak_db_1.MysqlStore {
8
+ executor;
9
+ relationAuth;
10
+ constructor(storageSchema, contextBuilder, mysqlConfiguration, authDeduceRelationMap, selectFreeEntities = [], updateFreeDict = {}, onVolatileTrigger) {
11
+ super(storageSchema, mysqlConfiguration);
12
+ this.executor = new TriggerExecutor_1.TriggerExecutor((scene) => contextBuilder(scene), undefined, onVolatileTrigger);
13
+ this.relationAuth = new RelationAuth_1.RelationAuth(storageSchema, authDeduceRelationMap, selectFreeEntities, updateFreeDict);
14
+ }
15
+ async cascadeUpdateAsync(entity, operation, context, option) {
16
+ // 如果是在modi处理过程中,所有的trigger也可以延时到apply时再处理(这时候因为modi中的数据并不实际存在,处理会有问题)
17
+ if (!option.blockTrigger) {
18
+ await this.executor.preOperation(entity, operation, context, option);
19
+ }
20
+ const result = await super.cascadeUpdateAsync(entity, operation, context, option);
21
+ if (!option.blockTrigger) {
22
+ await this.executor.postOperation(entity, operation, context, option);
23
+ }
24
+ return result;
25
+ }
26
+ async operate(entity, operation, context, option) {
27
+ const autoCommit = !context.getCurrentTxnId();
28
+ let result;
29
+ if (autoCommit) {
30
+ await context.begin();
31
+ }
32
+ try {
33
+ await this.relationAuth.checkRelationAsync(entity, operation, context);
34
+ result = await super.operate(entity, operation, context, option);
35
+ }
36
+ catch (err) {
37
+ await context.rollback();
38
+ throw err;
39
+ }
40
+ if (autoCommit) {
41
+ await context.commit();
42
+ }
43
+ return result;
44
+ }
45
+ async select(entity, selection, context, option) {
46
+ const autoCommit = !context.getCurrentTxnId();
47
+ if (autoCommit) {
48
+ await context.begin();
49
+ }
50
+ let result;
51
+ // select的trigger应加在根select之前,cascade的select不加处理
52
+ Object.assign(selection, {
53
+ action: 'select',
54
+ });
55
+ if (!option.blockTrigger) {
56
+ await this.executor.preOperation(entity, selection, context, option);
57
+ }
58
+ if (!option.dontCollect) {
59
+ await this.relationAuth.checkRelationAsync(entity, selection, context);
60
+ }
61
+ try {
62
+ result = await super.select(entity, selection, context, option);
63
+ if (!option.blockTrigger) {
64
+ await this.executor.postOperation(entity, selection, context, option, result);
65
+ }
66
+ }
67
+ catch (err) {
68
+ await context.rollback();
69
+ throw err;
70
+ }
71
+ if (autoCommit) {
72
+ await context.commit();
73
+ }
74
+ return result;
75
+ }
76
+ async count(entity, selection, context, option) {
77
+ const autoCommit = !context.getCurrentTxnId();
78
+ let result;
79
+ if (autoCommit) {
80
+ await context.begin();
81
+ }
82
+ try {
83
+ // count不用检查权限,因为检查权限中本身要用到count
84
+ // const selection2 = Object.assign({
85
+ // action: 'select',
86
+ // }, selection) as ED[T]['Operation'];
87
+ // await this.relationAuth.checkRelationAsync(entity, selection2, context);
88
+ // if (!option.blockTrigger) {
89
+ // await this.executor.preOperation(entity, selection2, context, option);
90
+ // }
91
+ result = await super.count(entity, selection, context, option);
92
+ /* count应该不存在后trigger吧
93
+ if (!option.blockTrigger) {
94
+ await this.executor.postOperation(entity, selection2, context, option);
95
+ } */
96
+ }
97
+ catch (err) {
98
+ await context.rollback();
99
+ throw err;
100
+ }
101
+ if (autoCommit) {
102
+ await context.commit();
103
+ }
104
+ return result;
105
+ }
106
+ registerTrigger(trigger) {
107
+ this.executor.registerTrigger(trigger);
108
+ }
109
+ registerChecker(checker) {
110
+ this.executor.registerChecker(checker);
111
+ }
112
+ setOnVolatileTrigger(onVolatileTrigger) {
113
+ this.executor.setOnVolatileTrigger(onVolatileTrigger);
114
+ }
115
+ async execVolatileTrigger(entity, name, ids, context, option) {
116
+ return this.executor.execVolatileTrigger(entity, name, ids, context, option);
117
+ }
118
+ checkpoint(ts) {
119
+ return this.executor.checkpoint(ts);
120
+ }
121
+ }
122
+ exports.DbStore = DbStore;
@@ -0,0 +1,23 @@
1
+ import { EntityDict, StorageSchema, EndpointItem } from 'oak-domain/lib/types';
2
+ import { VolatileTrigger } from 'oak-domain/lib/types/Trigger';
3
+ import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
4
+ import { BackendRuntimeContext } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
5
+ import { SyncConfigWrapper } from './types/Sync';
6
+ export default class Synchronizer<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> {
7
+ private config;
8
+ private schema;
9
+ private selfEncryptInfo?;
10
+ private remotePullInfoMap;
11
+ private remotePushChannel;
12
+ private pushOper;
13
+ private loadPublicKey;
14
+ private makeCreateOperTrigger;
15
+ constructor(config: SyncConfigWrapper<ED>, schema: StorageSchema<ED>);
16
+ /**
17
+ * 根据sync的定义,生成对应的 commit triggers
18
+ * @returns
19
+ */
20
+ getSyncTriggers(): VolatileTrigger<ED, keyof ED, Cxt>[];
21
+ private checkOperationConsistent;
22
+ getSelfEndpoint(): EndpointItem<ED, Cxt>;
23
+ }