@ruiapp/rapid-core 0.8.9 → 0.8.10
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.
|
@@ -4,6 +4,7 @@ import { HttpStatus } from "./http-types";
|
|
|
4
4
|
import { IRpdServer } from "./server";
|
|
5
5
|
import { IDatabaseAccessor, IDatabaseClient } from "../types";
|
|
6
6
|
export type Next = () => Promise<void>;
|
|
7
|
+
export type TransactionState = "uninited" | "inited" | "started";
|
|
7
8
|
export declare class RouteContext {
|
|
8
9
|
#private;
|
|
9
10
|
readonly request: RapidRequest;
|
|
@@ -22,7 +23,8 @@ export declare class RouteContext {
|
|
|
22
23
|
json(obj: any, status?: HttpStatus, headers?: HeadersInit): void;
|
|
23
24
|
redirect(url: string, status?: HttpStatus): void;
|
|
24
25
|
getDbTransactionClient(): IDatabaseClient | undefined;
|
|
25
|
-
|
|
26
|
+
initDbTransactionClient(): Promise<IDatabaseClient>;
|
|
27
|
+
beginDbTransaction(): Promise<void>;
|
|
26
28
|
commitDbTransaction(): Promise<void>;
|
|
27
29
|
rollbackDbTransaction(): Promise<void>;
|
|
28
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -1052,12 +1052,14 @@ class RouteContext {
|
|
|
1052
1052
|
routeConfig;
|
|
1053
1053
|
#server;
|
|
1054
1054
|
#dbTransactionClient;
|
|
1055
|
+
#dbTransactionState;
|
|
1055
1056
|
static newSystemOperationContext(server) {
|
|
1056
1057
|
return new RouteContext(server);
|
|
1057
1058
|
}
|
|
1058
1059
|
constructor(server, request) {
|
|
1059
1060
|
this.#server = server;
|
|
1060
1061
|
this.databaseAccessor = server.getDatabaseAccessor();
|
|
1062
|
+
this.#dbTransactionState = "uninited";
|
|
1061
1063
|
this.request = request;
|
|
1062
1064
|
this.state = {};
|
|
1063
1065
|
this.response = new RapidResponse();
|
|
@@ -1091,27 +1093,45 @@ class RouteContext {
|
|
|
1091
1093
|
getDbTransactionClient() {
|
|
1092
1094
|
return this.#dbTransactionClient;
|
|
1093
1095
|
}
|
|
1094
|
-
async
|
|
1096
|
+
async initDbTransactionClient() {
|
|
1095
1097
|
let dbClient = this.#dbTransactionClient;
|
|
1096
1098
|
if (dbClient) {
|
|
1097
|
-
|
|
1099
|
+
return dbClient;
|
|
1098
1100
|
}
|
|
1099
1101
|
dbClient = await this.databaseAccessor.getClient();
|
|
1100
|
-
|
|
1102
|
+
this.#dbTransactionState = "inited";
|
|
1101
1103
|
this.#dbTransactionClient = dbClient;
|
|
1102
1104
|
return dbClient;
|
|
1103
1105
|
}
|
|
1106
|
+
async beginDbTransaction() {
|
|
1107
|
+
if (!this.#dbTransactionClient) {
|
|
1108
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
1109
|
+
}
|
|
1110
|
+
if (this.#dbTransactionState === "started") {
|
|
1111
|
+
throw new Error("Database transaction has been started. You can not begin a new transaction before you commit or rollback it.");
|
|
1112
|
+
}
|
|
1113
|
+
await this.databaseAccessor.queryDatabaseObject("BEGIN", [], this.#dbTransactionClient);
|
|
1114
|
+
this.#dbTransactionState = "started";
|
|
1115
|
+
}
|
|
1104
1116
|
async commitDbTransaction() {
|
|
1105
1117
|
if (!this.#dbTransactionClient) {
|
|
1118
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
1119
|
+
}
|
|
1120
|
+
if (this.#dbTransactionState !== "started") {
|
|
1106
1121
|
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
1107
1122
|
}
|
|
1108
1123
|
await this.databaseAccessor.queryDatabaseObject("COMMIT", [], this.#dbTransactionClient);
|
|
1124
|
+
this.#dbTransactionState = "inited";
|
|
1109
1125
|
}
|
|
1110
1126
|
async rollbackDbTransaction() {
|
|
1111
1127
|
if (!this.#dbTransactionClient) {
|
|
1128
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
1129
|
+
}
|
|
1130
|
+
if (this.#dbTransactionState !== "started") {
|
|
1112
1131
|
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
1113
1132
|
}
|
|
1114
1133
|
await this.databaseAccessor.queryDatabaseObject("ROLLBACK", [], this.#dbTransactionClient);
|
|
1134
|
+
this.#dbTransactionState = "inited";
|
|
1115
1135
|
}
|
|
1116
1136
|
}
|
|
1117
1137
|
|
|
@@ -5593,7 +5613,8 @@ async function runCollectionEntityActionHandler(ctx, options, code, autoMergeInp
|
|
|
5593
5613
|
if (runInTransaction) {
|
|
5594
5614
|
let transactionDbClient;
|
|
5595
5615
|
try {
|
|
5596
|
-
transactionDbClient = await routeContext.
|
|
5616
|
+
transactionDbClient = await routeContext.initDbTransactionClient();
|
|
5617
|
+
await routeContext.beginDbTransaction();
|
|
5597
5618
|
const result = handleEntityAction(entityManager, autoMergeInput ? mergedInput : input);
|
|
5598
5619
|
if (result instanceof Promise) {
|
|
5599
5620
|
ctx.output = await result;
|
package/package.json
CHANGED
package/src/core/routeContext.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { isArray, isObject } from "lodash";
|
|
2
1
|
import { RapidRequest } from "./request";
|
|
3
2
|
import { RapidResponse } from "./response";
|
|
4
|
-
import { HttpStatus
|
|
3
|
+
import { HttpStatus } from "./http-types";
|
|
5
4
|
import { IRpdServer } from "./server";
|
|
6
|
-
import { Logger } from "~/facilities/log/LogFacility";
|
|
7
5
|
import { IDatabaseAccessor, IDatabaseClient } from "~/types";
|
|
8
6
|
|
|
9
7
|
export type Next = () => Promise<void>;
|
|
10
8
|
|
|
9
|
+
export type TransactionState = "uninited" | "inited" | "started";
|
|
10
|
+
|
|
11
11
|
// TODO: should divide to RequestContext and OperationContext
|
|
12
12
|
|
|
13
13
|
export class RouteContext {
|
|
@@ -21,6 +21,7 @@ export class RouteContext {
|
|
|
21
21
|
routeConfig: any;
|
|
22
22
|
#server: IRpdServer;
|
|
23
23
|
#dbTransactionClient: IDatabaseClient | undefined;
|
|
24
|
+
#dbTransactionState: TransactionState;
|
|
24
25
|
|
|
25
26
|
static newSystemOperationContext(server: IRpdServer) {
|
|
26
27
|
return new RouteContext(server);
|
|
@@ -29,6 +30,8 @@ export class RouteContext {
|
|
|
29
30
|
constructor(server: IRpdServer, request?: RapidRequest) {
|
|
30
31
|
this.#server = server;
|
|
31
32
|
this.databaseAccessor = server.getDatabaseAccessor();
|
|
33
|
+
this.#dbTransactionState = "uninited";
|
|
34
|
+
|
|
32
35
|
this.request = request;
|
|
33
36
|
this.state = {};
|
|
34
37
|
this.response = new RapidResponse();
|
|
@@ -71,29 +74,54 @@ export class RouteContext {
|
|
|
71
74
|
return this.#dbTransactionClient;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
|
-
async
|
|
77
|
+
async initDbTransactionClient(): Promise<IDatabaseClient> {
|
|
75
78
|
let dbClient = this.#dbTransactionClient;
|
|
76
79
|
if (dbClient) {
|
|
77
|
-
|
|
80
|
+
return dbClient;
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
dbClient = await this.databaseAccessor.getClient();
|
|
81
|
-
|
|
84
|
+
this.#dbTransactionState = "inited";
|
|
82
85
|
this.#dbTransactionClient = dbClient;
|
|
83
86
|
return dbClient;
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
async beginDbTransaction(): Promise<void> {
|
|
90
|
+
if (!this.#dbTransactionClient) {
|
|
91
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (this.#dbTransactionState === "started") {
|
|
95
|
+
throw new Error("Database transaction has been started. You can not begin a new transaction before you commit or rollback it.");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
await this.databaseAccessor.queryDatabaseObject("BEGIN", [], this.#dbTransactionClient);
|
|
99
|
+
this.#dbTransactionState = "started";
|
|
100
|
+
}
|
|
101
|
+
|
|
86
102
|
async commitDbTransaction(): Promise<void> {
|
|
87
103
|
if (!this.#dbTransactionClient) {
|
|
104
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (this.#dbTransactionState !== "started") {
|
|
88
108
|
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
89
109
|
}
|
|
110
|
+
|
|
90
111
|
await this.databaseAccessor.queryDatabaseObject("COMMIT", [], this.#dbTransactionClient);
|
|
112
|
+
this.#dbTransactionState = "inited";
|
|
91
113
|
}
|
|
92
114
|
|
|
93
115
|
async rollbackDbTransaction(): Promise<void> {
|
|
94
116
|
if (!this.#dbTransactionClient) {
|
|
117
|
+
throw new Error("Database transaction has not been inited. You should call initDbTransactionClient() first.");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (this.#dbTransactionState !== "started") {
|
|
95
121
|
throw new Error("Database transaction has not been started. You should call beginDbTransaction() first.");
|
|
96
122
|
}
|
|
123
|
+
|
|
97
124
|
await this.databaseAccessor.queryDatabaseObject("ROLLBACK", [], this.#dbTransactionClient);
|
|
125
|
+
this.#dbTransactionState = "inited";
|
|
98
126
|
}
|
|
99
127
|
}
|
|
@@ -28,7 +28,8 @@ export default async function runCollectionEntityActionHandler(
|
|
|
28
28
|
let transactionDbClient: IDatabaseClient;
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
transactionDbClient = await routeContext.
|
|
31
|
+
transactionDbClient = await routeContext.initDbTransactionClient();
|
|
32
|
+
await routeContext.beginDbTransaction();
|
|
32
33
|
|
|
33
34
|
const result = handleEntityAction(entityManager, autoMergeInput ? mergedInput : input);
|
|
34
35
|
if (result instanceof Promise) {
|