适配了domain带来的类型变化
This commit is contained in:
parent
7e6ab43b00
commit
19d0036ab7
|
|
@ -1,3 +1,2 @@
|
|||
import TreeStore from "./store";
|
||||
import { Context } from './context';
|
||||
export { TreeStore, Context, };
|
||||
export { TreeStore, };
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Context = exports.TreeStore = void 0;
|
||||
exports.TreeStore = void 0;
|
||||
const store_1 = __importDefault(require("./store"));
|
||||
exports.TreeStore = store_1.default;
|
||||
const context_1 = require("./context");
|
||||
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
|
||||
|
|
|
|||
|
|
@ -1,23 +1,12 @@
|
|||
import { SelectionResult2, DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult, OperateParams, OpRecord, EntityDict } from "oak-domain/lib/types/Entity";
|
||||
import { DeduceCreateSingleOperation, DeduceRemoveOperation, DeduceUpdateOperation, OperationResult, OperateParams, OpRecord, EntityDict, SelectRowShape } from "oak-domain/lib/types/Entity";
|
||||
import { CascadeStore } from 'oak-domain/lib/store/CascadeStore';
|
||||
import { StorageSchema } from 'oak-domain/lib/types/Storage';
|
||||
import { Context } from "./context";
|
||||
import { NodeDict, RowNode } from "./types/type";
|
||||
export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
||||
store: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: RowNode;
|
||||
};
|
||||
};
|
||||
immutable: boolean;
|
||||
activeTxnDict: {
|
||||
[T: string]: {
|
||||
nodeHeader?: RowNode;
|
||||
create: number;
|
||||
update: number;
|
||||
remove: number;
|
||||
};
|
||||
};
|
||||
import { Context } from "oak-domain/lib/types/Context";
|
||||
import { NodeDict } from "./types/type";
|
||||
export default class TreeStore<ED extends EntityDict, Cxt extends Context<ED>> extends CascadeStore<ED, Cxt> {
|
||||
private store;
|
||||
private activeTxnDict;
|
||||
private stat;
|
||||
setInitialData(data: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: ED[T]['OpSchema'];
|
||||
|
|
@ -28,10 +17,15 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
[ID: string]: ED[T]['OpSchema'];
|
||||
};
|
||||
};
|
||||
constructor(storageSchema: StorageSchema<ED>, immutable?: boolean, initialData?: {
|
||||
constructor(storageSchema: StorageSchema<ED>, initialData?: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: ED[T]['OpSchema'];
|
||||
};
|
||||
}, stat?: {
|
||||
create: number;
|
||||
update: number;
|
||||
remove: number;
|
||||
commit: number;
|
||||
});
|
||||
private constructRow;
|
||||
private translateLogicFilter;
|
||||
|
|
@ -60,17 +54,25 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
* @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<Array<ED[T]['OpSchema']>>;
|
||||
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>;
|
||||
protected selectAbjointRow<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], 'indexFrom' | 'count' | 'data' | 'sorter'>, context: Cxt, params?: OperateParams): Promise<Array<ED[T]['OpSchema']>>;
|
||||
protected updateAbjointRow<T extends keyof ED>(entity: T, operation: DeduceCreateSingleOperation<ED[T]['Schema']> | DeduceUpdateOperation<ED[T]['Schema']> | DeduceRemoveOperation<ED[T]['Schema']>, context: Cxt, params?: OperateParams): Promise<void>;
|
||||
private doOperation;
|
||||
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: Partial<ED[T]['OpSchema']>, data: ED[T]['Selection']['data'], result: object, nodeDict: NodeDict, context: Context<ED>): Promise<void>;
|
||||
operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, params?: OperateParams): Promise<OperationResult>;
|
||||
protected formProjection<T extends keyof ED>(entity: T, row: Partial<ED[T]['OpSchema']>, data: ED[T]['Selection']['data'], result: object, nodeDict: NodeDict, context: Cxt): Promise<void>;
|
||||
private formResult;
|
||||
select<T extends keyof ED, S extends ED[T]['Selection']>(entity: T, selection: S, context: Context<ED>, params?: Object): Promise<SelectionResult2<ED[T]['Schema'], S['data']>>;
|
||||
count<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], "action" | "data" | "sorter">, context: Context<ED>, params?: Object): Promise<number>;
|
||||
select<T extends keyof ED, S extends ED[T]['Selection']>(entity: T, selection: S, context: Cxt, params?: Object): Promise<{
|
||||
result: SelectRowShape<ED[T]["Schema"], ED[T]["Selection"]["data"]>[];
|
||||
}>;
|
||||
count<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], "action" | "data" | "sorter">, context: Cxt, params?: Object): Promise<number>;
|
||||
private addToTxnNode;
|
||||
begin(uuid: string): void;
|
||||
commit(uuid: string): void;
|
||||
rollback(uuid: string): void;
|
||||
sync(opRecords: Array<OpRecord<ED>>, context: Context<ED>): Promise<void>;
|
||||
getStat(): {
|
||||
create: number;
|
||||
update: number;
|
||||
remove: number;
|
||||
commit: number;
|
||||
};
|
||||
begin(): Promise<string>;
|
||||
commit(uuid: string): Promise<void>;
|
||||
rollback(uuid: string): Promise<void>;
|
||||
sync(opRecords: Array<OpRecord<ED>>, context: Cxt): Promise<void>;
|
||||
}
|
||||
|
|
|
|||
200
lib/store.js
200
lib/store.js
|
|
@ -12,19 +12,23 @@ const RowStore_1 = require("oak-domain/lib/types/RowStore");
|
|||
const Demand_2 = require("oak-domain/lib/types/Demand");
|
||||
const relation_1 = require("oak-domain/lib/store/relation");
|
||||
const Expression_1 = require("oak-domain/lib/types/Expression");
|
||||
const uuid_1 = require("uuid");
|
||||
;
|
||||
;
|
||||
function obscurePass(row, attr, params) {
|
||||
return !!(params.obscure && row[attr] === undefined);
|
||||
}
|
||||
class TreeStore extends CascadeStore_1.CascadeStore {
|
||||
store;
|
||||
immutable;
|
||||
activeTxnDict;
|
||||
stat;
|
||||
setInitialData(data) {
|
||||
for (const entity in data) {
|
||||
if (!this.store[entity]) {
|
||||
this.store[entity] = {};
|
||||
}
|
||||
for (const rowId in data[entity]) {
|
||||
(0, lodash_1.set)(this.store, `${entity}.${rowId}.#current`, data[entity][rowId]);
|
||||
(0, lodash_1.set)(this.store, `${entity}.${rowId}.$current`, data[entity][rowId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -38,18 +42,23 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
constructor(storageSchema, immutable = false, initialData) {
|
||||
constructor(storageSchema, initialData, stat) {
|
||||
super(storageSchema);
|
||||
this.immutable = immutable;
|
||||
this.store = {};
|
||||
if (initialData) {
|
||||
this.setInitialData(initialData);
|
||||
}
|
||||
this.activeTxnDict = {};
|
||||
this.stat = stat || {
|
||||
create: 0,
|
||||
update: 0,
|
||||
remove: 0,
|
||||
commit: 0,
|
||||
};
|
||||
}
|
||||
constructRow(node, context) {
|
||||
let data = (0, lodash_1.cloneDeep)(node.$current);
|
||||
if (context.uuid && node.$uuid === context.uuid) {
|
||||
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
||||
if (!node.$next) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -102,12 +111,12 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
* @param context
|
||||
* @returns
|
||||
*/
|
||||
translateExpressionNode(entity, expression, context) {
|
||||
translateExpressionNode(entity, expression, context, params) {
|
||||
if ((0, Expression_1.isExpression)(expression)) {
|
||||
const op = Object.keys(expression)[0];
|
||||
const params = expression[op];
|
||||
if ((0, Expression_1.opMultipleParams)(op)) {
|
||||
const paramsTranslated = params.map(ele => this.translateExpressionNode(entity, ele, context));
|
||||
const paramsTranslated = params.map(ele => this.translateExpressionNode(entity, ele, context, params));
|
||||
return (row, nodeDict) => {
|
||||
let later = false;
|
||||
let results = paramsTranslated.map((ele) => {
|
||||
|
|
@ -121,7 +130,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
return ele;
|
||||
});
|
||||
if (!later) {
|
||||
return (0, Expression_1.execOp)(op, results);
|
||||
return (0, Expression_1.execOp)(op, results, params.obscure);
|
||||
}
|
||||
const laterCheckFn = (nodeDict2) => {
|
||||
results = results.map((ele) => {
|
||||
|
|
@ -134,13 +143,13 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
if (results.find(ele => typeof ele === 'function')) {
|
||||
return laterCheckFn;
|
||||
}
|
||||
return (0, Expression_1.execOp)(op, results);
|
||||
return (0, Expression_1.execOp)(op, results, params.obscure);
|
||||
};
|
||||
return laterCheckFn;
|
||||
};
|
||||
}
|
||||
else {
|
||||
const paramsTranslated = this.translateExpressionNode(entity, params, context);
|
||||
const paramsTranslated = this.translateExpressionNode(entity, params, context, params);
|
||||
if (typeof paramsTranslated === 'function') {
|
||||
return (row, nodeDict) => {
|
||||
let result = paramsTranslated(row, nodeDict);
|
||||
|
|
@ -154,12 +163,12 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
};
|
||||
return laterCheckFn;
|
||||
}
|
||||
return (0, Expression_1.execOp)(op, result);
|
||||
return (0, Expression_1.execOp)(op, result, params.obscure);
|
||||
};
|
||||
}
|
||||
else {
|
||||
return () => {
|
||||
return (0, Expression_1.execOp)(op, paramsTranslated);
|
||||
return (0, Expression_1.execOp)(op, paramsTranslated, params.obscure);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -193,8 +202,8 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
return expression;
|
||||
}
|
||||
}
|
||||
translateExpression(entity, expression, context) {
|
||||
const expr = this.translateExpressionNode(entity, expression, context);
|
||||
translateExpression(entity, expression, context, params) {
|
||||
const expr = this.translateExpressionNode(entity, expression, context, params);
|
||||
return async (row, nodeDict) => {
|
||||
if (typeof expr !== 'function') {
|
||||
return expr;
|
||||
|
|
@ -203,7 +212,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
return result;
|
||||
};
|
||||
}
|
||||
translateFulltext(entity, filter, context) {
|
||||
translateFulltext(entity, filter, context, params) {
|
||||
// 全文索引查找
|
||||
const { [entity]: { indexes } } = this.storageSchema;
|
||||
const fulltextIndex = indexes.find(ele => ele.config && ele.config.type === 'fulltext');
|
||||
|
|
@ -213,7 +222,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const row = this.constructRow(node, context);
|
||||
for (const attr of attributes) {
|
||||
const { name } = attr;
|
||||
if (row && row[name] && typeof row[name] === 'string' && row[name].contains($search)) {
|
||||
if (row && row[name] && (typeof row[name] === 'string' && row[name].contains($search) || obscurePass(row, name, params))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -221,63 +230,64 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
};
|
||||
}
|
||||
async translateAttribute(filter, attr, context, params) {
|
||||
// 如果是模糊查询且该属性为undefined,说明没取到,返回true
|
||||
function obscurePassLocal(row) {
|
||||
return obscurePass(row, attr, params);
|
||||
}
|
||||
if (typeof filter !== 'object') {
|
||||
return async (node) => {
|
||||
const row = this.constructRow(node, context);
|
||||
return row ? row[attr] === filter : false;
|
||||
return row ? row[attr] === filter || obscurePassLocal(row) : false;
|
||||
};
|
||||
}
|
||||
const fns = [];
|
||||
for (const op in filter) {
|
||||
switch (op) {
|
||||
case '$gt': {
|
||||
fns.push(async (row) => row[attr] > filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] > filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$lt': {
|
||||
fns.push(async (row) => row[attr] < filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] < filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$gte': {
|
||||
fns.push(async (row) => row[attr] >= filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] >= filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$lte': {
|
||||
fns.push(async (row) => row[attr] <= filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] <= filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$eq': {
|
||||
fns.push(async (row) => row[attr] === filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] === filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$ne': {
|
||||
fns.push(async (row) => row[attr] !== filter[op]);
|
||||
fns.push(async (row) => row && (row[attr] !== filter[op]) || obscurePassLocal(row));
|
||||
break;
|
||||
}
|
||||
case '$between': {
|
||||
fns.push(async (row) => {
|
||||
return row[attr] >= filter[op][0] && row[attr] <= filter[op][1];
|
||||
return row && (row[attr] >= filter[op][0] && row[attr] <= filter[op][1] || obscurePassLocal(row));
|
||||
});
|
||||
break;
|
||||
}
|
||||
case '$startsWith': {
|
||||
fns.push(async (row) => {
|
||||
(0, assert_1.default)(typeof row[attr] === 'string');
|
||||
return row[attr].startsWith(filter[op]);
|
||||
return row && (row[attr].startsWith(filter[op]) || obscurePassLocal(row));
|
||||
});
|
||||
break;
|
||||
}
|
||||
case '$endsWith': {
|
||||
fns.push(async (row) => {
|
||||
(0, assert_1.default)(typeof row[attr] === 'string');
|
||||
return row[attr].$endsWith(filter[op]);
|
||||
return row && (row[attr].$endsWith(filter[op]) || obscurePassLocal(row));
|
||||
});
|
||||
break;
|
||||
}
|
||||
case '$includes': {
|
||||
fns.push(async (row) => {
|
||||
(0, assert_1.default)(typeof row[attr] === 'string');
|
||||
return row[attr].includes(filter[op]);
|
||||
return row && (row[attr].includes(filter[op]) || obscurePassLocal(row));
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
@ -286,10 +296,10 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
(0, assert_1.default)(typeof exists === 'boolean');
|
||||
fns.push(async (row) => {
|
||||
if (exists) {
|
||||
return [null, undefined].includes(row[attr]);
|
||||
return [null].includes(row[attr]) || obscurePassLocal(row);
|
||||
}
|
||||
else {
|
||||
return ![null, undefined].includes(row[attr]);
|
||||
return ![null, undefined].includes(row[attr]) || obscurePassLocal(row);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
|
@ -298,35 +308,41 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const inData = filter[op];
|
||||
(0, assert_1.default)(typeof inData === 'object');
|
||||
if (inData instanceof Array) {
|
||||
fns.push(async (row) => inData.includes(row[attr]));
|
||||
fns.push(async (row) => inData.includes(row[attr]) || obscurePassLocal(row));
|
||||
}
|
||||
else {
|
||||
// 这里只有当子查询中的filter不包含引用外部的子查询时才可以提前计算,否则必须等到执行时再计算
|
||||
try {
|
||||
const legalSets = (await this.selectAbjointRow(inData.entity, inData, context, params)).map((ele) => {
|
||||
const { data } = inData;
|
||||
const key = Object.keys(data)[0];
|
||||
return ele[key];
|
||||
});
|
||||
fns.push(async (row) => legalSets.includes(row[attr]));
|
||||
// 如果是obscure,则返回的集合中有没有都不能否决“可能有”,所以可以直接返回true
|
||||
if (params.obscure) {
|
||||
fns.push(async () => true);
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof OakError_1.OakError && err.$$code === RowStore_1.RowStore.$$CODES.expressionUnresolved[0]) {
|
||||
fns.push(async (row, nodeDict) => {
|
||||
(0, lodash_1.assign)(params, {
|
||||
nodeDict,
|
||||
});
|
||||
const legalSets = (await this.selectAbjointRow(inData.entity, inData, context, params)).map((ele) => {
|
||||
const { data } = inData;
|
||||
const key = Object.keys(data)[0];
|
||||
return ele[key];
|
||||
});
|
||||
(0, lodash_1.unset)(params, 'nodeDict');
|
||||
return legalSets.includes(row[attr]);
|
||||
else {
|
||||
// 这里只有当子查询中的filter不包含引用外部的子查询时才可以提前计算,否则必须等到执行时再计算
|
||||
try {
|
||||
const legalSets = (await this.selectAbjointRow(inData.entity, inData, context, params)).map((ele) => {
|
||||
const { data } = inData;
|
||||
const key = Object.keys(data)[0];
|
||||
return ele[key];
|
||||
});
|
||||
fns.push(async (row) => legalSets.includes(row[attr]));
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
catch (err) {
|
||||
if (err instanceof OakError_1.OakError && err.$$code === RowStore_1.RowStore.$$CODES.expressionUnresolved[0]) {
|
||||
fns.push(async (row, nodeDict) => {
|
||||
(0, lodash_1.assign)(params, {
|
||||
nodeDict,
|
||||
});
|
||||
const legalSets = (await this.selectAbjointRow(inData.entity, inData, context, params)).map((ele) => {
|
||||
const { data } = inData;
|
||||
const key = Object.keys(data)[0];
|
||||
return ele[key];
|
||||
});
|
||||
(0, lodash_1.unset)(params, 'nodeDict');
|
||||
return legalSets.includes(row[attr]);
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -336,9 +352,10 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const inData = filter[op];
|
||||
(0, assert_1.default)(typeof inData === 'object');
|
||||
if (inData instanceof Array) {
|
||||
fns.push(async (row) => !inData.includes(row[attr]));
|
||||
fns.push(async (row) => !inData.includes(row[attr]) || obscurePassLocal(row));
|
||||
}
|
||||
else {
|
||||
// obscure对nin没有影响,如果返回的子查询结果中包含此行就一定是false,否则一定为true(obscure只考虑数据不完整,不考虑不准确),但若相应属性为undefined则任然可以认为true
|
||||
// 这里只有当子查询中的filter不包含引用外部的子查询时才可以提前计算,否则必须等到执行时再计算
|
||||
try {
|
||||
const legalSets = (await this.selectAbjointRow(inData.entity, inData, context, params)).map((ele) => {
|
||||
|
|
@ -346,7 +363,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const key = Object.keys(data)[0];
|
||||
return ele[key];
|
||||
});
|
||||
fns.push(async (row) => !legalSets.includes(row[attr]));
|
||||
fns.push(async (row) => !legalSets.includes(row[attr]) || obscurePassLocal(row));
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof OakError_1.OakError && err.$$code === RowStore_1.RowStore.$$CODES.expressionUnresolved[0]) {
|
||||
|
|
@ -360,7 +377,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
return ele[key];
|
||||
});
|
||||
(0, lodash_1.unset)(params, 'nodeDict');
|
||||
return !legalSets.includes(row[attr]);
|
||||
return !legalSets.includes(row[attr]) || obscurePassLocal(row);
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
|
@ -398,7 +415,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
fns.push(this.translateLogicFilter(entity, filter, attr, context, params));
|
||||
}
|
||||
else if (attr.toLowerCase().startsWith(Demand_1.EXPRESSION_PREFIX)) {
|
||||
const fn = this.translateExpression(entity, filter[attr], context);
|
||||
const fn = this.translateExpression(entity, filter[attr], context, params);
|
||||
fns.push(async (node, nodeDict, exprResolveFns) => {
|
||||
const row = this.constructRow(node, context);
|
||||
if (!row) {
|
||||
|
|
@ -412,7 +429,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
});
|
||||
}
|
||||
else if (attr.toLowerCase() === '$text') {
|
||||
fns.push(this.translateFulltext(entity, filter[attr], context));
|
||||
fns.push(this.translateFulltext(entity, filter[attr], context, params));
|
||||
}
|
||||
else {
|
||||
// 属性级过滤
|
||||
|
|
@ -426,11 +443,19 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const fn = await this.translateFilter(attr, filter[attr], context, params);
|
||||
fns.push(async (node, nodeDict, exprResolveFns) => {
|
||||
const row = this.constructRow(node, context);
|
||||
if (obscurePass(row, 'entity', params) || obscurePass(row, 'entityId', params)) {
|
||||
return true;
|
||||
}
|
||||
if (row.entity !== attr || row.entityId) {
|
||||
return false;
|
||||
}
|
||||
const node2 = (0, lodash_1.get)(this.store, `${attr}.${row.entityId}`);
|
||||
(0, assert_1.default)(node2);
|
||||
if (!node2) {
|
||||
if (params.obscure) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return fn(node2, nodeDict, exprResolveFns);
|
||||
});
|
||||
}
|
||||
|
|
@ -440,9 +465,17 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const fn = await this.translateFilter(relation, filter[attr], context, params);
|
||||
fns.push(async (node, nodeDict, exprResolveFns) => {
|
||||
const row = this.constructRow(node, context);
|
||||
if (obscurePass(row, `${attr}Id`, params)) {
|
||||
return true;
|
||||
}
|
||||
if (row[`${attr}Id`]) {
|
||||
const node2 = (0, lodash_1.get)(this.store, `${relation}.${row[`${attr}Id`]}`);
|
||||
(0, assert_1.default)(node2);
|
||||
if (!node2) {
|
||||
if (params.obscure) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return fn(node2, nodeDict, exprResolveFns);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -638,7 +671,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
$$updateAt$$: data.$$updateAt$$ || now,
|
||||
});
|
||||
const node2 = {
|
||||
$uuid: context.uuid,
|
||||
$txnId: context.getCurrentTxnId(),
|
||||
$current: null,
|
||||
$next: data2,
|
||||
$path: `${entity}.${id}`,
|
||||
|
|
@ -668,8 +701,8 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const ids = rows.map(ele => ele.id);
|
||||
ids.forEach((id) => {
|
||||
const node = (this.store[entity])[id];
|
||||
(0, assert_1.default)(node && (!node.$uuid || node.$uuid === context.uuid));
|
||||
node.$uuid = context.uuid;
|
||||
(0, assert_1.default)(node && (!node.$txnId || node.$txnId === context.getCurrentTxnId()));
|
||||
node.$txnId = context.getCurrentTxnId();
|
||||
if (action === 'remove') {
|
||||
node.$next = null;
|
||||
node.$path = `${entity}.${id}`;
|
||||
|
|
@ -719,7 +752,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
}
|
||||
async operate(entity, operation, context, params) {
|
||||
let autoCommit = false;
|
||||
if (!context.uuid) {
|
||||
if (!context.getCurrentTxnId()) {
|
||||
autoCommit = true;
|
||||
await context.begin();
|
||||
}
|
||||
|
|
@ -744,7 +777,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
const laterExprDict = {};
|
||||
for (const attr in data) {
|
||||
if (attr.startsWith(Demand_1.EXPRESSION_PREFIX)) {
|
||||
const ExprNodeTranslator = this.translateExpression(entity, data2[attr], context);
|
||||
const ExprNodeTranslator = this.translateExpression(entity, data2[attr], context, {});
|
||||
const exprResult = await ExprNodeTranslator(row, nodeDict);
|
||||
if (typeof exprResult === 'function') {
|
||||
(0, lodash_1.assign)(laterExprDict, {
|
||||
|
|
@ -842,7 +875,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
async select(entity, selection, context, params) {
|
||||
let autoCommit = false;
|
||||
let result;
|
||||
if (!context.uuid) {
|
||||
if (!context.getCurrentTxnId()) {
|
||||
autoCommit = true;
|
||||
await context.begin();
|
||||
}
|
||||
|
|
@ -873,7 +906,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
return rows.length;
|
||||
}
|
||||
addToTxnNode(node, context, action) {
|
||||
const txnNode = this.activeTxnDict[context.uuid];
|
||||
const txnNode = this.activeTxnDict[context.getCurrentTxnId()];
|
||||
(0, assert_1.default)(txnNode);
|
||||
(0, assert_1.default)(!node.$nextNode);
|
||||
if (txnNode.nodeHeader) {
|
||||
|
|
@ -885,7 +918,11 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
}
|
||||
txnNode[action]++;
|
||||
}
|
||||
begin(uuid) {
|
||||
getStat() {
|
||||
return this.stat;
|
||||
}
|
||||
async begin() {
|
||||
const uuid = (0, uuid_1.v4)({ random: await getRandomValues(16) });
|
||||
(0, assert_1.default)(!this.activeTxnDict.hasOwnProperty(uuid));
|
||||
(0, lodash_1.assign)(this.activeTxnDict, {
|
||||
[uuid]: {
|
||||
|
|
@ -894,17 +931,18 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
remove: 0,
|
||||
},
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
commit(uuid) {
|
||||
async commit(uuid) {
|
||||
(0, assert_1.default)(this.activeTxnDict.hasOwnProperty(uuid));
|
||||
let node = this.activeTxnDict[uuid].nodeHeader;
|
||||
while (node) {
|
||||
const node2 = node.$nextNode;
|
||||
(0, assert_1.default)(node.$uuid === uuid);
|
||||
(0, assert_1.default)(node.$txnId === uuid);
|
||||
if (node.$next) {
|
||||
// create/update
|
||||
node.$current = (0, lodash_1.assign)(node.$current, node.$next);
|
||||
(0, lodash_1.unset)(node, '$uuid');
|
||||
(0, lodash_1.unset)(node, '$txnId');
|
||||
(0, lodash_1.unset)(node, '$next');
|
||||
(0, lodash_1.unset)(node, '$path');
|
||||
(0, lodash_1.unset)(node, '$nextNode');
|
||||
|
|
@ -916,17 +954,23 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
}
|
||||
node = node2;
|
||||
}
|
||||
if (this.activeTxnDict[uuid].create || this.activeTxnDict[uuid].update || this.activeTxnDict[uuid].remove) {
|
||||
this.stat.create += this.activeTxnDict[uuid].create;
|
||||
this.stat.update += this.activeTxnDict[uuid].update;
|
||||
this.stat.remove += this.activeTxnDict[uuid].remove;
|
||||
this.stat.commit++;
|
||||
}
|
||||
(0, lodash_1.unset)(this.activeTxnDict, uuid);
|
||||
}
|
||||
rollback(uuid) {
|
||||
async rollback(uuid) {
|
||||
(0, assert_1.default)(this.activeTxnDict.hasOwnProperty(uuid));
|
||||
let node = this.activeTxnDict[uuid].nodeHeader;
|
||||
while (node) {
|
||||
const node2 = node.$nextNode;
|
||||
(0, assert_1.default)(node.$uuid === uuid);
|
||||
(0, assert_1.default)(node.$txnId === uuid);
|
||||
if (node.$current) {
|
||||
// update/remove
|
||||
(0, lodash_1.unset)(node, '$uuid');
|
||||
(0, lodash_1.unset)(node, '$txnId');
|
||||
(0, lodash_1.unset)(node, '$next');
|
||||
(0, lodash_1.unset)(node, '$path');
|
||||
(0, lodash_1.unset)(node, '$nextNode');
|
||||
|
|
@ -943,7 +987,7 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
|||
// 将输入的OpRecord同步到数据中
|
||||
async sync(opRecords, context) {
|
||||
let autoCommit = false;
|
||||
if (!context.uuid) {
|
||||
if (!context.getCurrentTxnId()) {
|
||||
await context.begin();
|
||||
autoCommit = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { NodeId } from "oak-domain/lib/types/Demand";
|
||||
import { EntityShape } from "oak-domain/src/types/Entity";
|
||||
export declare type RowNode = {
|
||||
$uuid?: string;
|
||||
$txnId?: string;
|
||||
$next?: Partial<EntityShape> | null;
|
||||
$current?: EntityShape | null;
|
||||
$nextNode?: RowNode;
|
||||
|
|
|
|||
44
src/store.ts
44
src/store.ts
|
|
@ -1,6 +1,6 @@
|
|||
import { assign, cloneDeep, get, keys, last, set, unset } from 'lodash';
|
||||
import assert from 'assert';
|
||||
import { SelectionResult2, DeduceCreateSingleOperation, DeduceFilter, DeduceSelection, EntityShape, DeduceRemoveOperation, DeduceUpdateOperation, DeduceSorter, DeduceSorterAttr, OperationResult, OperateParams, OpRecord, DeduceCreateOperationData, DeduceUpdateOperationData, UpdateOpResult, RemoveOpResult, SelectOpResult, EntityDict, SelectRowShape } from "oak-domain/lib/types/Entity";
|
||||
import { DeduceCreateSingleOperation, DeduceFilter, DeduceSelection, EntityShape, DeduceRemoveOperation, DeduceUpdateOperation, DeduceSorter, DeduceSorterAttr, OperationResult, OperateParams, OpRecord, DeduceCreateOperationData, DeduceUpdateOperationData, UpdateOpResult, RemoveOpResult, SelectOpResult, EntityDict, SelectRowShape } from "oak-domain/lib/types/Entity";
|
||||
import { ExpressionKey, EXPRESSION_PREFIX, NodeId, RefAttr } from 'oak-domain/lib/types/Demand';
|
||||
import { CascadeStore } from 'oak-domain/lib/store/CascadeStore';
|
||||
import { StorageSchema } from 'oak-domain/lib/types/Storage';
|
||||
|
|
@ -26,7 +26,7 @@ function obscurePass(row: any, attr: string, params: OperateParams): boolean {
|
|||
return !!(params.obscure && row[attr] === undefined);
|
||||
}
|
||||
|
||||
export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
||||
export default class TreeStore<ED extends EntityDict, Cxt extends Context<ED>> extends CascadeStore<ED, Cxt> {
|
||||
private store: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: RowNode;
|
||||
|
|
@ -105,7 +105,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
};
|
||||
}
|
||||
|
||||
private constructRow(node: RowNode, context: Context<ED>) {
|
||||
private constructRow(node: RowNode, context: Cxt) {
|
||||
let data = cloneDeep(node.$current);
|
||||
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
||||
if (!node.$next) {
|
||||
|
|
@ -122,7 +122,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
entity: T,
|
||||
filter: DeduceFilter<ED[T]['Schema']>,
|
||||
attr: string,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params: OperateParams): (node: RowNode, nodeDict: NodeDict, exprResolveFns: Array<ExprResolveFn>) => Promise<boolean> {
|
||||
switch (attr) {
|
||||
case '$and': {
|
||||
|
|
@ -175,7 +175,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
private translateExpressionNode<T extends keyof ED>(
|
||||
entity: T,
|
||||
expression: Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']> | ExpressionConstant,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params: OperateParams): ExprNodeTranslator | ExpressionConstant {
|
||||
|
||||
if (isExpression(expression)) {
|
||||
|
|
@ -286,7 +286,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
private translateExpression<T extends keyof ED>(
|
||||
entity: T,
|
||||
expression: Expression<keyof ED[T]['Schema']>,
|
||||
context: Context<ED>, params: OperateParams): (row: Partial<ED[T]['OpSchema']>, nodeDict: NodeDict) => Promise<ExpressionConstant | ExprLaterCheckFn> {
|
||||
context: Cxt, params: OperateParams): (row: Partial<ED[T]['OpSchema']>, nodeDict: NodeDict) => Promise<ExpressionConstant | ExprLaterCheckFn> {
|
||||
const expr = this.translateExpressionNode(entity, expression, context, params);
|
||||
|
||||
return async (row, nodeDict) => {
|
||||
|
|
@ -301,7 +301,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
private translateFulltext<T extends keyof ED>(
|
||||
entity: T,
|
||||
filter: Q_FullTextValue,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params: OperateParams): (node: RowNode) => Promise<boolean> {
|
||||
// 全文索引查找
|
||||
const { [entity]: { indexes } } = this.storageSchema;
|
||||
|
|
@ -326,7 +326,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
|
||||
private async translateAttribute<T extends keyof ED>(filter: Q_NumberValue | Q_StringValue | Q_BooleanValue | ED[T]['Selection'] & {
|
||||
entity: T;
|
||||
}, attr: string, context: Context<ED>, params: OperateParams): Promise<(node: RowNode, nodeDict: NodeDict, exprResolveFns: Array<ExprResolveFn>) => Promise<boolean>> {
|
||||
}, attr: string, context: Cxt, params: OperateParams): Promise<(node: RowNode, nodeDict: NodeDict, exprResolveFns: Array<ExprResolveFn>) => Promise<boolean>> {
|
||||
// 如果是模糊查询且该属性为undefined,说明没取到,返回true
|
||||
function obscurePassLocal(row: any) {
|
||||
return obscurePass(row, attr, params);
|
||||
|
|
@ -523,7 +523,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
private async translateFilter<T extends keyof ED>(
|
||||
entity: T,
|
||||
filter: DeduceFilter<ED[T]['Schema']>,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params: OperateParams): Promise<(node: RowNode, nodeDict: NodeDict, exprResolveFns: Array<ExprResolveFn>) => Promise<boolean>> {
|
||||
const fns: Array<(node: RowNode, nodeDict: NodeDict, exprResolveFns: Array<ExprResolveFn>) => Promise<boolean>> = [];
|
||||
|
||||
|
|
@ -634,7 +634,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
};
|
||||
}
|
||||
|
||||
private translateSorter<T extends keyof ED>(entity: T, sorter: DeduceSorter<ED[T]['Schema']>, context: Context<ED>):
|
||||
private translateSorter<T extends keyof ED>(entity: T, sorter: DeduceSorter<ED[T]['Schema']>, context: Cxt):
|
||||
(row1: object | null | undefined, row2: object | null | undefined) => number {
|
||||
const compare = <T2 extends keyof ED>(
|
||||
row1: object | null | undefined,
|
||||
|
|
@ -725,7 +725,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
* @param rows
|
||||
* @param context
|
||||
*/
|
||||
private addToResultSelections<T extends keyof ED>(entity: T, rows: Array<ED[T]['OpSchema']>, context: Context<ED>) {
|
||||
private addToResultSelections<T extends keyof ED>(entity: T, rows: Array<ED[T]['OpSchema']>, context: Cxt) {
|
||||
const { opRecords } = context;
|
||||
|
||||
let lastOperation = last(opRecords);
|
||||
|
|
@ -770,7 +770,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
protected async selectAbjointRow<T extends keyof ED>(
|
||||
entity: T,
|
||||
selection: Omit<ED[T]['Selection'], 'indexFrom' | 'count' | 'data' | 'sorter'>,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params: OperateParams = {}): Promise<Array<ED[T]['OpSchema']>> {
|
||||
const { filter } = selection;
|
||||
const { nodeDict } = params as {
|
||||
|
|
@ -817,7 +817,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
protected async updateAbjointRow<T extends keyof ED>(
|
||||
entity: T,
|
||||
operation: DeduceCreateSingleOperation<ED[T]['Schema']> | DeduceUpdateOperation<ED[T]['Schema']> | DeduceRemoveOperation<ED[T]['Schema']>,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
params?: OperateParams): Promise<void> {
|
||||
const { data, action } = operation;
|
||||
|
||||
|
|
@ -905,7 +905,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
}
|
||||
}
|
||||
|
||||
private async doOperation<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult> {
|
||||
private async doOperation<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, params?: OperateParams): Promise<OperationResult> {
|
||||
const { action } = operation;
|
||||
if (action === 'select') {
|
||||
const rows = await this.cascadeSelect(entity, operation as any, context, params);
|
||||
|
|
@ -922,7 +922,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
}
|
||||
}
|
||||
|
||||
async operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Context<ED>, params?: OperateParams): Promise<OperationResult> {
|
||||
async operate<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, params?: OperateParams): Promise<OperationResult> {
|
||||
let autoCommit = false;
|
||||
if (!context.getCurrentTxnId()) {
|
||||
autoCommit = true;
|
||||
|
|
@ -949,7 +949,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
data: ED[T]['Selection']['data'],
|
||||
result: object,
|
||||
nodeDict: NodeDict,
|
||||
context: Context<ED>) {
|
||||
context: Cxt) {
|
||||
const row2 = row as any;
|
||||
const data2 = data as any;
|
||||
|
||||
|
|
@ -1035,7 +1035,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
entity: T,
|
||||
rows: Array<Partial<ED[T]['Schema']>>,
|
||||
selection: Omit<S, 'filter'>,
|
||||
context: Context<ED>,
|
||||
context: Cxt,
|
||||
nodeDict?: NodeDict) {
|
||||
const { data, sorter, indexFrom, count } = selection;
|
||||
// 先计算projection
|
||||
|
|
@ -1068,8 +1068,8 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
async select<T extends keyof ED, S extends ED[T]['Selection']>(
|
||||
entity: T,
|
||||
selection: S,
|
||||
context: Context<ED>,
|
||||
params?: Object): Promise<SelectionResult2<ED[T]['Schema'], S['data']>> {
|
||||
context: Cxt,
|
||||
params?: Object) {
|
||||
let autoCommit = false;
|
||||
let result;
|
||||
if (!context.getCurrentTxnId()) {
|
||||
|
|
@ -1095,7 +1095,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
};
|
||||
}
|
||||
|
||||
async count<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], "action" | "data" | "sorter">, context: Context<ED>, params?: Object): Promise<number> {
|
||||
async count<T extends keyof ED>(entity: T, selection: Omit<ED[T]['Selection'], "action" | "data" | "sorter">, context: Cxt, params?: Object): Promise<number> {
|
||||
const rows = await this.cascadeSelect(entity, assign({}, selection, {
|
||||
data: {
|
||||
id: 1,
|
||||
|
|
@ -1105,7 +1105,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
return rows.length;
|
||||
}
|
||||
|
||||
private addToTxnNode(node: RowNode, context: Context<ED>, action: 'create' | 'update' | 'remove') {
|
||||
private addToTxnNode(node: RowNode, context: Cxt, action: 'create' | 'update' | 'remove') {
|
||||
const txnNode = this.activeTxnDict[context.getCurrentTxnId()!];
|
||||
assert(txnNode);
|
||||
assert(!node.$nextNode);
|
||||
|
|
@ -1191,7 +1191,7 @@ export default class TreeStore<ED extends EntityDict> extends CascadeStore<ED> {
|
|||
}
|
||||
|
||||
// 将输入的OpRecord同步到数据中
|
||||
async sync(opRecords: Array<OpRecord<ED>>, context: Context<ED>) {
|
||||
async sync(opRecords: Array<OpRecord<ED>>, context: Cxt) {
|
||||
let autoCommit = false;
|
||||
if (!context.getCurrentTxnId()) {
|
||||
await context.begin();
|
||||
|
|
|
|||
34
test/test.ts
34
test/test.ts
|
|
@ -2,17 +2,17 @@ import { v4 } from 'uuid';
|
|||
import { describe, it } from 'mocha';
|
||||
import TreeStore from '../src/store';
|
||||
import { EntityDict } from './app-domain/EntityDict';
|
||||
import { Context } from '../src/context';
|
||||
import { storageSchema } from './app-domain/Storage';
|
||||
import assert from 'assert';
|
||||
import { CreateSingleOperation } from './app-domain/System/Schema';
|
||||
import { UniversalContext } from 'oak-domain/lib/store/UniversalContext';
|
||||
|
||||
describe('基础测试', function () {
|
||||
this.timeout(1000000);
|
||||
|
||||
it('[1.0]简单查询', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
const created = await store.operate('application', {
|
||||
action: 'create',
|
||||
data: [{
|
||||
|
|
@ -73,8 +73,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.1]子查询', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('user', {
|
||||
action: 'create',
|
||||
|
|
@ -115,8 +115,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.2]行内属性上的表达式', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('user', {
|
||||
action: 'create',
|
||||
|
|
@ -149,8 +149,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.3]跨filter结点的表达式', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('application', {
|
||||
action: 'create',
|
||||
|
|
@ -227,8 +227,8 @@ describe('基础测试', function () {
|
|||
|
||||
|
||||
it('[1.4]跨filter子查询的表达式', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('application', {
|
||||
action: 'create',
|
||||
|
|
@ -345,8 +345,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.5]projection中的跨结点表达式', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('application', {
|
||||
action: 'create',
|
||||
|
|
@ -445,8 +445,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.6]projection中的一对多跨结点表达式', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('system', {
|
||||
action: 'create',
|
||||
|
|
@ -518,8 +518,8 @@ describe('基础测试', function () {
|
|||
});
|
||||
|
||||
it('[1.7]事务性测试', async () => {
|
||||
const store = new TreeStore<EntityDict>(storageSchema);
|
||||
const context = new Context(store);
|
||||
const store = new TreeStore<EntityDict, UniversalContext<EntityDict>>(storageSchema);
|
||||
const context = new UniversalContext(store);
|
||||
|
||||
await store.operate('system', {
|
||||
action: 'create',
|
||||
|
|
|
|||
Loading…
Reference in New Issue