diff --git a/lib/store/CascadeStore.js b/lib/store/CascadeStore.js index 8e545d2..71c646d 100644 --- a/lib/store/CascadeStore.js +++ b/lib/store/CascadeStore.js @@ -1283,16 +1283,15 @@ class CascadeStore extends RowStore_1.RowStore { if (updateAttrCount === 0) { return {}; } + // 尝试和当前targetEntity的最后一条create/update进行合并,优化modi的条数 const upsertModis = await this.selectAbjointRowAsync('modi', { data: { id: 1, data: 1, + action: 1, }, filter: { targetEntity: entity, - action: { - $in: ['create', 'update'], - }, entity: option.modiParentEntity, entityId: option.modiParentId, iState: 'active', @@ -1314,17 +1313,19 @@ class CascadeStore extends RowStore_1.RowStore { count: 1, }, context, option); if (upsertModis.length > 0) { - const { data: originData, id: originId } = upsertModis[0]; - modiUpsert = { - id: 'dummy', - action: 'update', - data: { - data: Object.assign({}, originData, data), - }, - filter: { - id: originId, - } - }; + const { data: originData, id: originId, action } = upsertModis[0]; + if (['create', 'update'].includes(action)) { + modiUpsert = { + id: 'dummy', + action: 'update', + data: { + data: Object.assign({}, originData, data), + }, + filter: { + id: originId, + } + }; + } } } if (!modiUpsert) { diff --git a/lib/store/IntrinsicCheckers.js b/lib/store/IntrinsicCheckers.js index eb39ef9..58b3286 100644 --- a/lib/store/IntrinsicCheckers.js +++ b/lib/store/IntrinsicCheckers.js @@ -79,7 +79,7 @@ function createUniqueCheckers(schema) { entity, action: 'create', type: 'logicalData', - priority: types_1.CHECKER_MAX_PRIORITY, + priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测 checker: (operation, context) => { const { data } = operation; if (data instanceof Array) { @@ -95,9 +95,9 @@ function createUniqueCheckers(schema) { } }, { entity, - action: 'update', + action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性 type: 'logicalData', - priority: types_1.CHECKER_MAX_PRIORITY, + priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测 checker: (operation, context) => { const { data, filter: operationFilter } = operation; if (data) { @@ -227,7 +227,7 @@ function createActionTransformerCheckers(actionDefDict) { action: 'create', type: 'logical', entity, - priority: 10, + priority: 10, // 优先级要高,先于真正的data检查进行 checker: (operation) => { const { data } = operation; if (data instanceof Array) { diff --git a/lib/store/relation.d.ts b/lib/store/relation.d.ts index 8f7a881..5afd59c 100644 --- a/lib/store/relation.d.ts +++ b/lib/store/relation.d.ts @@ -9,4 +9,4 @@ import { StorageSchema } from "../types/Storage"; * @param row * @returns */ -export declare function judgeRelation(schema: StorageSchema, entity: keyof ED, attr: string, allowUnrecoganized?: boolean): string | 1 | 2 | string[] | 0 | -1; +export declare function judgeRelation(schema: StorageSchema, entity: keyof ED, attr: string, allowUnrecognized?: boolean): string | 1 | 2 | string[] | 0 | -1; diff --git a/lib/store/relation.js b/lib/store/relation.js index 94a81be..771fabe 100644 --- a/lib/store/relation.js +++ b/lib/store/relation.js @@ -13,7 +13,7 @@ const Entity_1 = require("../types/Entity"); * @param row * @returns */ -function judgeRelation(schema, entity, attr, allowUnrecoganized) { +function judgeRelation(schema, entity, attr, allowUnrecognized) { const { [entity]: { attributes } } = schema; if (attr.startsWith(Demand_1.EXPRESSION_PREFIX) || attr.startsWith('#')) { // 表达式属性或者metadata @@ -27,8 +27,8 @@ function judgeRelation(schema, entity, attr, allowUnrecoganized) { const firstDelimiter = attr.indexOf('$'); const entity2 = attr.slice(0, firstDelimiter); (0, assert_1.default)(schema.hasOwnProperty(entity2)); - const secondDelemiter = attr.indexOf('$', firstDelimiter + 1); - const foreignKey = attr.slice(firstDelimiter + 1, secondDelemiter > 0 ? secondDelemiter : attr.length); + const secondDelimiter = attr.indexOf('$', firstDelimiter + 1); + const foreignKey = attr.slice(firstDelimiter + 1, secondDelimiter > 0 ? secondDelimiter : attr.length); const { [entity2]: { attributes: attributes2 } } = schema; if (foreignKey === 'entity') { // 基于反指对象的反向关联 @@ -63,7 +63,7 @@ function judgeRelation(schema, entity, attr, allowUnrecoganized) { if (Entity_1.initinctiveAttributes.includes(attr)) { return 1; } - else if (allowUnrecoganized) { + else if (allowUnrecognized) { return -1; } else { diff --git a/lib/types/Auth.d.ts b/lib/types/Auth.d.ts index c47137c..b7213c6 100644 --- a/lib/types/Auth.d.ts +++ b/lib/types/Auth.d.ts @@ -4,7 +4,7 @@ import { SyncContext } from "../store/SyncRowStore"; import { EntityDict, OperateOption, SelectOption } from "../types/Entity"; import { EntityDict as BaseEntityDict } from '../base-app-domain'; import { ModiTurn } from './Trigger'; -export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData'; +export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData' | 'relation'; /** * conditionalFilter是指该action发生时,operation所操作的行中有满足conditionalFilter的行 * 被转化成trigger的filter条件,详细可看trigger中的说明 diff --git a/lib/types/Exception.d.ts b/lib/types/Exception.d.ts index 7ca6577..5850d3e 100644 --- a/lib/types/Exception.d.ts +++ b/lib/types/Exception.d.ts @@ -169,6 +169,12 @@ export declare class OakExternalException extends OakUserException { + constructor(message?: string); +} export declare function makeException(data: { name: string; message?: string; diff --git a/lib/types/Exception.js b/lib/types/Exception.js index 88cd7b5..7a77498 100644 --- a/lib/types/Exception.js +++ b/lib/types/Exception.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.makeException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakException = void 0; +exports.makeException = exports.OakSocketConnectException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakException = void 0; const relation_1 = require("../store/relation"); const lodash_1 = require("../utils/lodash"); class OakException extends Error { @@ -385,6 +385,16 @@ class OakExternalException extends OakUserException { } } exports.OakExternalException = OakExternalException; +/** + * socket连接异常 + */ +class OakSocketConnectException extends OakUserException { + constructor(message) { + super(message || '连接出现问题,请尝试刷新页面'); + } +} +exports.OakSocketConnectException = OakSocketConnectException; +; function makeException(data) { const { name } = data; let e = undefined; @@ -473,6 +483,10 @@ function makeException(data) { e = new OakServerProxyException(data.message); break; } + case 'OakSocketConnectException': { + e = new OakSocketConnectException(data.message); + break; + } default: return; } diff --git a/lib/types/Trigger.js b/lib/types/Trigger.js index 6bee66f..d5f1088 100644 --- a/lib/types/Trigger.js +++ b/lib/types/Trigger.js @@ -17,6 +17,7 @@ exports.CHECKER_PRIORITY_MAP = { logical: 33, row: 51, data: 61, + relation: 56 }; ; ; diff --git a/lib/utils/assert.d.ts b/lib/utils/assert.d.ts index c502695..932ffd1 100644 --- a/lib/utils/assert.d.ts +++ b/lib/utils/assert.d.ts @@ -1,3 +1,4 @@ +/// /** * 防止assert打包体积过大,从这里引用 */ diff --git a/lib/utils/relationPath.js b/lib/utils/relationPath.js index 00c7c5e..03a5133 100644 --- a/lib/utils/relationPath.js +++ b/lib/utils/relationPath.js @@ -60,7 +60,7 @@ function destructRelationPath(schema, entity, path, relationFilter, recursive) { }, filter: relationFilter, } // as ED['userRelation']['Selection'] - }, + }, // as ED[keyof ED]['Selection']['data'], getData: (d) => { return d.userRelation$entity; }, diff --git a/package.json b/package.json index 510313c..16bd69a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oak-domain", - "version": "5.1.1", + "version": "5.1.2", "author": { "name": "XuChang" }, diff --git a/src/store/CascadeStore.ts b/src/store/CascadeStore.ts index 7e38010..1676d60 100644 --- a/src/store/CascadeStore.ts +++ b/src/store/CascadeStore.ts @@ -1563,16 +1563,15 @@ export abstract class CascadeStore exten if (updateAttrCount === 0) { return {}; } + // 尝试和当前targetEntity的最后一条create/update进行合并,优化modi的条数 const upsertModis = await this.selectAbjointRowAsync('modi', { data: { id: 1, data: 1, + action: 1, }, filter: { targetEntity: entity as string, - action: { - $in: ['create', 'update'], - }, entity: option.modiParentEntity!, entityId: option.modiParentId!, iState: 'active', @@ -1594,17 +1593,19 @@ export abstract class CascadeStore exten count: 1, }, context, option); if (upsertModis.length > 0) { - const { data: originData, id: originId } = upsertModis[0]; - modiUpsert = { - id: 'dummy', - action: 'update', - data: { - data: Object.assign({}, originData, data), - }, - filter: { - id: originId as string, - } - }; + const { data: originData, id: originId, action } = upsertModis[0]; + if (['create', 'update'].includes(action!)) { + modiUpsert = { + id: 'dummy', + action: 'update', + data: { + data: Object.assign({}, originData, data), + }, + filter: { + id: originId as string, + } + }; + } } } if (!modiUpsert) { diff --git a/src/store/relation.ts b/src/store/relation.ts index 0fb25e2..9e96910 100644 --- a/src/store/relation.ts +++ b/src/store/relation.ts @@ -12,7 +12,7 @@ import { StorageSchema } from "../types/Storage"; * @param row * @returns */ -export function judgeRelation(schema: StorageSchema, entity: keyof ED, attr: string, allowUnrecoganized?: boolean) { +export function judgeRelation(schema: StorageSchema, entity: keyof ED, attr: string, allowUnrecognized?: boolean) { const { [entity]: { attributes } } = schema; if (attr.startsWith(EXPRESSION_PREFIX) || attr.startsWith('#')) { @@ -29,8 +29,8 @@ export function judgeRelation(schema: St const firstDelimiter = attr.indexOf('$'); const entity2 = attr.slice(0, firstDelimiter); assert (schema.hasOwnProperty(entity2)); - const secondDelemiter = attr.indexOf('$', firstDelimiter + 1); - const foreignKey = attr.slice(firstDelimiter + 1, secondDelemiter > 0 ? secondDelemiter : attr.length); + const secondDelimiter = attr.indexOf('$', firstDelimiter + 1); + const foreignKey = attr.slice(firstDelimiter + 1, secondDelimiter > 0 ? secondDelimiter : attr.length); const { [entity2]: { attributes: attributes2 } } = schema; if (foreignKey === 'entity') { @@ -66,7 +66,7 @@ export function judgeRelation(schema: St if(initinctiveAttributes.includes(attr)) { return 1; } - else if (allowUnrecoganized) { + else if (allowUnrecognized) { return -1; } else { diff --git a/src/types/Auth.ts b/src/types/Auth.ts index d812548..d4b45ab 100644 --- a/src/types/Auth.ts +++ b/src/types/Auth.ts @@ -5,7 +5,7 @@ import { EntityDict, OperateOption, SelectOption } from "../types/Entity"; import { EntityDict as BaseEntityDict } from '../base-app-domain'; import { ModiTurn } from './Trigger'; -export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData'; +export type CheckerType = 'row' | 'data' | 'logical' | 'logicalData' | 'relation'; /** * conditionalFilter是指该action发生时,operation所操作的行中有满足conditionalFilter的行 diff --git a/src/types/Exception.ts b/src/types/Exception.ts index 5367df7..eee92d6 100644 --- a/src/types/Exception.ts +++ b/src/types/Exception.ts @@ -432,6 +432,15 @@ export class OakExternalException extend } } +/** + * socket连接异常 + */ +export class OakSocketConnectException extends OakUserException { + constructor(message?: string) { + super(message || '连接出现问题,请尝试刷新页面'); + } +}; + export function makeException(data: { name: string; message?: string; @@ -529,6 +538,10 @@ export function makeException(data: { e = new OakServerProxyException(data.message); break; } + case 'OakSocketConnectException': { + e = new OakSocketConnectException(data.message); + break; + } default: return; } diff --git a/src/types/Trigger.ts b/src/types/Trigger.ts index 4642ff4..21ee511 100644 --- a/src/types/Trigger.ts +++ b/src/types/Trigger.ts @@ -27,6 +27,7 @@ export const CHECKER_PRIORITY_MAP: Record = { logical: 33, row: 51, data: 61, + relation: 56 }; interface TriggerBase {