适配新domain
This commit is contained in:
parent
9875f5f4c5
commit
7984af515f
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
|||
44
lib/store.js
44
lib/store.js
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
59
src/store.ts
59
src/store.ts
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue