Merge branch 'release'
This commit is contained in:
commit
fc9c65a7ef
|
|
@ -11,6 +11,7 @@ var types_1 = require("../types");
|
|||
var lodash_1 = require("../utils/lodash");
|
||||
var filter_2 = require("./filter");
|
||||
var uuid_1 = require("../utils/uuid");
|
||||
var selection_1 = require("./selection");
|
||||
/**这个用来处理级联的select和update,对不同能力的 */
|
||||
var CascadeStore = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(CascadeStore, _super);
|
||||
|
|
@ -1252,6 +1253,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|||
};
|
||||
CascadeStore.prototype.cascadeUpdate = function (entity, operation, context, option) {
|
||||
var e_5, _a, e_6, _b, e_7, _c;
|
||||
(0, selection_1.reinforceOperation)(this.getSchema(), entity, operation);
|
||||
var action = operation.action, data = operation.data, filter = operation.filter, id = operation.id;
|
||||
var opData;
|
||||
var wholeBeforeFns = [];
|
||||
|
|
@ -1328,6 +1330,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|||
return tslib_1.__generator(this, function (_h) {
|
||||
switch (_h.label) {
|
||||
case 0:
|
||||
(0, selection_1.reinforceOperation)(this.getSchema(), entity, operation);
|
||||
action = operation.action, data = operation.data, filter = operation.filter, id = operation.id;
|
||||
wholeBeforeFns = [];
|
||||
wholeAfterFns = [];
|
||||
|
|
@ -1426,6 +1429,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|||
});
|
||||
};
|
||||
CascadeStore.prototype.cascadeSelect = function (entity, selection, context, option) {
|
||||
(0, selection_1.reinforceSelection)(this.getSchema(), entity, selection);
|
||||
var data = selection.data, filter = selection.filter, indexFrom = selection.indexFrom, count = selection.count, sorter = selection.sorter;
|
||||
var _a = this.destructCascadeSelect(entity, data, context, this.cascadeSelect, this.aggregateSync, option), projection = _a.projection, cascadeSelectionFns = _a.cascadeSelectionFns;
|
||||
var rows = this.selectAbjointRow(entity, {
|
||||
|
|
@ -1547,6 +1551,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
(0, selection_1.reinforceSelection)(this.getSchema(), entity, selection);
|
||||
data = selection.data, filter = selection.filter, indexFrom = selection.indexFrom, count = selection.count, sorter = selection.sorter;
|
||||
_a = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option), projection = _a.projection, cascadeSelectionFns = _a.cascadeSelectionFns;
|
||||
return [4 /*yield*/, this.selectAbjointRowAsync(entity, {
|
||||
|
|
|
|||
|
|
@ -44,20 +44,19 @@ function translateCheckerInAsyncContext(checker) {
|
|||
var fn = (function (_a, context, option) {
|
||||
var operation = _a.operation;
|
||||
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||
var operationFilter, action, filter2, _b, entity2, selection2, rows2, data_1, rows2, data_2;
|
||||
var _c, _d;
|
||||
return tslib_1.__generator(this, function (_e) {
|
||||
switch (_e.label) {
|
||||
var operationFilter, action, filter2, _b, entity2, selection2, rows2, e, rows2, e;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
operationFilter = operation.filter, action = operation.action;
|
||||
if (!(typeof filter_2 === 'function')) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, filter_2(operation, context, option)];
|
||||
case 1:
|
||||
_b = _e.sent();
|
||||
_b = _c.sent();
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
_b = filter_2;
|
||||
_e.label = 3;
|
||||
_c.label = 3;
|
||||
case 3:
|
||||
filter2 = _b;
|
||||
if (!['select', 'count', 'stat'].includes(action)) return [3 /*break*/, 4];
|
||||
|
|
@ -65,7 +64,7 @@ function translateCheckerInAsyncContext(checker) {
|
|||
return [2 /*return*/, 0];
|
||||
case 4: return [4 /*yield*/, (0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter || {}, true)];
|
||||
case 5:
|
||||
if (_e.sent()) {
|
||||
if (_c.sent()) {
|
||||
return [2 /*return*/, 0];
|
||||
}
|
||||
if (!inconsistentRows_1) return [3 /*break*/, 7];
|
||||
|
|
@ -75,20 +74,10 @@ function translateCheckerInAsyncContext(checker) {
|
|||
blockTrigger: true,
|
||||
})];
|
||||
case 6:
|
||||
rows2 = _e.sent();
|
||||
data_1 = {};
|
||||
rows2.forEach(function (ele) {
|
||||
var _a;
|
||||
return Object.assign(data_1, (_a = {},
|
||||
_a[ele.id] = ele,
|
||||
_a));
|
||||
});
|
||||
throw new Exception_1.OakRowInconsistencyException({
|
||||
a: 's',
|
||||
d: (_c = {},
|
||||
_c[entity2] = data_1,
|
||||
_c)
|
||||
}, errMsg_1);
|
||||
rows2 = _c.sent();
|
||||
e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_1);
|
||||
e.addData(entity2, rows2);
|
||||
throw e;
|
||||
case 7: return [4 /*yield*/, context.select(entity, {
|
||||
data: (0, actionDef_1.getFullProjection)(entity, context.getSchema()),
|
||||
filter: Object.assign({}, operationFilter, {
|
||||
|
|
@ -99,20 +88,10 @@ function translateCheckerInAsyncContext(checker) {
|
|||
blockTrigger: true,
|
||||
})];
|
||||
case 8:
|
||||
rows2 = _e.sent();
|
||||
data_2 = {};
|
||||
rows2.forEach(function (ele) {
|
||||
var _a;
|
||||
return Object.assign(data_2, (_a = {},
|
||||
_a[ele.id] = ele,
|
||||
_a));
|
||||
});
|
||||
throw new Exception_1.OakRowInconsistencyException({
|
||||
a: 's',
|
||||
d: (_d = {},
|
||||
_d[entity] = data_2,
|
||||
_d)
|
||||
}, errMsg_1);
|
||||
rows2 = _c.sent();
|
||||
e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_1);
|
||||
e.addData(entity, rows2);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -228,7 +207,8 @@ function translateCheckerInSyncContext(checker) {
|
|||
if ((0, filter_1.checkFilterContains)(entity, context, filter2, operationFilter, true)) {
|
||||
return;
|
||||
}
|
||||
throw new Exception_1.OakRowInconsistencyException(undefined, errMsg_3);
|
||||
var e = new Exception_1.OakRowInconsistencyException(undefined, errMsg_3);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
return {
|
||||
|
|
@ -578,8 +558,8 @@ function createRemoveCheckers(schema, authDict) {
|
|||
var promises = [];
|
||||
if (OneToManyMatrix[entity]) {
|
||||
var _loop_5 = function (otm) {
|
||||
var _g, _h, _j, _k;
|
||||
var _l = tslib_1.__read(otm, 2), e = _l[0], attr = _l[1];
|
||||
var _g, _h;
|
||||
var _j = tslib_1.__read(otm, 2), e = _j[0], attr = _j[1];
|
||||
var proj = (_g = {
|
||||
id: 1
|
||||
},
|
||||
|
|
@ -596,33 +576,20 @@ function createRemoveCheckers(schema, authDict) {
|
|||
}, { dontCollect: true });
|
||||
if (result instanceof Promise) {
|
||||
promises.push(result.then(function (_a) {
|
||||
var _b, _c;
|
||||
var _d = tslib_1.__read(_a, 1), row = _d[0];
|
||||
var _b = tslib_1.__read(_a, 1), row = _b[0];
|
||||
if (row) {
|
||||
var record = {
|
||||
a: 's',
|
||||
d: (_b = {},
|
||||
_b[e] = (_c = {},
|
||||
_c[row.id] = row,
|
||||
_c),
|
||||
_b)
|
||||
};
|
||||
throw new Exception_1.OakRowInconsistencyException(record, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
var err = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
err.addData(e, [row]);
|
||||
throw err;
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
var _m = tslib_1.__read(result, 1), row = _m[0];
|
||||
var _k = tslib_1.__read(result, 1), row = _k[0];
|
||||
if (row) {
|
||||
var record = {
|
||||
a: 's',
|
||||
d: (_j = {},
|
||||
_j[e] = (_k = {},
|
||||
_k[row.id] = row,
|
||||
_k),
|
||||
_j)
|
||||
};
|
||||
throw new Exception_1.OakRowInconsistencyException(record, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
var err = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(e, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
err.addData(e, [row]);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -642,15 +609,15 @@ function createRemoveCheckers(schema, authDict) {
|
|||
}
|
||||
if (OneToManyOnEntityMatrix[entity]) {
|
||||
var _loop_6 = function (otm) {
|
||||
var _o, _p, _q;
|
||||
var _l, _m, _o;
|
||||
var proj = {
|
||||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
};
|
||||
var filter = operation.filter && (_o = {},
|
||||
_o[entity] = operation.filter,
|
||||
_o);
|
||||
var filter = operation.filter && (_l = {},
|
||||
_l[entity] = operation.filter,
|
||||
_l);
|
||||
var result = context.select(otm, {
|
||||
data: proj,
|
||||
filter: filter,
|
||||
|
|
@ -659,33 +626,28 @@ function createRemoveCheckers(schema, authDict) {
|
|||
}, { dontCollect: true });
|
||||
if (result instanceof Promise) {
|
||||
promises.push(result.then(function (_a) {
|
||||
var _b, _c;
|
||||
var _d = tslib_1.__read(_a, 1), row = _d[0];
|
||||
var _b = tslib_1.__read(_a, 1), row = _b[0];
|
||||
if (row) {
|
||||
var record = {
|
||||
a: 's',
|
||||
d: (_b = {},
|
||||
_b[otm] = (_c = {},
|
||||
_c[row.id] = row,
|
||||
_c),
|
||||
_b)
|
||||
};
|
||||
throw new Exception_1.OakRowInconsistencyException(record, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
var e = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
e.addData(otm, [row]);
|
||||
throw e;
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
var _r = tslib_1.__read(result, 1), row = _r[0];
|
||||
var _p = tslib_1.__read(result, 1), row = _p[0];
|
||||
if (row) {
|
||||
var record = {
|
||||
a: 's',
|
||||
d: (_p = {},
|
||||
_p[otm] = (_q = {},
|
||||
_q[row.id] = row,
|
||||
_q),
|
||||
_p)
|
||||
d: (_m = {},
|
||||
_m[otm] = (_o = {},
|
||||
_o[row.id] = row,
|
||||
_o),
|
||||
_m)
|
||||
};
|
||||
throw new Exception_1.OakRowInconsistencyException(record, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
var e = new Exception_1.OakRowInconsistencyException(undefined, "\u60A8\u65E0\u6CD5\u5220\u9664\u5B58\u5728\u6709\u6548\u6570\u636E\u300C".concat(otm, "\u300D\u5173\u8054\u7684\u884C"));
|
||||
e.addData(otm, [row]);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,19 @@
|
|||
import { StorageSchema } from '../types';
|
||||
import { EntityDict } from '../types/Entity';
|
||||
declare type SelectionRewriter<ED extends EntityDict> = (schema: StorageSchema<ED>, entity: keyof ED, selection: ED[keyof ED]['Selection']) => void;
|
||||
export declare function registerSelectionRewriter<ED extends EntityDict>(rewriter: SelectionRewriter<ED>): void;
|
||||
declare type OperationRewriter<ED extends EntityDict> = (schema: StorageSchema<ED>, entity: keyof ED, operate: ED[keyof ED]['Operation']) => void;
|
||||
export declare function registerOperationRewriter<ED extends EntityDict>(rewriter: OperationRewriter<ED>): void;
|
||||
/**
|
||||
* 对selection进行一些完善,避免编程人员的疏漏
|
||||
* @param selection
|
||||
*/
|
||||
export declare function reinforceSelection<ED extends EntityDict>(schema: StorageSchema<ED>, entity: keyof ED, selection: ED[keyof ED]['Selection']): void;
|
||||
/**
|
||||
* 对operation进行一些完善,作为operation算子的注入点
|
||||
* @param schema
|
||||
* @param entity
|
||||
* @param selection
|
||||
*/
|
||||
export declare function reinforceOperation<ED extends EntityDict>(schema: StorageSchema<ED>, entity: keyof ED, operation: ED[keyof ED]['Operation']): void;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,37 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.reinforceSelection = void 0;
|
||||
exports.reinforceOperation = exports.reinforceSelection = exports.registerOperationRewriter = exports.registerSelectionRewriter = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var types_1 = require("../types");
|
||||
var Demand_1 = require("../types/Demand");
|
||||
var filter_1 = require("./filter");
|
||||
var relation_1 = require("./relation");
|
||||
var SelectionRewriters = [];
|
||||
function registerSelectionRewriter(rewriter) {
|
||||
SelectionRewriters.push(rewriter);
|
||||
}
|
||||
exports.registerSelectionRewriter = registerSelectionRewriter;
|
||||
function getSelectionRewriters() {
|
||||
return SelectionRewriters;
|
||||
}
|
||||
var OperationRewriters = [];
|
||||
function registerOperationRewriter(rewriter) {
|
||||
OperationRewriters.push(rewriter);
|
||||
}
|
||||
exports.registerOperationRewriter = registerOperationRewriter;
|
||||
function getOperationRewriters() {
|
||||
return OperationRewriters;
|
||||
}
|
||||
/**
|
||||
* 对selection进行一些完善,避免编程人员的疏漏
|
||||
* @param selection
|
||||
*/
|
||||
function reinforceSelection(schema, entity, selection) {
|
||||
var filter = selection.filter, data = selection.data, sorter = selection.sorter;
|
||||
Object.assign(data, {
|
||||
'$$createAt$$': 1,
|
||||
}); // 有的页面依赖于其它页面取数据,有时两个页面的filter的差异会导致有一个加createAt,有一个不加,此时可能产生前台取数据不完整的异常。先统一加上
|
||||
var checkNode = function (projectionNode, attrs) {
|
||||
attrs.forEach(function (attr) {
|
||||
var _a;
|
||||
|
|
@ -234,5 +253,16 @@ function reinforceSelection(schema, entity, selection) {
|
|||
$$createAt$$: 1,
|
||||
});
|
||||
}
|
||||
SelectionRewriters.forEach(function (ele) { return ele(schema, entity, selection); });
|
||||
}
|
||||
exports.reinforceSelection = reinforceSelection;
|
||||
/**
|
||||
* 对operation进行一些完善,作为operation算子的注入点
|
||||
* @param schema
|
||||
* @param entity
|
||||
* @param selection
|
||||
*/
|
||||
function reinforceOperation(schema, entity, operation) {
|
||||
OperationRewriters.forEach(function (ele) { return ele(schema, entity, operation); });
|
||||
}
|
||||
exports.reinforceOperation = reinforceOperation;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export declare type AuthDef<ED extends EntityDict, T extends keyof ED> = {
|
|||
relationAuth?: CascadeRelationAuth<NonNullable<ED[T]['Relation']>>;
|
||||
actionAuth?: CascadeActionAuth<ED[T]['Action']>;
|
||||
cascadeRemove?: {
|
||||
[E in keyof ED[T]['OpSchema'] | '@entity']?: ActionOnRemove;
|
||||
[E in (keyof ED | '@entity')]?: ActionOnRemove;
|
||||
};
|
||||
};
|
||||
export declare type AuthDefDict<ED extends EntityDict> = {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export declare abstract class Connector<ED extends EntityDict, BackCxt extends A
|
|||
body: any;
|
||||
headers?: Record<string, any>;
|
||||
};
|
||||
abstract serializeException(exception: OakException, headers: IncomingHttpHeaders, body: any): {
|
||||
abstract serializeException(exception: OakException<ED>, headers: IncomingHttpHeaders, body: any): {
|
||||
body: any;
|
||||
headers?: Record<string, any>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export declare type SelectOpResult<ED extends EntityDict> = {
|
|||
a: 's';
|
||||
d: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: ED[T]['OpSchema'];
|
||||
[ID: string]: Partial<ED[T]['OpSchema']>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { EntityDict, OpRecord } from "./Entity";
|
||||
export declare class OakException extends Error {
|
||||
import { EntityDict, OpRecord, SelectOpResult } from "./Entity";
|
||||
export declare class OakException<ED extends EntityDict> extends Error {
|
||||
opRecord: SelectOpResult<ED>;
|
||||
constructor(message?: string);
|
||||
addData<T extends keyof ED>(entity: T, rows: Partial<ED[T]['OpSchema']>[]): void;
|
||||
setOpRecords(opRecord: SelectOpResult<ED>): void;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class OakDataException extends OakException {
|
||||
export declare class OakDataException<ED extends EntityDict> extends OakException<ED> {
|
||||
}
|
||||
export declare class OakUniqueViolationException extends OakException {
|
||||
export declare class OakUniqueViolationException<ED extends EntityDict> extends OakException<ED> {
|
||||
rows: Array<{
|
||||
id?: string;
|
||||
attrs: string[];
|
||||
|
|
@ -15,14 +18,14 @@ export declare class OakUniqueViolationException extends OakException {
|
|||
attrs: string[];
|
||||
}>, message?: string);
|
||||
}
|
||||
export declare class OakImportDataParseException extends OakException {
|
||||
export declare class OakImportDataParseException<ED extends EntityDict> extends OakException<ED> {
|
||||
line: number;
|
||||
header?: string;
|
||||
constructor(message: string, line: number, header?: string);
|
||||
}
|
||||
export declare class OakOperExistedException extends OakDataException {
|
||||
export declare class OakOperExistedException<ED extends EntityDict> extends OakDataException<ED> {
|
||||
}
|
||||
export declare class OakRowUnexistedException extends OakDataException {
|
||||
export declare class OakRowUnexistedException<ED extends EntityDict> extends OakDataException<ED> {
|
||||
private rows;
|
||||
constructor(rows: Array<{
|
||||
entity: any;
|
||||
|
|
@ -36,22 +39,20 @@ export declare class OakRowUnexistedException extends OakDataException {
|
|||
}
|
||||
export declare class OakExternalException extends Error {
|
||||
}
|
||||
export declare class OakUserException extends OakException {
|
||||
export declare class OakUserException<ED extends EntityDict> extends OakException<ED> {
|
||||
}
|
||||
/**
|
||||
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
||||
*
|
||||
*/
|
||||
export declare class OakRowInconsistencyException<ED extends EntityDict> extends OakUserException {
|
||||
private data?;
|
||||
export declare class OakRowInconsistencyException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(data?: OpRecord<ED>, message?: string);
|
||||
getData(): OpRecord<ED> | undefined;
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* 当输入的数据非法时抛此异常,attributes表示非法的属性
|
||||
*/
|
||||
export declare class OakInputIllegalException extends OakUserException {
|
||||
export declare class OakInputIllegalException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
private attributes;
|
||||
private entity;
|
||||
constructor(entity: string, attributes: string[], message?: string);
|
||||
|
|
@ -63,24 +64,24 @@ export declare class OakInputIllegalException extends OakUserException {
|
|||
/**
|
||||
* 用户权限不够时抛的异常
|
||||
*/
|
||||
export declare class OakUserUnpermittedException extends OakUserException {
|
||||
export declare class OakUserUnpermittedException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
}
|
||||
/**
|
||||
* 用户未登录抛的异常
|
||||
*/
|
||||
export declare class OakUnloggedInException extends OakUserException {
|
||||
export declare class OakUnloggedInException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
/**
|
||||
* 用户未登录抛的异常
|
||||
*/
|
||||
export declare class OakRowLockedException extends OakUserException {
|
||||
export declare class OakRowLockedException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string);
|
||||
}
|
||||
/**
|
||||
* 要插入行时,发现已经有相同的行数据
|
||||
*/
|
||||
export declare class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException {
|
||||
export declare class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException<ED> {
|
||||
private data;
|
||||
private entity;
|
||||
constructor(entity: T, data: ED[T]['OpSchema'], message?: string);
|
||||
|
|
@ -88,11 +89,12 @@ export declare class OakCongruentRowExists<ED extends EntityDict, T extends keyo
|
|||
getEntity(): T;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class OakDeadlock extends OakUserException {
|
||||
export declare class OakDeadlock<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string | undefined);
|
||||
}
|
||||
export declare function makeException(data: {
|
||||
export declare function makeException<ED extends EntityDict>(data: {
|
||||
name: string;
|
||||
message?: string;
|
||||
opRecords: SelectOpResult<ED>;
|
||||
[A: string]: any;
|
||||
}): OakException | OakExternalException | undefined;
|
||||
}): OakException<EntityDict> | undefined;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserUnpermittedException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakUserException = exports.OakExternalException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakDataException = exports.OakException = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var OakException = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(OakException, _super);
|
||||
function OakException(message) {
|
||||
|
|
@ -17,12 +18,36 @@ var OakException = /** @class */ (function (_super) {
|
|||
else {
|
||||
_this.__proto__ = _newTarget.prototype;
|
||||
}
|
||||
_this.opRecord = {
|
||||
a: 's',
|
||||
d: {},
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
OakException.prototype.addData = function (entity, rows) {
|
||||
var d = this.opRecord.d;
|
||||
var addSingleRow = function (rowRoot, row) {
|
||||
var id = row.id;
|
||||
if (rowRoot[id]) {
|
||||
Object.assign(rowRoot[id], row);
|
||||
}
|
||||
else {
|
||||
rowRoot[id] = row;
|
||||
}
|
||||
};
|
||||
if (!d[entity]) {
|
||||
d[entity] = {};
|
||||
}
|
||||
rows.forEach(function (row) { return addSingleRow(d[entity], row); });
|
||||
};
|
||||
OakException.prototype.setOpRecords = function (opRecord) {
|
||||
this.opRecord = opRecord;
|
||||
};
|
||||
OakException.prototype.toString = function () {
|
||||
return JSON.stringify({
|
||||
name: this.constructor.name,
|
||||
message: this.message,
|
||||
opRecord: this.opRecord,
|
||||
});
|
||||
};
|
||||
return OakException;
|
||||
|
|
@ -109,17 +134,13 @@ var OakRowInconsistencyException = /** @class */ (function (_super) {
|
|||
tslib_1.__extends(OakRowInconsistencyException, _super);
|
||||
function OakRowInconsistencyException(data, message) {
|
||||
var _this = _super.call(this, message) || this;
|
||||
_this.data = data;
|
||||
(0, assert_1.default)(!data, '现在使用addData接口来传数据');
|
||||
return _this;
|
||||
}
|
||||
OakRowInconsistencyException.prototype.getData = function () {
|
||||
return this.data;
|
||||
};
|
||||
OakRowInconsistencyException.prototype.toString = function () {
|
||||
return JSON.stringify({
|
||||
name: this.constructor.name,
|
||||
message: this.message,
|
||||
data: this.data,
|
||||
});
|
||||
};
|
||||
return OakRowInconsistencyException;
|
||||
|
|
@ -235,46 +256,69 @@ function makeException(data) {
|
|||
var name = data.name;
|
||||
switch (name) {
|
||||
case 'OakException': {
|
||||
return new OakException(data.message);
|
||||
var e = new OakException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUserException': {
|
||||
return new OakUserException(data.message);
|
||||
}
|
||||
case 'OakExternalException': {
|
||||
return new OakExternalException(data.message);
|
||||
var e = new OakUserException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowInconsistencyException': {
|
||||
return new OakRowInconsistencyException(data.data, data.message);
|
||||
var e = new OakRowInconsistencyException(data.data, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakInputIllegalException': {
|
||||
return new OakInputIllegalException(data.entity, data.attributes, data.message);
|
||||
var e = new OakInputIllegalException(data.entity, data.attributes, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUserUnpermittedException': {
|
||||
return new OakUserUnpermittedException(data.message);
|
||||
var e = new OakUserUnpermittedException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUnloggedInException': {
|
||||
return new OakUnloggedInException(data.message);
|
||||
var e = new OakUnloggedInException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakCongruentRowExists': {
|
||||
return new OakCongruentRowExists(data.entity, data.data, data.message);
|
||||
var e = new OakCongruentRowExists(data.entity, data.data, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowLockedException': {
|
||||
return new OakRowLockedException(data.message);
|
||||
var e = new OakRowLockedException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowUnexistedException': {
|
||||
return new OakRowUnexistedException(data.rows);
|
||||
var e = new OakRowUnexistedException(data.rows);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakDeadlock': {
|
||||
return new OakDeadlock(data.message);
|
||||
var e = new OakDeadlock(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakDataException': {
|
||||
return new OakDataException(data.message);
|
||||
var e = new OakDataException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUniqueViolationException': {
|
||||
return new OakUniqueViolationException(data.rows, data.message);
|
||||
var e = new OakUniqueViolationException(data.rows, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakImportDataParseException': {
|
||||
return new OakImportDataParseException(data.message, data.line, data.header);
|
||||
var e = new OakImportDataParseException(data.message, data.line, data.header);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export declare class SimpleConnector<ED extends EntityDict, BackCxt extends Asyn
|
|||
private serverUrl;
|
||||
private makeException;
|
||||
private contextBuilder;
|
||||
constructor(serverUrl: string, makeException: (exceptionData: any) => OakException, contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>);
|
||||
constructor(serverUrl: string, makeException: (exceptionData: any) => OakException<ED>, contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>);
|
||||
callAspect(name: string, params: any, context: FrontCxt): Promise<{
|
||||
result: any;
|
||||
opRecords: OpRecord<ED>[];
|
||||
|
|
@ -23,7 +23,7 @@ export declare class SimpleConnector<ED extends EntityDict, BackCxt extends Asyn
|
|||
body: any;
|
||||
headers?: Record<string, any> | undefined;
|
||||
};
|
||||
serializeException(exception: OakException, headers: IncomingHttpHeaders, body: any): {
|
||||
serializeException(exception: OakException<ED>, headers: IncomingHttpHeaders, body: any): {
|
||||
body: any;
|
||||
headers?: Record<string, any> | undefined;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oak-domain",
|
||||
"version": "2.5.2",
|
||||
"version": "2.6.1",
|
||||
"author": {
|
||||
"name": "XuChang"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { getRelevantIds } from "./filter";
|
|||
import { CreateOperation as CreateOperOperation } from '../base-app-domain/Oper/Schema';
|
||||
import { CreateOperation as CreateModiOperation, UpdateOperation as UpdateModiOperation } from '../base-app-domain/Modi/Schema';
|
||||
import { generateNewIdAsync } from "../utils/uuid";
|
||||
import { reinforceOperation, reinforceSelection } from "./selection";
|
||||
|
||||
/**这个用来处理级联的select和update,对不同能力的 */
|
||||
export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> extends RowStore<ED> {
|
||||
|
|
@ -1311,6 +1312,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
|||
operation: ED[T]['Operation'],
|
||||
context: Cxt,
|
||||
option: OP): OperationResult<ED> {
|
||||
reinforceOperation(this.getSchema(), entity, operation);
|
||||
const { action, data, filter, id } = operation;
|
||||
let opData: any;
|
||||
const wholeBeforeFns: Array<() => any> = [];
|
||||
|
|
@ -1375,6 +1377,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
|||
operation: ED[T]['Operation'],
|
||||
context: Cxt,
|
||||
option: OP): Promise<OperationResult<ED>> {
|
||||
reinforceOperation(this.getSchema(), entity, operation);
|
||||
const { action, data, filter, id } = operation;
|
||||
let opData: any;
|
||||
const wholeBeforeFns: Array<() => Promise<any>> = [];
|
||||
|
|
@ -1437,6 +1440,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
|||
selection: ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
option: OP): Partial<ED[T]['Schema']>[] {
|
||||
reinforceSelection(this.getSchema(), entity, selection);
|
||||
const { data, filter, indexFrom, count, sorter } = selection;
|
||||
const { projection, cascadeSelectionFns } = this.destructCascadeSelect(
|
||||
entity,
|
||||
|
|
@ -1576,6 +1580,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
|||
selection: ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
option: OP): Promise<Partial<ED[T]['Schema']>[]> {
|
||||
reinforceSelection(this.getSchema(), entity, selection);
|
||||
const { data, filter, indexFrom, count, sorter } = selection;
|
||||
const { projection, cascadeSelectionFns } = this.destructCascadeSelect(
|
||||
entity,
|
||||
|
|
|
|||
|
|
@ -55,19 +55,10 @@ export function translateCheckerInAsyncContext<
|
|||
dontCollect: true,
|
||||
blockTrigger: true,
|
||||
});
|
||||
const data = {};
|
||||
rows2.forEach(
|
||||
ele => Object.assign(data, {
|
||||
[ele.id as string]: ele,
|
||||
})
|
||||
);
|
||||
|
||||
throw new OakRowInconsistencyException({
|
||||
a: 's',
|
||||
d: {
|
||||
[entity2]: data,
|
||||
}
|
||||
}, errMsg);
|
||||
const e = new OakRowInconsistencyException<ED>(undefined, errMsg);
|
||||
e.addData(entity2, rows2);
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
const rows2 = await context.select(entity, {
|
||||
|
|
@ -79,19 +70,10 @@ export function translateCheckerInAsyncContext<
|
|||
dontCollect: true,
|
||||
blockTrigger: true,
|
||||
});
|
||||
const data = {};
|
||||
rows2.forEach(
|
||||
ele => Object.assign(data, {
|
||||
[ele.id as string]: ele,
|
||||
})
|
||||
);
|
||||
|
||||
throw new OakRowInconsistencyException({
|
||||
a: 's',
|
||||
d: {
|
||||
[entity]: data,
|
||||
}
|
||||
}, errMsg);
|
||||
const e = new OakRowInconsistencyException<ED>(undefined, errMsg);
|
||||
e.addData(entity, rows2);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}) as UpdateTriggerInTxn<ED, keyof ED, Cxt>['fn'];
|
||||
|
|
@ -191,7 +173,8 @@ export function translateCheckerInSyncContext<
|
|||
if (checkFilterContains<ED, T, Cxt>(entity, context, filter2, operationFilter, true)) {
|
||||
return;
|
||||
}
|
||||
throw new OakRowInconsistencyException(undefined, errMsg);
|
||||
const e = new OakRowInconsistencyException(undefined, errMsg);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
return {
|
||||
|
|
@ -568,15 +551,9 @@ export function createRemoveCheckers<ED extends EntityDict & BaseEntityDict, Cxt
|
|||
result.then(
|
||||
([row]) => {
|
||||
if (row) {
|
||||
const record = {
|
||||
a: 's',
|
||||
d: {
|
||||
[e]: {
|
||||
[row.id!]: row,
|
||||
}
|
||||
}
|
||||
} as SelectOpResult<ED>;
|
||||
throw new OakRowInconsistencyException(record, `您无法删除存在有效数据「${e as string}」关联的行`);
|
||||
const err = new OakRowInconsistencyException<ED>(undefined, `您无法删除存在有效数据「${e as string}」关联的行`);
|
||||
err.addData(e, [row]);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -585,15 +562,9 @@ export function createRemoveCheckers<ED extends EntityDict & BaseEntityDict, Cxt
|
|||
else {
|
||||
const [row] = result;
|
||||
if (row) {
|
||||
const record = {
|
||||
a: 's',
|
||||
d: {
|
||||
[e]: {
|
||||
[row.id!]: row,
|
||||
}
|
||||
}
|
||||
} as SelectOpResult<ED>;
|
||||
throw new OakRowInconsistencyException(record, `您无法删除存在有效数据「${e as string}」关联的行`);
|
||||
const err = new OakRowInconsistencyException<ED>(undefined, `您无法删除存在有效数据「${e as string}」关联的行`);
|
||||
err.addData(e, [row]);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -619,15 +590,9 @@ export function createRemoveCheckers<ED extends EntityDict & BaseEntityDict, Cxt
|
|||
result.then(
|
||||
([row]) => {
|
||||
if (row) {
|
||||
const record = {
|
||||
a: 's',
|
||||
d: {
|
||||
[otm]: {
|
||||
[row.id!]: row,
|
||||
}
|
||||
}
|
||||
} as SelectOpResult<ED>;
|
||||
throw new OakRowInconsistencyException(record, `您无法删除存在有效数据「${otm as string}」关联的行`);
|
||||
const e = new OakRowInconsistencyException<ED>(undefined, `您无法删除存在有效数据「${otm as string}」关联的行`);
|
||||
e.addData(otm, [row]);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -644,7 +609,9 @@ export function createRemoveCheckers<ED extends EntityDict & BaseEntityDict, Cxt
|
|||
}
|
||||
}
|
||||
} as SelectOpResult<ED>;
|
||||
throw new OakRowInconsistencyException(record, `您无法删除存在有效数据「${otm as string}」关联的行`);
|
||||
const e = new OakRowInconsistencyException<ED>(undefined, `您无法删除存在有效数据「${otm as string}」关联的行`);
|
||||
e.addData(otm, [row]);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,39 @@ import { EntityDict } from '../types/Entity';
|
|||
import { getRelevantIds } from './filter';
|
||||
import { judgeRelation } from './relation';
|
||||
|
||||
type SelectionRewriter<ED extends EntityDict> = (schema: StorageSchema<ED>, entity: keyof ED, selection: ED[keyof ED]['Selection']) => void;
|
||||
|
||||
const SelectionRewriters: SelectionRewriter<any>[] = [];
|
||||
|
||||
export function registerSelectionRewriter<ED extends EntityDict>(rewriter: SelectionRewriter<ED>) {
|
||||
SelectionRewriters.push(rewriter);
|
||||
}
|
||||
|
||||
function getSelectionRewriters<ED extends EntityDict>() {
|
||||
return SelectionRewriters as SelectionRewriter<ED>[];
|
||||
}
|
||||
|
||||
type OperationRewriter<ED extends EntityDict> = (schema: StorageSchema<ED>, entity: keyof ED, operate: ED[keyof ED]['Operation']) => void;
|
||||
|
||||
const OperationRewriters: OperationRewriter<any>[] = [];
|
||||
|
||||
export function registerOperationRewriter<ED extends EntityDict>(rewriter: OperationRewriter<ED>) {
|
||||
OperationRewriters.push(rewriter);
|
||||
}
|
||||
|
||||
function getOperationRewriters<ED extends EntityDict>() {
|
||||
return OperationRewriters as OperationRewriter<ED>[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 对selection进行一些完善,避免编程人员的疏漏
|
||||
* @param selection
|
||||
*/
|
||||
export function reinforceSelection<ED extends EntityDict>(schema: StorageSchema<ED>, entity: keyof ED, selection: ED[keyof ED]['Selection']) {
|
||||
const { filter, data, sorter } = selection;
|
||||
Object.assign(data, {
|
||||
'$$createAt$$': 1,
|
||||
}); // 有的页面依赖于其它页面取数据,有时两个页面的filter的差异会导致有一个加createAt,有一个不加,此时可能产生前台取数据不完整的异常。先统一加上
|
||||
|
||||
const checkNode = (projectionNode: ED[keyof ED]['Selection']['data'], attrs: string[]) => {
|
||||
attrs.forEach(
|
||||
|
|
@ -232,4 +259,20 @@ export function reinforceSelection<ED extends EntityDict>(schema: StorageSchema<
|
|||
$$createAt$$: 1,
|
||||
});
|
||||
}
|
||||
|
||||
SelectionRewriters.forEach(
|
||||
ele => ele(schema, entity, selection)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对operation进行一些完善,作为operation算子的注入点
|
||||
* @param schema
|
||||
* @param entity
|
||||
* @param selection
|
||||
*/
|
||||
export function reinforceOperation<ED extends EntityDict>(schema: StorageSchema<ED>, entity: keyof ED, operation: ED[keyof ED]['Operation']) {
|
||||
OperationRewriters.forEach(
|
||||
ele => ele(schema, entity, operation)
|
||||
);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ export type AuthDef<ED extends EntityDict, T extends keyof ED> = {
|
|||
relationAuth?: CascadeRelationAuth<NonNullable<ED[T]['Relation']>>;
|
||||
actionAuth?: CascadeActionAuth<ED[T]['Action']>;
|
||||
cascadeRemove?: {
|
||||
[E in keyof ED[T]['OpSchema'] | '@entity']?: ActionOnRemove;
|
||||
[E in (keyof ED | '@entity')]?: ActionOnRemove;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export abstract class Connector<ED extends EntityDict, BackCxt extends AsyncCont
|
|||
headers?: Record<string, any>;
|
||||
};
|
||||
|
||||
abstract serializeException(exception: OakException, headers: IncomingHttpHeaders, body: any): {
|
||||
abstract serializeException(exception: OakException<ED>, headers: IncomingHttpHeaders, body: any): {
|
||||
body: any;
|
||||
headers?: Record<string, any>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ export type SelectOpResult<ED extends EntityDict> = {
|
|||
a: 's',
|
||||
d: {
|
||||
[T in keyof ED]?: {
|
||||
[ID: string]: ED[T]['OpSchema'];
|
||||
[ID: string]: Partial<ED[T]['OpSchema']>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { EntityDict, OpRecord } from "./Entity";
|
||||
import assert from "assert";
|
||||
import { EntityDict, OpRecord, SelectOpResult } from "./Entity";
|
||||
|
||||
export class OakException extends Error {
|
||||
export class OakException<ED extends EntityDict> extends Error {
|
||||
opRecord: SelectOpResult<ED>;
|
||||
constructor(message?: string) {
|
||||
super(message);
|
||||
this.name = new.target.name;
|
||||
|
|
@ -12,21 +14,49 @@ export class OakException extends Error {
|
|||
} else {
|
||||
(this as any).__proto__ = new.target.prototype;
|
||||
}
|
||||
this.opRecord = {
|
||||
a: 's',
|
||||
d: {},
|
||||
};
|
||||
}
|
||||
|
||||
addData<T extends keyof ED>(entity: T, rows: Partial<ED[T]['OpSchema']>[]) {
|
||||
const { d } = this.opRecord;
|
||||
const addSingleRow = (rowRoot: Record<string, Partial<ED[T]['OpSchema']>>, row: Partial<ED[T]['OpSchema']>) => {
|
||||
const { id } = row;
|
||||
if (rowRoot[id!]) {
|
||||
Object.assign(rowRoot[id!], row);
|
||||
}
|
||||
else {
|
||||
rowRoot[id!] = row;
|
||||
}
|
||||
};
|
||||
if (!d[entity]) {
|
||||
d[entity] = {};
|
||||
}
|
||||
rows.forEach(
|
||||
row => addSingleRow(d[entity]!, row)
|
||||
);
|
||||
}
|
||||
|
||||
setOpRecords(opRecord: SelectOpResult<ED>) {
|
||||
this.opRecord = opRecord;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return JSON.stringify({
|
||||
name: this.constructor.name,
|
||||
message: this.message,
|
||||
opRecord: this.opRecord,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class OakDataException extends OakException {
|
||||
export class OakDataException<ED extends EntityDict> extends OakException<ED> {
|
||||
// 表示由数据层发现的异常
|
||||
}
|
||||
|
||||
export class OakUniqueViolationException extends OakException {
|
||||
export class OakUniqueViolationException<ED extends EntityDict> extends OakException<ED> {
|
||||
rows: Array<{
|
||||
id?: string;
|
||||
attrs: string[];
|
||||
|
|
@ -40,7 +70,7 @@ export class OakUniqueViolationException extends OakException {
|
|||
}
|
||||
}
|
||||
|
||||
export class OakImportDataParseException extends OakException {
|
||||
export class OakImportDataParseException<ED extends EntityDict> extends OakException<ED> {
|
||||
line: number;
|
||||
header?: string;
|
||||
|
||||
|
|
@ -52,11 +82,11 @@ export class OakImportDataParseException extends OakException {
|
|||
}
|
||||
}
|
||||
|
||||
export class OakOperExistedException extends OakDataException {
|
||||
export class OakOperExistedException<ED extends EntityDict> extends OakDataException<ED> {
|
||||
// 进行操作时发现同样id的Oper对象已经存在
|
||||
}
|
||||
|
||||
export class OakRowUnexistedException extends OakDataException {
|
||||
export class OakRowUnexistedException<ED extends EntityDict> extends OakDataException<ED> {
|
||||
private rows: Array<{
|
||||
entity: any;
|
||||
selection: any;
|
||||
|
|
@ -80,7 +110,7 @@ export class OakExternalException extends Error {
|
|||
// 表示由oak生态外部造成的异常,比如网络中断
|
||||
}
|
||||
|
||||
export class OakUserException extends OakException {
|
||||
export class OakUserException<ED extends EntityDict> extends OakException<ED> {
|
||||
// 继承了这个类的异常统一视为“可接受的、由用户操作造成的异常”
|
||||
};
|
||||
|
||||
|
|
@ -89,22 +119,16 @@ export class OakUserException extends OakException {
|
|||
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
|
||||
*
|
||||
*/
|
||||
export class OakRowInconsistencyException<ED extends EntityDict> extends OakUserException {
|
||||
private data?: OpRecord<ED>;
|
||||
export class OakRowInconsistencyException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(data?: OpRecord<ED>, message?: string) {
|
||||
super(message);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.data;
|
||||
assert(!data, '现在使用addData接口来传数据');
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return JSON.stringify({
|
||||
name: this.constructor.name,
|
||||
message: this.message,
|
||||
data: this.data,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -112,7 +136,7 @@ export class OakRowInconsistencyException<ED extends EntityDict> extends OakUser
|
|||
/**
|
||||
* 当输入的数据非法时抛此异常,attributes表示非法的属性
|
||||
*/
|
||||
export class OakInputIllegalException extends OakUserException {
|
||||
export class OakInputIllegalException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
private attributes: string[];
|
||||
private entity: string;
|
||||
constructor(entity: string, attributes: string[], message?: string) {
|
||||
|
|
@ -148,14 +172,14 @@ export class OakInputIllegalException extends OakUserException {
|
|||
/**
|
||||
* 用户权限不够时抛的异常
|
||||
*/
|
||||
export class OakUserUnpermittedException extends OakUserException {
|
||||
export class OakUserUnpermittedException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户未登录抛的异常
|
||||
*/
|
||||
export class OakUnloggedInException extends OakUserException {
|
||||
export class OakUnloggedInException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string) {
|
||||
super(message || '您尚未登录');
|
||||
}
|
||||
|
|
@ -165,7 +189,7 @@ export class OakUnloggedInException extends OakUserException {
|
|||
/**
|
||||
* 用户未登录抛的异常
|
||||
*/
|
||||
export class OakRowLockedException extends OakUserException {
|
||||
export class OakRowLockedException<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string) {
|
||||
super(message || '该行数据正在被更新中,请稍后再试');
|
||||
}
|
||||
|
|
@ -173,7 +197,7 @@ export class OakUnloggedInException extends OakUserException {
|
|||
/**
|
||||
* 要插入行时,发现已经有相同的行数据
|
||||
*/
|
||||
export class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException {
|
||||
export class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException<ED> {
|
||||
private data: ED[T]['OpSchema'];
|
||||
private entity: T;
|
||||
constructor(entity: T, data: ED[T]['OpSchema'], message?: string) {
|
||||
|
|
@ -200,60 +224,84 @@ export class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> ex
|
|||
}
|
||||
}
|
||||
|
||||
export class OakDeadlock extends OakUserException {
|
||||
export class OakDeadlock<ED extends EntityDict> extends OakUserException<ED> {
|
||||
constructor(message?: string | undefined) {
|
||||
super(message || '发现死锁');
|
||||
}
|
||||
};
|
||||
|
||||
export function makeException(data: {
|
||||
export function makeException<ED extends EntityDict>(data: {
|
||||
name: string;
|
||||
message?: string;
|
||||
opRecords: SelectOpResult<ED>;
|
||||
[A: string]: any;
|
||||
}) {
|
||||
const { name } = data;
|
||||
switch (name) {
|
||||
case 'OakException': {
|
||||
return new OakException(data.message);
|
||||
const e = new OakException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUserException': {
|
||||
return new OakUserException(data.message);
|
||||
}
|
||||
case 'OakExternalException': {
|
||||
return new OakExternalException(data.message);
|
||||
const e = new OakUserException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowInconsistencyException': {
|
||||
return new OakRowInconsistencyException(data.data, data.message);
|
||||
const e = new OakRowInconsistencyException(data.data, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakInputIllegalException': {
|
||||
return new OakInputIllegalException(data.entity, data.attributes, data.message);
|
||||
const e = new OakInputIllegalException(data.entity, data.attributes, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUserUnpermittedException': {
|
||||
return new OakUserUnpermittedException(data.message);
|
||||
const e = new OakUserUnpermittedException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUnloggedInException': {
|
||||
return new OakUnloggedInException(data.message);
|
||||
const e = new OakUnloggedInException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakCongruentRowExists': {
|
||||
return new OakCongruentRowExists(data.entity, data.data, data.message);
|
||||
const e = new OakCongruentRowExists(data.entity, data.data, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowLockedException': {
|
||||
return new OakRowLockedException(data.message);
|
||||
const e = new OakRowLockedException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakRowUnexistedException': {
|
||||
return new OakRowUnexistedException(data.rows);
|
||||
const e = new OakRowUnexistedException(data.rows);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakDeadlock': {
|
||||
return new OakDeadlock(data.message);
|
||||
const e = new OakDeadlock(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakDataException': {
|
||||
return new OakDataException(data.message);
|
||||
const e = new OakDataException(data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakUniqueViolationException': {
|
||||
return new OakUniqueViolationException(data.rows, data.message);
|
||||
const e = new OakUniqueViolationException(data.rows, data.message);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
case 'OakImportDataParseException': {
|
||||
return new OakImportDataParseException(data.message!, data.line, data.header);
|
||||
const e = new OakImportDataParseException(data.message!, data.line, data.header);
|
||||
e.setOpRecords(data.opRecords);
|
||||
return e;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ function makeContentTypeAndBody(data: any) {
|
|||
export class SimpleConnector<ED extends EntityDict, BackCxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>> extends Connector<ED, BackCxt, FrontCxt> {
|
||||
static ROUTER = '/aspect';
|
||||
private serverUrl: string;
|
||||
private makeException: (exceptionData: any) => OakException;
|
||||
private makeException: (exceptionData: any) => OakException<ED>;
|
||||
private contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>;
|
||||
|
||||
constructor(serverUrl: string, makeException: (exceptionData: any) => OakException, contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>) {
|
||||
constructor(serverUrl: string, makeException: (exceptionData: any) => OakException<ED>, contextBuilder: (str: string | undefined) => (store: AsyncRowStore<ED, BackCxt>) => Promise<BackCxt>) {
|
||||
super();
|
||||
this.serverUrl = `${serverUrl}${SimpleConnector.ROUTER}`;
|
||||
this.makeException = makeException;
|
||||
|
|
@ -100,7 +100,7 @@ export class SimpleConnector<ED extends EntityDict, BackCxt extends AsyncContext
|
|||
};
|
||||
}
|
||||
|
||||
serializeException(exception: OakException, headers: IncomingHttpHeaders, body: any): { body: any; headers?: Record<string, any> | undefined; } {
|
||||
serializeException(exception: OakException<ED>, headers: IncomingHttpHeaders, body: any): { body: any; headers?: Record<string, any> | undefined; } {
|
||||
return {
|
||||
body: {
|
||||
exception: exception.toString(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue