cascadeSelect把selectionId传到子查询中

This commit is contained in:
Xu Chang 2025-05-08 14:31:12 +08:00
parent 6c5c0b8159
commit f87c797921
3 changed files with 32 additions and 16 deletions

View File

@ -33,7 +33,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
protected abstract updateAbjointRowAsync<T extends keyof ED, OP extends OperateOption, Cxt extends AsyncContext<ED>>(entity: T, operation: ED[T]['Create'] | ED[T]['Update'] | ED[T]['Remove'], context: Cxt, option: OP): Promise<number>; protected abstract updateAbjointRowAsync<T extends keyof ED, OP extends OperateOption, Cxt extends AsyncContext<ED>>(entity: T, operation: ED[T]['Create'] | ED[T]['Update'] | ED[T]['Remove'], context: Cxt, option: OP): Promise<number>;
protected abstract aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>; protected abstract aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
protected abstract aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>; protected abstract aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
protected destructCascadeSelect<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, projection2: ED[T]['Projection'], context: Cxt, cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>, aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>, option: OP): { protected destructCascadeSelect<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, projection2: ED[T]['Projection'], context: Cxt, cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>, aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>, option: OP, selectionId?: string): {
projection: ED[T]["Projection"]; projection: ED[T]["Projection"];
cascadeSelectionFns: ((result: Partial<ED[T]['Schema']>[]) => Promise<void> | void)[]; cascadeSelectionFns: ((result: Partial<ED[T]['Schema']>[]) => Promise<void> | void)[];
}; };

View File

