重新处理了查询中total和randomRange的处理

This commit is contained in:
Xu Chang 2023-11-16 20:12:42 +08:00
parent f641a86710
commit 2683447e13
5 changed files with 71 additions and 13 deletions

View File

@ -20,6 +20,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
protected abstract selectAbjointRow<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial<ED[T]['Schema']>[];
protected abstract updateAbjointRow<T extends keyof ED, OP extends OperateOption, Cxt extends SyncContext<ED>>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): number;
protected abstract selectAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Promise<Partial<ED[T]['Schema']>[]>;
protected abstract countAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, 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 aggregateSync<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 aggregateAsync<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']>>;

View File

@ -506,7 +506,7 @@ class CascadeStore extends RowStore_1.RowStore {
}
else {
(0, assert_1.default)(relation instanceof Array);
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter } = projection2[attr];
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange } = projection2[attr];
const [entity2, foreignKey] = relation;
const isAggr = attr.endsWith('$$aggr');
const otmAggrFn = (result) => {
@ -576,6 +576,7 @@ class CascadeStore extends RowStore_1.RowStore {
data: subProjection,
filter: filter2,
sorter: subSorter,
total,
}, context, option);
if (subRows instanceof Promise) {
return subRows.then((subRowss) => dealWithSubRows(subRowss));
@ -603,7 +604,9 @@ class CascadeStore extends RowStore_1.RowStore {
filter: filter2,
sorter: subSorter,
indexFrom,
count
count,
total,
randomRange,
}, context, option);
if (subRows instanceof Promise) {
return subRows.then((subRowss) => dealWithSubRows2(row, subRowss));
@ -1608,15 +1611,29 @@ class CascadeStore extends RowStore_1.RowStore {
});
}
async cascadeSelectAsync(entity, selection, context, option) {
const { data, filter, indexFrom, count, sorter } = selection;
const { data, filter, indexFrom, count, sorter, total, randomRange } = selection;
const { projection, cascadeSelectionFns } = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option);
const rows = await this.selectAbjointRowAsync(entity, {
const rows2 = await this.selectAbjointRowAsync(entity, {
data: projection,
filter,
indexFrom,
count,
count: randomRange || count,
sorter
}, context, option);
// 处理随机取值
let rows = !randomRange ? rows2 : [];
if (randomRange) {
const possibility = count / rows2.length;
let reduced = rows2.length - count;
rows = rows2.filter(() => {
const rand = Math.random();
if (rand > possibility && reduced) {
reduced--;
return false;
}
return true;
});
}
if (!option.dontCollect) {
this.addToResultSelections(entity, rows, context);
}
@ -1640,6 +1657,12 @@ class CascadeStore extends RowStore_1.RowStore {
throw new types_1.OakRowUnexistedException(ruException);
}
}
if (total) {
const total2 = await this.countAsync(entity, selection, context, option);
Object.assign(rows, {
'#total': total2,
});
}
return rows;
}
async selectAsync(entity, selection, context, option) {

View File

@ -62,6 +62,7 @@ export type Selection<A extends ReadOnlyAction, D extends Projection, F extends
sorter?: S;
} & FilterPart<A, F> & {
randomRange?: number;
total?: number;
};
export interface EntityShape {
id: PrimaryKey;

View File

@ -1,6 +1,6 @@
import assert from "assert";
import {
EntityDict, OperateOption, SelectOption, OperationResult, CreateAtAttribute,
EntityDict, OperateOption, SelectOption, OperationResult, CreateAtAttribute,
UpdateAtAttribute, AggregationResult, DeleteAtAttribute
} from "../types/Entity";
import { EntityDict as BaseEntityDict } from '../base-app-domain';
@ -171,7 +171,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
const checkSorterNode = (
entity2: keyof ED,
sorterNode: NonNullable<ED[keyof ED]['Selection']['sorter']>,
sorterNode: ED[keyof ED]['Selection']['sorter'],
projectionNode: ED[keyof ED]['Selection']['data']) => {
const checkSortAttr = (e2: keyof ED, sortAttr: Record<string, any>, projNode: ED[keyof ED]['Selection']['data']) => {
@ -202,7 +202,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}
}
}
sorterNode.forEach(
sorterNode!.forEach(
(node) => {
const { $attr } = node;
checkSortAttr(entity2, $attr, projectionNode);
@ -398,6 +398,13 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
context: Cxt,
option: OP): Promise<Partial<ED[T]['Schema']>[]>;
protected abstract countAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(
entity: T,
selection: Pick<ED[T]['Selection'], 'filter' | 'count'>,
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'],
@ -661,7 +668,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}
else {
assert(relation instanceof Array);
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter } = projection2[attr];
const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange } = projection2[attr];
const [entity2, foreignKey] = relation;
const isAggr = attr.endsWith('$$aggr');
@ -745,6 +752,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
data: subProjection,
filter: filter2,
sorter: subSorter,
total,
}, context, option);
if (subRows instanceof Promise) {
return subRows.then(
@ -777,7 +785,9 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
filter: filter2,
sorter: subSorter,
indexFrom,
count
count,
total,
randomRange,
}, context, option);
if (subRows instanceof Promise) {
return subRows.then(
@ -1966,7 +1976,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
selection: ED[T]['Selection'],
context: Cxt,
option: OP): Promise<Partial<ED[T]['Schema']>[]> {
const { data, filter, indexFrom, count, sorter } = selection;
const { data, filter, indexFrom, count, sorter, total, randomRange } = selection;
const { projection, cascadeSelectionFns } = this.destructCascadeSelect(
entity,
data,
@ -1975,14 +1985,30 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
this.aggregateAsync,
option);
const rows = await this.selectAbjointRowAsync(entity, {
const rows2 = await this.selectAbjointRowAsync(entity, {
data: projection,
filter,
indexFrom,
count,
count: randomRange || count,
sorter
}, context, option);
// 处理随机取值
let rows = !randomRange ? rows2 : [];
if (randomRange) {
const possibility = count! / rows2.length;
let reduced = rows2.length - count!;
rows = rows2.filter(
() => {
const rand = Math.random();
if (rand > possibility && reduced) {
reduced--;
return false;
}
return true;
}
);
}
if (!option.dontCollect) {
this.addToResultSelections(entity, rows, context);
@ -2017,6 +2043,12 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
}
}
if (total) {
const total2 = await this.countAsync(entity, selection, context, option);
Object.assign(rows, {
'#total': total2,
});
}
return rows;
}

View File

@ -76,6 +76,7 @@ export type Selection<A extends ReadOnlyAction,
sorter?: S;
} & FilterPart<A, F> & {
randomRange?: number;
total?: number;
};
export interface EntityShape {