cascadeStore在reinforceSelection时,前台处理的不够精细,会造成无限递归

This commit is contained in:
Xu Chang 2023-07-24 20:19:50 +08:00
parent 46c037db48
commit 5a2651a4c3
2 changed files with 118 additions and 115 deletions

View File

@ -189,95 +189,97 @@ var CascadeStore = /** @class */ (function (_super) {
}
var toBeAssignNode2 = {}; // 用来记录在表达式中涉及到的结点
var projectionNodeDict = {};
var checkProjectionNode = function (entity2, projectionNode) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var necessaryAttrs, attr, exprResult, nodeName, rel, data_1, userId;
var checkProjectionNode = function (entity2, projectionNode) {
var _a, _b, _c;
return tslib_1.__generator(this, function (_d) {
necessaryAttrs = ['id', '$$createAt$$'];
for (attr in projectionNode) {
if (attr === '#id') {
(0, assert_1.default)(!projectionNodeDict[projectionNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(projectionNode[attr]));
Object.assign(projectionNodeDict, (_a = {},
_a[projectionNode[attr]] = projectionNode,
_a));
if (toBeAssignNode2[projectionNode[attr]]) {
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]]);
var necessaryAttrs = ['id', '$$createAt$$']; // 有的页面依赖于其它页面取数据有时两个页面的filter的差异会导致有一个加createAt有一个不加此时可能产生前台取数据不完整的异常。先统一加上
for (var attr in projectionNode) {
if (attr === '#id') {
(0, assert_1.default)(!projectionNodeDict[projectionNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(projectionNode[attr]));
Object.assign(projectionNodeDict, (_a = {},
_a[projectionNode[attr]] = projectionNode,
_a));
if (toBeAssignNode2[projectionNode[attr]]) {
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]]);
}
}
else {
if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
var exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]);
for (var nodeName in exprResult) {
if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]);
}
else if (projectionNodeDict[nodeName]) {
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]);
}
else {
if (toBeAssignNode2[nodeName]) {
(_b = toBeAssignNode2[nodeName]).push.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false));
}
else {
Object.assign(toBeAssignNode2, (_c = {},
_c[nodeName] = exprResult[nodeName],
_c));
}
}
}
}
else {
if (attr.toLowerCase().startsWith(types_1.EXPRESSION_PREFIX)) {
exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]);
for (nodeName in exprResult) {
if (nodeName === '#current') {
checkNode(projectionNode, exprResult[nodeName]);
}
else if (projectionNodeDict[nodeName]) {
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]);
}
else {
if (toBeAssignNode2[nodeName]) {
(_b = toBeAssignNode2[nodeName]).push.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false));
}
else {
Object.assign(toBeAssignNode2, (_c = {},
_c[nodeName] = exprResult[nodeName],
_c));
}
}
}
var rel = (0, relation_1.judgeRelation)(_this.getSchema(), entity2, attr);
if (rel === 1) {
necessaryAttrs.push(attr);
}
else {
rel = (0, relation_1.judgeRelation)(this.getSchema(), entity2, attr);
if (rel === 1) {
necessaryAttrs.push(attr);
else if (rel === 2) {
// entity/entityId反指
necessaryAttrs.push('entity', 'entityId');
checkProjectionNode(attr, projectionNode[attr]);
}
else if (typeof rel === 'string') {
necessaryAttrs.push("".concat(attr, "Id"));
checkProjectionNode(rel, projectionNode[attr]);
}
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
var data_1 = projectionNode[attr].data;
if (rel[1]) {
checkNode(data_1, [rel[1]]);
}
else if (rel === 2) {
// entity/entityId反指
necessaryAttrs.push('entity', 'entityId');
checkProjectionNode(attr, projectionNode[attr]);
}
else if (typeof rel === 'string') {
necessaryAttrs.push("".concat(attr, "Id"));
checkProjectionNode(rel, projectionNode[attr]);
}
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
data_1 = projectionNode[attr].data;
if (rel[1]) {
checkNode(data_1, [rel[1]]);
}
else {
checkNode(data_1, ['entity', 'entityId']);
}
this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities);
else {
checkNode(data_1, ['entity', 'entityId']);
}
_this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities);
}
}
checkNode(projectionNode, necessaryAttrs);
}
// 如果对象中指向一对多的Modi此时加上指向Modi的projection
if (this.getSchema()[entity2].toModi) {
Object.assign(projectionNode, {
modi$entity: {
$entity: 'modi',
data: {
id: 1,
targetEntity: 1,
entity: 1,
entityId: 1,
action: 1,
iState: 1,
data: 1,
filter: 1,
},
filter: {
iState: 'active',
},
}
});
}
userId = context.getCurrentUserId(true);
if (context instanceof AsyncRowStore_1.AsyncContext && userId && !env_1.SYSTEM_RESERVE_ENTITIES.includes(entity2)) {
if (this.getSchema()[entity2].relation && !projectionNode.userRelation$entity) {
checkNode(projectionNode, necessaryAttrs);
}
// 如果对象中指向一对多的Modi此时加上指向Modi的projection
if (_this.getSchema()[entity2].toModi) {
Object.assign(projectionNode, {
modi$entity: {
$entity: 'modi',
data: {
id: 1,
targetEntity: 1,
entity: 1,
entityId: 1,
action: 1,
iState: 1,
data: 1,
filter: 1,
},
filter: {
iState: 'active',
},
}
});
}
// 如果对象上有relation关系在此将本用户相关的relation和actionAuth全部取出
// 还要将actionAuth上没有relation关系但destEntity为本对象的行也全部取出这些是指向userId的可能路径
// 放在这里有点怪异,暂先这样
if (context instanceof AsyncRowStore_1.AsyncContext) {
var userId = context.getCurrentUserId(true);
if (userId && !env_1.SYSTEM_RESERVE_ENTITIES.includes(entity2)) {
if (_this.getSchema()[entity2].relation && !projectionNode.userRelation$entity) {
Object.assign(projectionNode, {
userRelation$entity: {
$entity: 'userRelation',
@ -311,9 +313,8 @@ var CascadeStore = /** @class */ (function (_super) {
}
noRelationDestEntities.push(entity2);
}
return [2 /*return*/];
});
}); };
}
};
checkProjectionNode(entity, data);
if (!sorter && relevantIds.length === 0) {
// 如果没有sorter就给予一个按createAt逆序的sorter

View File

@ -198,7 +198,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const toBeAssignNode2: Record<string, string[]> = {}; // 用来记录在表达式中涉及到的结点
const projectionNodeDict: Record<string, ED[keyof ED]['Selection']['data']> = {};
const checkProjectionNode = async (entity2: keyof ED, projectionNode: ED[keyof ED]['Selection']['data']) => {
const checkProjectionNode = (entity2: keyof ED, projectionNode: ED[keyof ED]['Selection']['data']) => {
const necessaryAttrs: string[] = ['id', '$$createAt$$']; // 有的页面依赖于其它页面取数据有时两个页面的filter的差异会导致有一个加createAt有一个不加此时可能产生前台取数据不完整的异常。先统一加上
for (const attr in projectionNode) {
if (attr === '#id') {
@ -286,41 +286,43 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
// 如果对象上有relation关系在此将本用户相关的relation和actionAuth全部取出
// 还要将actionAuth上没有relation关系但destEntity为本对象的行也全部取出这些是指向userId的可能路径
// 放在这里有点怪异,暂先这样
const userId = context.getCurrentUserId(true);
if (context instanceof AsyncContext && userId && !SYSTEM_RESERVE_ENTITIES.includes(entity2 as string)) {
if (this.getSchema()[entity2].relation && !projectionNode.userRelation$entity) {
Object.assign(projectionNode, {
userRelation$entity: {
$entity: 'userRelation',
data: {
id: 1,
entity: 1,
entityId: 1,
userId: 1,
relationId: 1,
relation: {
if (context instanceof AsyncContext) {
const userId = context.getCurrentUserId(true);
if (userId && !SYSTEM_RESERVE_ENTITIES.includes(entity2 as string)) {
if (this.getSchema()[entity2].relation && !projectionNode.userRelation$entity) {
Object.assign(projectionNode, {
userRelation$entity: {
$entity: 'userRelation',
data: {
id: 1,
name: 1,
display: 1,
actionAuth$relation: {
$entity: 'actionAuth',
data: {
id: 1,
deActions: 1,
destEntity: 1,
path: 1,
relationId: 1,
},
entity: 1,
entityId: 1,
userId: 1,
relationId: 1,
relation: {
id: 1,
name: 1,
display: 1,
actionAuth$relation: {
$entity: 'actionAuth',
data: {
id: 1,
deActions: 1,
destEntity: 1,
path: 1,
relationId: 1,
},
}
}
}
},
filter: {
userId,
},
} as ED['userRelation']['Selection'],
});
},
filter: {
userId,
},
} as ED['userRelation']['Selection'],
});
}
noRelationDestEntities.push(entity2 as string);
}
noRelationDestEntities.push(entity2 as string);
}
};
checkProjectionNode(entity, data);