@ -317,7 +317,7 @@ class CascadeStore extends RowStore_1.RowStore {
registerSelectionRewriter(rewriter) { registerSelectionRewriter(rewriter) {
this.selectionRewriters.push(rewriter); this.selectionRewriters.push(rewriter);
} }
destructCascadeSelect(entity, projection2, context, cascadeSelectFn, aggregateFn, option) { destructCascadeSelect(entity, projection2, context, cascadeSelectFn, aggregateFn, option, selectionId) {
const cascadeSelectionFns = []; const cascadeSelectionFns = [];
const supportMtoJoin = this.supportManyToOneJoin(); const supportMtoJoin = this.supportManyToOneJoin();
const { toModi } = this.getSchema()[entity]; const { toModi } = this.getSchema()[entity];
@ -352,7 +352,7 @@ class CascadeStore extends RowStore_1.RowStore {
}); });
} }
}); });
const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option); const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => { subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2)); return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
})); }));
@ -372,6 +372,7 @@ class CascadeStore extends RowStore_1.RowStore {
throw new types_1.OakRowUnexistedException([{ throw new types_1.OakRowUnexistedException([{
entity: attr, entity: attr,
selection: { selection: {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -400,6 +401,7 @@ class CascadeStore extends RowStore_1.RowStore {
}; };
if (entityIds.length > 0) { if (entityIds.length > 0) {
const subRows = cascadeSelectFn.call(this, attr, { const subRows = cascadeSelectFn.call(this, attr, {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -440,7 +442,7 @@ class CascadeStore extends RowStore_1.RowStore {
} }
}); });
} }
const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option); const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => { subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2)); return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
})); }));
@ -489,6 +491,7 @@ class CascadeStore extends RowStore_1.RowStore {
}; };
if (ids.length > 0) { if (ids.length > 0) {
const subRows = cascadeSelectFn.call(this, relation, { const subRows = cascadeSelectFn.call(this, relation, {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -506,7 +509,7 @@ class CascadeStore extends RowStore_1.RowStore {
} }
else { else {
(0, assert_1.default)(relation instanceof Array); (0, assert_1.default)(relation instanceof Array);
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange } = projection2[attr]; const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange, id: subSelectionId } = projection2[attr];
const [entity2, foreignKey] = relation; const [entity2, foreignKey] = relation;
const isAggr = attr.endsWith('$$aggr'); const isAggr = attr.endsWith('$$aggr');
const otmAggrFn = (result) => { const otmAggrFn = (result) => {
@ -573,6 +576,7 @@ class CascadeStore extends RowStore_1.RowStore {
}, },
}, subFilter]); }, subFilter]);
const subRows = cascadeSelectFn.call(this, entity2, { const subRows = cascadeSelectFn.call(this, entity2, {
id: subSelectionId || selectionId,
data: subProjection, data: subProjection,
filter: filter2, filter: filter2,
sorter: subSorter, sorter: subSorter,
@ -600,6 +604,7 @@ class CascadeStore extends RowStore_1.RowStore {
entityId: row.id, entityId: row.id,
}, subFilter]); }, subFilter]);
const subRows = cascadeSelectFn.call(this, entity2, { const subRows = cascadeSelectFn.call(this, entity2, {
id: subSelectionId || selectionId,
data: subProjection, data: subProjection,
filter: filter2, filter: filter2,
sorter: subSorter, sorter: subSorter,
@ -1734,8 +1739,8 @@ class CascadeStore extends RowStore_1.RowStore {
}); });
} }
async cascadeSelectAsync(entity, selection, context, option) { async cascadeSelectAsync(entity, selection, context, option) {
const { data, filter, indexFrom, count, sorter, total, randomRange, distinct } = selection; const { data, filter, indexFrom, count, sorter, total, randomRange, distinct, id: selectionId } = selection;
const { projection, cascadeSelectionFns } = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option); const { projection, cascadeSelectionFns } = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option, selectionId);
const rows2 = await this.selectAbjointRowAsync(entity, { const rows2 = await this.selectAbjointRowAsync(entity, {
data: projection, data: projection,
filter, filter,

View File

@ -444,7 +444,9 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
context: Cxt, context: Cxt,
cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>, cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>,
aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>, aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>,
option: OP) { option: OP,
selectionId?: string
) {
const cascadeSelectionFns: Array<(result: Partial<ED[T]['Schema']>[]) => Promise<void> | void> = []; const cascadeSelectionFns: Array<(result: Partial<ED[T]['Schema']>[]) => Promise<void> | void> = [];
const supportMtoJoin = this.supportManyToOneJoin(); const supportMtoJoin = this.supportManyToOneJoin();
@ -488,7 +490,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const { const {
projection: subProjection, projection: subProjection,
cascadeSelectionFns: subCascadeSelectionFns, cascadeSelectionFns: subCascadeSelectionFns,
} = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option); } = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
subCascadeSelectionFns.forEach( subCascadeSelectionFns.forEach(
ele => cascadeSelectionFns.push( ele => cascadeSelectionFns.push(
(result) => { (result) => {
@ -518,6 +520,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
throw new OakRowUnexistedException([{ throw new OakRowUnexistedException([{
entity: attr, entity: attr,
selection: { selection: {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -552,6 +555,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
if (entityIds.length > 0) { if (entityIds.length > 0) {
const subRows = cascadeSelectFn.call(this, attr as any, { const subRows = cascadeSelectFn.call(this, attr as any, {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -602,7 +606,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const { const {
projection: subProjection, projection: subProjection,
cascadeSelectionFns: subCascadeSelectionFns, cascadeSelectionFns: subCascadeSelectionFns,
} = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option); } = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
subCascadeSelectionFns.forEach( subCascadeSelectionFns.forEach(
ele => cascadeSelectionFns.push( ele => cascadeSelectionFns.push(
(result) => { (result) => {
@ -666,7 +670,8 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}; };
if (ids.length > 0) { if (ids.length > 0) {
const subRows = cascadeSelectFn.call(this, relation, { const subRows = cascadeSelectFn.call(this, relation, {
id: selectionId,
data: projection2[attr], data: projection2[attr],
filter: { filter: {
id: { id: {
@ -687,7 +692,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
else { else {
assert(relation instanceof Array); assert(relation instanceof Array);
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange } = projection2[attr]; const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange, id: subSelectionId } = projection2[attr];
const [entity2, foreignKey] = relation; const [entity2, foreignKey] = relation;
const isAggr = attr.endsWith('$$aggr'); const isAggr = attr.endsWith('$$aggr');
@ -768,6 +773,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}, },
}, subFilter]); }, subFilter]);
const subRows = cascadeSelectFn.call(this, entity2, { const subRows = cascadeSelectFn.call(this, entity2, {
id: subSelectionId || selectionId,
data: subProjection, data: subProjection,
filter: filter2, filter: filter2,
sorter: subSorter, sorter: subSorter,
@ -800,6 +806,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
entityId: row.id!, entityId: row.id!,
}, subFilter]); }, subFilter]);
const subRows = cascadeSelectFn.call(this, entity2, { const subRows = cascadeSelectFn.call(this, entity2, {
id: subSelectionId || selectionId,
data: subProjection, data: subProjection,
filter: filter2, filter: filter2,
sorter: subSorter, sorter: subSorter,
@ -1999,7 +2006,8 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
context, context,
this.cascadeSelect, this.cascadeSelect,
this.aggregateSync, this.aggregateSync,
option); option
);
const rows = this.selectAbjointRow(entity, { const rows = this.selectAbjointRow(entity, {
data: projection, data: projection,
@ -2141,15 +2149,18 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
entity: T, entity: T,
selection: ED[T]['Selection'], selection: ED[T]['Selection'],
context: Cxt, context: Cxt,
option: OP): Promise<Partial<ED[T]['Schema']>[]> { option: OP,
const { data, filter, indexFrom, count, sorter, total, randomRange, distinct } = selection; ): Promise<Partial<ED[T]['Schema']>[]> {
const { data, filter, indexFrom, count, sorter, total, randomRange, distinct, id: selectionId } = selection;
const { projection, cascadeSelectionFns } = this.destructCascadeSelect( const { projection, cascadeSelectionFns } = this.destructCascadeSelect(
entity, entity,
data, data,
context, context,
this.cascadeSelectAsync, this.cascadeSelectAsync,
this.aggregateAsync, this.aggregateAsync,
option); option,
selectionId
);
const rows2 = await this.selectAbjointRowAsync(entity, { const rows2 = await this.selectAbjointRowAsync(entity, {
data: projection, data: projection,