Merge branch 'dev' of gitea.51mars.com:Oak-Team/oak-domain into dev
This commit is contained in:
commit
34018c09b3
|
|
@ -29,6 +29,12 @@ export declare abstract class AsyncContext<ED extends EntityDict> implements Con
|
||||||
private resetEvents;
|
private resetEvents;
|
||||||
on(event: 'commit' | 'rollback', callback: (records: OpRecord<ED>[], cxtStr: string) => Promise<void>): void;
|
on(event: 'commit' | 'rollback', callback: (records: OpRecord<ED>[], cxtStr: string) => Promise<void>): void;
|
||||||
saveOpRecord<T extends keyof ED>(entity: T, operation: ED[T]['Operation']): void;
|
saveOpRecord<T extends keyof ED>(entity: T, operation: ED[T]['Operation']): void;
|
||||||
|
/**
|
||||||
|
* 查询某operation所处理的row ids
|
||||||
|
* 如果该operation还未执行,可能返回空数组(不知道实际关联的row id);但是在after的trigger中,返回是准确的ids值(此时如果是空数组说明没有有关row id)
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
getRowIdsOfOperation(operation: ED[keyof ED]['Operation']): string[];
|
||||||
/**
|
/**
|
||||||
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
||||||
* @param options
|
* @param options
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ exports.AsyncContext = void 0;
|
||||||
const tslib_1 = require("tslib");
|
const tslib_1 = require("tslib");
|
||||||
const action_1 = require("../actions/action");
|
const action_1 = require("../actions/action");
|
||||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||||
|
const filter_1 = require("./filter");
|
||||||
/**
|
/**
|
||||||
* 服务器端执行的异步环境的底层抽象
|
* 服务器端执行的异步环境的底层抽象
|
||||||
*/
|
*/
|
||||||
|
|
@ -75,7 +76,7 @@ class AsyncContext {
|
||||||
id,
|
id,
|
||||||
a: 'c',
|
a: 'c',
|
||||||
e: entity,
|
e: entity,
|
||||||
d: data
|
d: data,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +101,35 @@ class AsyncContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 查询某operation所处理的row ids
|
||||||
|
* 如果该operation还未执行,可能返回空数组(不知道实际关联的row id);但是在after的trigger中,返回是准确的ids值(此时如果是空数组说明没有有关row id)
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
getRowIdsOfOperation(operation) {
|
||||||
|
const { id, action, data, filter } = operation;
|
||||||
|
if (action === 'create') {
|
||||||
|
if (data instanceof Array) {
|
||||||
|
return data.map(ele => ele.id);
|
||||||
|
}
|
||||||
|
return [data.id];
|
||||||
|
}
|
||||||
|
else if (filter) {
|
||||||
|
const ids = (0, filter_1.getRelevantIds)(filter);
|
||||||
|
if (ids.length > 0) {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const oper = this.opRecords.find(ele => ele.id === id);
|
||||||
|
if (oper) {
|
||||||
|
const { a } = oper;
|
||||||
|
(0, assert_1.default)(a !== 'create');
|
||||||
|
const { f } = oper;
|
||||||
|
(0, assert_1.default)(f && f?.id?.$in && f.id.$in instanceof Array);
|
||||||
|
return f.id.$in;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
||||||
* @param options
|
* @param options
|
||||||
|
|
|
||||||
|
|
@ -1217,6 +1217,7 @@ class CascadeStore extends RowStore_1.RowStore {
|
||||||
};
|
};
|
||||||
const rows = await this.selectAbjointRowAsync(entity, selection, context, {
|
const rows = await this.selectAbjointRowAsync(entity, selection, context, {
|
||||||
dontCollect: true,
|
dontCollect: true,
|
||||||
|
forUpdate: true,
|
||||||
});
|
});
|
||||||
ids.push(...(rows.map(ele => ele.id)));
|
ids.push(...(rows.map(ele => ele.id)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ function createUniqueCheckers(schema) {
|
||||||
entity,
|
entity,
|
||||||
action: 'create',
|
action: 'create',
|
||||||
type: 'logicalData',
|
type: 'logicalData',
|
||||||
priority: types_1.CHECKER_MAX_PRIORITY,
|
priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
|
||||||
checker: (operation, context) => {
|
checker: (operation, context) => {
|
||||||
const { data } = operation;
|
const { data } = operation;
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
|
|
@ -95,9 +95,9 @@ function createUniqueCheckers(schema) {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
entity,
|
entity,
|
||||||
action: 'update',
|
action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性
|
||||||
type: 'logicalData',
|
type: 'logicalData',
|
||||||
priority: types_1.CHECKER_MAX_PRIORITY,
|
priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
|
||||||
checker: (operation, context) => {
|
checker: (operation, context) => {
|
||||||
const { data, filter: operationFilter } = operation;
|
const { data, filter: operationFilter } = operation;
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
@ -227,7 +227,7 @@ function createActionTransformerCheckers(actionDefDict) {
|
||||||
action: 'create',
|
action: 'create',
|
||||||
type: 'logical',
|
type: 'logical',
|
||||||
entity,
|
entity,
|
||||||
priority: 10,
|
priority: 10, // 优先级要高,先于真正的data检查进行
|
||||||
checker: (operation) => {
|
checker: (operation) => {
|
||||||
const { data } = operation;
|
const { data } = operation;
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
|
|
|
||||||
|
|
@ -647,6 +647,7 @@ function judgeValueRelation(value1, value2, contained) {
|
||||||
else if (r) {
|
else if (r) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 互斥
|
// 互斥
|
||||||
if (r) {
|
if (r) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/// <reference types="node" />
|
||||||
/**
|
/**
|
||||||
* 防止assert打包体积过大,从这里引用
|
* 防止assert打包体积过大,从这里引用
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ function destructRelationPath(schema, entity, path, relationFilter, recursive) {
|
||||||
},
|
},
|
||||||
filter: relationFilter,
|
filter: relationFilter,
|
||||||
} // as ED['userRelation']['Selection']
|
} // as ED['userRelation']['Selection']
|
||||||
},
|
}, // as ED[keyof ED]['Selection']['data'],
|
||||||
getData: (d) => {
|
getData: (d) => {
|
||||||
return d.userRelation$entity;
|
return d.userRelation$entity;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ declare const url: {
|
||||||
revokeObjectURL(url: string): void;
|
revokeObjectURL(url: string): void;
|
||||||
};
|
};
|
||||||
declare const urlSearchParams: {
|
declare const urlSearchParams: {
|
||||||
new (init?: string | Record<string, string> | string[][] | URLSearchParams | undefined): URLSearchParams;
|
new (init?: string | string[][] | Record<string, string> | URLSearchParams | undefined): URLSearchParams;
|
||||||
prototype: URLSearchParams;
|
prototype: URLSearchParams;
|
||||||
};
|
};
|
||||||
export { url, urlSearchParams };
|
export { url, urlSearchParams };
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ declare const url: {
|
||||||
revokeObjectURL(url: string): void;
|
revokeObjectURL(url: string): void;
|
||||||
};
|
};
|
||||||
declare const urlSearchParams: {
|
declare const urlSearchParams: {
|
||||||
new (init?: string | Record<string, string> | string[][] | URLSearchParams | undefined): URLSearchParams;
|
new (init?: string | string[][] | Record<string, string> | URLSearchParams | undefined): URLSearchParams;
|
||||||
prototype: URLSearchParams;
|
prototype: URLSearchParams;
|
||||||
};
|
};
|
||||||
export { url, urlSearchParams };
|
export { url, urlSearchParams };
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "oak-domain",
|
"name": "oak-domain",
|
||||||
"version": "5.0.16",
|
"version": "5.0.17",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "XuChang"
|
"name": "XuChang"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
|
|
||||||
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult, ClusterInfo } from "../types";
|
import { EntityDict, RowStore, OperateOption, OperationResult, SelectOption, Context, TxnOption, OpRecord, AggregationResult, ClusterInfo, CreateOpResult, UpdateOpResult } from "../types";
|
||||||
import { readOnlyActions } from '../actions/action';
|
import { readOnlyActions } from '../actions/action';
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { IncomingHttpHeaders } from "http";
|
import { IncomingHttpHeaders } from "http";
|
||||||
|
import { getRelevantIds } from "./filter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服务器端执行的异步环境的底层抽象
|
* 服务器端执行的异步环境的底层抽象
|
||||||
|
|
@ -91,7 +92,7 @@ export abstract class AsyncContext<ED extends EntityDict> implements Context {
|
||||||
id,
|
id,
|
||||||
a: 'c',
|
a: 'c',
|
||||||
e: entity,
|
e: entity,
|
||||||
d: data as ED[T]['OpSchema']
|
d: data as ED[T]['OpSchema'],
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -117,6 +118,39 @@ export abstract class AsyncContext<ED extends EntityDict> implements Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询某operation所处理的row ids
|
||||||
|
* 如果该operation还未执行,可能返回空数组(不知道实际关联的row id);但是在after的trigger中,返回是准确的ids值(此时如果是空数组说明没有有关row id)
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
getRowIdsOfOperation(operation: ED[keyof ED]['Operation']): string[] {
|
||||||
|
const { id, action, data, filter } = operation;
|
||||||
|
if (action === 'create') {
|
||||||
|
if (data instanceof Array) {
|
||||||
|
return data.map(ele => ele.id);
|
||||||
|
}
|
||||||
|
return [data.id!];
|
||||||
|
}
|
||||||
|
else if (filter) {
|
||||||
|
const ids = getRelevantIds(filter);
|
||||||
|
if (ids.length > 0 ) {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const oper = this.opRecords.find(
|
||||||
|
ele => (ele as CreateOpResult<ED, keyof ED>).id === id
|
||||||
|
);
|
||||||
|
if (oper) {
|
||||||
|
const { a } = oper;
|
||||||
|
assert (a !== 'create');
|
||||||
|
const { f } = oper as UpdateOpResult<ED, keyof ED>;
|
||||||
|
assert(f && f?.id?.$in && f!.id!.$in! instanceof Array);
|
||||||
|
return f!.id!.$in!;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
* 一个context中不应该有并发的事务,这里将事务串行化,使用的时候千万要注意不要自己等自己
|
||||||
* @param options
|
* @param options
|
||||||
|
|
|
||||||
|
|
@ -1490,6 +1490,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
|
||||||
};
|
};
|
||||||
const rows = await this.selectAbjointRowAsync(entity, selection, context, {
|
const rows = await this.selectAbjointRowAsync(entity, selection, context, {
|
||||||
dontCollect: true,
|
dontCollect: true,
|
||||||
|
forUpdate: true,
|
||||||
});
|
});
|
||||||
ids.push(...(rows.map(ele => ele.id! as string)));
|
ids.push(...(rows.map(ele => ele.id! as string)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -744,6 +744,7 @@ export function judgeValueRelation(value1: any, value2: any, contained: boolean)
|
||||||
else if (r) {
|
else if (r) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 互斥
|
// 互斥
|
||||||
if (r) {
|
if (r) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue