修正了reinforceSelection中的部分无用代码,增加了几个未来用于subscribe的结构定义
This commit is contained in:
parent
a506f2acc2
commit
060c208804
|
|
@ -24,13 +24,12 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
}
|
}
|
||||||
CascadeStore.prototype.reinforceSelectionAsync = function (entity, selection, context, option) {
|
CascadeStore.prototype.reinforceSelectionAsync = function (entity, selection, context, option) {
|
||||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||||
var noRelationDestEntities, rewriterPromises;
|
var rewriterPromises;
|
||||||
var _this = this;
|
var _this = this;
|
||||||
return tslib_1.__generator(this, function (_a) {
|
return tslib_1.__generator(this, function (_a) {
|
||||||
switch (_a.label) {
|
switch (_a.label) {
|
||||||
case 0:
|
case 0:
|
||||||
noRelationDestEntities = [];
|
this.reinforceSelectionInner(entity, selection, context);
|
||||||
this.reinforceSelectionInner(entity, selection, context, noRelationDestEntities);
|
|
||||||
rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); });
|
rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); });
|
||||||
if (!(rewriterPromises.length > 0)) return [3 /*break*/, 2];
|
if (!(rewriterPromises.length > 0)) return [3 /*break*/, 2];
|
||||||
return [4 /*yield*/, Promise.all(rewriterPromises)];
|
return [4 /*yield*/, Promise.all(rewriterPromises)];
|
||||||
|
|
@ -44,13 +43,16 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
};
|
};
|
||||||
CascadeStore.prototype.reinforceSelectionSync = function (entity, selection, context, option) {
|
CascadeStore.prototype.reinforceSelectionSync = function (entity, selection, context, option) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
this.reinforceSelectionInner(entity, selection, context, []);
|
this.reinforceSelectionInner(entity, selection, context);
|
||||||
var rewriterPromises = this.selectionRewriters.map(function (ele) { return ele(_this.getSchema(), entity, selection, context); });
|
this.selectionRewriters.forEach(function (ele) {
|
||||||
|
var result = ele(_this.getSchema(), entity, selection, context);
|
||||||
|
(0, assert_1.default)(!(result instanceof Promise));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
CascadeStore.prototype.reinforceSelectionInner = function (entity, selection, context, noRelationDestEntities) {
|
CascadeStore.prototype.reinforceSelectionInner = function (entity, selection, context) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
var filter = selection.filter, data = selection.data, sorter = selection.sorter;
|
var filter = selection.filter, data = selection.data, sorter = selection.sorter;
|
||||||
var checkNode = function (projectionNode, attrs) {
|
var assignNecessaryProjectionAttrs = function (projectionNode, attrs) {
|
||||||
attrs.forEach(function (attr) {
|
attrs.forEach(function (attr) {
|
||||||
var _a;
|
var _a;
|
||||||
if (!projectionNode.hasOwnProperty(attr)) {
|
if (!projectionNode.hasOwnProperty(attr)) {
|
||||||
|
|
@ -60,29 +62,24 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var relevantIds = [];
|
var checkFilterNode = function (entity2, filterNode, projectionNode, toBeAssignNode, filterNodeDict) {
|
||||||
if (filter) {
|
|
||||||
var toBeAssignNode_1 = {}; // 用来记录在表达式中涉及到的结点
|
|
||||||
// filter当中所关联到的属性必须在projection中
|
|
||||||
var filterNodeDict_1 = {};
|
|
||||||
var checkFilterNode_1 = function (entity2, filterNode, projectionNode) {
|
|
||||||
var _a, e_1, _b, _c, _d, _e, _f;
|
var _a, e_1, _b, _c, _d, _e, _f;
|
||||||
var necessaryAttrs = ['id'];
|
var necessaryAttrs = ['id'];
|
||||||
for (var attr in filterNode) {
|
for (var attr in filterNode) {
|
||||||
if (attr === '#id') {
|
if (attr === '#id') {
|
||||||
(0, assert_1.default)(!filterNodeDict_1[filterNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(filterNode[attr]));
|
(0, assert_1.default)(!filterNodeDict[filterNode[attr]], "projection\u4E2D\u7ED3\u70B9\u7684id\u6709\u91CD\u590D, ".concat(filterNode[attr]));
|
||||||
Object.assign(filterNodeDict_1, (_a = {},
|
Object.assign(filterNodeDict, (_a = {},
|
||||||
_a[filterNode[attr]] = projectionNode,
|
_a[filterNode[attr]] = projectionNode,
|
||||||
_a));
|
_a));
|
||||||
if (toBeAssignNode_1[filterNode[attr]]) {
|
if (toBeAssignNode[filterNode[attr]]) {
|
||||||
checkNode(projectionNode, toBeAssignNode_1[filterNode[attr]]);
|
assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode[filterNode[attr]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (['$and', '$or'].includes(attr)) {
|
else if (['$and', '$or'].includes(attr)) {
|
||||||
try {
|
try {
|
||||||
for (var _g = (e_1 = void 0, tslib_1.__values(filterNode[attr])), _h = _g.next(); !_h.done; _h = _g.next()) {
|
for (var _g = (e_1 = void 0, tslib_1.__values(filterNode[attr])), _h = _g.next(); !_h.done; _h = _g.next()) {
|
||||||
var node = _h.value;
|
var node = _h.value;
|
||||||
checkFilterNode_1(entity2, node, projectionNode);
|
checkFilterNode(entity2, node, projectionNode, toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||||
|
|
@ -94,7 +91,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (attr === '$not') {
|
else if (attr === '$not') {
|
||||||
checkFilterNode_1(entity2, filterNode[attr], projectionNode);
|
checkFilterNode(entity2, filterNode[attr], projectionNode, toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (attr === '$text') {
|
else if (attr === '$text') {
|
||||||
// 全文检索首先要有fulltext索引,其次要把fulltext的相关属性加到projection里
|
// 全文检索首先要有fulltext索引,其次要把fulltext的相关属性加到projection里
|
||||||
|
|
@ -108,17 +105,17 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
var exprResult = (0, types_1.getAttrRefInExpression)(filterNode[attr]);
|
var exprResult = (0, types_1.getAttrRefInExpression)(filterNode[attr]);
|
||||||
for (var nodeName in exprResult) {
|
for (var nodeName in exprResult) {
|
||||||
if (nodeName === '#current') {
|
if (nodeName === '#current') {
|
||||||
checkNode(projectionNode, exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else if (filterNodeDict_1[nodeName]) {
|
else if (filterNodeDict[nodeName]) {
|
||||||
checkNode(filterNodeDict_1[nodeName], exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(filterNodeDict[nodeName], exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (toBeAssignNode_1[nodeName]) {
|
if (toBeAssignNode[nodeName]) {
|
||||||
(_c = toBeAssignNode_1[nodeName]).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false));
|
(_c = toBeAssignNode[nodeName]).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(exprResult[nodeName]), false));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object.assign(toBeAssignNode_1, (_d = {},
|
Object.assign(toBeAssignNode, (_d = {},
|
||||||
_d[nodeName] = exprResult[nodeName],
|
_d[nodeName] = exprResult[nodeName],
|
||||||
_d));
|
_d));
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +137,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
},
|
},
|
||||||
_e));
|
_e));
|
||||||
}
|
}
|
||||||
checkFilterNode_1(attr, filterNode[attr], projectionNode[attr]);
|
checkFilterNode(attr, filterNode[attr], projectionNode[attr], toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (typeof rel === 'string') {
|
else if (typeof rel === 'string') {
|
||||||
necessaryAttrs.push("".concat(attr, "Id"));
|
necessaryAttrs.push("".concat(attr, "Id"));
|
||||||
|
|
@ -151,17 +148,22 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
},
|
},
|
||||||
_f));
|
_f));
|
||||||
}
|
}
|
||||||
checkFilterNode_1(rel, filterNode[attr], projectionNode[attr]);
|
checkFilterNode(rel, filterNode[attr], projectionNode[attr], toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (rel instanceof Array) {
|
else if (rel instanceof Array) {
|
||||||
// 现在filter中还不支持一对多的语义,先放着吧
|
// 子查询,暂时不处理
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkNode(projectionNode, necessaryAttrs);
|
assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
checkFilterNode_1(entity, filter, data);
|
var relevantIds = [];
|
||||||
|
if (filter) {
|
||||||
|
var toBeAssignNode = {}; // 用来记录在表达式中涉及到的结点
|
||||||
|
// filter当中所关联到的属性必须在projection中
|
||||||
|
var filterNodeDict = {};
|
||||||
|
checkFilterNode(entity, filter, data, toBeAssignNode, filterNodeDict);
|
||||||
relevantIds = (0, filter_2.getRelevantIds)(filter);
|
relevantIds = (0, filter_2.getRelevantIds)(filter);
|
||||||
}
|
}
|
||||||
// sorter感觉现在取不取影响不大,前端的list直接获取返回的ids了,先不管之
|
// sorter感觉现在取不取影响不大,前端的list直接获取返回的ids了,先不管之
|
||||||
|
|
@ -179,7 +181,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
_a[projectionNode[attr]] = projectionNode,
|
_a[projectionNode[attr]] = projectionNode,
|
||||||
_a));
|
_a));
|
||||||
if (toBeAssignNode2[projectionNode[attr]]) {
|
if (toBeAssignNode2[projectionNode[attr]]) {
|
||||||
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]]);
|
assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode2[projectionNode[attr]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -187,10 +189,10 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
var exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]);
|
var exprResult = (0, types_1.getAttrRefInExpression)(projectionNode[attr]);
|
||||||
for (var nodeName in exprResult) {
|
for (var nodeName in exprResult) {
|
||||||
if (nodeName === '#current') {
|
if (nodeName === '#current') {
|
||||||
checkNode(projectionNode, exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else if (projectionNodeDict[nodeName]) {
|
else if (projectionNodeDict[nodeName]) {
|
||||||
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNodeDict[nodeName], exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (toBeAssignNode2[nodeName]) {
|
if (toBeAssignNode2[nodeName]) {
|
||||||
|
|
@ -219,18 +221,18 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
checkProjectionNode(rel, projectionNode[attr]);
|
checkProjectionNode(rel, projectionNode[attr]);
|
||||||
}
|
}
|
||||||
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
|
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
|
||||||
var data_1 = projectionNode[attr].data;
|
var _d = projectionNode[attr], data_1 = _d.data, filter_3 = _d.filter;
|
||||||
if (rel[1]) {
|
if (rel[1]) {
|
||||||
checkNode(data_1, [rel[1]]);
|
assignNecessaryProjectionAttrs(data_1, [rel[1]]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkNode(data_1, ['entity', 'entityId']);
|
assignNecessaryProjectionAttrs(data_1, ['entity', 'entityId']);
|
||||||
}
|
}
|
||||||
_this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities);
|
_this.reinforceSelectionInner(rel[0], projectionNode[attr], context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkNode(projectionNode, necessaryAttrs);
|
assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
|
||||||
}
|
}
|
||||||
// 如果对象中指向一对多的Modi,此时加上指向Modi的projection
|
// 如果对象中指向一对多的Modi,此时加上指向Modi的projection
|
||||||
if (_this.getSchema()[entity2].toModi) {
|
if (_this.getSchema()[entity2].toModi) {
|
||||||
|
|
@ -281,7 +283,6 @@ var CascadeStore = /** @class */ (function (_super) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
noRelationDestEntities.push(entity2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -190,4 +190,9 @@ export declare type AuthDeduceRelationMap<ED extends EntityDict> = {
|
||||||
};
|
};
|
||||||
export declare type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
|
export declare type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
|
||||||
export declare type OtmKey<K extends string> = K | `${K}$${number}`;
|
export declare type OtmKey<K extends string> = K | `${K}$${number}`;
|
||||||
|
export interface SubDataDef<ED extends EntityDict, T extends keyof ED> {
|
||||||
|
id: string;
|
||||||
|
entity: T;
|
||||||
|
filter: ED[T]['Selection']['filter'];
|
||||||
|
}
|
||||||
export {};
|
export {};
|
||||||
|
|
|
||||||
|
|
@ -12,3 +12,4 @@ exports.initinctiveAttributes = [exports.PrimaryKeyAttribute, exports.TriggerDat
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
;
|
;
|
||||||
|
;
|
||||||
|
|
|
||||||
|
|
@ -30,59 +30,38 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
private operationRewriters: OperationRewriter<ED, AsyncContext<ED> | SyncContext<ED>>[] = [];
|
private operationRewriters: OperationRewriter<ED, AsyncContext<ED> | SyncContext<ED>>[] = [];
|
||||||
|
|
||||||
private async reinforceSelectionAsync<Cxt extends AsyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
|
private async reinforceSelectionAsync<Cxt extends AsyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
|
||||||
const noRelationDestEntities: string[] = [];
|
|
||||||
|
|
||||||
this.reinforceSelectionInner(entity, selection, context, noRelationDestEntities);
|
|
||||||
|
this.reinforceSelectionInner(entity, selection, context);
|
||||||
|
|
||||||
const rewriterPromises = this.selectionRewriters.map(
|
const rewriterPromises = this.selectionRewriters.map(
|
||||||
ele => ele(this.getSchema(), entity, selection, context)
|
ele => ele(this.getSchema(), entity, selection, context)
|
||||||
);
|
);
|
||||||
|
|
||||||
// 这个设计每次都要取actionAuth的数据,感觉不是很优雅。by Xc 20230722
|
|
||||||
// 这个设计废除了,前台页面自己来取需要的actionAUth,通过cache的缓存和KeepFresh机制来减少对后台数据的访问
|
|
||||||
/* if (noRelationDestEntities.length > 0 && !option.dontCollect) {
|
|
||||||
rewriterPromises.push(
|
|
||||||
context.select('actionAuth', {
|
|
||||||
data: {
|
|
||||||
id: 1,
|
|
||||||
deActions: 1,
|
|
||||||
destEntity: 1,
|
|
||||||
paths: 1,
|
|
||||||
relationId: 1,
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
relationId: {
|
|
||||||
$exists: false,
|
|
||||||
},
|
|
||||||
destEntity: {
|
|
||||||
$in: noRelationDestEntities,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, {}) as any
|
|
||||||
);
|
|
||||||
} */
|
|
||||||
|
|
||||||
if (rewriterPromises.length > 0) {
|
if (rewriterPromises.length > 0) {
|
||||||
await Promise.all(rewriterPromises);
|
await Promise.all(rewriterPromises);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private reinforceSelectionSync<Cxt extends SyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
|
private reinforceSelectionSync<Cxt extends SyncContext<ED>, OP extends SelectOption>(entity: keyof ED, selection: ED[keyof ED]['Selection'], context: Cxt, option: OP) {
|
||||||
this.reinforceSelectionInner(entity, selection, context, []);
|
this.reinforceSelectionInner(entity, selection, context);
|
||||||
|
|
||||||
const rewriterPromises = this.selectionRewriters.map(
|
this.selectionRewriters.forEach(
|
||||||
ele => ele(this.getSchema(), entity, selection, context)
|
ele => {
|
||||||
|
const result = ele(this.getSchema(), entity, selection, context);
|
||||||
|
assert(!(result instanceof Promise));
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private reinforceSelectionInner<Cxt extends AsyncContext<ED> | SyncContext<ED>, OP extends SelectOption>(
|
private reinforceSelectionInner<Cxt extends AsyncContext<ED> | SyncContext<ED>, OP extends SelectOption>(
|
||||||
entity: keyof ED,
|
entity: keyof ED,
|
||||||
selection: ED[keyof ED]['Selection'],
|
selection: ED[keyof ED]['Selection'],
|
||||||
context: Cxt,
|
context: Cxt
|
||||||
noRelationDestEntities: string[]) {
|
) {
|
||||||
const { filter, data, sorter } = selection;
|
const { filter, data, sorter } = selection;
|
||||||
|
|
||||||
const checkNode = (projectionNode: ED[keyof ED]['Selection']['data'], attrs: string[]) => {
|
const assignNecessaryProjectionAttrs = (projectionNode: ED[keyof ED]['Selection']['data'], attrs: string[]) => {
|
||||||
attrs.forEach(
|
attrs.forEach(
|
||||||
(attr) => {
|
(attr) => {
|
||||||
if (!projectionNode.hasOwnProperty(attr)) {
|
if (!projectionNode.hasOwnProperty(attr)) {
|
||||||
|
|
@ -94,12 +73,13 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let relevantIds: string[] = [];
|
|
||||||
if (filter) {
|
const checkFilterNode = (
|
||||||
const toBeAssignNode: Record<string, string[]> = {}; // 用来记录在表达式中涉及到的结点
|
entity2: keyof ED,
|
||||||
// filter当中所关联到的属性必须在projection中
|
filterNode: ED[keyof ED]['Selection']['filter'],
|
||||||
const filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']> = {};
|
projectionNode: ED[keyof ED]['Selection']['data'],
|
||||||
const checkFilterNode = (entity2: keyof ED, filterNode: ED[keyof ED]['Selection']['filter'], projectionNode: ED[keyof ED]['Selection']['data']) => {
|
toBeAssignNode: Record<string, string[]>,
|
||||||
|
filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']>) => {
|
||||||
const necessaryAttrs: string[] = ['id'];
|
const necessaryAttrs: string[] = ['id'];
|
||||||
for (const attr in filterNode) {
|
for (const attr in filterNode) {
|
||||||
if (attr === '#id') {
|
if (attr === '#id') {
|
||||||
|
|
@ -108,16 +88,16 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
[filterNode[attr]!]: projectionNode,
|
[filterNode[attr]!]: projectionNode,
|
||||||
});
|
});
|
||||||
if (toBeAssignNode[filterNode[attr]!]) {
|
if (toBeAssignNode[filterNode[attr]!]) {
|
||||||
checkNode(projectionNode, toBeAssignNode[filterNode[attr]!]);
|
assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode[filterNode[attr]!]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (['$and', '$or'].includes(attr)) {
|
else if (['$and', '$or'].includes(attr)) {
|
||||||
for (const node of filterNode[attr]!) {
|
for (const node of filterNode[attr]!) {
|
||||||
checkFilterNode(entity2, node, projectionNode);
|
checkFilterNode(entity2, node, projectionNode, toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (attr === '$not') {
|
else if (attr === '$not') {
|
||||||
checkFilterNode(entity2, filterNode[attr]!, projectionNode);
|
checkFilterNode(entity2, filterNode[attr]!, projectionNode, toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (attr === '$text') {
|
else if (attr === '$text') {
|
||||||
// 全文检索首先要有fulltext索引,其次要把fulltext的相关属性加到projection里
|
// 全文检索首先要有fulltext索引,其次要把fulltext的相关属性加到projection里
|
||||||
|
|
@ -135,10 +115,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
const exprResult = getAttrRefInExpression(filterNode[attr]!);
|
const exprResult = getAttrRefInExpression(filterNode[attr]!);
|
||||||
for (const nodeName in exprResult) {
|
for (const nodeName in exprResult) {
|
||||||
if (nodeName === '#current') {
|
if (nodeName === '#current') {
|
||||||
checkNode(projectionNode, exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else if (filterNodeDict[nodeName]) {
|
else if (filterNodeDict[nodeName]) {
|
||||||
checkNode(filterNodeDict[nodeName], exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(filterNodeDict[nodeName], exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (toBeAssignNode[nodeName]) {
|
if (toBeAssignNode[nodeName]) {
|
||||||
|
|
@ -167,7 +147,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
checkFilterNode(attr, filterNode[attr]!, projectionNode[attr]);
|
checkFilterNode(attr, filterNode[attr]!, projectionNode[attr], toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (typeof rel === 'string') {
|
else if (typeof rel === 'string') {
|
||||||
necessaryAttrs.push(`${attr}Id`);
|
necessaryAttrs.push(`${attr}Id`);
|
||||||
|
|
@ -178,18 +158,24 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
checkFilterNode(rel, filterNode[attr]!, projectionNode[attr]);
|
checkFilterNode(rel, filterNode[attr]!, projectionNode[attr], toBeAssignNode, filterNodeDict);
|
||||||
}
|
}
|
||||||
else if (rel instanceof Array) {
|
else if (rel instanceof Array) {
|
||||||
// 现在filter中还不支持一对多的语义,先放着吧
|
// 子查询,暂时不处理
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkNode(projectionNode, necessaryAttrs);
|
assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
checkFilterNode(entity, filter, data);
|
let relevantIds: string[] = [];
|
||||||
|
if (filter) {
|
||||||
|
const toBeAssignNode: Record<string, string[]> = {}; // 用来记录在表达式中涉及到的结点
|
||||||
|
// filter当中所关联到的属性必须在projection中
|
||||||
|
const filterNodeDict: Record<string, ED[keyof ED]['Selection']['data']> = {};
|
||||||
|
|
||||||
|
checkFilterNode(entity, filter, data, toBeAssignNode, filterNodeDict);
|
||||||
relevantIds = getRelevantIds(filter);
|
relevantIds = getRelevantIds(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +194,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
[projectionNode[attr]!]: projectionNode,
|
[projectionNode[attr]!]: projectionNode,
|
||||||
});
|
});
|
||||||
if (toBeAssignNode2[projectionNode[attr]!]) {
|
if (toBeAssignNode2[projectionNode[attr]!]) {
|
||||||
checkNode(projectionNode, toBeAssignNode2[projectionNode[attr]!]);
|
assignNecessaryProjectionAttrs(projectionNode, toBeAssignNode2[projectionNode[attr]!]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -216,10 +202,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
const exprResult = getAttrRefInExpression(projectionNode[attr]!);
|
const exprResult = getAttrRefInExpression(projectionNode[attr]!);
|
||||||
for (const nodeName in exprResult) {
|
for (const nodeName in exprResult) {
|
||||||
if (nodeName === '#current') {
|
if (nodeName === '#current') {
|
||||||
checkNode(projectionNode, exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNode, exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else if (projectionNodeDict[nodeName]) {
|
else if (projectionNodeDict[nodeName]) {
|
||||||
checkNode(projectionNodeDict[nodeName], exprResult[nodeName]);
|
assignNecessaryProjectionAttrs(projectionNodeDict[nodeName], exprResult[nodeName]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (toBeAssignNode2[nodeName]) {
|
if (toBeAssignNode2[nodeName]) {
|
||||||
|
|
@ -248,18 +234,18 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
checkProjectionNode(rel, projectionNode[attr]);
|
checkProjectionNode(rel, projectionNode[attr]);
|
||||||
}
|
}
|
||||||
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
|
else if (rel instanceof Array && !attr.endsWith('$$aggr')) {
|
||||||
const { data } = projectionNode[attr];
|
const { data, filter } = projectionNode[attr];
|
||||||
if (rel[1]) {
|
if (rel[1]) {
|
||||||
checkNode(data, [rel[1]]);
|
assignNecessaryProjectionAttrs(data, [rel[1]]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkNode(data, ['entity', 'entityId']);
|
assignNecessaryProjectionAttrs(data, ['entity', 'entityId']);
|
||||||
}
|
}
|
||||||
this.reinforceSelectionInner(rel[0], projectionNode[attr], context, noRelationDestEntities);
|
this.reinforceSelectionInner(rel[0], projectionNode[attr], context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkNode(projectionNode, necessaryAttrs);
|
assignNecessaryProjectionAttrs(projectionNode, necessaryAttrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果对象中指向一对多的Modi,此时加上指向Modi的projection
|
// 如果对象中指向一对多的Modi,此时加上指向Modi的projection
|
||||||
|
|
@ -312,7 +298,6 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
} as ED['userRelation']['Selection'],
|
} as ED['userRelation']['Selection'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
noRelationDestEntities.push(entity2 as string);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { EntityDict } from "./Entity";
|
import { EntityDict, SubDataDef } from "./Entity";
|
||||||
import { OpRecord } from "./Entity";
|
import { OpRecord } from "./Entity";
|
||||||
import { AsyncContext } from "../store/AsyncRowStore";
|
import { AsyncContext } from "../store/AsyncRowStore";
|
||||||
|
|
||||||
|
|
@ -12,4 +12,10 @@ export interface AspectWrapper<ED extends EntityDict, Cxt extends AsyncContext<E
|
||||||
opRecords?: OpRecord<ED>[];
|
opRecords?: OpRecord<ED>[];
|
||||||
message?: string | null;
|
message?: string | null;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
/* sub: (data: Array<SubDataDef<ED, keyof ED>>) => Promise<void>;
|
||||||
|
|
||||||
|
unsub: (ids: string[]) => Promise<void>;
|
||||||
|
|
||||||
|
registerSubCallback: (callback: (records: OpRecord<ED>[]) => void) => Promise<void>; */
|
||||||
};
|
};
|
||||||
|
|
@ -268,3 +268,9 @@ export type AuthDeduceRelationMap<ED extends EntityDict> = {
|
||||||
export type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
|
export type SelectFreeEntities<ED extends EntityDict> = (keyof ED)[];
|
||||||
// 一对多的键值的扩展
|
// 一对多的键值的扩展
|
||||||
export type OtmKey<K extends string> = K | `${K}$${number}`;
|
export type OtmKey<K extends string> = K | `${K}$${number}`;
|
||||||
|
|
||||||
|
export interface SubDataDef<ED extends EntityDict, T extends keyof ED> {
|
||||||
|
id: string;
|
||||||
|
entity: T,
|
||||||
|
filter: ED[T]['Selection']['filter'],
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue