增加了cacheInsesativeActions配置
This commit is contained in:
parent
ff67645f62
commit
22b66e824f
|
|
@ -113,7 +113,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict> extends Featu
|
|||
action: ED[T]['Action'];
|
||||
data?: ED[T]['Operation']['data'];
|
||||
filter?: ED[T]['Filter'];
|
||||
}, checkerTypes?: CheckerType[]): boolean | { [A in ED[T]["Action"]]: boolean | OakUserException<ED>; }[ED[T]["Action"]];
|
||||
}, checkerTypes?: CheckerType[], cacheInsensative?: true): boolean | { [A in ED[T]["Action"]]: boolean | OakUserException<ED>; }[ED[T]["Action"]];
|
||||
redoOperation(opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
|
|||
|
|
@ -360,17 +360,19 @@ export class Cache extends Feature {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
checkOperation(entity, operation, checkerTypes) {
|
||||
checkOperation(entity, operation, checkerTypes, cacheInsensative) {
|
||||
// 缓存同一id对同一action的判断,避免性能低下
|
||||
const { action, data, filter } = operation;
|
||||
let id;
|
||||
let ts;
|
||||
const checkTypeString = checkerTypes ? checkerTypes.join('-') : '$$all';
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts][entity][id][checkTypeString][action];
|
||||
if (!cacheInsensative) {
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts][entity][id][checkTypeString][action];
|
||||
}
|
||||
}
|
||||
}
|
||||
let rollback = this.begin(true);
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ function checkActionsAndCascadeEntities(rows, option) {
|
|||
const filter = (filter1 && filter2) ? combineFilters(this.state.oakEntity, this.features.cache.getSchema(), [
|
||||
filter1, filter2
|
||||
]) : (filter1 || filter2);
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes) === true) {
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes, option.cacheInsensativeActions?.includes(a2) || undefined) === true) {
|
||||
const action2 = checkActionAttrsIfNecessary(this.features.cache, this.state.oakEntity, action, rows.id);
|
||||
legalActions.push(action2);
|
||||
if (rows['#oakLegalActions']) {
|
||||
|
|
|
|||
|
|
@ -185,12 +185,12 @@ const oakBehavior = Behavior({
|
|||
select(entity, selection) {
|
||||
return select.call(this, entity, selection);
|
||||
},
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes) {
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes, cacheInsensative) {
|
||||
return this.features.cache.checkOperation(entity, {
|
||||
action,
|
||||
data,
|
||||
filter,
|
||||
}, checkerTypes);
|
||||
}, checkerTypes, cacheInsensative);
|
||||
},
|
||||
tryExecute(path, action) {
|
||||
const path2 = path
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export declare function createComponent<IsList extends boolean, ED extends Entit
|
|||
isDirty(path?: string | undefined): boolean;
|
||||
getFreshValue(path?: string | undefined): Partial<import("oak-domain/lib/types").GeneralEntityShape> | Partial<import("oak-domain/lib/types").GeneralEntityShape>[] | undefined;
|
||||
select<T2_2 extends keyof ED>(entity: T2_2, selection: ED[T2_2]["Selection"]): Partial<import("oak-domain/lib/types").GeneralEntityShape>[];
|
||||
checkOperation<T2_3 extends keyof ED>(entity: T2_3, operation: Omit<ED[T2_3]["Operation"], "id">, checkerTypes?: CheckerType[] | undefined): boolean | { [A in ED[T2_3]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[T2_3]["Action"]];
|
||||
checkOperation<T2_3 extends keyof ED>(entity: T2_3, operation: Omit<ED[T2_3]["Operation"], "id">, checkerTypes?: CheckerType[] | undefined, cacheInsensative?: true | undefined): boolean | { [A in ED[T2_3]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[T2_3]["Action"]];
|
||||
tryExecute(path?: string | undefined, action?: string | undefined): boolean | { [A_1 in ED[keyof ED]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[keyof ED]["Action"]];
|
||||
getOperations<T_7 extends keyof ED>(path?: string | undefined): {
|
||||
entity: keyof ED;
|
||||
|
|
|
|||
|
|
@ -179,8 +179,8 @@ class OakComponentBase extends React.PureComponent {
|
|||
select(entity, selection) {
|
||||
return select.call(this, entity, selection);
|
||||
}
|
||||
checkOperation(entity, operation, checkerTypes) {
|
||||
return this.features.cache.checkOperation(entity, operation, checkerTypes);
|
||||
checkOperation(entity, operation, checkerTypes, cacheInsensative) {
|
||||
return this.features.cache.checkOperation(entity, operation, checkerTypes, cacheInsensative);
|
||||
}
|
||||
tryExecute(path, action) {
|
||||
const path2 = path
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ interface ComponentOption<IsList extends boolean, ED extends EntityDict & BaseEn
|
|||
* 需要校验的actions
|
||||
*/
|
||||
actions?: ActionDef<ED, T>[] | ((this: ComponentPublicThisType<ED, T, Cxt, FrontCxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod, EMethod>) => ActionDef<ED, T>[]);
|
||||
cacheInsensativeActions?: ActionDef<ED, T>[];
|
||||
/**
|
||||
* 需要获取的数据字段
|
||||
* 若嵌套在list中,需要保证父list组件能够覆盖子组件的projection
|
||||
|
|
@ -269,7 +270,7 @@ export type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T
|
|||
action: ED[T2]['Action'];
|
||||
data?: ED[T2]['Operation']['data'];
|
||||
filter?: ED[T2]['Filter'];
|
||||
}, checkerTypes?: CheckerType[]) => boolean | OakUserException<ED>;
|
||||
}, checkerTypes?: CheckerType[], cacheInsensative?: true) => boolean | OakUserException<ED>;
|
||||
tryExecute: (path?: string, action?: ED[T]['Action']) => boolean | OakUserException<ED>;
|
||||
getOperations: (path?: string) => {
|
||||
operation: ED[T]['Operation'];
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict> extends Featu
|
|||
action: ED[T]['Action'];
|
||||
data?: ED[T]['Operation']['data'];
|
||||
filter?: ED[T]['Filter'];
|
||||
}, checkerTypes?: CheckerType[]): boolean | { [A in ED[T]["Action"]]: boolean | OakUserException<ED>; }[ED[T]["Action"]];
|
||||
}, checkerTypes?: CheckerType[], cacheInsensative?: true): boolean | { [A in ED[T]["Action"]]: boolean | OakUserException<ED>; }[ED[T]["Action"]];
|
||||
redoOperation(opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
|
|||
|
|
@ -363,17 +363,19 @@ class Cache extends Feature_1.Feature {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
checkOperation(entity, operation, checkerTypes) {
|
||||
checkOperation(entity, operation, checkerTypes, cacheInsensative) {
|
||||
// 缓存同一id对同一action的判断,避免性能低下
|
||||
const { action, data, filter } = operation;
|
||||
let id;
|
||||
let ts;
|
||||
const checkTypeString = checkerTypes ? checkerTypes.join('-') : '$$all';
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts][entity][id][checkTypeString][action];
|
||||
if (!cacheInsensative) {
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts][entity][id][checkTypeString][action];
|
||||
}
|
||||
}
|
||||
}
|
||||
let rollback = this.begin(true);
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ function checkActionsAndCascadeEntities(rows, option) {
|
|||
const filter = (filter1 && filter2) ? (0, filter_1.combineFilters)(this.state.oakEntity, this.features.cache.getSchema(), [
|
||||
filter1, filter2
|
||||
]) : (filter1 || filter2);
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes) === true) {
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes, option.cacheInsensativeActions?.includes(a2) || undefined) === true) {
|
||||
const action2 = checkActionAttrsIfNecessary(this.features.cache, this.state.oakEntity, action, rows.id);
|
||||
legalActions.push(action2);
|
||||
if (rows['#oakLegalActions']) {
|
||||
|
|
|
|||
|
|
@ -188,12 +188,12 @@ const oakBehavior = Behavior({
|
|||
select(entity, selection) {
|
||||
return page_common_1.select.call(this, entity, selection);
|
||||
},
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes) {
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes, cacheInsensative) {
|
||||
return this.features.cache.checkOperation(entity, {
|
||||
action,
|
||||
data,
|
||||
filter,
|
||||
}, checkerTypes);
|
||||
}, checkerTypes, cacheInsensative);
|
||||
},
|
||||
tryExecute(path, action) {
|
||||
const path2 = path
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export declare function createComponent<IsList extends boolean, ED extends Entit
|
|||
isDirty(path?: string | undefined): boolean;
|
||||
getFreshValue(path?: string | undefined): Partial<import("oak-domain/lib/types").GeneralEntityShape> | Partial<import("oak-domain/lib/types").GeneralEntityShape>[] | undefined;
|
||||
select<T2_2 extends keyof ED>(entity: T2_2, selection: ED[T2_2]["Selection"]): Partial<import("oak-domain/lib/types").GeneralEntityShape>[];
|
||||
checkOperation<T2_3 extends keyof ED>(entity: T2_3, operation: Omit<ED[T2_3]["Operation"], "id">, checkerTypes?: CheckerType[] | undefined): boolean | { [A in ED[T2_3]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[T2_3]["Action"]];
|
||||
checkOperation<T2_3 extends keyof ED>(entity: T2_3, operation: Omit<ED[T2_3]["Operation"], "id">, checkerTypes?: CheckerType[] | undefined, cacheInsensative?: true | undefined): boolean | { [A in ED[T2_3]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[T2_3]["Action"]];
|
||||
tryExecute(path?: string | undefined, action?: string | undefined): boolean | { [A_1 in ED[keyof ED]["Action"]]: boolean | import("oak-domain/lib/types").OakUserException<ED>; }[ED[keyof ED]["Action"]];
|
||||
getOperations<T_7 extends keyof ED>(path?: string | undefined): {
|
||||
entity: keyof ED;
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@ class OakComponentBase extends react_1.default.PureComponent {
|
|||
select(entity, selection) {
|
||||
return page_common_1.select.call(this, entity, selection);
|
||||
}
|
||||
checkOperation(entity, operation, checkerTypes) {
|
||||
return this.features.cache.checkOperation(entity, operation, checkerTypes);
|
||||
checkOperation(entity, operation, checkerTypes, cacheInsensative) {
|
||||
return this.features.cache.checkOperation(entity, operation, checkerTypes, cacheInsensative);
|
||||
}
|
||||
tryExecute(path, action) {
|
||||
const path2 = path
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ interface ComponentOption<IsList extends boolean, ED extends EntityDict & BaseEn
|
|||
* 需要校验的actions
|
||||
*/
|
||||
actions?: ActionDef<ED, T>[] | ((this: ComponentPublicThisType<ED, T, Cxt, FrontCxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod, EMethod>) => ActionDef<ED, T>[]);
|
||||
cacheInsensativeActions?: ActionDef<ED, T>[];
|
||||
/**
|
||||
* 需要获取的数据字段
|
||||
* 若嵌套在list中,需要保证父list组件能够覆盖子组件的projection
|
||||
|
|
@ -269,7 +270,7 @@ export type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T
|
|||
action: ED[T2]['Action'];
|
||||
data?: ED[T2]['Operation']['data'];
|
||||
filter?: ED[T2]['Filter'];
|
||||
}, checkerTypes?: CheckerType[]) => boolean | OakUserException<ED>;
|
||||
}, checkerTypes?: CheckerType[], cacheInsensative?: true) => boolean | OakUserException<ED>;
|
||||
tryExecute: (path?: string, action?: ED[T]['Action']) => boolean | OakUserException<ED>;
|
||||
getOperations: (path?: string) => {
|
||||
operation: ED[T]['Operation'];
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export class Cache<ED extends EntityDict & BaseEntityDict> extends Feature {
|
|||
private attrUpdateMatrix?: AttrUpdateMatrix<ED>;
|
||||
private connector: Connector<ED, SyncContext<ED>>;
|
||||
private baseRelationAuth: BaseRelationAuth<ED>;
|
||||
|
||||
|
||||
// 缓存在某一时间戳状态下,对某行进行某个action的判断结果
|
||||
private entityActionAuthDict: {
|
||||
[ts: number]: {
|
||||
|
|
@ -288,7 +288,7 @@ export class Cache<ED extends EntityDict & BaseEntityDict> extends Feature {
|
|||
else {
|
||||
if (oldest > 0) {
|
||||
// 说明key曾经都取过了,只取updateAt在oldest之后的数据
|
||||
selection.filter = selection.filter ?combineFilters(entity, this.getSchema(), [selection.filter, {
|
||||
selection.filter = selection.filter ? combineFilters(entity, this.getSchema(), [selection.filter, {
|
||||
$$updateAt$$: {
|
||||
$gte: oldest,
|
||||
}
|
||||
|
|
@ -500,19 +500,21 @@ export class Cache<ED extends EntityDict & BaseEntityDict> extends Feature {
|
|||
data?: ED[T]['Operation']['data'],
|
||||
filter?: ED[T]['Filter'],
|
||||
},
|
||||
checkerTypes?: CheckerType[]
|
||||
checkerTypes?: CheckerType[],
|
||||
cacheInsensative?: true,
|
||||
) {
|
||||
// 缓存同一id对同一action的判断,避免性能低下
|
||||
const { action, data, filter } = operation;
|
||||
let id: string | undefined;
|
||||
let ts: number | undefined;
|
||||
|
||||
const checkTypeString = checkerTypes ? checkerTypes.join('-') : '$$all';
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts]![entity]![id]![checkTypeString]![action]!;
|
||||
if (!cacheInsensative) {
|
||||
if (filter && !data && typeof filter.id === 'string') {
|
||||
id = filter.id;
|
||||
ts = this.cacheStore.getLastUpdateTs();
|
||||
if (this.entityActionAuthDict[ts]?.[entity]?.[id]?.[checkTypeString]?.hasOwnProperty(action)) {
|
||||
return this.entityActionAuthDict[ts]![entity]![id]![checkTypeString]![action]!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ function checkActionsAndCascadeEntities<
|
|||
const filter = (filter1 && filter2) ? combineFilters<ED, T>(this.state.oakEntity, this.features.cache.getSchema(), [
|
||||
filter1, filter2
|
||||
]) : (filter1 || filter2);
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes) === true) {
|
||||
if (filter && this.checkOperation(this.state.oakEntity, { action: a2, filter }, checkTypes, option.cacheInsensativeActions?.includes(a2) || undefined) === true) {
|
||||
const action2 = checkActionAttrsIfNecessary(this.features.cache, this.state.oakEntity, action, rows.id!);
|
||||
legalActions.push(action2);
|
||||
if (rows['#oakLegalActions']) {
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ const oakBehavior = Behavior<
|
|||
return select.call(this as any, entity as any, selection);
|
||||
},
|
||||
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes) {
|
||||
checkOperation(entity, { action, data, filter }, checkerTypes, cacheInsensative) {
|
||||
return this.features.cache.checkOperation(
|
||||
entity,
|
||||
{
|
||||
|
|
@ -323,7 +323,8 @@ const oakBehavior = Behavior<
|
|||
data,
|
||||
filter,
|
||||
},
|
||||
checkerTypes as CheckerType[]
|
||||
checkerTypes as CheckerType[],
|
||||
cacheInsensative
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -354,12 +354,14 @@ abstract class OakComponentBase<
|
|||
checkOperation<T2 extends keyof ED>(
|
||||
entity: T2,
|
||||
operation: Omit<ED[T2]['Operation'], 'id'>,
|
||||
checkerTypes?: CheckerType[]
|
||||
checkerTypes?: CheckerType[],
|
||||
cacheInsensative?: true,
|
||||
) {
|
||||
return this.features.cache.checkOperation(
|
||||
entity,
|
||||
operation,
|
||||
checkerTypes as CheckerType[]
|
||||
checkerTypes as CheckerType[],
|
||||
cacheInsensative
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ interface ComponentOption<
|
|||
* 需要校验的actions
|
||||
*/
|
||||
actions?: ActionDef<ED, T>[] | ((this: ComponentPublicThisType<ED, T, Cxt, FrontCxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod, EMethod>) => ActionDef<ED, T>[]);
|
||||
cacheInsensativeActions?: ActionDef<ED, T>[];
|
||||
/**
|
||||
* 需要获取的数据字段
|
||||
* 若嵌套在list中,需要保证父list组件能够覆盖子组件的projection
|
||||
|
|
@ -494,7 +495,8 @@ export type OakCommonComponentMethods<
|
|||
data?: ED[T2]['Operation']['data'],
|
||||
filter?: ED[T2]['Filter'],
|
||||
},
|
||||
checkerTypes?: CheckerType[]
|
||||
checkerTypes?: CheckerType[],
|
||||
cacheInsensative?: true
|
||||
) => boolean | OakUserException<ED>;
|
||||
tryExecute: (path?: string, action?: ED[T]['Action']) => boolean | OakUserException<ED>;
|
||||
getOperations: (
|
||||
|
|
|
|||
Loading…
Reference in New Issue