增加了aggregate的相关定义

This commit is contained in:
Xu Chang 2023-01-03 19:13:04 +08:00
parent 348d981300
commit d079aafd72
15 changed files with 160 additions and 25 deletions

View File

@ -2,7 +2,7 @@ import { String } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { Action, ParticularAction, IState } from "./Action"; import { Action, ParticularAction, IState } from "./Action";
import * as ModiEntity from "../ModiEntity/Schema"; import * as ModiEntity from "../ModiEntity/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
@ -49,7 +49,7 @@ export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export declare type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id: number; id?: number;
$$createAt$$?: number; $$createAt$$?: number;
$$updateAt$$?: number; $$updateAt$$?: number;
$$seq$$?: number; $$seq$$?: number;
@ -121,6 +121,7 @@ export declare type SortNode = {
export declare type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export declare type Aggregation = Omit<DeduceAggregation<Schema, Projection, Filter, Sorter>, "id">;
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>; export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId">> & ({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId">> & ({
entity?: string; entity?: string;
@ -150,6 +151,7 @@ export declare type EntityDef = {
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<Action> | string; Action: OakMakeAction<Action> | string;
Selection: Selection; Selection: Selection;
Aggregation: Aggregation;
Operation: Operation; Operation: Operation;
Create: CreateOperation; Create: CreateOperation;
Update: UpdateOperation; Update: UpdateOperation;

View File

@ -2,7 +2,7 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as Modi from "../Modi/Schema"; import * as Modi from "../Modi/Schema";
import * as User from "../User/Schema"; import * as User from "../User/Schema";
@ -36,7 +36,7 @@ export declare type Filter<E = Q_EnumValue<"user" | string>> = MakeFilter<AttrFi
export declare type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id: number; id?: number;
$$createAt$$?: number; $$createAt$$?: number;
$$updateAt$$?: number; $$updateAt$$?: number;
$$seq$$?: number; $$seq$$?: number;
@ -96,6 +96,7 @@ export declare type SortNode = {
export declare type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export declare type Aggregation = Omit<DeduceAggregation<Schema, Projection, Filter, Sorter>, "id">;
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>; export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({
modiId?: never; modiId?: never;
@ -166,6 +167,7 @@ export declare type EntityDef = {
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;
Selection: Selection; Selection: Selection;
Aggregation: Aggregation;
Operation: Operation; Operation: Operation;
Create: CreateOperation; Create: CreateOperation;
Update: UpdateOperation; Update: UpdateOperation;

View File

@ -2,7 +2,7 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as User from "../User/Schema"; import * as User from "../User/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
@ -41,7 +41,7 @@ export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export declare type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id: number; id?: number;
$$createAt$$?: number; $$createAt$$?: number;
$$updateAt$$?: number; $$updateAt$$?: number;
$$seq$$?: number; $$seq$$?: number;
@ -102,6 +102,7 @@ export declare type SortNode = {
export declare type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export declare type Aggregation = Omit<DeduceAggregation<Schema, Projection, Filter, Sorter>, "id">;
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>; export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "operatorId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "operatorId">> & (({
operatorId?: never; operatorId?: never;
@ -148,6 +149,7 @@ export declare type EntityDef = {
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;
Selection: Selection; Selection: Selection;
Aggregation: Aggregation;
Operation: Operation; Operation: Operation;
Create: CreateOperation; Create: CreateOperation;
Update: UpdateOperation; Update: UpdateOperation;

View File

@ -2,7 +2,7 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as Oper from "../Oper/Schema"; import * as Oper from "../Oper/Schema";
import * as Modi from "../Modi/Schema"; import * as Modi from "../Modi/Schema";
@ -39,7 +39,7 @@ export declare type Filter<E = Q_EnumValue<"modi" | "user" | string>> = MakeFilt
export declare type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id: number; id?: number;
$$createAt$$?: number; $$createAt$$?: number;
$$updateAt$$?: number; $$updateAt$$?: number;
$$seq$$?: number; $$seq$$?: number;
@ -106,6 +106,7 @@ export declare type SortNode = {
export declare type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export declare type Aggregation = Omit<DeduceAggregation<Schema, Projection, Filter, Sorter>, "id">;
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>; export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({
operId?: never; operId?: never;
@ -183,6 +184,7 @@ export declare type EntityDef = {
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;
Selection: Selection; Selection: Selection;
Aggregation: Aggregation;
Operation: Operation; Operation: Operation;
Create: CreateOperation; Create: CreateOperation;
Update: UpdateOperation; Update: UpdateOperation;

View File

@ -2,7 +2,7 @@ import { String, Text } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { GenericAction, RelationAction } from "../../actions/action"; import { GenericAction, RelationAction } from "../../actions/action";
import * as Oper from "../Oper/Schema"; import * as Oper from "../Oper/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
@ -36,7 +36,7 @@ export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export declare type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id: number; id?: number;
$$createAt$$?: number; $$createAt$$?: number;
$$updateAt$$?: number; $$updateAt$$?: number;
$$seq$$?: number; $$seq$$?: number;
@ -100,6 +100,7 @@ export declare type SortNode = {
export declare type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">;
export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export declare type Aggregation = Omit<DeduceAggregation<Schema, Projection, Filter, Sorter>, "id">;
export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>; export declare type Exportation = OakOperation<"export", ExportProjection, Filter, Sorter>;
export declare type CreateOperationData = FormCreateData<OpSchema> & { export declare type CreateOperationData = FormCreateData<OpSchema> & {
oper$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>; oper$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>;
@ -127,6 +128,7 @@ export declare type EntityDef = {
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<GenericAction | RelationAction> | string; Action: OakMakeAction<GenericAction | RelationAction> | string;
Selection: Selection; Selection: Selection;
Aggregation: Aggregation;
Operation: Operation; Operation: Operation;
Create: CreateOperation; Create: CreateOperation;
Update: UpdateOperation; Update: UpdateOperation;

View File

@ -1161,7 +1161,7 @@ function constructProjection(statements, entity) {
var _a, e_4, _b, e_5, _c; var _a, e_4, _b, e_5, _c;
var schemaAttrs = Schema[entity].schemaAttrs; var schemaAttrs = Schema[entity].schemaAttrs;
var properties = [ var properties = [
['id', true], ['id', false],
['$$createAt$$', false], ['$$createAt$$', false],
['$$updateAt$$', false], ['$$updateAt$$', false],
['$$seq$$', false], ['$$seq$$', false],
@ -1717,6 +1717,14 @@ function constructActions(statements, entity) {
factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined) factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined)
]), ]),
factory.createLiteralTypeNode(factory.createStringLiteral("action")) factory.createLiteralTypeNode(factory.createStringLiteral("action"))
])), factory.createTypeAliasDeclaration(undefined, [factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Aggregation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [
factory.createTypeReferenceNode(factory.createIdentifier("DeduceAggregation"), [
factory.createTypeReferenceNode(factory.createIdentifier("Schema"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Filter"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Sorter"), undefined)
]),
factory.createLiteralTypeNode(factory.createStringLiteral("id"))
]))); ])));
// Exportation // Exportation
statements.push(factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Exportation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("OakOperation"), [ statements.push(factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Exportation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("OakOperation"), [
@ -2539,6 +2547,7 @@ var initialStatements = function () { return [
factory.createImportDeclaration(undefined, undefined, factory.createImportClause(false, undefined, factory.createNamedImports([ factory.createImportDeclaration(undefined, undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormCreateData")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormCreateData")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormUpdateData")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormUpdateData")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("DeduceAggregation")),
factory.createImportSpecifier(false, factory.createIdentifier("Operation"), factory.createIdentifier("OakOperation")), factory.createImportSpecifier(false, factory.createIdentifier("Operation"), factory.createIdentifier("OakOperation")),
factory.createImportSpecifier(false, factory.createIdentifier("MakeAction"), factory.createIdentifier("OakMakeAction")), factory.createImportSpecifier(false, factory.createIdentifier("MakeAction"), factory.createIdentifier("OakMakeAction")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityShape")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityShape")),
@ -2676,6 +2685,7 @@ function outputSchema(outputDir, printer) {
factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)
]) : actionTypeNode), ]) : actionTypeNode),
factory.createPropertySignature(undefined, factory.createIdentifier("Selection"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Selection"), undefined)), factory.createPropertySignature(undefined, factory.createIdentifier("Selection"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Selection"), undefined)),
factory.createPropertySignature(undefined, factory.createIdentifier("Aggregation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Aggregation"), undefined)),
factory.createPropertySignature(undefined, factory.createIdentifier("Operation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Operation"), undefined)), factory.createPropertySignature(undefined, factory.createIdentifier("Operation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Operation"), undefined)),
factory.createPropertySignature(undefined, factory.createIdentifier("Create"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("CreateOperation"), undefined)), factory.createPropertySignature(undefined, factory.createIdentifier("Create"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("CreateOperation"), undefined)),
factory.createPropertySignature(undefined, factory.createIdentifier("Update"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("UpdateOperation"), undefined)), factory.createPropertySignature(undefined, factory.createIdentifier("Update"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("UpdateOperation"), undefined)),

View File

@ -1,5 +1,5 @@
/// <reference types="node" /> /// <reference types="node" />
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord } from "../types"; import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult } from "../types";
import { IncomingHttpHeaders } from "http"; import { IncomingHttpHeaders } from "http";
export declare abstract class AsyncContext<ED extends EntityDict> implements Context { export declare abstract class AsyncContext<ED extends EntityDict> implements Context {
private rowStore; private rowStore;
@ -39,6 +39,7 @@ export declare abstract class AsyncContext<ED extends EntityDict> implements Con
export interface AsyncRowStore<ED extends EntityDict, Cxt extends Context> extends RowStore<ED> { export interface AsyncRowStore<ED extends EntityDict, Cxt extends Context> extends RowStore<ED> {
operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): Promise<OperationResult<ED>>; operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): Promise<OperationResult<ED>>;
select<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Promise<Partial<ED[T]['Schema']>[]>; select<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Promise<Partial<ED[T]['Schema']>[]>;
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): Promise<number>; count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): Promise<number>;
begin(option?: TxnOption): Promise<string>; begin(option?: TxnOption): Promise<string>;
commit(txnId: string): Promise<void>; commit(txnId: string): Promise<void>;

View File

@ -1,4 +1,4 @@
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, TxnOption, Context } from "../types"; import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, TxnOption, Context, AggregationResult } from "../types";
export declare abstract class SyncContext<ED extends EntityDict> implements Context { export declare abstract class SyncContext<ED extends EntityDict> implements Context {
private rowStore; private rowStore;
private uuid?; private uuid?;
@ -21,6 +21,7 @@ export interface SyncRowStore<ED extends EntityDict, Cxt extends Context> extend
operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): OperationResult<ED>; operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): OperationResult<ED>;
select<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial<ED[T]['Schema']>[]; select<T extends keyof ED, OP extends SelectOption>(entity: T, selection: ED[T]['Selection'], context: Cxt, option: OP): Partial<ED[T]['Schema']>[];
count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number; count<T extends keyof ED, OP extends SelectOption>(entity: T, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, context: Cxt, option: OP): number;
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
begin(option?: TxnOption): string; begin(option?: TxnOption): string;
commit(txnId: string): void; commit(txnId: string): void;
rollback(txnId: string): void; rollback(txnId: string): void;

15
lib/types/Entity.d.ts vendored
View File

@ -73,6 +73,7 @@ export interface EntityDef {
Action: string; Action: string;
ParticularAction?: string; ParticularAction?: string;
Selection: Omit<DeduceSelection<this['Schema']>, 'action'>; Selection: Omit<DeduceSelection<this['Schema']>, 'action'>;
Aggregation: Omit<DeduceAggregation<this['Schema'], DeduceProjection<this['Schema']>, DeduceFilter<this['Schema']>, DeduceSorter<this['Schema']>>, 'action'>;
Operation: DeduceOperation<this['Schema']>; Operation: DeduceOperation<this['Schema']>;
Create: DeduceCreateOperation<this['Schema']>; Create: DeduceCreateOperation<this['Schema']>;
CreateSingle: DeduceCreateSingleOperation<this['Schema']>; CreateSingle: DeduceCreateSingleOperation<this['Schema']>;
@ -90,7 +91,18 @@ declare type DeduceProjection<SH extends GeneralEntityShape> = {
'#id'?: NodeId; '#id'?: NodeId;
} & { } & {
[K in keyof SH]?: number | OtmSubProjection | any; [K in keyof SH]?: number | OtmSubProjection | any;
} & Partial<ExprOp<keyof SH>>; } & Partial<ExprOp<keyof SH | string>>;
export declare type AggregationOp = `$max-${number}` | `$min-${number}` | `$avg-${number}` | `$count-${number}` | `$sum-${number}`;
export declare type DeduceAggregationData<SH extends GeneralEntityShape, P extends DeduceProjection<SH>> = {
[A in AggregationOp]?: P;
} & {
$aggr?: P;
};
export declare type AggregationResult<SH extends GeneralEntityShape> = Array<{
[A in AggregationOp]?: number | string;
} & {
data?: Partial<SH>;
}>;
export declare type AttrFilter<SH extends GeneralEntityShape> = { export declare type AttrFilter<SH extends GeneralEntityShape> = {
[K in keyof SH]: any; [K in keyof SH]: any;
}; };
@ -104,6 +116,7 @@ export declare type DeduceSorterItem<SH extends GeneralEntityShape> = {
}; };
export declare type DeduceSorter<SH extends GeneralEntityShape> = Array<DeduceSorterItem<SH>>; export declare type DeduceSorter<SH extends GeneralEntityShape> = Array<DeduceSorterItem<SH>>;
export declare type DeduceSelection<SH extends GeneralEntityShape> = Selection<DeduceProjection<SH>, DeduceFilter<SH>, DeduceSorter<SH>>; export declare type DeduceSelection<SH extends GeneralEntityShape> = Selection<DeduceProjection<SH>, DeduceFilter<SH>, DeduceSorter<SH>>;
export declare type DeduceAggregation<SH extends GeneralEntityShape, P extends DeduceProjection<SH>, F extends DeduceFilter<SH>, S extends DeduceSorter<SH>> = Omit<Operation<'aggregate', DeduceAggregationData<SH, P>, F, S>, 'action'>;
export declare type DeduceCreateOperationData<SH extends GeneralEntityShape> = { export declare type DeduceCreateOperationData<SH extends GeneralEntityShape> = {
id: string; id: string;
} & { } & {

View File

@ -361,7 +361,7 @@ function getAttrRefInExpression(expression) {
_a['#current'] = [], _a['#current'] = [],
_a); _a);
var check = function (node) { var check = function (node) {
var _a; var _a, e_3, _b;
if (node['#attr']) { if (node['#attr']) {
result['#current'].push(node['#attr']); result['#current'].push(node['#attr']);
} }
@ -375,9 +375,24 @@ function getAttrRefInExpression(expression) {
_a)); _a));
} }
} }
else if (node instanceof Array) {
try {
for (var node_1 = tslib_1.__values(node), node_1_1 = node_1.next(); !node_1_1.done; node_1_1 = node_1.next()) {
var subNode = node_1_1.value;
check(subNode);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (node_1_1 && !node_1_1.done && (_b = node_1.return)) _b.call(node_1);
}
finally { if (e_3) throw e_3.error; }
}
}
else { else {
for (var attr in expression) { for (var attr in node) {
check(expression[attr]); check(node[attr]);
} }
} }
}; };

