@ruiapp/rapid-core 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/routeContext.d.ts +9 -0
- package/dist/core/server.d.ts +2 -1
- package/dist/dataAccess/dataAccessor.d.ts +8 -8
- package/dist/helpers/runCollectionEntityActionHandler.d.ts +1 -1
- package/dist/index.js +288 -202
- package/dist/plugins/dataManage/actionHandlers/deleteCollectionEntities.d.ts +1 -0
- package/dist/plugins/sequence/SequenceService.d.ts +3 -2
- package/dist/plugins/sequence/segments/autoIncrement.d.ts +2 -1
- package/dist/plugins/sequence/segments/dayOfMonth.d.ts +2 -1
- package/dist/plugins/sequence/segments/literal.d.ts +2 -1
- package/dist/plugins/sequence/segments/month.d.ts +2 -1
- package/dist/plugins/sequence/segments/parameter.d.ts +2 -1
- package/dist/plugins/sequence/segments/year.d.ts +2 -1
- package/dist/server.d.ts +1 -0
- package/dist/types.d.ts +13 -8
- package/package.json +1 -1
- package/src/core/routeContext.ts +53 -0
- package/src/core/server.ts +2 -0
- package/src/dataAccess/dataAccessor.ts +15 -15
- package/src/dataAccess/entityManager.ts +66 -50
- package/src/helpers/runCollectionEntityActionHandler.ts +37 -7
- package/src/plugins/auth/actionHandlers/changePassword.ts +22 -15
- package/src/plugins/auth/actionHandlers/createSession.ts +14 -11
- package/src/plugins/auth/actionHandlers/resetPassword.ts +21 -14
- package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +7 -12
- package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +3 -2
- package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +52 -13
- package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +12 -16
- package/src/plugins/dataManage/actionHandlers/deleteCollectionEntities.ts +32 -25
- package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +12 -14
- package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +3 -2
- package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +12 -12
- package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +8 -13
- package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +26 -29
- package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +6 -6
- package/src/plugins/fileManage/actionHandlers/downloadFile.ts +3 -3
- package/src/plugins/metaManage/MetaManagePlugin.ts +3 -2
- package/src/plugins/sequence/SequencePlugin.ts +29 -19
- package/src/plugins/sequence/SequenceService.ts +25 -14
- package/src/plugins/sequence/actionHandlers/generateSn.ts +3 -3
- package/src/plugins/sequence/segments/autoIncrement.ts +36 -24
- package/src/plugins/sequence/segments/dayOfMonth.ts +2 -0
- package/src/plugins/sequence/segments/literal.ts +2 -0
- package/src/plugins/sequence/segments/month.ts +2 -0
- package/src/plugins/sequence/segments/parameter.ts +2 -0
- package/src/plugins/sequence/segments/year.ts +2 -0
- package/src/plugins/stateMachine/StateMachinePlugin.ts +26 -16
- package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +14 -11
- package/src/server.ts +4 -0
- package/src/types.ts +14 -8
|
@@ -3,6 +3,7 @@ import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
|
3
3
|
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export interface DeleteCollectionEntitiesInput {
|
|
5
5
|
filters: FindEntityOptions["filters"];
|
|
6
|
+
noTransaction?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export declare const code = "deleteCollectionEntities";
|
|
8
9
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IRpdServer } from "../../core/server";
|
|
2
2
|
import { SequenceSegmentConfig } from "./SequencePluginTypes";
|
|
3
|
+
import { RouteContext } from "../../core/routeContext";
|
|
3
4
|
export interface GenerateSequenceNumbersInput {
|
|
4
5
|
ruleCode: string;
|
|
5
6
|
parameters: Record<string, string>;
|
|
@@ -10,10 +11,10 @@ export interface GenerateSequenceNumbersOutput {
|
|
|
10
11
|
}
|
|
11
12
|
export interface SegmentResolver {
|
|
12
13
|
segmentType: string;
|
|
13
|
-
resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
14
|
+
resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
14
15
|
}
|
|
15
16
|
export default class SequenceService {
|
|
16
17
|
#private;
|
|
17
18
|
constructor(server: IRpdServer);
|
|
18
|
-
generateSn(server: IRpdServer, input: GenerateSequenceNumbersInput): Promise<string[]>;
|
|
19
|
+
generateSn(routeContext: RouteContext | null, server: IRpdServer, input: GenerateSequenceNumbersInput): Promise<string[]>;
|
|
19
20
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
2
2
|
import { IRpdServer } from "../../../core/server";
|
|
3
3
|
import { SequenceAutoIncrementSegmentConfig } from "../SequencePluginTypes";
|
|
4
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
4
5
|
export declare const segmentType = "autoIncrement";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceAutoIncrementSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceAutoIncrementSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
1
2
|
import { SequenceDayOfMonthSegmentConfig } from "../SequencePluginTypes";
|
|
2
3
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
3
4
|
import { IRpdServer } from "../../../core/server";
|
|
4
5
|
export declare const segmentType = "dayOfMonth";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceDayOfMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceDayOfMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
1
2
|
import { SequenceLiteralSegmentConfig } from "../SequencePluginTypes";
|
|
2
3
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
3
4
|
import { IRpdServer } from "../../../core/server";
|
|
4
5
|
export declare const segmentType = "literal";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceLiteralSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceLiteralSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
1
2
|
import { SequenceMonthSegmentConfig } from "../SequencePluginTypes";
|
|
2
3
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
3
4
|
import { IRpdServer } from "../../../core/server";
|
|
4
5
|
export declare const segmentType = "month";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
1
2
|
import { SequenceParameterSegmentConfig } from "../SequencePluginTypes";
|
|
2
3
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
3
4
|
import { IRpdServer } from "../../../core/server";
|
|
4
5
|
export declare const segmentType = "parameter";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceParameterSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceParameterSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RouteContext } from "../../../core/routeContext";
|
|
1
2
|
import { SequenceYearSegmentConfig } from "../SequencePluginTypes";
|
|
2
3
|
import { GenerateSequenceNumbersInput } from "../SequenceService";
|
|
3
4
|
import { IRpdServer } from "../../../core/server";
|
|
4
5
|
export declare const segmentType = "year";
|
|
5
|
-
export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceYearSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
|
6
|
+
export declare function resolveSegmentValue(routeContext: RouteContext, server: IRpdServer, ruleCode: string, config: SequenceYearSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
|
package/dist/server.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare class RapidServer implements IRpdServer {
|
|
|
23
23
|
constructor(options: InitServerOptions);
|
|
24
24
|
getLogger(): Logger;
|
|
25
25
|
getApplicationConfig(): RpdApplicationConfig;
|
|
26
|
+
getDatabaseAccessor(): IDatabaseAccessor;
|
|
26
27
|
appendApplicationConfig(config: Partial<RpdApplicationConfig>): void;
|
|
27
28
|
appendModelProperties(modelSingularCode: string, properties: RpdDataModelProperty[]): void;
|
|
28
29
|
registerActionHandler(plugin: RapidPlugin, options: IPluginActionHandler): void;
|
package/dist/types.d.ts
CHANGED
|
@@ -20,8 +20,13 @@ export type DatabaseQuery = {
|
|
|
20
20
|
command: string;
|
|
21
21
|
params?: unknown[] | Record<string, unknown>;
|
|
22
22
|
};
|
|
23
|
+
export interface IDatabaseClient {
|
|
24
|
+
release(): any;
|
|
25
|
+
query(sql: any, params?: any): Promise<any>;
|
|
26
|
+
}
|
|
23
27
|
export interface IDatabaseAccessor {
|
|
24
|
-
|
|
28
|
+
getClient(): Promise<IDatabaseClient>;
|
|
29
|
+
queryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>, client?: IDatabaseClient) => Promise<any[]>;
|
|
25
30
|
}
|
|
26
31
|
export interface RunEntityActionHandlerOptions {
|
|
27
32
|
/** 模型所在的命名空间 */
|
|
@@ -380,13 +385,13 @@ export interface RpdRouteActionConfig {
|
|
|
380
385
|
}
|
|
381
386
|
export interface IRpdDataAccessor<T = any> {
|
|
382
387
|
getModel(): RpdDataModel;
|
|
383
|
-
create(entity: any): Promise<any>;
|
|
384
|
-
updateById(id: any, entity: any): Promise<any>;
|
|
385
|
-
find(options: FindRowOptions): Promise<T[]>;
|
|
386
|
-
findOne(options: FindRowOptions): Promise<T | null>;
|
|
387
|
-
findById(id: any): Promise<T | null>;
|
|
388
|
-
count(options: CountRowOptions): Promise<number>;
|
|
389
|
-
deleteById(id: any): Promise<void>;
|
|
388
|
+
create(entity: any, databaseClient: IDatabaseClient | null): Promise<any>;
|
|
389
|
+
updateById(id: any, entity: any, databaseClient: IDatabaseClient | null): Promise<any>;
|
|
390
|
+
find(options: FindRowOptions, databaseClient: IDatabaseClient | null): Promise<T[]>;
|
|
391
|
+
findOne(options: FindRowOptions, databaseClient: IDatabaseClient | null): Promise<T | null>;
|
|
392
|
+
findById(id: any, databaseClient: IDatabaseClient | null): Promise<T | null>;
|
|
393
|
+
count(options: CountRowOptions, databaseClient: IDatabaseClient | null): Promise<number>;
|
|
394
|
+
deleteById(id: any, databaseClient: IDatabaseClient | null): Promise<void>;
|
|
390
395
|
}
|
|
391
396
|
export type EntityFilterRelationalOperators = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | "notContains" | "containsCS" | "notContainsCS" | "startsWith" | "notStartsWith" | "endsWith" | "notEndsWith";
|
|
392
397
|
export type EntityFilterArrayOperators = "arrayContains" | "arrayOverlap";
|
package/package.json
CHANGED
package/src/core/routeContext.ts
CHANGED
|
@@ -4,23 +4,32 @@ import { RapidResponse } from "./response";
|
|
|
4
4
|
import { HttpStatus, ResponseData } from "./http-types";
|
|
5
5
|
import { IRpdServer } from "./server";
|
|
6
6
|
import { Logger } from "~/facilities/log/LogFacility";
|
|
7
|
+
import { IDatabaseAccessor, IDatabaseClient } from "~/types";
|
|
7
8
|
|
|
8
9
|
export type Next = () => Promise<void>;
|
|
9
10
|
|
|
11
|
+
// TODO: should divide to RequestContext and OperationContext
|
|
12
|
+
|
|
10
13
|
export class RouteContext {
|
|
11
14
|
readonly request: RapidRequest;
|
|
12
15
|
readonly response: RapidResponse;
|
|
13
16
|
readonly state: Record<string, any>;
|
|
17
|
+
readonly databaseAccessor: IDatabaseAccessor;
|
|
14
18
|
method: string;
|
|
15
19
|
path: string;
|
|
16
20
|
params: Record<string, string>;
|
|
17
21
|
routeConfig: any;
|
|
22
|
+
#server: IRpdServer;
|
|
23
|
+
#dbTransactionClient: IDatabaseClient | null;
|
|
18
24
|
|
|
19
25
|
static newSystemOperationContext(server: IRpdServer) {
|
|
20
26
|
return new RouteContext(server);
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
constructor(server: IRpdServer, request?: RapidRequest) {
|
|
30
|
+
this.#server = server;
|
|
31
|
+
this.#dbTransactionClient = null;
|
|
32
|
+
this.databaseAccessor = server.getDatabaseAccessor();
|
|
24
33
|
this.request = request;
|
|
25
34
|
this.state = {};
|
|
26
35
|
this.response = new RapidResponse();
|
|
@@ -32,6 +41,20 @@ export class RouteContext {
|
|
|
32
41
|
}
|
|
33
42
|
}
|
|
34
43
|
|
|
44
|
+
clone(): RouteContext {
|
|
45
|
+
const clonedContext = new RouteContext(this.#server);
|
|
46
|
+
clonedContext.method = this.method;
|
|
47
|
+
clonedContext.path = this.path;
|
|
48
|
+
clonedContext.params = this.params;
|
|
49
|
+
clonedContext.setState(this.state);
|
|
50
|
+
|
|
51
|
+
return clonedContext;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
setState(state: Record<string, any>) {
|
|
55
|
+
Object.assign(this.state, state);
|
|
56
|
+
}
|
|
57
|
+
|
|
35
58
|
// `koa-tree-router` uses this method to set headers
|
|
36
59
|
set(headerName: string, headerValue: string) {
|
|
37
60
|
this.response.headers.set(headerName, headerValue);
|
|
@@ -44,4 +67,34 @@ export class RouteContext {
|
|
|
44
67
|
redirect(url: string, status?: HttpStatus) {
|
|
45
68
|
this.response.redirect(url, status);
|
|
46
69
|
}
|
|
70
|
+
|
|
71
|
+
getDbTransactionClient(): IDatabaseClient | null {
|
|
72
|
+
return this.#dbTransactionClient;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async beginDbTransaction(): Promise<IDatabaseClient> {
|
|
76
|
+
let dbClient = this.#dbTransactionClient;
|
|
77
|
+
if (dbClient) {
|
|
78
|
+
throw new Error("Database transaction has been started. You can not start a transaction more than once in a request context.");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
dbClient = await this.databaseAccessor.getClient();
|
|
82
|
+
await this.databaseAccessor.queryDatabaseObject("BEGIN", [], dbClient);
|
|
83
|
+
this.#dbTransactionClient = dbClient;
|
|
84
|
+
return dbClient;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async commitDbTransaction(): Promise<void> {
|
|
88
|
+
if (!this.#dbTransactionClient) {
|
|
89
|
+
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
90
|
+
}
|
|
91
|
+
await this.databaseAccessor.queryDatabaseObject("COMMIT", [], this.#dbTransactionClient);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async rollbackDbTransaction(): Promise<void> {
|
|
95
|
+
if (!this.#dbTransactionClient) {
|
|
96
|
+
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
97
|
+
}
|
|
98
|
+
await this.databaseAccessor.queryDatabaseObject("ROLLBACK", [], this.#dbTransactionClient);
|
|
99
|
+
}
|
|
47
100
|
}
|
package/src/core/server.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
EntityWatcherType,
|
|
5
5
|
GetDataAccessorOptions,
|
|
6
6
|
GetModelOptions,
|
|
7
|
+
IDatabaseAccessor,
|
|
7
8
|
IDatabaseConfig,
|
|
8
9
|
IQueryBuilder,
|
|
9
10
|
IRpdDataAccessor,
|
|
@@ -30,6 +31,7 @@ export interface IRpdServer {
|
|
|
30
31
|
|
|
31
32
|
getFacility<TFacility = any>(name: string, options?: any): Promise<TFacility>;
|
|
32
33
|
|
|
34
|
+
getDatabaseAccessor(): IDatabaseAccessor;
|
|
33
35
|
queryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
|
|
34
36
|
tryQueryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
|
|
35
37
|
registerMiddleware(middleware: any): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateEntityOptions, IRpdDataAccessor, RpdDataModel, IDatabaseAccessor, DatabaseQuery } from "~/types";
|
|
1
|
+
import { CreateEntityOptions, IRpdDataAccessor, RpdDataModel, IDatabaseAccessor, DatabaseQuery, IDatabaseClient } from "~/types";
|
|
2
2
|
import QueryBuilder from "~/queryBuilder/queryBuilder";
|
|
3
3
|
import { first, set } from "lodash";
|
|
4
4
|
import { IRpdServer } from "~/core/server";
|
|
@@ -30,16 +30,16 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
30
30
|
return this.#model;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
async create(entity: Partial<T
|
|
33
|
+
async create(entity: Partial<T>, databaseClient: IDatabaseClient | null): Promise<T> {
|
|
34
34
|
const options: CreateEntityOptions = {
|
|
35
35
|
entity,
|
|
36
36
|
};
|
|
37
37
|
const query = this.#queryBuilder.insert(this.#model, options);
|
|
38
|
-
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
38
|
+
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params, databaseClient);
|
|
39
39
|
return first(result);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
async updateById(id: any, entity: Partial<T
|
|
42
|
+
async updateById(id: any, entity: Partial<T>, databaseClient: IDatabaseClient | null): Promise<{ count: number }> {
|
|
43
43
|
const options: UpdateRowOptions = {
|
|
44
44
|
entity,
|
|
45
45
|
filters: [
|
|
@@ -53,11 +53,11 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
53
53
|
],
|
|
54
54
|
};
|
|
55
55
|
const query = this.#queryBuilder.update(this.#model, options);
|
|
56
|
-
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
56
|
+
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params, databaseClient);
|
|
57
57
|
return first(result);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
async find(options: FindRowOptions): Promise<T[]> {
|
|
60
|
+
async find(options: FindRowOptions, databaseClient: IDatabaseClient | null): Promise<T[]> {
|
|
61
61
|
this.#logger.debug(`Finding '${this.#model.singularCode}' entity.`, { options });
|
|
62
62
|
let query: DatabaseQuery;
|
|
63
63
|
if (this.#model.base) {
|
|
@@ -70,19 +70,19 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
try {
|
|
73
|
-
return await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
73
|
+
return await this.#databaseAccessor.queryDatabaseObject(query.command, query.params, databaseClient);
|
|
74
74
|
} catch (err) {
|
|
75
75
|
throw newDatabaseError(`Failed to find entities. ${err.message}`, err);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
async findOne(options: FindRowOptions): Promise<T> {
|
|
79
|
+
async findOne(options: FindRowOptions, databaseClient: IDatabaseClient | null): Promise<T> {
|
|
80
80
|
set(options, "pagination.limit", 1);
|
|
81
|
-
const list = await this.find(options);
|
|
81
|
+
const list = await this.find(options, databaseClient);
|
|
82
82
|
return first(list);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
async findById(id: any): Promise<T | null> {
|
|
85
|
+
async findById(id: any, databaseClient: IDatabaseClient | null): Promise<T | null> {
|
|
86
86
|
const options: FindRowOptions = {
|
|
87
87
|
filters: [
|
|
88
88
|
{
|
|
@@ -94,11 +94,11 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
94
94
|
},
|
|
95
95
|
],
|
|
96
96
|
};
|
|
97
|
-
const result = await this.findOne(options);
|
|
97
|
+
const result = await this.findOne(options, databaseClient);
|
|
98
98
|
return result;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
async count(options: CountRowOptions): Promise<number> {
|
|
101
|
+
async count(options: CountRowOptions, databaseClient: IDatabaseClient | null): Promise<number> {
|
|
102
102
|
let query: DatabaseQuery;
|
|
103
103
|
if (this.#model.base) {
|
|
104
104
|
const baseModel = this.#server.getModel({
|
|
@@ -108,7 +108,7 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
108
108
|
} else {
|
|
109
109
|
query = this.#queryBuilder.count(this.#model, options);
|
|
110
110
|
}
|
|
111
|
-
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
111
|
+
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params, databaseClient);
|
|
112
112
|
|
|
113
113
|
const row = first(result);
|
|
114
114
|
if (row) {
|
|
@@ -117,7 +117,7 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
117
117
|
return 0;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
async deleteById(id: any) {
|
|
120
|
+
async deleteById(id: any, databaseClient: IDatabaseClient | null) {
|
|
121
121
|
const options: FindRowOptions = {
|
|
122
122
|
filters: [
|
|
123
123
|
{
|
|
@@ -130,6 +130,6 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
130
130
|
],
|
|
131
131
|
};
|
|
132
132
|
const query = this.#queryBuilder.delete(this.#model, options);
|
|
133
|
-
await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
133
|
+
await this.#databaseAccessor.queryDatabaseObject(query.command, query.params, databaseClient);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -143,6 +143,7 @@ function convertEntityOrderByToRowOrderBy(server: IRpdServer, model: RpdDataMode
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor, options: FindEntityOptions) {
|
|
146
|
+
const routeContext = options.routeContext;
|
|
146
147
|
const model = dataAccessor.getModel();
|
|
147
148
|
let baseModel: RpdDataModel | undefined;
|
|
148
149
|
if (model.base) {
|
|
@@ -242,14 +243,14 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
242
243
|
});
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
const rowFilters = await convertEntityFiltersToRowFilters(server, model, baseModel, options.filters);
|
|
246
|
+
const rowFilters = await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, options.filters);
|
|
246
247
|
const findRowOptions: FindRowOptions = {
|
|
247
248
|
filters: rowFilters,
|
|
248
249
|
orderBy: convertEntityOrderByToRowOrderBy(server, model, baseModel, options.orderBy),
|
|
249
250
|
pagination: options.pagination,
|
|
250
251
|
fields: columnsToSelect,
|
|
251
252
|
};
|
|
252
|
-
const rows = await dataAccessor.find(findRowOptions);
|
|
253
|
+
const rows = await dataAccessor.find(findRowOptions, routeContext?.getDbTransactionClient());
|
|
253
254
|
if (!rows.length) {
|
|
254
255
|
return [];
|
|
255
256
|
}
|
|
@@ -374,6 +375,7 @@ async function findById(server: IRpdServer, dataAccessor: IRpdDataAccessor, opti
|
|
|
374
375
|
}
|
|
375
376
|
|
|
376
377
|
async function convertEntityFiltersToRowFilters(
|
|
378
|
+
routeContext: RouteContext,
|
|
377
379
|
server: IRpdServer,
|
|
378
380
|
model: RpdDataModel,
|
|
379
381
|
baseModel: RpdDataModel,
|
|
@@ -389,7 +391,7 @@ async function convertEntityFiltersToRowFilters(
|
|
|
389
391
|
if (operator === "and" || operator === "or") {
|
|
390
392
|
replacedFilters.push({
|
|
391
393
|
operator: operator,
|
|
392
|
-
filters: await convertEntityFiltersToRowFilters(server, model, baseModel, filter.filters),
|
|
394
|
+
filters: await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, filter.filters),
|
|
393
395
|
});
|
|
394
396
|
} else if (operator === "exists" || operator === "notExists") {
|
|
395
397
|
const relationProperty: RpdDataModelProperty = getEntityPropertyByCode(server, model, filter.field);
|
|
@@ -444,15 +446,18 @@ async function convertEntityFiltersToRowFilters(
|
|
|
444
446
|
singularCode: relatedModel.base,
|
|
445
447
|
});
|
|
446
448
|
}
|
|
447
|
-
const rows = await dataAccessor.find(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
449
|
+
const rows = await dataAccessor.find(
|
|
450
|
+
{
|
|
451
|
+
filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
|
|
452
|
+
fields: [
|
|
453
|
+
{
|
|
454
|
+
name: "id",
|
|
455
|
+
tableName: relatedModel.tableName,
|
|
456
|
+
},
|
|
457
|
+
],
|
|
458
|
+
},
|
|
459
|
+
routeContext?.getDbTransactionClient(),
|
|
460
|
+
);
|
|
456
461
|
const entityIds = map(rows, (entity: any) => entity["id"]);
|
|
457
462
|
replacedFilters.push({
|
|
458
463
|
field: {
|
|
@@ -478,15 +483,18 @@ async function convertEntityFiltersToRowFilters(
|
|
|
478
483
|
singularCode: relatedModel.base,
|
|
479
484
|
});
|
|
480
485
|
}
|
|
481
|
-
const targetEntities = await targetEntityDataAccessor.find(
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
486
|
+
const targetEntities = await targetEntityDataAccessor.find(
|
|
487
|
+
{
|
|
488
|
+
filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
|
|
489
|
+
fields: [
|
|
490
|
+
{
|
|
491
|
+
name: relationProperty.selfIdColumnName,
|
|
492
|
+
tableName: relatedModel.tableName,
|
|
493
|
+
},
|
|
494
|
+
],
|
|
495
|
+
},
|
|
496
|
+
routeContext?.getDbTransactionClient(),
|
|
497
|
+
);
|
|
490
498
|
const selfEntityIds = map(targetEntities, (entity: any) => entity[relationProperty.selfIdColumnName!]);
|
|
491
499
|
replacedFilters.push({
|
|
492
500
|
field: {
|
|
@@ -519,15 +527,18 @@ async function convertEntityFiltersToRowFilters(
|
|
|
519
527
|
singularCode: relatedModel.base,
|
|
520
528
|
});
|
|
521
529
|
}
|
|
522
|
-
const targetEntities = await targetEntityDataAccessor.find(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
530
|
+
const targetEntities = await targetEntityDataAccessor.find(
|
|
531
|
+
{
|
|
532
|
+
filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
|
|
533
|
+
fields: [
|
|
534
|
+
{
|
|
535
|
+
name: "id",
|
|
536
|
+
tableName: relatedModel.tableName,
|
|
537
|
+
},
|
|
538
|
+
],
|
|
539
|
+
},
|
|
540
|
+
routeContext?.getDbTransactionClient(),
|
|
541
|
+
);
|
|
531
542
|
const targetEntityIds = map(targetEntities, (entity: any) => entity["id"]);
|
|
532
543
|
|
|
533
544
|
const command = `SELECT * FROM ${server.queryBuilder.quoteTable({
|
|
@@ -880,7 +891,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
880
891
|
|
|
881
892
|
row.id = newBaseRow.id;
|
|
882
893
|
}
|
|
883
|
-
const newRow = await dataAccessor.create(row);
|
|
894
|
+
const newRow = await dataAccessor.create(row, routeContext?.getDbTransactionClient());
|
|
884
895
|
const newEntity = mapDbRowToEntity(server, model, Object.assign({}, newBaseRow, newRow, newEntityOneRelationProps), true);
|
|
885
896
|
|
|
886
897
|
// save one-relation properties that has selfIdColumnName
|
|
@@ -908,7 +919,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
908
919
|
const relationFieldChanges = {
|
|
909
920
|
[property.targetIdColumnName]: newTargetEntity.id,
|
|
910
921
|
};
|
|
911
|
-
await dataAccessorOfMainEntity.updateById(newEntity.id, relationFieldChanges);
|
|
922
|
+
await dataAccessorOfMainEntity.updateById(newEntity.id, relationFieldChanges, routeContext?.getDbTransactionClient());
|
|
912
923
|
newEntity[property.code] = newTargetEntity;
|
|
913
924
|
}
|
|
914
925
|
}
|
|
@@ -955,7 +966,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
955
966
|
newEntity[property.code].push(newTargetEntity);
|
|
956
967
|
} else {
|
|
957
968
|
// related entity is existed
|
|
958
|
-
const targetEntity = await targetDataAccessor.findById(relatedEntityId);
|
|
969
|
+
const targetEntity = await targetDataAccessor.findById(relatedEntityId, routeContext?.getDbTransactionClient());
|
|
959
970
|
if (!targetEntity) {
|
|
960
971
|
throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
|
|
961
972
|
}
|
|
@@ -968,7 +979,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
968
979
|
const params = [newEntity.id, relatedEntityId];
|
|
969
980
|
await server.queryDatabaseObject(command, params);
|
|
970
981
|
} else {
|
|
971
|
-
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: newEntity.id });
|
|
982
|
+
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: newEntity.id }, routeContext?.getDbTransactionClient());
|
|
972
983
|
targetEntity[property.selfIdColumnName!] = newEntity.id;
|
|
973
984
|
}
|
|
974
985
|
newEntity[property.code].push(targetEntity);
|
|
@@ -976,7 +987,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
976
987
|
} else {
|
|
977
988
|
// fieldValue is id
|
|
978
989
|
relatedEntityId = relatedEntityToBeSaved;
|
|
979
|
-
const targetEntity = await targetDataAccessor.findById(relatedEntityId);
|
|
990
|
+
const targetEntity = await targetDataAccessor.findById(relatedEntityId, routeContext?.getDbTransactionClient());
|
|
980
991
|
if (!targetEntity) {
|
|
981
992
|
throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
|
|
982
993
|
}
|
|
@@ -989,7 +1000,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
989
1000
|
const params = [newEntity.id, relatedEntityId];
|
|
990
1001
|
await server.queryDatabaseObject(command, params);
|
|
991
1002
|
} else {
|
|
992
|
-
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: newEntity.id });
|
|
1003
|
+
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: newEntity.id }, routeContext?.getDbTransactionClient());
|
|
993
1004
|
targetEntity[property.selfIdColumnName!] = newEntity.id;
|
|
994
1005
|
}
|
|
995
1006
|
|
|
@@ -1205,7 +1216,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1205
1216
|
|
|
1206
1217
|
let updatedRow = row;
|
|
1207
1218
|
if (Object.keys(row).length) {
|
|
1208
|
-
updatedRow = await dataAccessor.updateById(id, row);
|
|
1219
|
+
updatedRow = await dataAccessor.updateById(id, row, routeContext?.getDbTransactionClient());
|
|
1209
1220
|
}
|
|
1210
1221
|
let updatedBaseRow = baseRow;
|
|
1211
1222
|
let baseDataAccessor: any;
|
|
@@ -1246,7 +1257,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1246
1257
|
const relationFieldChanges = {
|
|
1247
1258
|
[property.targetIdColumnName]: newTargetEntity.id,
|
|
1248
1259
|
};
|
|
1249
|
-
await dataAccessorOfMainEntity.updateById(updatedEntity.id, relationFieldChanges);
|
|
1260
|
+
await dataAccessorOfMainEntity.updateById(updatedEntity.id, relationFieldChanges, routeContext?.getDbTransactionClient());
|
|
1250
1261
|
updatedEntity[property.code] = newTargetEntity;
|
|
1251
1262
|
changes[property.code] = newTargetEntity;
|
|
1252
1263
|
}
|
|
@@ -1339,7 +1350,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1339
1350
|
relatedEntities.push(newTargetEntity);
|
|
1340
1351
|
} else {
|
|
1341
1352
|
// related entity is existed
|
|
1342
|
-
let targetEntity = await targetDataAccessor.findById(relatedEntityId);
|
|
1353
|
+
let targetEntity = await targetDataAccessor.findById(relatedEntityId, routeContext?.getDbTransactionClient());
|
|
1343
1354
|
if (!targetEntity) {
|
|
1344
1355
|
throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' does not exist.`);
|
|
1345
1356
|
}
|
|
@@ -1377,7 +1388,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1377
1388
|
const params = [id, relatedEntityId];
|
|
1378
1389
|
await server.queryDatabaseObject(command, params);
|
|
1379
1390
|
} else {
|
|
1380
|
-
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
|
|
1391
|
+
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id }, routeContext?.getDbTransactionClient());
|
|
1381
1392
|
targetEntity[property.selfIdColumnName!] = id;
|
|
1382
1393
|
}
|
|
1383
1394
|
}
|
|
@@ -1386,7 +1397,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1386
1397
|
} else {
|
|
1387
1398
|
// fieldValue is id
|
|
1388
1399
|
relatedEntityId = relatedEntityToBeSaved;
|
|
1389
|
-
const targetEntity = await targetDataAccessor.findById(relatedEntityId);
|
|
1400
|
+
const targetEntity = await targetDataAccessor.findById(relatedEntityId, routeContext?.getDbTransactionClient());
|
|
1390
1401
|
if (!targetEntity) {
|
|
1391
1402
|
throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
|
|
1392
1403
|
}
|
|
@@ -1400,7 +1411,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1400
1411
|
const params = [id, relatedEntityId];
|
|
1401
1412
|
await server.queryDatabaseObject(command, params);
|
|
1402
1413
|
} else {
|
|
1403
|
-
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
|
|
1414
|
+
await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id }, routeContext?.getDbTransactionClient());
|
|
1404
1415
|
targetEntity[property.selfIdColumnName!] = id;
|
|
1405
1416
|
}
|
|
1406
1417
|
}
|
|
@@ -1537,6 +1548,7 @@ export default class EntityManager<TEntity = any> {
|
|
|
1537
1548
|
}
|
|
1538
1549
|
|
|
1539
1550
|
async count(options: CountEntityOptions): Promise<number> {
|
|
1551
|
+
const routeContext = options.routeContext;
|
|
1540
1552
|
const model = this.#dataAccessor.getModel();
|
|
1541
1553
|
let baseModel: RpdDataModel;
|
|
1542
1554
|
if (model.base) {
|
|
@@ -1545,9 +1557,9 @@ export default class EntityManager<TEntity = any> {
|
|
|
1545
1557
|
});
|
|
1546
1558
|
}
|
|
1547
1559
|
const countRowOptions: CountRowOptions = {
|
|
1548
|
-
filters: await convertEntityFiltersToRowFilters(this.#server, model, baseModel, options.filters),
|
|
1560
|
+
filters: await convertEntityFiltersToRowFilters(routeContext, this.#server, model, baseModel, options.filters),
|
|
1549
1561
|
};
|
|
1550
|
-
return await this.#dataAccessor.count(countRowOptions);
|
|
1562
|
+
return await this.#dataAccessor.count(countRowOptions, routeContext?.getDbTransactionClient());
|
|
1551
1563
|
}
|
|
1552
1564
|
|
|
1553
1565
|
async deleteById(options: DeleteEntityByIdOptions | string | number, plugin?: RapidPlugin): Promise<void> {
|
|
@@ -1593,17 +1605,21 @@ export default class EntityManager<TEntity = any> {
|
|
|
1593
1605
|
})
|
|
1594
1606
|
: this.#dataAccessor;
|
|
1595
1607
|
const currentUserId = routeContext?.state?.userId;
|
|
1596
|
-
await dataAccessor.updateById(
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1608
|
+
await dataAccessor.updateById(
|
|
1609
|
+
id,
|
|
1610
|
+
{
|
|
1611
|
+
deleted_at: getNowStringWithTimezone(),
|
|
1612
|
+
deleter_id: currentUserId,
|
|
1613
|
+
},
|
|
1614
|
+
routeContext?.getDbTransactionClient(),
|
|
1615
|
+
);
|
|
1600
1616
|
} else {
|
|
1601
|
-
await this.#dataAccessor.deleteById(id);
|
|
1617
|
+
await this.#dataAccessor.deleteById(id, routeContext?.getDbTransactionClient());
|
|
1602
1618
|
if (model.base) {
|
|
1603
1619
|
const baseDataAccessor = this.#server.getDataAccessor({
|
|
1604
1620
|
singularCode: model.base,
|
|
1605
1621
|
});
|
|
1606
|
-
await baseDataAccessor.deleteById(id);
|
|
1622
|
+
await baseDataAccessor.deleteById(id, routeContext?.getDbTransactionClient());
|
|
1607
1623
|
}
|
|
1608
1624
|
}
|
|
1609
1625
|
|