@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
- beginDbTransaction(): Promise<IDatabaseClient>;
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 += " LIKE ";
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 LIKE ";
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 += " LIKE ";
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 LIKE ";
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 += " LIKE ";
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 LIKE ";
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 beginDbTransaction() {
1096
+ async initDbTransactionClient() {
1095
1097
  let dbClient = this.#dbTransactionClient;
1096
1098
  if (dbClient) {
1097
- throw new Error("Database transaction has been started. You can not start a transaction more than once in a request context.");
1099
+ return dbClient;
1098
1100
  }
1099
1101
  dbClient = await this.databaseAccessor.getClient();
1100
- await this.databaseAccessor.queryDatabaseObject("BEGIN", [], dbClient);
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.beginDbTransaction();
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.8.8",
3
+ "version": "0.8.10",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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, ResponseData } from "./http-types";
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 beginDbTransaction(): Promise<IDatabaseClient> {
77
+ async initDbTransactionClient(): Promise<IDatabaseClient> {
75
78
  let dbClient = this.#dbTransactionClient;
76
79
  if (dbClient) {
77
- throw new Error("Database transaction has been started. You can not start a transaction more than once in a request context.");
80
+ return dbClient;
78
81
  }
79
82
 
80
83
  dbClient = await this.databaseAccessor.getClient();
81
- await this.databaseAccessor.queryDatabaseObject("BEGIN", [], dbClient);
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.beginDbTransaction();
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 += " LIKE ";
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 LIKE ";
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 += " LIKE ";
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 LIKE ";
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 += " LIKE ";
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 LIKE ";
593
+ command += " NOT ILIKE ";
594
594
 
595
595
  if (ctx.paramToLiteral) {
596
596
  // TODO: implement it