缓存在某一时间戳状态下,对某行进行某个action的判断结果

This commit is contained in:
Xu Chang 2024-09-15 15:18:11 +08:00
parent b06ed4f025
commit c2c073dc21
7 changed files with 57 additions and 49 deletions

View File

@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncContext = void 0;
const tslib_1 = require("tslib");
const types_1 = require("../types");
const action_1 = require("../actions/action");
const assert_1 = tslib_1.__importDefault(require("assert"));
const filter_1 = require("./filter");
@ -81,9 +82,14 @@ class AsyncContext {
break;
}
case 'remove': {
const deleteAt = data[types_1.DeleteAtAttribute];
(0, assert_1.default)(deleteAt);
this.opRecords.push({
id,
a: 'r',
d: {
[types_1.DeleteAtAttribute]: deleteAt,
},
e: entity,
f: filter,
});

View File

@ -67,7 +67,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
afterFns: (() => R)[];
};
protected preProcessDataCreated<T extends keyof ED>(entity: T, data: ED[T]['Create']['data']): void;
protected preProcessDataUpdated(data: Record<string, any>): void;
protected preProcessDataUpdated(action: string, data: Record<string, any>, async?: true): void;
judgeRelation(entity: keyof ED, attr: string): string | 1 | 2 | string[] | 0 | -1;
/**
* update过程无关的例程放在这里later动作的处理oper的记录以及对record的收集等

View File

@ -1012,8 +1012,8 @@ class CascadeStore extends RowStore_1.RowStore {
}
}
Object.assign(data2, {
[Entity_1.CreateAtAttribute]: now,
[Entity_1.UpdateAtAttribute]: now,
[Entity_1.CreateAtAttribute]: data2[Entity_1.CreateAtAttribute] || now,
[Entity_1.UpdateAtAttribute]: data2[Entity_1.UpdateAtAttribute] || now,
[Entity_1.DeleteAtAttribute]: null,
});
};
@ -1025,9 +1025,18 @@ class CascadeStore extends RowStore_1.RowStore {
}
}
// 对更新的数据去掉所有的undefined属性
preProcessDataUpdated(data) {
preProcessDataUpdated(action, data, async) {
const undefinedKeys = Object.keys(data).filter(ele => data[ele] === undefined);
undefinedKeys.forEach(ele => (0, lodash_1.unset)(data, ele));
// 优化一下,如果不更新任何属性,则不实际执行
const now = Date.now();
// 后台应该还是以实际操作时间为准前台以传入的updateAt来界定操作的产生“时间”这里可用来避免同一次更新被算做多次
if ((Object.keys(data).length > 0 || action !== 'update') && (!data[Entity_1.UpdateAtAttribute] || async)) {
data[Entity_1.UpdateAtAttribute] = now;
}
if (action === 'remove' && (!data[Entity_1.DeleteAtAttribute] || async)) {
data[Entity_1.DeleteAtAttribute] = now;
}
}
judgeRelation(entity, attr) {
return (0, relation_1.judgeRelation)(this.storageSchema, entity, attr);
@ -1257,7 +1266,7 @@ class CascadeStore extends RowStore_1.RowStore {
});
}
if (data) {
this.preProcessDataUpdated(data);
this.preProcessDataUpdated(action, data, true);
}
if (option.modiParentEntity && !['modi', 'modiEntity'].includes(entity)) {
// 延时更新变成对modi的插入
@ -1406,10 +1415,6 @@ class CascadeStore extends RowStore_1.RowStore {
else {
const updateAttrCount = Object.keys(data).length;
if (updateAttrCount > 0) {
// 优化一下,如果不更新任何属性,则不实际执行
Object.assign(data, {
[Entity_1.UpdateAtAttribute]: now,
});
if (!option.dontCollect) {
context.saveOpRecord(entity, {
id: operId,
@ -1423,11 +1428,6 @@ class CascadeStore extends RowStore_1.RowStore {
});
}
}
else if (action !== 'update') {
// 如果不是update动作而是用户自定义的动作这里还是要记录oper
await createOper();
return {};
}
else {
return {};
}
@ -1483,15 +1483,10 @@ class CascadeStore extends RowStore_1.RowStore {
if (action === 'remove') {
}
else {
this.preProcessDataUpdated(action, data);
const updateAttrCount = Object.keys(data).length;
if (updateAttrCount > 0) {
if (updateAttrCount == 0) {
// 优化一下,如果不更新任何属性,则不实际执行
Object.assign(data, {
$$updateAt$$: now,
});
this.preProcessDataUpdated(data);
}
else {
return 0;
}
}

View File

@ -162,6 +162,9 @@ export type UpdateOpResult<ED extends EntityDict, T extends keyof ED> = {
export type RemoveOpResult<ED extends EntityDict, T extends keyof ED> = {
id: string;
a: 'r';
d: {
[DeleteAtAttribute]: number;
};
e: T;
f?: Filter;
};

View File

@ -1,5 +1,5 @@
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult, ClusterInfo, CreateOpResult, UpdateOpResult } from "../types";
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult, ClusterInfo, CreateOpResult, UpdateOpResult, DeleteAtAttribute } from "../types";
import { EntityDict as BaseEntityDict } from '../base-app-domain';
import { readOnlyActions } from '../actions/action';
import assert from "assert";
@ -44,7 +44,7 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
const newContext = (new (Object.getPrototypeOf(this).constructor)(this.rowStore)) as typeof this;
await newContext.begin();
await newContext.initialize(data, true);
newContext.opRecords = [];
newContext.events = {
commit: [],
@ -61,7 +61,7 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
throw err;
}
}
getHeader(key: string): string | string[] | undefined {
if (this.headers) {
return this.headers[key];
@ -98,9 +98,14 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
break;
}
case 'remove': {
const deleteAt = (<ED[T]['Remove']['data']>data)[DeleteAtAttribute];
assert(deleteAt);
this.opRecords.push({
id,
a: 'r',
d: {
[DeleteAtAttribute]: deleteAt,
},
e: entity,
f: filter,
});
@ -134,7 +139,7 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
}
else if (filter) {
const ids = getRelevantIds(filter);
if (ids.length > 0 ) {
if (ids.length > 0) {
return ids;
}
}
@ -144,7 +149,7 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
);
if (oper) {
const { a } = oper;
assert (a !== 'create');
assert(a !== 'create');
const { f } = oper as UpdateOpResult<ED, keyof ED>;
assert(f && f?.id?.$in && f!.id!.$in! instanceof Array);
return f!.id!.$in!;
@ -188,7 +193,7 @@ export abstract class AsyncContext<ED extends EntityDict & BaseEntityDict> imple
if (this.uuid) {
await this.rowStore.rollback(this.uuid!);
const { rollback: rollbackEvents } = this.events;
// 回退时不能等在跨事务trigger上
const cxtStr = await this.toString();
rollbackEvents.forEach(

View File

@ -1260,8 +1260,8 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}
}
Object.assign(data2, {
[CreateAtAttribute]: now,
[UpdateAtAttribute]: now,
[CreateAtAttribute]: data2[CreateAtAttribute] || now,
[UpdateAtAttribute]: data2[UpdateAtAttribute] || now,
[DeleteAtAttribute]: null,
});
}
@ -1276,13 +1276,23 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}
// 对更新的数据去掉所有的undefined属性
protected preProcessDataUpdated(data: Record<string, any>) {
protected preProcessDataUpdated(action: string, data: Record<string, any>, async?: true) {
const undefinedKeys = Object.keys(data).filter(
ele => data[ele] === undefined
);
undefinedKeys.forEach(
ele => unset(data, ele)
);
// 优化一下,如果不更新任何属性,则不实际执行
const now = Date.now();
// 后台应该还是以实际操作时间为准前台以传入的updateAt来界定操作的产生“时间”这里可用来避免同一次更新被算做多次
if ((Object.keys(data).length > 0 || action !== 'update') && (!data[UpdateAtAttribute] || async)) {
data[UpdateAtAttribute] = now;
}
if (action === 'remove' && (!data[DeleteAtAttribute] || async)) {
data[DeleteAtAttribute] = now;
}
}
@ -1535,7 +1545,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
);
}
if (data) {
this.preProcessDataUpdated(data);
this.preProcessDataUpdated(action, data, true);
}
if (option.modiParentEntity && !['modi', 'modiEntity'].includes(entity as string)) {
@ -1681,22 +1691,18 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
context.saveOpRecord(entity, {
id: operId,
action,
data: {},
data: data as ED[T]['Update']['data'],
filter: {
id: {
$in: ids,
}
}
},
});
}
}
else {
const updateAttrCount = Object.keys(data).length;
if (updateAttrCount > 0) {
// 优化一下,如果不更新任何属性,则不实际执行
Object.assign(data, {
[UpdateAtAttribute]: now,
});
if (!option.dontCollect) {
context.saveOpRecord(entity, {
id: operId,
@ -1710,11 +1716,6 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
});
}
}
else if (action !== 'update') {
// 如果不是update动作而是用户自定义的动作这里还是要记录oper
await createOper();
return {};
}
else {
return {};
}
@ -1784,15 +1785,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
if (action === 'remove') {
}
else {
this.preProcessDataUpdated(action, data);
const updateAttrCount = Object.keys(data).length;
if (updateAttrCount > 0) {
if (updateAttrCount == 0) {
// 优化一下,如果不更新任何属性,则不实际执行
Object.assign(data, {
$$updateAt$$: now,
});
this.preProcessDataUpdated(data);
}
else {
return 0;
}
}

View File

@ -208,6 +208,9 @@ export type UpdateOpResult<ED extends EntityDict, T extends keyof ED> = {
export type RemoveOpResult<ED extends EntityDict, T extends keyof ED> = {
id: string;
a: 'r',
d: {
[DeleteAtAttribute]: number;
};
e: T;
f?: Filter;
};