View File

@ -641,7 +641,7 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
assert(ts.isTypeReferenceNode(type!) && ts.isIdentifier(type.typeName), `${moduleName}」中entityId属性的定义不是String<64>类型entityId是系统用于表示反指指针的保留属性请勿他用`); assert(ts.isTypeReferenceNode(type!) && ts.isIdentifier(type.typeName), `${moduleName}」中entityId属性的定义不是String<64>类型entityId是系统用于表示反指指针的保留属性请勿他用`);
const { typeArguments } = type; const { typeArguments } = type;
assert(type.typeName.text === 'String' && typeArguments && typeArguments.length === 1, `${moduleName}」中entityId属性的定义不是String<64>类型entityId是系统用于表示反指指针的保留属性请勿他用`); assert(type.typeName.text === 'String' && typeArguments && typeArguments.length === 1, `${moduleName}」中entityId属性的定义不是String<64>类型entityId是系统用于表示反指指针的保留属性请勿他用`);
const [node] = typeArguments; const [node] = typeArguments;
if (ts.isLiteralTypeNode(node) && ts.isNumericLiteral(node.literal)) { if (ts.isLiteralTypeNode(node) && ts.isNumericLiteral(node.literal)) {
if (parseInt(node.literal.text) !== 64) { if (parseInt(node.literal.text) !== 64) {
@ -1738,7 +1738,7 @@ function constructFilter(statements: Array<ts.Statement>, entity: string) {
function constructProjection(statements: Array<ts.Statement>, entity: string) { function constructProjection(statements: Array<ts.Statement>, entity: string) {
const { schemaAttrs } = Schema[entity]; const { schemaAttrs } = Schema[entity];
const properties: Array<[string | ts.PropertyName, boolean, ts.TypeNode?, ts.TypeNode?]> = [ const properties: Array<[string | ts.PropertyName, boolean, ts.TypeNode?, ts.TypeNode?]> = [
['id', true], ['id', false],
['$$createAt$$', false], ['$$createAt$$', false],
['$$updateAt$$', false], ['$$updateAt$$', false],
['$$seq$$', false], ['$$seq$$', false],
@ -2780,6 +2780,39 @@ function constructActions(statements: Array<ts.Statement>, entity: string) {
factory.createLiteralTypeNode(factory.createStringLiteral("action")) factory.createLiteralTypeNode(factory.createStringLiteral("action"))
] ]
) )
),
factory.createTypeAliasDeclaration(
undefined,
[factory.createToken(ts.SyntaxKind.ExportKeyword)],
factory.createIdentifier("Aggregation"),
undefined,
factory.createTypeReferenceNode(
factory.createIdentifier("Omit"),
[
factory.createTypeReferenceNode(
factory.createIdentifier("DeduceAggregation"),
[
factory.createTypeReferenceNode(
factory.createIdentifier("Schema"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Projection"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Filter"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Sorter"),
undefined
)
]
),
factory.createLiteralTypeNode(factory.createStringLiteral("id"))
]
)
) )
); );
@ -4395,6 +4428,11 @@ const initialStatements = () => [
undefined, undefined,
factory.createIdentifier("FormUpdateData") factory.createIdentifier("FormUpdateData")
), ),
factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier("DeduceAggregation")
),
factory.createImportSpecifier( factory.createImportSpecifier(
false, false,
factory.createIdentifier("Operation"), factory.createIdentifier("Operation"),
@ -4834,6 +4872,15 @@ function outputSchema(outputDir: string, printer: ts.Printer) {
undefined undefined
) )
), ),
factory.createPropertySignature(
undefined,
factory.createIdentifier("Aggregation"),
undefined,
factory.createTypeReferenceNode(
factory.createIdentifier("Aggregation"),
undefined
)
),
factory.createPropertySignature( factory.createPropertySignature(
undefined, undefined,
factory.createIdentifier("Operation"), factory.createIdentifier("Operation"),

View File

@ -1,5 +1,5 @@
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord } from "../types"; import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult } from "../types";
import assert from "assert"; import assert from "assert";
import { IncomingHttpHeaders } from "http"; import { IncomingHttpHeaders } from "http";
@ -145,6 +145,13 @@ export interface AsyncRowStore<ED extends EntityDict, Cxt extends Context> exten
option: OP option: OP
): Promise<Partial<ED[T]['Schema']>[]>; ): Promise<Partial<ED[T]['Schema']>[]>;
aggregate<T extends keyof ED, OP extends SelectOption> (
entity: T,
aggregation: ED[T]['Aggregation'],
context: Cxt,
option: OP
): Promise<AggregationResult<ED[T]['Schema']>>;
count<T extends keyof ED, OP extends SelectOption> ( count<T extends keyof ED, OP extends SelectOption> (
entity: T, entity: T,
selection: Pick<ED[T]['Selection'], 'filter' | 'count'>, selection: Pick<ED[T]['Selection'], 'filter' | 'count'>,

View File

@ -1,6 +1,5 @@
import assert from 'assert'; import assert from 'assert';
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, TxnOption, Context } from "../types"; import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, TxnOption, Context, AggregationResult } from "../types";
import { AsyncContext } from './AsyncRowStore';
export abstract class SyncContext<ED extends EntityDict> implements Context { export abstract class SyncContext<ED extends EntityDict> implements Context {
private rowStore: SyncRowStore<ED, this>; private rowStore: SyncRowStore<ED, this>;
@ -84,6 +83,13 @@ export interface SyncRowStore<ED extends EntityDict, Cxt extends Context> extend
option: OP option: OP
): number; ): number;
aggregate<T extends keyof ED, OP extends SelectOption> (
entity: T,
aggregation: ED[T]['Aggregation'],
context: Cxt,
option: OP
): AggregationResult<ED[T]['Schema']>;
begin(option?: TxnOption): string; begin(option?: TxnOption): string;

