@ruiapp/rapid-core 0.8.8 → 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
|
@@ -614,7 +614,7 @@ function buildRangeFilterQuery(ctx, filter) {
|
|
|
614
614
|
}
|
|
615
615
|
function buildContainsFilterQuery(ctx, filter) {
|
|
616
616
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
617
|
-
command += "
|
|
617
|
+
command += " ILIKE ";
|
|
618
618
|
if (ctx.paramToLiteral) ;
|
|
619
619
|
else {
|
|
620
620
|
ctx.params.push(`%${filter.value}%`);
|
|
@@ -624,7 +624,7 @@ function buildContainsFilterQuery(ctx, filter) {
|
|
|
624
624
|
}
|
|
625
625
|
function buildNotContainsFilterQuery(ctx, filter) {
|
|
626
626
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
627
|
-
command += " NOT
|
|
627
|
+
command += " NOT ILIKE ";
|
|
628
628
|
if (ctx.paramToLiteral) ;
|
|
629
629
|
else {
|
|
630
630
|
ctx.params.push(`%${filter.value}%`);
|
|
@@ -634,7 +634,7 @@ function buildNotContainsFilterQuery(ctx, filter) {
|
|
|
634
634
|
}
|
|
635
635
|
function buildStartsWithFilterQuery(ctx, filter) {
|
|
636
636
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
637
|
-
command += "
|
|
637
|
+
command += " ILIKE ";
|
|
638
638
|
if (ctx.paramToLiteral) ;
|
|
639
639
|
else {
|
|
640
640
|
ctx.params.push(`${filter.value}%`);
|
|
@@ -644,7 +644,7 @@ function buildStartsWithFilterQuery(ctx, filter) {
|
|
|
644
644
|
}
|
|
645
645
|
function buildNotStartsWithFilterQuery(ctx, filter) {
|
|
646
646
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
647
|
-
command += " NOT
|
|
647
|
+
command += " NOT ILIKE ";
|
|
648
648
|
if (ctx.paramToLiteral) ;
|
|
649
649
|
else {
|
|
650
650
|
ctx.params.push(`${filter.value}%`);
|
|
@@ -654,7 +654,7 @@ function buildNotStartsWithFilterQuery(ctx, filter) {
|
|
|
654
654
|
}
|
|
655
655
|
function buildEndsWithFilterQuery(ctx, filter) {
|
|
656
656
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
657
|
-
command += "
|
|
657
|
+
command += " ILIKE ";
|
|
658
658
|
if (ctx.paramToLiteral) ;
|
|
659
659
|
else {
|
|
660
660
|
ctx.params.push(`%${filter.value}`);
|
|
@@ -664,7 +664,7 @@ function buildEndsWithFilterQuery(ctx, filter) {
|
|
|
664
664
|
}
|
|
665
665
|
function buildNotEndsWithFilterQuery(ctx, filter) {
|
|
666
666
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
667
|
-
command += " NOT
|
|
667
|
+
command += " NOT ILIKE ";
|
|
668
668
|
if (ctx.paramToLiteral) ;
|
|
669
669
|
else {
|
|
670
670
|
ctx.params.push(`%${filter.value}`);
|
|
@@ -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) {
|
|
@@ -516,7 +516,7 @@ function buildRangeFilterQuery(ctx: BuildQueryContext, filter: FindRowRangeFilte
|
|
|
516
516
|
function buildContainsFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
517
517
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
518
518
|
|
|
519
|
-
command += "
|
|
519
|
+
command += " ILIKE ";
|
|
520
520
|
|
|
521
521
|
if (ctx.paramToLiteral) {
|
|
522
522
|
// TODO: implement it
|
|
@@ -531,7 +531,7 @@ function buildContainsFilterQuery(ctx: BuildQueryContext, filter: FindRowRelatio
|
|
|
531
531
|
function buildNotContainsFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
532
532
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
533
533
|
|
|
534
|
-
command += " NOT
|
|
534
|
+
command += " NOT ILIKE ";
|
|
535
535
|
if (ctx.paramToLiteral) {
|
|
536
536
|
// TODO: implement it
|
|
537
537
|
} else {
|
|
@@ -545,7 +545,7 @@ function buildNotContainsFilterQuery(ctx: BuildQueryContext, filter: FindRowRela
|
|
|
545
545
|
function buildStartsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
546
546
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
547
547
|
|
|
548
|
-
command += "
|
|
548
|
+
command += " ILIKE ";
|
|
549
549
|
|
|
550
550
|
if (ctx.paramToLiteral) {
|
|
551
551
|
// TODO: implement it
|
|
@@ -560,7 +560,7 @@ function buildStartsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelat
|
|
|
560
560
|
function buildNotStartsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
561
561
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
562
562
|
|
|
563
|
-
command += " NOT
|
|
563
|
+
command += " NOT ILIKE ";
|
|
564
564
|
|
|
565
565
|
if (ctx.paramToLiteral) {
|
|
566
566
|
// TODO: implement it
|
|
@@ -575,7 +575,7 @@ function buildNotStartsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRe
|
|
|
575
575
|
function buildEndsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
576
576
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
577
577
|
|
|
578
|
-
command += "
|
|
578
|
+
command += " ILIKE ";
|
|
579
579
|
|
|
580
580
|
if (ctx.paramToLiteral) {
|
|
581
581
|
// TODO: implement it
|
|
@@ -590,7 +590,7 @@ function buildEndsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelatio
|
|
|
590
590
|
function buildNotEndsWithFilterQuery(ctx: BuildQueryContext, filter: FindRowRelationalFilterOptions) {
|
|
591
591
|
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
592
592
|
|
|
593
|
-
command += " NOT
|
|
593
|
+
command += " NOT ILIKE ";
|
|
594
594
|
|
|
595
595
|
if (ctx.paramToLiteral) {
|
|
596
596
|
// TODO: implement it
|