Merge branch 'release'
This commit is contained in:
commit
9b6d3d875d
|
|
@ -162,6 +162,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
|||
checkSortAttr(attr, sortAttr[attr], projNode[attr]);
|
||||
}
|
||||
}
|
||||
assignNecessaryProjectionAttrs(projNode, necessaryAttrs);
|
||||
};
|
||||
sorterNode.forEach((node) => {
|
||||
const { $attr } = node;
|
||||
|
|
|
|||
|
|
@ -304,9 +304,17 @@ class TriggerExecutor {
|
|||
return execPreTrigger(idx + 1);
|
||||
}
|
||||
}
|
||||
const number = await trigger.fn({ operation: operation }, context, option);
|
||||
if (number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const number = await trigger.fn({ operation: operation }, context, option);
|
||||
if (number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
catch (err) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
return execPreTrigger(idx + 1);
|
||||
};
|
||||
|
|
@ -338,26 +346,41 @@ class TriggerExecutor {
|
|||
(0, assert_1.default)(trigger && trigger.when === 'commit');
|
||||
(0, assert_1.default)(ids.length > 0);
|
||||
const { fn } = trigger;
|
||||
const callback = await fn({ ids }, context, option);
|
||||
if (trigger.strict === 'makeSure') {
|
||||
// 这里开root模式,否则还可能有权限问题
|
||||
context.openRootMode();
|
||||
await context.operate(entity, {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
[Entity_1.TriggerDataAttribute]: null,
|
||||
[Entity_1.TriggerUuidAttribute]: null,
|
||||
},
|
||||
filter: {
|
||||
id: {
|
||||
$in: ids,
|
||||
}
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const callback = await fn({ ids }, context, option);
|
||||
if (trigger.strict === 'makeSure') {
|
||||
// 这里开root模式,否则还可能有权限问题
|
||||
const closeRoot2 = context.openRootMode();
|
||||
try {
|
||||
await context.operate(entity, {
|
||||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||||
action: 'update',
|
||||
data: {
|
||||
[Entity_1.TriggerDataAttribute]: null,
|
||||
[Entity_1.TriggerUuidAttribute]: null,
|
||||
},
|
||||
filter: {
|
||||
id: {
|
||||
$in: ids,
|
||||
}
|
||||
}
|
||||
}, { includedDeleted: true, blockTrigger: true });
|
||||
closeRoot2 && closeRoot2();
|
||||
}
|
||||
}, { includedDeleted: true, blockTrigger: true });
|
||||
catch (err2) {
|
||||
closeRoot2 && closeRoot2();
|
||||
throw err2;
|
||||
}
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
await callback(context, option);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
await callback(context, option);
|
||||
catch (err) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -407,12 +430,20 @@ class TriggerExecutor {
|
|||
return;
|
||||
}
|
||||
const trigger = postTriggers[idx];
|
||||
const number = await trigger.fn({
|
||||
operation: operation,
|
||||
result: result,
|
||||
}, context, option);
|
||||
if (number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const number = await trigger.fn({
|
||||
operation: operation,
|
||||
result: result,
|
||||
}, context, option);
|
||||
if (number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
catch (err) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
return execPostTrigger(idx + 1);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ interface TriggerBase<ED extends EntityDict, T extends keyof ED> {
|
|||
checkerType?: CheckerType;
|
||||
entity: T;
|
||||
name: string;
|
||||
asRoot?: true;
|
||||
priority?: number;
|
||||
}
|
||||
export interface CreateTriggerBase<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> extends TriggerBase<ED, T> {
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ import { EntityDict } from '../types/Entity';
|
|||
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
||||
import { StorageSchema } from '../types/Storage';
|
||||
export declare function makeProjection<ED extends BaseEntityDict & EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>): ED[T]["Selection"]["data"];
|
||||
export declare function traverseProjection<ED extends BaseEntityDict & EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>, projection: ED[T]['Selection']['data'], callback: <T2 extends keyof ED>(entity2: T2, projection2: ED[T2]['Selection']['data']) => void): void;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.makeProjection = void 0;
|
||||
exports.traverseProjection = exports.makeProjection = void 0;
|
||||
const Entity_1 = require("../types/Entity");
|
||||
const relation_1 = require("../store/relation");
|
||||
function makeProjection(entity, schema) {
|
||||
const { attributes } = schema[entity];
|
||||
const attrs = Object.keys(attributes);
|
||||
|
|
@ -13,3 +14,22 @@ function makeProjection(entity, schema) {
|
|||
return projection;
|
||||
}
|
||||
exports.makeProjection = makeProjection;
|
||||
function traverseProjection(entity, schema, projection, callback) {
|
||||
const access = (entity2, proj) => {
|
||||
callback(entity2, proj);
|
||||
for (const attr in proj) {
|
||||
const rel = (0, relation_1.judgeRelation)(schema, entity2, attr);
|
||||
if (rel === 2) {
|
||||
access(attr, proj[attr]);
|
||||
}
|
||||
else if (typeof rel === 'string') {
|
||||
access(rel, proj[attr]);
|
||||
}
|
||||
else if (rel instanceof Array) {
|
||||
access(rel[0], proj[attr].data);
|
||||
}
|
||||
}
|
||||
};
|
||||
access(entity, projection);
|
||||
}
|
||||
exports.traverseProjection = traverseProjection;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "oak-domain",
|
||||
"version": "5.0.9",
|
||||
"version": "5.0.10",
|
||||
"author": {
|
||||
"name": "XuChang"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
|||
checkSortAttr(attr, sortAttr[attr], projNode[attr]);
|
||||
}
|
||||
}
|
||||
assignNecessaryProjectionAttrs(projNode, necessaryAttrs);
|
||||
}
|
||||
sorterNode!.forEach(
|
||||
(node) => {
|
||||
|
|
|
|||
|
|
@ -386,9 +386,17 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
return execPreTrigger(idx + 1);
|
||||
}
|
||||
}
|
||||
const number = await (trigger as CreateTriggerInTxn<ED, T, Cxt>).fn({ operation: operation as ED[T]['Create'] }, context, option as OperateOption);
|
||||
if (number as number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const number = await (trigger as CreateTriggerInTxn<ED, T, Cxt>).fn({ operation: operation as ED[T]['Create'] }, context, option as OperateOption);
|
||||
if (number as number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
catch (err: any) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
return execPreTrigger(idx + 1);
|
||||
};
|
||||
|
|
@ -429,27 +437,43 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
assert(trigger && trigger.when === 'commit');
|
||||
assert(ids.length > 0);
|
||||
const { fn } = trigger as VolatileTrigger<ED, T, Cxt>;
|
||||
const callback = await fn({ ids }, context, option);
|
||||
if (trigger.strict === 'makeSure') {
|
||||
// 这里开root模式,否则还可能有权限问题
|
||||
context.openRootMode();
|
||||
await context.operate(entity, {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
[TriggerDataAttribute]: null,
|
||||
[TriggerUuidAttribute]: null,
|
||||
},
|
||||
filter: {
|
||||
id: {
|
||||
$in: ids,
|
||||
}
|
||||
}
|
||||
}, { includedDeleted: true, blockTrigger: true });
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
await callback(context, option);
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const callback = await fn({ ids }, context, option);
|
||||
if (trigger.strict === 'makeSure') {
|
||||
// 这里开root模式,否则还可能有权限问题
|
||||
const closeRoot2 = context.openRootMode();
|
||||
try {
|
||||
await context.operate(entity, {
|
||||
id: await generateNewIdAsync(),
|
||||
action: 'update',
|
||||
data: {
|
||||
[TriggerDataAttribute]: null,
|
||||
[TriggerUuidAttribute]: null,
|
||||
},
|
||||
filter: {
|
||||
id: {
|
||||
$in: ids,
|
||||
}
|
||||
}
|
||||
}, { includedDeleted: true, blockTrigger: true });
|
||||
closeRoot2 && closeRoot2();
|
||||
}
|
||||
catch (err2: any) {
|
||||
closeRoot2 && closeRoot2();
|
||||
throw err2;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
await callback(context, option);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
catch(err: any) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -514,12 +538,21 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt extends
|
|||
return;
|
||||
}
|
||||
const trigger = postTriggers[idx];
|
||||
const number = await (trigger as SelectTriggerAfter<ED, T, Cxt>).fn({
|
||||
operation: operation as ED[T]['Selection'],
|
||||
result: result!,
|
||||
}, context, option as SelectOption);
|
||||
if (number as number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
|
||||
const closeRoot = trigger.asRoot && context.openRootMode();
|
||||
try {
|
||||
const number = await (trigger as SelectTriggerAfter<ED, T, Cxt>).fn({
|
||||
operation: operation as ED[T]['Selection'],
|
||||
result: result!,
|
||||
}, context, option as SelectOption);
|
||||
if (number as number > 0 && process.env.NODE_ENV === 'development') {
|
||||
this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
|
||||
}
|
||||
closeRoot && closeRoot();
|
||||
}
|
||||
catch (err: any) {
|
||||
closeRoot && closeRoot();
|
||||
throw err;
|
||||
}
|
||||
return execPostTrigger(idx + 1);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { EntityDict } from '../types/Entity';
|
||||
import { EntityDict, TriggerUuidAttribute } from '../types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
||||
import { AsyncContext } from '../store/AsyncRowStore';
|
||||
import { vaccumEntities } from './vaccum';
|
||||
|
|
@ -22,9 +22,14 @@ export type VaccumOperOption<ED extends EntityDict & BaseEntityDict> = {
|
|||
export async function vaccumOper<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(option: VaccumOperOption<ED>, context: Cxt) {
|
||||
const { aliveLine, excludeOpers, ...rest } = option;
|
||||
|
||||
const operFilter: ED['oper']['Selection']['filter'] = {};
|
||||
const notFilters: ED['oper']['Selection']['filter'][] = [
|
||||
{
|
||||
[TriggerUuidAttribute]: {
|
||||
$exists: false,
|
||||
}
|
||||
} as any,
|
||||
];
|
||||
if (excludeOpers) {
|
||||
const notFilters: ED['oper']['Selection']['filter'][] = [];
|
||||
for (const key in excludeOpers) {
|
||||
if (excludeOpers[key]!.length > 0) {
|
||||
notFilters.push({
|
||||
|
|
@ -40,27 +45,28 @@ export async function vaccumOper<ED extends EntityDict & BaseEntityDict, Cxt ext
|
|||
});
|
||||
}
|
||||
}
|
||||
if (notFilters.length > 0) {
|
||||
operFilter.$not = {
|
||||
$or: notFilters as NonNullable<ED['oper']['Selection']['filter']>[],
|
||||
};
|
||||
}
|
||||
}
|
||||
return vaccumEntities({
|
||||
return vaccumEntities<ED, Cxt>({
|
||||
entities: [{
|
||||
entity: 'operEntity',
|
||||
aliveLine: aliveLine + 10000,
|
||||
filter: {
|
||||
oper: combineFilters('operEntity', context.getSchema(), [operFilter, {
|
||||
oper: {
|
||||
$$createAt$$: {
|
||||
$lt: aliveLine,
|
||||
}
|
||||
}]),
|
||||
},
|
||||
$not: combineFilters('oper', context.getSchema(), notFilters),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
entity: 'oper',
|
||||
aliveLine,
|
||||
filter: operFilter,
|
||||
filter: {
|
||||
$$createAt$$: {
|
||||
$lt: aliveLine,
|
||||
},
|
||||
$not: combineFilters('oper', context.getSchema(), notFilters),
|
||||
},
|
||||
}],
|
||||
...rest,
|
||||
}, context);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ interface TriggerBase<ED extends EntityDict, T extends keyof ED> {
|
|||
checkerType?: CheckerType;
|
||||
entity: T;
|
||||
name: string;
|
||||
asRoot?: true;
|
||||
priority?: number;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { EntityDict, PrimaryKeyAttribute, CreateAtAttribute, UpdateAtAttribute, DeleteAtAttribute } from '../types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
||||
import { StorageSchema } from '../types/Storage';
|
||||
import { judgeRelation } from '../store/relation';
|
||||
|
||||
export function makeProjection<ED extends BaseEntityDict & EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>) {
|
||||
const { attributes } = schema[entity];
|
||||
|
|
@ -17,4 +18,29 @@ export function makeProjection<ED extends BaseEntityDict & EntityDict, T extends
|
|||
);
|
||||
|
||||
return projection;
|
||||
}
|
||||
|
||||
export function traverseProjection<ED extends BaseEntityDict & EntityDict, T extends keyof ED>(
|
||||
entity: T,
|
||||
schema: StorageSchema<ED>,
|
||||
projection: ED[T]['Selection']['data'],
|
||||
callback: <T2 extends keyof ED>(entity2: T2, projection2: ED[T2]['Selection']['data']) => void) {
|
||||
|
||||
const access = <T2 extends keyof ED>(entity2: T2, proj: ED[T2]['Selection']['data']) => {
|
||||
callback(entity2, proj);
|
||||
for (const attr in proj) {
|
||||
const rel = judgeRelation(schema, entity2, attr);
|
||||
if (rel === 2) {
|
||||
access(attr, proj[attr]);
|
||||
}
|
||||
else if (typeof rel === 'string') {
|
||||
access(rel, proj[attr]);
|
||||
}
|
||||
else if (rel instanceof Array) {
|
||||
access(rel[0], proj[attr]!.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
access(entity, projection);
|
||||
}
|
||||
Loading…
Reference in New Issue