View File

@ -92,6 +92,7 @@ export interface EntityDef {
Action: string; Action: string;
ParticularAction?: string; ParticularAction?: string;
Selection: Omit<DeduceSelection<this['Schema']>, 'action'>; Selection: Omit<DeduceSelection<this['Schema']>, 'action'>;
Aggregation: Omit<DeduceAggregation<this['Schema'], DeduceProjection<this['Schema']>, DeduceFilter<this['Schema']>, DeduceSorter<this['Schema']>>, 'action'>;
Operation: DeduceOperation<this['Schema']>; Operation: DeduceOperation<this['Schema']>;
Create: DeduceCreateOperation<this['Schema']>; Create: DeduceCreateOperation<this['Schema']>;
CreateSingle: DeduceCreateSingleOperation<this['Schema']>; CreateSingle: DeduceCreateSingleOperation<this['Schema']>;
@ -112,8 +113,21 @@ type DeduceProjection<SH extends GeneralEntityShape> = {
'#id'?: NodeId; '#id'?: NodeId;
} & { } & {
[K in keyof SH]?: number | OtmSubProjection | any; [K in keyof SH]?: number | OtmSubProjection | any;
} & Partial<ExprOp<keyof SH>>; } & Partial<ExprOp<keyof SH | string>>;
export type AggregationOp = `$max-${number}` | `$min-${number}` | `$avg-${number}` | `$count-${number}` | `$sum-${number}`;
export type DeduceAggregationData<SH extends GeneralEntityShape, P extends DeduceProjection<SH>> = {
[A in AggregationOp]?: P;
} & {
$aggr?: P;
};
export type AggregationResult<SH extends GeneralEntityShape> = Array<{
[A in AggregationOp]?: number | string;
} & {
data?: Partial<SH>
}>;
export type AttrFilter<SH extends GeneralEntityShape> = { export type AttrFilter<SH extends GeneralEntityShape> = {
[K in keyof SH]: any; [K in keyof SH]: any;
@ -134,6 +148,12 @@ export type DeduceSorter<SH extends GeneralEntityShape> = Array<DeduceSorterItem
export type DeduceSelection<SH extends GeneralEntityShape> = Selection<DeduceProjection<SH>, DeduceFilter<SH>, DeduceSorter<SH>>; export type DeduceSelection<SH extends GeneralEntityShape> = Selection<DeduceProjection<SH>, DeduceFilter<SH>, DeduceSorter<SH>>;
export type DeduceAggregation<
SH extends GeneralEntityShape,
P extends DeduceProjection<SH>,
F extends DeduceFilter<SH>,
S extends DeduceSorter<SH>> = Omit<Operation<'aggregate', DeduceAggregationData<SH, P>, F, S>, 'action'>;
export type DeduceCreateOperationData<SH extends GeneralEntityShape> = { export type DeduceCreateOperationData<SH extends GeneralEntityShape> = {
id: string; id: string;
} & { } & {

View File

@ -467,9 +467,14 @@ export function getAttrRefInExpression(expression: Expression<any>) {
}); });
} }
} }
else if (node instanceof Array) {
for (const subNode of node) {
check(subNode);
}
}
else { else {
for (const attr in expression) { for (const attr in node) {
check((expression as any)[attr]); check((node as any)[attr]);
} }
} }
}; };