适配新domain

This commit is contained in:
Xu Chang 2022-03-21 17:42:11 +08:00
parent 9875f5f4c5
commit 7984af515f
6 changed files with 81 additions and 57 deletions

8
lib/context.d.ts vendored
View File

@ -1,12 +1,10 @@
import { Context as ContextInterface } from 'oak-domain/lib/types/Context';
import { EntityDef, OperationResult } from 'oak-domain/lib/types/Entity';
import { EntityDict, OpRecord } from 'oak-domain/lib/types/Entity';
import TreeStore from './store';
export declare class Context<ED extends {
[E: string]: EntityDef;
}> implements ContextInterface<ED> {
export declare class Context<ED extends EntityDict> implements ContextInterface<ED> {
rowStore: TreeStore<ED>;
uuid?: string;
result?: OperationResult<ED>;
opRecords: OpRecord<ED>[];
constructor(store: TreeStore<ED>);
on(event: 'commit' | 'rollback', callback: (context: ContextInterface<ED>) => Promise<void>): void;
begin(options?: object): Promise<void>;

View File

@ -9,19 +9,18 @@ const uuid_1 = require("uuid");
class Context {
rowStore;
uuid;
result;
opRecords;
constructor(store) {
this.rowStore = store;
this.opRecords = [];
}
on(event, callback) {
throw new Error('not implemented here!');
}
async begin(options) {
(0, assert_1.default)(!this.uuid);
this.uuid = (0, uuid_1.v4)();
this.rowStore.begin(this.uuid);
this.result = {
operations: [],
};
}
async commit() {
(0, assert_1.default)(this.uuid);

7
lib/store.d.ts vendored
View File

@ -1,4 +1,4 @@
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult, OperateParams } from "oak-domain/lib/types/Entity";
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult, OperateParams, OpRecord } from "oak-domain/lib/types/Entity";
import { CascadeStore } from 'oak-domain/lib/schema/CascadeStore';
import { StorageSchema } from 'oak-domain/lib/types/Storage';
import { Context } from "./context";
@ -66,8 +66,8 @@ export default class TreeStore<ED extends {
protected selectAbjointRow<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], 'indexFrom' | 'count' | 'data' | 'sorter'>, context: Context<ED>, params?: Object): Promise<SelectionResult<ED, T>['result']>;
protected updateAbjointRow<T extends keyof ED>(entity: T, operation: DeduceCreateSingleOperation<ED[T]['Schema']> | DeduceUpdateOperation<ED[T]['Schema']> | DeduceRemoveOperation<ED[T]['Schema']>, context: Context<ED>, params?: OperateParams): Promise<void>;
private doOperation;
operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult<ED>>;
protected formProjection<T extends keyof ED>(entity: T, row: ED[T]['Schema'], data: ED[T]['Selection']['data'], result: Partial<ED[T]['Schema']>, nodeDict: NodeDict, context: Context<ED>): Promise<void>;
operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult>;
protected formProjection<T extends keyof ED>(entity: T, row: ED[T]['OpSchema'], data: ED[T]['Selection']['data'], result: Partial<ED[T]['Schema']>, nodeDict: NodeDict, context: Context<ED>): Promise<void>;
private formResult;
select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Context<ED>, params?: Object): Promise<SelectionResult<ED, T>>;
count<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], "action" | "data" | "sorter">, context: Context<ED>, params?: Object): Promise<number>;
@ -75,4 +75,5 @@ export default class TreeStore<ED extends {
begin(uuid: string): void;
commit(uuid: string): void;
rollback(uuid: string): void;
sync(opRecords: Array<OpRecord<ED>>, context: Context<ED>): Promise<void>;
}

View File

