Compare commits
12 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
2fd9a46011 | |
|
|
afe81e3fbb | |
|
|
0fc00a02b4 | |
|
|
a547f1d890 | |
|
|
b51889c9a9 | |
|
|
c82bf99fdb | |
|
|
5b5621216f | |
|
|
44d0df03cb | |
|
|
aa77a03f30 | |
|
|
ff0fcc8492 | |
|
|
e36cf430cf | |
|
|
a70f584e08 |
41
es/store.js
41
es/store.js
|
|
@ -5,6 +5,7 @@ import { EXPRESSION_PREFIX, SUB_QUERY_PREDICATE_KEYWORD } from 'oak-domain/lib/t
|
||||||
import { OakCongruentRowExists, OakException } from 'oak-domain/lib/types/Exception';
|
import { OakCongruentRowExists, OakException } from 'oak-domain/lib/types/Exception';
|
||||||
import { isRefAttrNode } from 'oak-domain/lib/types/Demand';
|
import { isRefAttrNode } from 'oak-domain/lib/types/Demand';
|
||||||
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
||||||
|
// Expression引入,下方声明改为any防止报错
|
||||||
import { execOp, isExpression, opMultipleParams } from 'oak-domain/lib/types/Expression';
|
import { execOp, isExpression, opMultipleParams } from 'oak-domain/lib/types/Expression';
|
||||||
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
||||||
import { CascadeStore, polishSelection } from 'oak-domain/lib/store/CascadeStore';
|
import { CascadeStore, polishSelection } from 'oak-domain/lib/store/CascadeStore';
|
||||||
|
|
@ -146,13 +147,12 @@ export default class TreeStore extends CascadeStore {
|
||||||
this.seq = {};
|
this.seq = {};
|
||||||
}
|
}
|
||||||
constructRow(node, context, option) {
|
constructRow(node, context, option) {
|
||||||
let data = cloneDeep(node.$current);
|
|
||||||
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
||||||
if (!node.$next) {
|
if (!node.$next) {
|
||||||
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
||||||
// bug fixed,这里如果是自己create再删除,data也是null
|
// bug fixed,这里如果是自己create再删除,data也是null
|
||||||
if (data && option?.includedDeleted) {
|
if (node.$current && option?.includedDeleted) {
|
||||||
return Object.assign({}, data, {
|
return Object.assign({}, node.$current, {
|
||||||
[DeleteAtAttribute]: 1,
|
[DeleteAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -160,19 +160,21 @@ export default class TreeStore extends CascadeStore {
|
||||||
}
|
}
|
||||||
else if (!node.$current) {
|
else if (!node.$current) {
|
||||||
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncContext && {
|
||||||
[CreateAtAttribute]: 1,
|
[CreateAtAttribute]: 1,
|
||||||
[UpdateAtAttribute]: 1,
|
[UpdateAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 本事务更新的,若在cache中$$updateAt$$置为1
|
// 本事务更新的,若在cache中$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncContext && {
|
||||||
[UpdateAtAttribute]: 1,
|
[UpdateAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return {
|
||||||
|
...node.$current,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
testFilterFns(node, nodeDict, exprResolveFns, fns) {
|
testFilterFns(node, nodeDict, exprResolveFns, fns) {
|
||||||
const { self, otm, mto } = fns;
|
const { self, otm, mto } = fns;
|
||||||
|
|
@ -290,12 +292,16 @@ export default class TreeStore extends CascadeStore {
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
translateExpressionNode(entity, expression, context, option) {
|
translateExpressionNode(entity,
|
||||||
|
// expression: Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']> | ExpressionConstant,
|
||||||
|
expression, context, option) {
|
||||||
if (isExpression(expression)) {
|
if (isExpression(expression)) {
|
||||||
const op = Object.keys(expression)[0];
|
const op = Object.keys(expression)[0];
|
||||||
const option2 = expression[op];
|
const option2 = expression[op];
|
||||||
if (opMultipleParams(op)) {
|
if (opMultipleParams(op)) {
|
||||||
const paramsTranslated = option2.map(ele => this.translateExpressionNode(entity, ele, context, option2));
|
const paramsTranslated = option2.map(
|
||||||
|
// const paramsTranslated = (option2 as (Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']>)[]).map(
|
||||||
|
ele => this.translateExpressionNode(entity, ele, context, option2));
|
||||||
return (row, nodeDict) => {
|
return (row, nodeDict) => {
|
||||||
let later = false;
|
let later = false;
|
||||||
let results = paramsTranslated.map((ele) => {
|
let results = paramsTranslated.map((ele) => {
|
||||||
|
|
@ -385,7 +391,9 @@ export default class TreeStore extends CascadeStore {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
translateExpression(entity, expression, context, option) {
|
translateExpression(entity,
|
||||||
|
// expression: Expression<keyof ED[T]['Schema']>,
|
||||||
|
expression, context, option) {
|
||||||
const expr = this.translateExpressionNode(entity, expression, context, option);
|
const expr = this.translateExpressionNode(entity, expression, context, option);
|
||||||
return (row, nodeDict) => {
|
return (row, nodeDict) => {
|
||||||
if (typeof expr !== 'function') {
|
if (typeof expr !== 'function') {
|
||||||
|
|
@ -566,6 +574,21 @@ export default class TreeStore extends CascadeStore {
|
||||||
}).length > 0;
|
}).length > 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case '$length': {
|
||||||
|
// json中的数组长度查询
|
||||||
|
const length = value;
|
||||||
|
return (row) => {
|
||||||
|
const data = path ? get(row, path) : row;
|
||||||
|
assert(data instanceof Array, '$length operator can only used on array attribute');
|
||||||
|
if (typeof length === 'number') {
|
||||||
|
return data.length === length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const op = Object.keys(length)[0];
|
||||||
|
return this.translatePredicate(entity, 'length', op, length[op], option)(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`predicate ${predicate} is not recoganized`);
|
throw new Error(`predicate ${predicate} is not recoganized`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
41
lib/store.js
41
lib/store.js
|
|
@ -7,6 +7,7 @@ const Demand_1 = require("oak-domain/lib/types/Demand");
|
||||||
const Exception_1 = require("oak-domain/lib/types/Exception");
|
const Exception_1 = require("oak-domain/lib/types/Exception");
|
||||||
const Demand_2 = require("oak-domain/lib/types/Demand");
|
const Demand_2 = require("oak-domain/lib/types/Demand");
|
||||||
const relation_1 = require("oak-domain/lib/store/relation");
|
const relation_1 = require("oak-domain/lib/store/relation");
|
||||||
|
// Expression引入,下方声明改为any防止报错
|
||||||
const Expression_1 = require("oak-domain/lib/types/Expression");
|
const Expression_1 = require("oak-domain/lib/types/Expression");
|
||||||
const SyncRowStore_1 = require("oak-domain/lib/store/SyncRowStore");
|
const SyncRowStore_1 = require("oak-domain/lib/store/SyncRowStore");
|
||||||
const CascadeStore_1 = require("oak-domain/lib/store/CascadeStore");
|
const CascadeStore_1 = require("oak-domain/lib/store/CascadeStore");
|
||||||
|
|
@ -148,13 +149,12 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
||||||
this.seq = {};
|
this.seq = {};
|
||||||
}
|
}
|
||||||
constructRow(node, context, option) {
|
constructRow(node, context, option) {
|
||||||
let data = (0, lodash_1.cloneDeep)(node.$current);
|
|
||||||
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
||||||
if (!node.$next) {
|
if (!node.$next) {
|
||||||
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
||||||
// bug fixed,这里如果是自己create再删除,data也是null
|
// bug fixed,这里如果是自己create再删除,data也是null
|
||||||
if (data && option?.includedDeleted) {
|
if (node.$current && option?.includedDeleted) {
|
||||||
return Object.assign({}, data, {
|
return Object.assign({}, node.$current, {
|
||||||
[Entity_1.DeleteAtAttribute]: 1,
|
[Entity_1.DeleteAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -162,19 +162,21 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
||||||
}
|
}
|
||||||
else if (!node.$current) {
|
else if (!node.$current) {
|
||||||
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncRowStore_1.SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncRowStore_1.SyncContext && {
|
||||||
[Entity_1.CreateAtAttribute]: 1,
|
[Entity_1.CreateAtAttribute]: 1,
|
||||||
[Entity_1.UpdateAtAttribute]: 1,
|
[Entity_1.UpdateAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 本事务更新的,若在cache中$$updateAt$$置为1
|
// 本事务更新的,若在cache中$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncRowStore_1.SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncRowStore_1.SyncContext && {
|
||||||
[Entity_1.UpdateAtAttribute]: 1,
|
[Entity_1.UpdateAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return {
|
||||||
|
...node.$current,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
testFilterFns(node, nodeDict, exprResolveFns, fns) {
|
testFilterFns(node, nodeDict, exprResolveFns, fns) {
|
||||||
const { self, otm, mto } = fns;
|
const { self, otm, mto } = fns;
|
||||||
|
|
@ -292,12 +294,16 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
||||||
* @param context
|
* @param context
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
translateExpressionNode(entity, expression, context, option) {
|
translateExpressionNode(entity,
|
||||||
|
// expression: Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']> | ExpressionConstant,
|
||||||
|
expression, context, option) {
|
||||||
if ((0, Expression_1.isExpression)(expression)) {
|
if ((0, Expression_1.isExpression)(expression)) {
|
||||||
const op = Object.keys(expression)[0];
|
const op = Object.keys(expression)[0];
|
||||||
const option2 = expression[op];
|
const option2 = expression[op];
|
||||||
if ((0, Expression_1.opMultipleParams)(op)) {
|
if ((0, Expression_1.opMultipleParams)(op)) {
|
||||||
const paramsTranslated = option2.map(ele => this.translateExpressionNode(entity, ele, context, option2));
|
const paramsTranslated = option2.map(
|
||||||
|
// const paramsTranslated = (option2 as (Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']>)[]).map(
|
||||||
|
ele => this.translateExpressionNode(entity, ele, context, option2));
|
||||||
return (row, nodeDict) => {
|
return (row, nodeDict) => {
|
||||||
let later = false;
|
let later = false;
|
||||||
let results = paramsTranslated.map((ele) => {
|
let results = paramsTranslated.map((ele) => {
|
||||||
|
|
@ -387,7 +393,9 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
translateExpression(entity, expression, context, option) {
|
translateExpression(entity,
|
||||||
|
// expression: Expression<keyof ED[T]['Schema']>,
|
||||||
|
expression, context, option) {
|
||||||
const expr = this.translateExpressionNode(entity, expression, context, option);
|
const expr = this.translateExpressionNode(entity, expression, context, option);
|
||||||
return (row, nodeDict) => {
|
return (row, nodeDict) => {
|
||||||
if (typeof expr !== 'function') {
|
if (typeof expr !== 'function') {
|
||||||
|
|
@ -568,6 +576,21 @@ class TreeStore extends CascadeStore_1.CascadeStore {
|
||||||
}).length > 0;
|
}).length > 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case '$length': {
|
||||||
|
// json中的数组长度查询
|
||||||
|
const length = value;
|
||||||
|
return (row) => {
|
||||||
|
const data = path ? (0, lodash_1.get)(row, path) : row;
|
||||||
|
(0, assert_1.assert)(data instanceof Array, '$length operator can only used on array attribute');
|
||||||
|
if (typeof length === 'number') {
|
||||||
|
return data.length === length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const op = Object.keys(length)[0];
|
||||||
|
return this.translatePredicate(entity, 'length', op, length[op], option)(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`predicate ${predicate} is not recoganized`);
|
throw new Error(`predicate ${predicate} is not recoganized`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "oak-memory-tree-store",
|
"name": "oak-memory-tree-store",
|
||||||
"version": "3.3.12",
|
"version": "3.3.15",
|
||||||
"description": "oak框架中内存级store的实现",
|
"description": "oak框架中内存级store的实现",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "XuChang"
|
"name": "XuChang"
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
"es/**/*"
|
"es/**/*"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"oak-domain": "^5.1.24",
|
"oak-domain": "file:../oak-domain",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
42
src/store.ts
42
src/store.ts
|
|
@ -15,6 +15,7 @@ import { StorageSchema } from 'oak-domain/lib/types/Storage';
|
||||||
import { ExprResolveFn, NodeDict, RowNode } from "./types/type";
|
import { ExprResolveFn, NodeDict, RowNode } from "./types/type";
|
||||||
import { isRefAttrNode, Q_BooleanValue, Q_FullTextValue, Q_NumberValue, Q_StringValue } from 'oak-domain/lib/types/Demand';
|
import { isRefAttrNode, Q_BooleanValue, Q_FullTextValue, Q_NumberValue, Q_StringValue } from 'oak-domain/lib/types/Demand';
|
||||||
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
import { judgeRelation } from 'oak-domain/lib/store/relation';
|
||||||
|
// Expression引入,下方声明改为any防止报错
|
||||||
import { execOp, Expression, ExpressionConstant, isExpression, opMultipleParams } from 'oak-domain/lib/types/Expression';
|
import { execOp, Expression, ExpressionConstant, isExpression, opMultipleParams } from 'oak-domain/lib/types/Expression';
|
||||||
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
|
||||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||||
|
|
@ -219,13 +220,12 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructRow<Cxt extends Context, OP extends TreeStoreSelectOption>(node: RowNode, context: Cxt, option?: OP) {
|
private constructRow<Cxt extends Context, OP extends TreeStoreSelectOption>(node: RowNode, context: Cxt, option?: OP) {
|
||||||
let data = cloneDeep(node.$current);
|
|
||||||
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
if (context.getCurrentTxnId() && node.$txnId === context.getCurrentTxnId()) {
|
||||||
if (!node.$next) {
|
if (!node.$next) {
|
||||||
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
// 如果要求返回delete数据,返回带$$deleteAt$$的行
|
||||||
// bug fixed,这里如果是自己create再删除,data也是null
|
// bug fixed,这里如果是自己create再删除,data也是null
|
||||||
if (data && option?.includedDeleted) {
|
if (node.$current && option?.includedDeleted) {
|
||||||
return Object.assign({}, data, {
|
return Object.assign({}, node.$current, {
|
||||||
[DeleteAtAttribute]: 1,
|
[DeleteAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -233,19 +233,21 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
}
|
}
|
||||||
else if (!node.$current) {
|
else if (!node.$current) {
|
||||||
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
// 本事务创建的,若在cache中$$createAt$$和$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncContext && {
|
||||||
[CreateAtAttribute]: 1,
|
[CreateAtAttribute]: 1,
|
||||||
[UpdateAtAttribute]: 1,
|
[UpdateAtAttribute]: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 本事务更新的,若在cache中$$updateAt$$置为1
|
// 本事务更新的,若在cache中$$updateAt$$置为1
|
||||||
return Object.assign({}, data, node.$next, context instanceof SyncContext && {
|
return Object.assign({}, node.$current, node.$next, context instanceof SyncContext && {
|
||||||
[UpdateAtAttribute]: 1,
|
[UpdateAtAttribute]: 1,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return {
|
||||||
|
...node.$current,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private testFilterFns(
|
private testFilterFns(
|
||||||
|
|
@ -397,7 +399,8 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
*/
|
*/
|
||||||
private translateExpressionNode<T extends keyof ED, OP extends TreeStoreSelectOption, Cxt extends Context>(
|
private translateExpressionNode<T extends keyof ED, OP extends TreeStoreSelectOption, Cxt extends Context>(
|
||||||
entity: T,
|
entity: T,
|
||||||
expression: Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']> | ExpressionConstant,
|
// expression: Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']> | ExpressionConstant,
|
||||||
|
expression: any,
|
||||||
context: Cxt,
|
context: Cxt,
|
||||||
option?: OP): ExprNodeTranslator | ExpressionConstant {
|
option?: OP): ExprNodeTranslator | ExpressionConstant {
|
||||||
|
|
||||||
|
|
@ -406,7 +409,8 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
const option2 = (expression as any)[op];
|
const option2 = (expression as any)[op];
|
||||||
|
|
||||||
if (opMultipleParams(op)) {
|
if (opMultipleParams(op)) {
|
||||||
const paramsTranslated = (option2 as (Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']>)[]).map(
|
const paramsTranslated = (option2 as any[]).map(
|
||||||
|
// const paramsTranslated = (option2 as (Expression<keyof ED[T]['Schema']> | RefAttr<keyof ED[T]['Schema']>)[]).map(
|
||||||
ele => this.translateExpressionNode(entity, ele, context, option2)
|
ele => this.translateExpressionNode(entity, ele, context, option2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -514,7 +518,8 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
|
|
||||||
private translateExpression<T extends keyof ED, OP extends TreeStoreSelectOption, Cxt extends Context>(
|
private translateExpression<T extends keyof ED, OP extends TreeStoreSelectOption, Cxt extends Context>(
|
||||||
entity: T,
|
entity: T,
|
||||||
expression: Expression<keyof ED[T]['Schema']>,
|
// expression: Expression<keyof ED[T]['Schema']>,
|
||||||
|
expression: any,
|
||||||
context: Cxt, option?: OP): (row: Partial<ED[T]['OpSchema']>, nodeDict: NodeDict) => ExpressionConstant | ExprLaterCheckFn {
|
context: Cxt, option?: OP): (row: Partial<ED[T]['OpSchema']>, nodeDict: NodeDict) => ExpressionConstant | ExprLaterCheckFn {
|
||||||
const expr = this.translateExpressionNode(entity, expression, context, option);
|
const expr = this.translateExpressionNode(entity, expression, context, option);
|
||||||
|
|
||||||
|
|
@ -707,6 +712,21 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
}).length > 0;
|
}).length > 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case '$length': {
|
||||||
|
// json中的数组长度查询
|
||||||
|
const length = value;
|
||||||
|
return (row) => {
|
||||||
|
const data = path ? get(row, path) : row;
|
||||||
|
assert(data instanceof Array, '$length operator can only used on array attribute');
|
||||||
|
if (typeof length === 'number') {
|
||||||
|
return data.length === length;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const op = Object.keys(length)[0];
|
||||||
|
return this.translatePredicate(entity, 'length', op, length[op], option)(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`predicate ${predicate} is not recoganized`);
|
throw new Error(`predicate ${predicate} is not recoganized`);
|
||||||
}
|
}
|
||||||
|
|
@ -2281,7 +2301,7 @@ export default class TreeStore<ED extends EntityDict & BaseEntityDict> extends C
|
||||||
}
|
}
|
||||||
else if (this.store[entity]?.[id]) {
|
else if (this.store[entity]?.[id]) {
|
||||||
const row = this.constructRow(this.store[entity]![id]!, context);
|
const row = this.constructRow(this.store[entity]![id]!, context);
|
||||||
if ((row[UpdateAtAttribute] as number) <= (d[entity]![id]![UpdateAtAttribute] as number)) {
|
if ((row![UpdateAtAttribute] as number) <= (d[entity]![id]![UpdateAtAttribute] as number)) {
|
||||||
this.updateAbjointRow(entity, {
|
this.updateAbjointRow(entity, {
|
||||||
id: 'dummy',
|
id: 'dummy',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
|
|
|
||||||
39
test/test.ts
39
test/test.ts
|
|
@ -1317,6 +1317,43 @@ describe('基础测试', function () {
|
||||||
}
|
}
|
||||||
}, context, {});
|
}, context, {});
|
||||||
|
|
||||||
|
const row12 = store.select('oper', {
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
data: {
|
||||||
|
name: 1,
|
||||||
|
price: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
id,
|
||||||
|
data: {
|
||||||
|
price: {
|
||||||
|
$length: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, context, {});
|
||||||
|
|
||||||
|
const row13 = store.select('oper', {
|
||||||
|
data: {
|
||||||
|
id: 1,
|
||||||
|
data: {
|
||||||
|
name: 1,
|
||||||
|
price: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
id,
|
||||||
|
data: {
|
||||||
|
price: {
|
||||||
|
$length: {
|
||||||
|
$gt: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, context, {});
|
||||||
context.commit();
|
context.commit();
|
||||||
assert(row.length === 1);
|
assert(row.length === 1);
|
||||||
assert(row2.length === 0);
|
assert(row2.length === 0);
|
||||||
|
|
@ -1329,6 +1366,8 @@ describe('基础测试', function () {
|
||||||
assert(row9.length === 1);
|
assert(row9.length === 1);
|
||||||
assert(row10.length === 1);
|
assert(row10.length === 1);
|
||||||
assert(row11.length === 0);
|
assert(row11.length === 0);
|
||||||
|
assert(row12.length === 1);
|
||||||
|
assert(row13.length === 0);
|
||||||
// console.log(JSON.stringify(row7));
|
// console.log(JSON.stringify(row7));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue