select也加上了result

This commit is contained in:
Xu Chang 2022-03-18 22:35:20 +08:00
parent 2642a90e4c
commit 9875f5f4c5
3 changed files with 177 additions and 22 deletions

13
lib/store.d.ts vendored
View File

@ -1,4 +1,4 @@
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult } from "oak-domain/lib/types/Entity";
import { EntityDef, SelectionResult, DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult, OperateParams } 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";
@ -56,10 +56,17 @@ export default class TreeStore<ED extends {
private translateAttribute;
private translateFilter;
private translateSorter;
/**
* result
* @param entity
* @param rows
* @param context
*/
private addToResultSelections;
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?: Object): Promise<void>;
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?: Object): Promise<OperationResult<ED>>;
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>;
private formResult;
select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Context<ED>, params?: Object): Promise<SelectionResult<ED, T>>;

View File

@ -45,13 +45,13 @@ class TreeStore extends CascadeStore_1.CascadeStore {
this.activeTxnDict = {};
}
constructRow(node, context) {
let data = node.$current;
let data = (0, lodash_1.cloneDeep)(node.$current);
if (context.uuid && node.$uuid === context.uuid) {
if (!node.$next) {
return null;
}
else {
data = (0, lodash_1.assign)({}, node.$current, node.$next);
(0, lodash_1.assign)(data, node.$next);
}
}
return data;
@ -539,6 +539,48 @@ class TreeStore extends CascadeStore_1.CascadeStore {
return 0;
};
}
/**
* 将一次查询的结果集加入result
* @param entity
* @param rows
* @param context
*/
addToResultSelections(entity, rows, context) {
const { result } = context;
const { operations } = result;
let lastOperation = (0, lodash_1.last)(operations);
if (lastOperation && lastOperation.a === 's') {
const entityBranch = lastOperation.d[entity];
if (entityBranch) {
rows.forEach((row) => {
const { id } = row;
if (!entityBranch[id]) {
(0, lodash_1.assign)(entityBranch, {
[id]: (0, lodash_1.cloneDeep)(row),
});
}
});
return;
}
}
else {
lastOperation = {
a: 's',
d: {},
};
operations.push(lastOperation);
}
const entityBranch = {};
rows.forEach((row) => {
const { id } = row;
(0, lodash_1.assign)(entityBranch, {
[id]: (0, lodash_1.cloneDeep)(row),
});
});
(0, lodash_1.assign)(lastOperation.d, {
[entity]: entityBranch,
});
}
async selectAbjointRow(entity, selection, context, params = {}) {
const { filter } = selection;
const { nodeDict } = params;
@ -572,9 +614,10 @@ class TreeStore extends CascadeStore_1.CascadeStore {
}
}
const rows = nodes.map((node) => this.constructRow(node, context));
this.addToResultSelections(entity, rows, context);
return rows;
}
async updateAbjointRow(entity, operation, context, params = {}) {
async updateAbjointRow(entity, operation, context, params) {
const { data, action } = operation;
switch (action) {
case 'create': {
@ -591,6 +634,13 @@ 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({
a: 'c',
e: entity,
d: data,
});
}
break;
}
default: {
@ -608,12 +658,27 @@ class TreeStore extends CascadeStore_1.CascadeStore {
node.$uuid = context.uuid;
if (action === 'remove') {
node.$next = null;
node.$path = `${entity}.${id}`,
this.addToTxnNode(node, context, 'remove');
node.$path = `${entity}.${id}`;
this.addToTxnNode(node, context, 'remove');
if (!params || !params.notCollect) {
context.result.operations.push({
a: 'r',
e: entity,
f: operation.filter,
});
}
}
else {
node.$next = data;
this.addToTxnNode(node, context, 'update');
if (!params || !params.notCollect) {
context.result.operations.push({
a: 'u',
e: entity,
d: data,
f: operation.filter,
});
}
}
});
break;
@ -690,11 +755,12 @@ class TreeStore extends CascadeStore_1.CascadeStore {
}
else if (relation === 2) {
const result2 = {};
const { entity, entityId } = row2;
await this.formProjection(attr, row2[attr], data2[attr], result2, nodeDict, context);
(0, lodash_1.assign)(result, {
[attr]: result2,
entity: row2.entity,
entityId: row2.entityId,
entity,
entityId,
});
}
else if (typeof relation === 'string') {
@ -702,7 +768,6 @@ class TreeStore extends CascadeStore_1.CascadeStore {
await this.formProjection(relation, row2[attr], data2[attr], result2, nodeDict, context);
(0, lodash_1.assign)(result, {
[attr]: result2,
[`${attr}Id`]: row2[`${attr}Id`],
});
}
else {
@ -739,8 +804,25 @@ class TreeStore extends CascadeStore_1.CascadeStore {
return rows2;
}
async select(entity, selection, context, params) {
const rows = await this.cascadeSelect(entity, selection, context, params);
const result = await this.formResult(entity, rows, selection, context);
let autoCommit = false;
let result;
if (!context.uuid) {
autoCommit = true;
await context.begin();
}
try {
const rows = await this.cascadeSelect(entity, selection, context, params);
result = await this.formResult(entity, rows, selection, context);
}
catch (err) {
if (autoCommit) {
await context.rollback();
}
throw err;
}
if (autoCommit) {
await context.commit();
}
const { stats } = context.result;
return {
result,

View File

@ -1,4 +1,4 @@
import { assign, get, set, unset } from 'lodash';
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 { ExpressionKey, EXPRESSION_PREFIX, NodeId, RefAttr } from 'oak-domain/lib/types/Demand';
@ -81,13 +81,13 @@ export default class TreeStore<ED extends {
}
private constructRow(node: RowNode, context: Context<ED>) {
let data = node.$current;
let data = cloneDeep(node.$current);
if (context.uuid && node.$uuid === context.uuid) {
if (!node.$next) {
return null;
}
else {
data = assign({}, node.$current, node.$next);
assign(data, node.$next);
}
}
return data;
@ -665,6 +665,55 @@ export default class TreeStore<ED extends {
}
}
/**
* result
* @param entity
* @param rows
* @param context
*/
private addToResultSelections<T extends keyof ED>(entity: T, rows: Array<ED[T]['OpSchema']>, context: Context<ED>) {
const { result } = context;
const { operations } = result!;
let lastOperation = last(operations);
if (lastOperation && lastOperation.a === 's') {
const entityBranch = lastOperation.d[entity];
if (entityBranch) {
rows.forEach(
(row) => {
const { id } = row;
if (!entityBranch![id!]) {
assign(entityBranch!, {
[id!]: cloneDeep(row),
});
}
}
);
return;
}
}
else {
lastOperation = {
a: 's',
d: {},
};
operations.push(lastOperation);
}
const entityBranch = {};
rows.forEach(
(row) => {
const { id } = row;
assign(entityBranch!, {
[id!]: cloneDeep(row),
});
}
);
assign(lastOperation.d, {
[entity]: entityBranch,
});
}
protected async selectAbjointRow<T extends keyof ED>(
entity: T,
selection: Omit<ED[T]['Selection'], 'indexFrom' | 'count' | 'data' | 'sorter'>,
@ -708,6 +757,7 @@ export default class TreeStore<ED extends {
(node) => this.constructRow(node, context) as EntityShape
);
this.addToResultSelections(entity, rows, context);
return rows;
}
@ -871,11 +921,12 @@ export default class TreeStore<ED extends {
}
else if (relation === 2) {
const result2 = {};
const { entity, entityId } = row2;
await this.formProjection(attr, row2[attr], data2[attr], result2, nodeDict, context);
assign(result, {
[attr]: result2,
entity: row2.entity,
entityId: row2.entityId,
entity,
entityId,
});
}
else if (typeof relation === 'string') {
@ -883,7 +934,6 @@ export default class TreeStore<ED extends {
await this.formProjection(relation, row2[attr], data2[attr], result2, nodeDict, context);
assign(result, {
[attr]: result2,
[`${attr}Id`]: row2[`${attr}Id`],
});
}
else {
@ -934,9 +984,25 @@ export default class TreeStore<ED extends {
}
async select<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Context<ED>, params?: Object): Promise<SelectionResult<ED, T>> {
const rows = await this.cascadeSelect(entity, selection, context, params);
const result = await this.formResult(entity, rows, selection, context);
let autoCommit = false;
let result;
if (!context.uuid) {
autoCommit = true;
await context.begin();
}
try {
const rows = await this.cascadeSelect(entity, selection, context, params);
result = await this.formResult(entity, rows, selection, context);
} catch (err) {
if (autoCommit) {
await context.rollback();
}
throw err;
}
if (autoCommit) {
await context.commit();
}
const { stats } = context.result!;
return {
result,