@ -546,9 +546,8 @@ class TreeStore extends CascadeStore_1.CascadeStore {
* @param context
*/
addToResultSelections(entity, rows, context) {
const { result } = context;
const { operations } = result;
let lastOperation = (0, lodash_1.last)(operations);
const { opRecords } = context;
let lastOperation = (0, lodash_1.last)(opRecords);
if (lastOperation && lastOperation.a === 's') {
const entityBranch = lastOperation.d[entity];
if (entityBranch) {
@ -568,7 +567,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
a: 's',
d: {},
};
operations.push(lastOperation);
opRecords.push(lastOperation);
}
const entityBranch = {};
rows.forEach((row) => {
@ -635,7 +634,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
(0, lodash_1.set)(this.store, `${entity}.${id}`, node);
this.addToTxnNode(node, context, 'create');
if (!params || !params.notCollect) {
context.result.operations.push({
context.opRecords.push({
a: 'c',
e: entity,
d: data,
@ -661,7 +660,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
node.$path = `${entity}.${id}`;
this.addToTxnNode(node, context, 'remove');
if (!params || !params.notCollect) {
context.result.operations.push({
context.opRecords.push({
a: 'r',
e: entity,
f: operation.filter,
@ -672,7 +671,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
node.$next = data;
this.addToTxnNode(node, context, 'update');
if (!params || !params.notCollect) {
context.result.operations.push({
context.opRecords.push({
a: 'u',
e: entity,
d: data,
@ -690,12 +689,11 @@ class TreeStore extends CascadeStore_1.CascadeStore {
if (action === 'select') {
const result = await this.cascadeSelect(entity, operation, context, params);
const ids = result.map((ele) => ele.id);
(0, lodash_1.assign)(context.result, {
ids,
});
return { ids };
}
else {
return this.cascadeUpdate(entity, operation, context, params);
this.cascadeUpdate(entity, operation, context, params);
return {};
}
}
async operate(entity, operation, context, params) {
@ -704,8 +702,9 @@ class TreeStore extends CascadeStore_1.CascadeStore {
autoCommit = true;
await context.begin();
}
let result;
try {
await this.doOperation(entity, operation, context, params);
result = await this.doOperation(entity, operation, context, params);
}
catch (err) {
if (autoCommit) {
@ -716,7 +715,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
if (autoCommit) {
await context.commit();
}
return context.result;
return result;
}
async formProjection(entity, row, data, result, nodeDict, context) {
const row2 = row;
@ -823,10 +822,9 @@ class TreeStore extends CascadeStore_1.CascadeStore {
if (autoCommit) {
await context.commit();
}
const { stats } = context.result;
return {
result,
stats,
// stats,
};
}
async count(entity, selection, context, params) {
@ -905,5 +903,21 @@ class TreeStore extends CascadeStore_1.CascadeStore {
}
(0, lodash_1.unset)(this.activeTxnDict, uuid);
}
// 将输入的OpRecord同步到数据中
async sync(opRecords, context) {
for (const record of opRecords) {
switch (record.a) {
case 'c': {
const { e, d } = record;
await this.doOperation(e, {
action: 'create',
data: d,
}, context, {
notCollect: true,
});
}
}
}
}
}
exports.default = TreeStore;

View File

@ -1,30 +1,27 @@
import assert from 'assert';
import { v4 } from 'uuid';
import { Context as ContextInterface } from 'oak-domain/lib/types/Context';
import { EntityDef, EntityShape, OperationResult } from 'oak-domain/lib/types/Entity';
import { EntityDef, EntityDict, OperationResult, OpRecord } from 'oak-domain/lib/types/Entity';
import TreeStore from './store';
export class Context<ED extends {
[E: string]: EntityDef;
}> implements ContextInterface<ED> {
export class Context<ED extends EntityDict> implements ContextInterface<ED> {
rowStore: TreeStore<ED>;
uuid?: string;
result?: OperationResult<ED>;
opRecords: OpRecord<ED>[];
constructor(store: TreeStore<ED>) {
this.rowStore = store;
this.opRecords = [];
}
on(event: 'commit' | 'rollback', callback: (context: ContextInterface<ED>) => Promise<void>): void {
throw new Error('not implemented here!');
}
async begin(options?: object): Promise<void> {
assert(!this.uuid);
this.uuid = v4();
this.rowStore.begin(this.uuid);
this.result = {
operations: [],
};
}
async commit(): Promise<void> {
assert(this.uuid);

View File

@ -1,6 +1,6 @@
import { assign, cloneDeep, get, last, set, unset } from 'lodash';
import assert from 'assert';
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceFilter, DeduceSelection, EntityShape, DeduceRemoveOperation, DeduceUpdateOperation, DeduceSorter, DeduceSorterAttr, OperationResult, OperateParams } from "oak-domain/lib/types/Entity";
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceFilter, DeduceSelection, EntityShape, DeduceRemoveOperation, DeduceUpdateOperation, DeduceSorter, DeduceSorterAttr, OperationResult, OperateParams, OpRecord } from "oak-domain/lib/types/Entity";
import { ExpressionKey, EXPRESSION_PREFIX, NodeId, RefAttr } from 'oak-domain/lib/types/Demand';
import { CascadeStore } from 'oak-domain/lib/schema/CascadeStore';
import { StorageSchema } from 'oak-domain/lib/types/Storage';
@ -260,7 +260,7 @@ export default class TreeStore<ED extends {
private translateExpression<T extends keyof ED>(
entity: T,
expression: Expression<keyof ED[T]['Schema']>,
context: Context<ED>): (row: ED[T]['Schema'], nodeDict: NodeDict) => Promise<ExpressionConstant | ExprLaterCheckFn> {
context: Context<ED>): (row: ED[T]['OpSchema'], nodeDict: NodeDict) => Promise<ExpressionConstant | ExprLaterCheckFn> {
const expr = this.translateExpressionNode(entity, expression, context);
return async (row, nodeDict) => {
@ -672,10 +672,9 @@ export default class TreeStore<ED extends {
* @param context
*/
private addToResultSelections<T extends keyof ED>(entity: T, rows: Array<ED[T]['OpSchema']>, context: Context<ED>) {
const { result } = context;
const { operations } = result!;
const { opRecords } = context;
let lastOperation = last(operations);
let lastOperation = last(opRecords);
if (lastOperation && lastOperation.a === 's') {
const entityBranch = lastOperation.d[entity];
if (entityBranch) {
@ -697,7 +696,7 @@ export default class TreeStore<ED extends {
a: 's',
d: {},
};
operations.push(lastOperation);
opRecords.push(lastOperation);
}
const entityBranch = {};
@ -784,7 +783,7 @@ export default class TreeStore<ED extends {
set(this.store, `${entity}.${id!}`, node);
this.addToTxnNode(node, context, 'create');
if (!params || !params.notCollect) {
context.result!.operations.push({
context.opRecords.push({
a: 'c',
e: entity,
d: data,
@ -812,7 +811,7 @@ export default class TreeStore<ED extends {
node.$path = `${entity}.${id!}`;
this.addToTxnNode(node, context, 'remove');
if (!params || !params.notCollect) {
context.result!.operations.push({
context.opRecords.push({
a: 'r',
e: entity,
f: (operation as DeduceRemoveOperation<ED[T]['Schema']>).filter,
@ -823,7 +822,7 @@ export default class TreeStore<ED extends {
node.$next = data as EntityShape;
this.addToTxnNode(node, context, 'update');
if (!params || !params.notCollect) {
context.result!.operations.push({
context.opRecords.push({
a: 'u',
e: entity,
d: data,
@ -838,30 +837,30 @@ export default class TreeStore<ED extends {
}
}
private async doOperation<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<void> {
private async doOperation<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult> {
const { action } = operation;
if (action === 'select') {
const result = await this.cascadeSelect(entity, operation as any, context, params);
const ids = result.map(
(ele) => ele.id
(ele) => ele.id!
);
assign(context.result, {
ids,
});
return { ids };
}
else {
return this.cascadeUpdate(entity, operation as any, context, params);
this.cascadeUpdate(entity, operation as any, context, params);
return {};
}
}
async operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult<ED>> {
async operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult> {
let autoCommit = false;
if (!context.uuid) {
autoCommit = true;
await context.begin();
}
let result;
try {
await this.doOperation(entity, operation, context, params);
result = await this.doOperation(entity, operation, context, params);
} catch (err) {
if (autoCommit) {
await context.rollback();
@ -871,12 +870,12 @@ export default class TreeStore<ED extends {
if (autoCommit) {
await context.commit();
}
return context.result!;
return result;
}
protected async formProjection<T extends keyof ED>(
entity: T,
row: ED[T]['Schema'],
row: ED[T]['OpSchema'],
data: ED[T]['Selection']['data'],
result: Partial<ED[T]['Schema']>,
nodeDict: NodeDict,
@ -960,7 +959,7 @@ export default class TreeStore<ED extends {
private async formResult<T extends keyof ED>(
entity: T,
rows: Array<Partial<ED[T]['Schema']>>,
rows: Array<ED[T]['OpSchema']>,
selection: Omit<ED[T]['Selection'], 'filter'>,
context: Context<ED>,
nodeDict?: NodeDict) {
@ -1003,10 +1002,9 @@ export default class TreeStore<ED extends {
if (autoCommit) {
await context.commit();
}
const { stats } = context.result!;
return {
result,
stats,
// stats,
};
}
@ -1091,4 +1089,21 @@ export default class TreeStore<ED extends {
}
unset(this.activeTxnDict, uuid);
}
// 将输入的OpRecord同步到数据中
async sync(opRecords: Array<OpRecord<ED>>, context: Context<ED>) {
for (const record of opRecords) {
switch (record.a) {
case 'c': {
const { e, d } = record;
await this.doOperation(e, {
action: 'create',
data: d as ED[keyof ED]['Schema'] & { id: string },
}, context, {
notCollect: true,
});
}
}
}
}
}