@nsshunt/stsdatamanagement 1.18.208 → 1.18.210
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/commonTypes.js.map +1 -1
- package/dist/dataAccessTypes.js +8 -0
- package/dist/dataAccessTypes.js.map +1 -0
- package/dist/dbaccess.js +1 -0
- package/dist/dbaccess.js.map +1 -1
- package/dist/pcaccesslayer-entity.test.js +2 -1
- package/dist/pcaccesslayer-entity.test.js.map +1 -1
- package/dist/pcaccesslayer.test.js +2 -1
- package/dist/pcaccesslayer.test.js.map +1 -1
- package/dist/pgaccesslayer.js +253 -199
- package/dist/pgaccesslayer.js.map +1 -1
- package/package.json +5 -5
- package/types/commonTypes.d.ts +2 -1
- package/types/commonTypes.d.ts.map +1 -1
- package/types/dataAccessTypes.d.ts +68 -0
- package/types/dataAccessTypes.d.ts.map +1 -0
- package/types/databaseutils.d.ts +1 -1
- package/types/databaseutils.d.ts.map +1 -1
- package/types/dbaccess.d.ts +1 -0
- package/types/dbaccess.d.ts.map +1 -1
- package/types/pgaccesslayer.d.ts +4 -4
- package/types/pgaccesslayer.d.ts.map +1 -1
package/dist/pgaccesslayer.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
|
|
2
|
-
import { StatusCodes } from
|
|
2
|
+
import { StatusCodes } from "http-status-codes";
|
|
3
3
|
import { Redis } from "ioredis";
|
|
4
|
-
import { goptions } from
|
|
5
|
-
import { PGPoolManager } from
|
|
6
|
-
import { IDBAccessLayerEvents, eOperations } from
|
|
7
|
-
import { TinyEmitter } from
|
|
4
|
+
import { goptions } from "@nsshunt/stsconfig";
|
|
5
|
+
import { PGPoolManager } from "./pgpoolmanager.js";
|
|
6
|
+
import { IDBAccessLayerEvents, eOperations, } from "./commonTypes.js";
|
|
7
|
+
import { TinyEmitter } from "tiny-emitter";
|
|
8
8
|
export var updateMode;
|
|
9
9
|
(function (updateMode) {
|
|
10
10
|
updateMode[updateMode["patchResources"] = 0] = "patchResources";
|
|
@@ -25,13 +25,13 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
25
25
|
const { useRedisDatabaseCache, redisDatabaseCacheUrl } = goptions;
|
|
26
26
|
this.#poolManager = new PGPoolManager({
|
|
27
27
|
logger: this.#options.logger,
|
|
28
|
-
usedefaultdb: this.#options.usedefaultdb
|
|
28
|
+
usedefaultdb: this.#options.usedefaultdb,
|
|
29
29
|
});
|
|
30
30
|
this.#poolManager.on(IDBAccessLayerEvents.UpdateInstruments, this.#UpdateInstruments);
|
|
31
31
|
if (useRedisDatabaseCache === true) {
|
|
32
32
|
const redisOptions = {
|
|
33
33
|
showFriendlyErrorStack: true,
|
|
34
|
-
maxRetriesPerRequest: 20
|
|
34
|
+
maxRetriesPerRequest: 20,
|
|
35
35
|
};
|
|
36
36
|
this.#cache = new Redis(redisDatabaseCacheUrl, redisOptions);
|
|
37
37
|
}
|
|
@@ -46,48 +46,50 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
46
46
|
this.#options.logger.error(message);
|
|
47
47
|
};
|
|
48
48
|
#buildQueryString = (filters, restype) => {
|
|
49
|
-
const { resname, entname, resvnum, entvnum, filter, incdel, startdate, enddate, resenddate, dbaction, dbactionuser } = filters;
|
|
49
|
+
const { resname, entname, resvnum, entvnum, filter, incdel, startdate, enddate, resenddate, dbaction, dbactionuser, } = filters;
|
|
50
50
|
// Build query string
|
|
51
51
|
const qparams = [];
|
|
52
|
-
let qstring =
|
|
53
|
-
let sep =
|
|
52
|
+
let qstring = " where ";
|
|
53
|
+
let sep = "";
|
|
54
54
|
let qnum = 0;
|
|
55
55
|
if (resname !== undefined) {
|
|
56
56
|
qparams.push(resname);
|
|
57
|
-
qstring += sep +
|
|
58
|
-
sep =
|
|
57
|
+
qstring += sep + "r.resname = $" + ++qnum;
|
|
58
|
+
sep = " and ";
|
|
59
59
|
}
|
|
60
60
|
if (entname !== undefined) {
|
|
61
61
|
qparams.push(entname);
|
|
62
|
-
qstring += sep +
|
|
63
|
-
sep =
|
|
62
|
+
qstring += sep + "e.entname = $" + ++qnum;
|
|
63
|
+
sep = " and ";
|
|
64
64
|
}
|
|
65
65
|
if (resvnum !== undefined) {
|
|
66
66
|
qparams.push(resvnum);
|
|
67
|
-
qstring += sep +
|
|
68
|
-
sep =
|
|
67
|
+
qstring += sep + "r.vnum = $" + ++qnum;
|
|
68
|
+
sep = " and ";
|
|
69
69
|
}
|
|
70
70
|
if (entvnum !== undefined) {
|
|
71
71
|
qparams.push(entvnum);
|
|
72
|
-
qstring += sep +
|
|
73
|
-
sep =
|
|
72
|
+
qstring += sep + "e.vnum = $" + ++qnum;
|
|
73
|
+
sep = " and ";
|
|
74
74
|
}
|
|
75
75
|
// Only get current version provided enddate is not specified
|
|
76
76
|
if (enddate === undefined) {
|
|
77
|
-
qstring += sep + restype +
|
|
78
|
-
sep =
|
|
77
|
+
qstring += sep + restype + ".validto is null";
|
|
78
|
+
sep = " and ";
|
|
79
79
|
}
|
|
80
|
-
if (Object.hasOwn(filters,
|
|
81
|
-
qstring += sep +
|
|
82
|
-
sep =
|
|
80
|
+
if (Object.hasOwn(filters, "resenddate") && resenddate === null) {
|
|
81
|
+
qstring += sep + "r.validto is null";
|
|
82
|
+
sep = " and ";
|
|
83
83
|
}
|
|
84
84
|
if (filter !== undefined) {
|
|
85
|
-
if (restype ===
|
|
85
|
+
if (restype === "r") {
|
|
86
86
|
// This old method using LIKE and % is slow AF esp when using order by in the clause
|
|
87
87
|
// qparams.push(filter);
|
|
88
88
|
// qstring += sep + restype + '.resname like $' + ++qnum;
|
|
89
89
|
let useFilter = filter;
|
|
90
|
-
if (filter &&
|
|
90
|
+
if (filter &&
|
|
91
|
+
filter.length > 0 &&
|
|
92
|
+
filter.charAt(filter.length - 1) === "%") {
|
|
91
93
|
useFilter = filter.slice(0, -1);
|
|
92
94
|
}
|
|
93
95
|
qparams.push(useFilter);
|
|
@@ -101,7 +103,9 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
101
103
|
//qparams.push(filter);
|
|
102
104
|
//qstring += sep + restype + '.entname like $' + ++qnum;
|
|
103
105
|
let useFilter = filter;
|
|
104
|
-
if (filter &&
|
|
106
|
+
if (filter &&
|
|
107
|
+
filter.length > 0 &&
|
|
108
|
+
filter.charAt(filter.length - 1) === "%") {
|
|
105
109
|
useFilter = filter.slice(0, -1);
|
|
106
110
|
}
|
|
107
111
|
qparams.push(useFilter);
|
|
@@ -110,32 +114,32 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
110
114
|
const p2 = ++qnum;
|
|
111
115
|
qstring += `${sep}${restype}.entname >= $${p1} and ${restype}.entname < $${p2}`;
|
|
112
116
|
}
|
|
113
|
-
sep =
|
|
117
|
+
sep = " and ";
|
|
114
118
|
}
|
|
115
119
|
if (startdate !== undefined) {
|
|
116
120
|
qparams.push(startdate);
|
|
117
|
-
qstring += sep + restype +
|
|
118
|
-
sep =
|
|
121
|
+
qstring += sep + restype + ".validfrom >= $" + ++qnum;
|
|
122
|
+
sep = " and ";
|
|
119
123
|
}
|
|
120
124
|
if (enddate !== undefined) {
|
|
121
125
|
qparams.push(enddate);
|
|
122
|
-
qstring += sep + restype +
|
|
123
|
-
sep =
|
|
126
|
+
qstring += sep + restype + ".validto <= $" + ++qnum;
|
|
127
|
+
sep = " and ";
|
|
124
128
|
}
|
|
125
|
-
if (incdel === undefined || incdel.toLowerCase() ===
|
|
129
|
+
if (incdel === undefined || incdel.toLowerCase() === "n") {
|
|
126
130
|
qparams.push(3);
|
|
127
|
-
qstring += sep + restype +
|
|
128
|
-
sep =
|
|
131
|
+
qstring += sep + restype + ".dbaction != $" + ++qnum;
|
|
132
|
+
sep = " and ";
|
|
129
133
|
}
|
|
130
134
|
if (dbaction !== undefined) {
|
|
131
135
|
qparams.push(dbaction);
|
|
132
|
-
qstring += sep + restype +
|
|
133
|
-
sep =
|
|
136
|
+
qstring += sep + restype + ".dbaction = $" + ++qnum;
|
|
137
|
+
sep = " and ";
|
|
134
138
|
}
|
|
135
139
|
if (dbactionuser !== undefined) {
|
|
136
140
|
qparams.push(dbactionuser);
|
|
137
|
-
qstring += sep + restype +
|
|
138
|
-
sep =
|
|
141
|
+
qstring += sep + restype + ".dbactionuser = $" + ++qnum;
|
|
142
|
+
sep = " and ";
|
|
139
143
|
}
|
|
140
144
|
if (qnum === 0) {
|
|
141
145
|
return null;
|
|
@@ -145,10 +149,10 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
145
149
|
}
|
|
146
150
|
};
|
|
147
151
|
#IsErrorWithMessage = (error) => {
|
|
148
|
-
return (typeof error ===
|
|
152
|
+
return (typeof error === "object" &&
|
|
149
153
|
error !== null &&
|
|
150
|
-
|
|
151
|
-
typeof error.message ===
|
|
154
|
+
"message" in error &&
|
|
155
|
+
typeof error.message === "string");
|
|
152
156
|
};
|
|
153
157
|
#ToErrorWithMessage = (maybeError) => {
|
|
154
158
|
if (this.#IsErrorWithMessage(maybeError))
|
|
@@ -172,8 +176,8 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
172
176
|
status,
|
|
173
177
|
operation: fname.toString(),
|
|
174
178
|
error: new Error(message),
|
|
175
|
-
errorMessage: message
|
|
176
|
-
}
|
|
179
|
+
errorMessage: message,
|
|
180
|
+
},
|
|
177
181
|
};
|
|
178
182
|
};
|
|
179
183
|
#LogAndGetErrorMessage = (options, status, fname, message) => {
|
|
@@ -204,24 +208,24 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
204
208
|
return true;
|
|
205
209
|
}
|
|
206
210
|
async GetResourceCount(options) {
|
|
207
|
-
const useOptions =
|
|
211
|
+
const useOptions = options ? options : {};
|
|
208
212
|
try {
|
|
209
213
|
let query = `select count(*) from stsresource r`;
|
|
210
214
|
let values = [];
|
|
211
|
-
const qs = this.#buildQueryString((options ? options.filters : {}),
|
|
215
|
+
const qs = this.#buildQueryString((options ? options.filters : {}), "r");
|
|
212
216
|
if (qs !== null) {
|
|
213
217
|
query += qs.qstring;
|
|
214
218
|
values = qs.qparams;
|
|
215
219
|
}
|
|
216
|
-
const client = await this.#poolManager?.connectReadOnly();
|
|
220
|
+
const client = (await this.#poolManager?.connectReadOnly());
|
|
217
221
|
try {
|
|
218
222
|
const { rows } = await client.query(query, values);
|
|
219
223
|
const dbResponse = rows[0];
|
|
220
224
|
return {
|
|
221
225
|
options: useOptions,
|
|
222
|
-
operation:
|
|
226
|
+
operation: "GetResourceCount",
|
|
223
227
|
status: StatusCodes.OK,
|
|
224
|
-
detail: parseInt(dbResponse.count) //@@ needs to be number
|
|
228
|
+
detail: parseInt(dbResponse.count), //@@ needs to be number
|
|
225
229
|
};
|
|
226
230
|
}
|
|
227
231
|
catch (error) {
|
|
@@ -237,20 +241,22 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
237
241
|
}
|
|
238
242
|
async GetEntityCount(options) {
|
|
239
243
|
try {
|
|
240
|
-
const requiredFields = [
|
|
241
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
244
|
+
const requiredFields = ["resname"];
|
|
245
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
242
246
|
if (checkAllKeys) {
|
|
243
247
|
let query = `select count(*) from stsentity e join stsresource r on e.resourceoid = r.oid`;
|
|
244
248
|
let values = [];
|
|
245
|
-
const qs = this.#buildQueryString((options
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
const qs = this.#buildQueryString((options
|
|
250
|
+
? {
|
|
251
|
+
resenddate: null,
|
|
252
|
+
...options.filters,
|
|
253
|
+
}
|
|
254
|
+
: {}), "e");
|
|
249
255
|
if (qs !== null) {
|
|
250
256
|
query += qs.qstring;
|
|
251
257
|
values = qs.qparams;
|
|
252
258
|
}
|
|
253
|
-
const client = await this.#poolManager?.connectReadOnly();
|
|
259
|
+
const client = (await this.#poolManager?.connectReadOnly());
|
|
254
260
|
try {
|
|
255
261
|
const { rows } = await client.query(query, values);
|
|
256
262
|
const dbResponse = rows[0];
|
|
@@ -258,7 +264,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
258
264
|
status: StatusCodes.OK,
|
|
259
265
|
options,
|
|
260
266
|
detail: parseInt(dbResponse.count), //@@ needs to be number
|
|
261
|
-
operation:
|
|
267
|
+
operation: "GetEntityCount",
|
|
262
268
|
};
|
|
263
269
|
}
|
|
264
270
|
catch (error) {
|
|
@@ -277,15 +283,15 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
277
283
|
}
|
|
278
284
|
}
|
|
279
285
|
async #__CreateResource(client, options, operation, resource) {
|
|
280
|
-
const requiredFields = [
|
|
281
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
286
|
+
const requiredFields = ["dbactionuser", "resname"];
|
|
287
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
282
288
|
if (checkAllKeys) {
|
|
283
289
|
let createQuery = null;
|
|
284
290
|
createQuery = `select * from create_stsresource($1, $2, $3)`;
|
|
285
291
|
const values = [
|
|
286
292
|
options.filters?.dbactionuser,
|
|
287
293
|
options.filters?.resname,
|
|
288
|
-
JSON.stringify(resource)
|
|
294
|
+
JSON.stringify(resource),
|
|
289
295
|
];
|
|
290
296
|
try {
|
|
291
297
|
const { rows } = await client.query(createQuery, values);
|
|
@@ -295,11 +301,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
295
301
|
status: StatusCodes.CREATED,
|
|
296
302
|
detail: dbResponse,
|
|
297
303
|
options,
|
|
298
|
-
operation
|
|
304
|
+
operation,
|
|
299
305
|
};
|
|
300
306
|
}
|
|
301
307
|
catch (error) {
|
|
302
|
-
if (error.code ===
|
|
308
|
+
if (error.code === "23505") {
|
|
303
309
|
return this.#LogAndGetErrorMessage(options, StatusCodes.CONFLICT, eOperations.CreateResource, `pgaccesslayer:__CreateResource(): resourceid [${options.filters?.resname}] already exists. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
304
310
|
}
|
|
305
311
|
else {
|
|
@@ -313,20 +319,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
313
319
|
}
|
|
314
320
|
async CreateResource(options, resource) {
|
|
315
321
|
try {
|
|
316
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
322
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
317
323
|
try {
|
|
318
|
-
await client.query(
|
|
324
|
+
await client.query("BEGIN");
|
|
319
325
|
const retVal = await this.#__CreateResource(client, options, eOperations.CreateResource, resource);
|
|
320
326
|
if (retVal.status === StatusCodes.CREATED) {
|
|
321
|
-
await client.query(
|
|
327
|
+
await client.query("COMMIT");
|
|
322
328
|
}
|
|
323
329
|
else {
|
|
324
|
-
await client.query(
|
|
330
|
+
await client.query("ROLLBACK");
|
|
325
331
|
}
|
|
326
332
|
return retVal;
|
|
327
333
|
}
|
|
328
334
|
catch (error) {
|
|
329
|
-
await client.query(
|
|
335
|
+
await client.query("ROLLBACK");
|
|
330
336
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.CreateResource, `pgaccesslayer:CreateResource(): Operation was not successful (__CreateResource). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
331
337
|
}
|
|
332
338
|
finally {
|
|
@@ -339,13 +345,13 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
339
345
|
}
|
|
340
346
|
async #__GetResource(client, options) {
|
|
341
347
|
try {
|
|
342
|
-
const requiredFields = [
|
|
343
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
348
|
+
const requiredFields = ["resname"];
|
|
349
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
344
350
|
if (checkAllKeys) {
|
|
345
|
-
let query =
|
|
351
|
+
let query = "select r.oid::bigint, r.resname, r.resdesc, r.vnum::bigint, r.validfrom, r.validto, r.dbaction, r.dbactionuser from stsresource r";
|
|
346
352
|
let values = [];
|
|
347
353
|
const resourceid = options.filters?.resname;
|
|
348
|
-
const qs = this.#buildQueryString(options.filters,
|
|
354
|
+
const qs = this.#buildQueryString(options.filters, "r");
|
|
349
355
|
if (qs !== null) {
|
|
350
356
|
query += qs.qstring;
|
|
351
357
|
values = qs.qparams;
|
|
@@ -371,7 +377,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
371
377
|
status: StatusCodes.OK,
|
|
372
378
|
detail: dbResponse,
|
|
373
379
|
operation: eOperations.GetResource,
|
|
374
|
-
options
|
|
380
|
+
options,
|
|
375
381
|
};
|
|
376
382
|
}
|
|
377
383
|
catch (error) {
|
|
@@ -390,10 +396,12 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
390
396
|
try {
|
|
391
397
|
let client;
|
|
392
398
|
if (options.useMultipleDatabases) {
|
|
393
|
-
client =
|
|
399
|
+
client =
|
|
400
|
+
(await this.#poolManager?.connectReadOnly());
|
|
394
401
|
}
|
|
395
402
|
else {
|
|
396
|
-
client =
|
|
403
|
+
client =
|
|
404
|
+
(await this.#poolManager?.connectReadWrite());
|
|
397
405
|
}
|
|
398
406
|
const retVal = await this.#__GetResource(client, options);
|
|
399
407
|
client.release();
|
|
@@ -409,7 +417,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
409
417
|
const values = [
|
|
410
418
|
options.filters?.dbactionuser,
|
|
411
419
|
options.filters?.resname,
|
|
412
|
-
JSON.stringify(resource)
|
|
420
|
+
JSON.stringify(resource),
|
|
413
421
|
];
|
|
414
422
|
try {
|
|
415
423
|
const { rows } = await client.query(createQuery, values);
|
|
@@ -419,11 +427,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
419
427
|
status: StatusCodes.OK,
|
|
420
428
|
detail: dbResponse,
|
|
421
429
|
operation,
|
|
422
|
-
options
|
|
430
|
+
options,
|
|
423
431
|
};
|
|
424
432
|
}
|
|
425
433
|
catch (error) {
|
|
426
|
-
if (error.code ===
|
|
434
|
+
if (error.code === "P0002") {
|
|
427
435
|
return this.#LogAndGetErrorMessage(options, StatusCodes.NOT_FOUND, eOperations.UpdateResource, `pgaccesslayer:__UpdateResource(): resourceid [${options.filters?.resname}] not found or not current. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
428
436
|
}
|
|
429
437
|
else {
|
|
@@ -437,20 +445,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
437
445
|
}
|
|
438
446
|
async UpdateResource(options, resource) {
|
|
439
447
|
try {
|
|
440
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
448
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
441
449
|
try {
|
|
442
|
-
await client.query(
|
|
450
|
+
await client.query("BEGIN");
|
|
443
451
|
const retVal = await this.#__UpdateResource(client, options, eOperations.UpdateResource, resource);
|
|
444
452
|
if (retVal.status === StatusCodes.OK) {
|
|
445
|
-
await client.query(
|
|
453
|
+
await client.query("COMMIT");
|
|
446
454
|
}
|
|
447
455
|
else {
|
|
448
|
-
await client.query(
|
|
456
|
+
await client.query("ROLLBACK");
|
|
449
457
|
}
|
|
450
458
|
return retVal;
|
|
451
459
|
}
|
|
452
460
|
catch (error) {
|
|
453
|
-
await client.query(
|
|
461
|
+
await client.query("ROLLBACK");
|
|
454
462
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.UpdateResource, `pgaccesslayer:UpdateResource(): Operation was not successful (__GetResource). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
455
463
|
}
|
|
456
464
|
finally {
|
|
@@ -463,28 +471,31 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
463
471
|
}
|
|
464
472
|
async PatchResource(options, resource) {
|
|
465
473
|
try {
|
|
466
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
474
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
467
475
|
try {
|
|
468
|
-
await client.query(
|
|
476
|
+
await client.query("BEGIN");
|
|
469
477
|
const currentResource = await this.#__GetResource(client, options);
|
|
470
478
|
if (currentResource.status === StatusCodes.OK) {
|
|
471
|
-
const updatedRecord = {
|
|
479
|
+
const updatedRecord = {
|
|
480
|
+
...currentResource.detail.resdesc,
|
|
481
|
+
...resource,
|
|
482
|
+
};
|
|
472
483
|
const retVal = await this.#__UpdateResource(client, options, eOperations.PatchResource, updatedRecord);
|
|
473
484
|
if (retVal.status === StatusCodes.OK) {
|
|
474
|
-
await client.query(
|
|
485
|
+
await client.query("COMMIT");
|
|
475
486
|
}
|
|
476
487
|
else {
|
|
477
|
-
await client.query(
|
|
488
|
+
await client.query("ROLLBACK");
|
|
478
489
|
}
|
|
479
490
|
return retVal;
|
|
480
491
|
}
|
|
481
492
|
else {
|
|
482
|
-
await client.query(
|
|
493
|
+
await client.query("ROLLBACK");
|
|
483
494
|
return currentResource;
|
|
484
495
|
}
|
|
485
496
|
}
|
|
486
497
|
catch (error) {
|
|
487
|
-
await client.query(
|
|
498
|
+
await client.query("ROLLBACK");
|
|
488
499
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.PatchResource, `pgaccesslayer:PatchResource(): Operation was not successful (__GetResource). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
489
500
|
}
|
|
490
501
|
finally {
|
|
@@ -497,75 +508,109 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
497
508
|
}
|
|
498
509
|
async #__UpdateOrPatchResources(resourceParameterRecords, mode, operation) {
|
|
499
510
|
try {
|
|
500
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
511
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
501
512
|
try {
|
|
502
|
-
await client.query(
|
|
513
|
+
await client.query("BEGIN");
|
|
503
514
|
const promArray = [];
|
|
504
|
-
resourceParameterRecords.forEach(rpr => {
|
|
515
|
+
resourceParameterRecords.forEach((rpr) => {
|
|
505
516
|
const UpdateRecordPromise = new Promise((resolve, reject) => {
|
|
506
|
-
if (mode === updateMode.updateResources ||
|
|
507
|
-
|
|
508
|
-
|
|
517
|
+
if (mode === updateMode.updateResources ||
|
|
518
|
+
mode === updateMode.patchResources ||
|
|
519
|
+
mode === updateMode.deleteResources) {
|
|
520
|
+
this.#__GetResource(client, rpr.opitons)
|
|
521
|
+
.then((currentResource) => {
|
|
522
|
+
if (currentResource.status ===
|
|
523
|
+
StatusCodes.OK) {
|
|
509
524
|
let updatedRecord;
|
|
510
525
|
switch (mode) {
|
|
511
526
|
case updateMode.patchResources:
|
|
512
|
-
updatedRecord = {
|
|
513
|
-
|
|
527
|
+
updatedRecord = {
|
|
528
|
+
...currentResource.detail.resdesc,
|
|
529
|
+
...rpr.resource,
|
|
530
|
+
};
|
|
531
|
+
this.#__UpdateResource(client, rpr.opitons, operation, updatedRecord)
|
|
532
|
+
.then((retVal) => resolve(retVal))
|
|
533
|
+
.catch((error) => reject(error));
|
|
514
534
|
break;
|
|
515
535
|
case updateMode.updateResources:
|
|
516
536
|
updatedRecord = rpr.resource;
|
|
517
|
-
this.#__UpdateResource(client, rpr.opitons, operation, updatedRecord)
|
|
537
|
+
this.#__UpdateResource(client, rpr.opitons, operation, updatedRecord)
|
|
538
|
+
.then((retVal) => resolve(retVal))
|
|
539
|
+
.catch((error) => reject(error));
|
|
518
540
|
break;
|
|
519
541
|
case updateMode.deleteResources:
|
|
520
|
-
this.#__DeleteResource(client, rpr.opitons, operation)
|
|
542
|
+
this.#__DeleteResource(client, rpr.opitons, operation)
|
|
543
|
+
.then((retVal) => resolve(retVal))
|
|
544
|
+
.catch((error) => reject(error));
|
|
521
545
|
break;
|
|
522
546
|
default:
|
|
523
547
|
reject(`pgaccesslayer:#__UpdateOrPatchResources(): Unknown mode (resource): [${mode}]`);
|
|
524
548
|
}
|
|
525
549
|
}
|
|
526
|
-
else if (currentResource.status ===
|
|
527
|
-
&&
|
|
528
|
-
|
|
550
|
+
else if (currentResource.status ===
|
|
551
|
+
StatusCodes.NOT_FOUND &&
|
|
552
|
+
mode ===
|
|
553
|
+
updateMode.updateResources &&
|
|
554
|
+
!rpr.opitons.errorOnBatchUpdate) {
|
|
529
555
|
const createNewResourceRecord = rpr.resource;
|
|
530
|
-
this.#__CreateResource(client, rpr.opitons, eOperations.UpdateResources, createNewResourceRecord)
|
|
556
|
+
this.#__CreateResource(client, rpr.opitons, eOperations.UpdateResources, createNewResourceRecord)
|
|
557
|
+
.then((retVal) => resolve(retVal))
|
|
558
|
+
.catch((error) => reject(error));
|
|
531
559
|
}
|
|
532
560
|
else {
|
|
533
561
|
resolve(currentResource);
|
|
534
562
|
}
|
|
535
|
-
})
|
|
563
|
+
})
|
|
564
|
+
.catch((error) => {
|
|
536
565
|
reject(error);
|
|
537
566
|
});
|
|
538
567
|
}
|
|
539
568
|
else {
|
|
540
|
-
this.#__GetEntity(client, rpr.opitons)
|
|
541
|
-
|
|
569
|
+
this.#__GetEntity(client, rpr.opitons)
|
|
570
|
+
.then((currentEntity) => {
|
|
571
|
+
if (currentEntity.status ===
|
|
572
|
+
StatusCodes.OK) {
|
|
542
573
|
let updatedRecord;
|
|
543
574
|
switch (mode) {
|
|
544
575
|
case updateMode.patchEntities:
|
|
545
|
-
updatedRecord = {
|
|
546
|
-
|
|
576
|
+
updatedRecord = {
|
|
577
|
+
...currentEntity.detail.entvalue,
|
|
578
|
+
...rpr.entity,
|
|
579
|
+
};
|
|
580
|
+
this.#__UpdateEntity(client, rpr.opitons, operation, updatedRecord)
|
|
581
|
+
.then((retVal) => resolve(retVal))
|
|
582
|
+
.catch((error) => reject(error));
|
|
547
583
|
break;
|
|
548
584
|
case updateMode.updateEntities:
|
|
549
585
|
updatedRecord = rpr.entity;
|
|
550
|
-
this.#__UpdateEntity(client, rpr.opitons, operation, updatedRecord)
|
|
586
|
+
this.#__UpdateEntity(client, rpr.opitons, operation, updatedRecord)
|
|
587
|
+
.then((retVal) => resolve(retVal))
|
|
588
|
+
.catch((error) => reject(error));
|
|
551
589
|
break;
|
|
552
590
|
case updateMode.deleteEntities:
|
|
553
|
-
this.#__DeleteEntity(client, rpr.opitons, operation)
|
|
591
|
+
this.#__DeleteEntity(client, rpr.opitons, operation)
|
|
592
|
+
.then((retVal) => resolve(retVal))
|
|
593
|
+
.catch((error) => reject(error));
|
|
554
594
|
break;
|
|
555
595
|
default:
|
|
556
596
|
reject(`pgaccesslayer:#__UpdateOrPatchResources(): Unknown mode (entity): [${mode}]`);
|
|
557
597
|
}
|
|
558
598
|
}
|
|
559
|
-
else if (currentEntity.status ===
|
|
560
|
-
&&
|
|
561
|
-
|
|
599
|
+
else if (currentEntity.status ===
|
|
600
|
+
StatusCodes.NOT_FOUND &&
|
|
601
|
+
mode ===
|
|
602
|
+
updateMode.updateEntities &&
|
|
603
|
+
!rpr.opitons.errorOnBatchUpdate) {
|
|
562
604
|
const createNewEntityRecord = rpr.entity;
|
|
563
|
-
this.#__CreateEntity(client, rpr.opitons, eOperations.UpdateEntities, createNewEntityRecord)
|
|
605
|
+
this.#__CreateEntity(client, rpr.opitons, eOperations.UpdateEntities, createNewEntityRecord)
|
|
606
|
+
.then((retVal) => resolve(retVal))
|
|
607
|
+
.catch((error) => reject(error));
|
|
564
608
|
}
|
|
565
609
|
else {
|
|
566
610
|
resolve(currentEntity);
|
|
567
611
|
}
|
|
568
|
-
})
|
|
612
|
+
})
|
|
613
|
+
.catch((error) => {
|
|
569
614
|
reject(error);
|
|
570
615
|
});
|
|
571
616
|
}
|
|
@@ -577,18 +622,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
577
622
|
promRetVal = await Promise.all(promArray);
|
|
578
623
|
}
|
|
579
624
|
catch (error) {
|
|
580
|
-
await client.query(
|
|
625
|
+
await client.query("ROLLBACK");
|
|
581
626
|
return this.#LogAndGetErrorMessage({}, StatusCodes.INTERNAL_SERVER_ERROR, operation, `pgaccesslayer:#__UpdateOrPatchResources(): Operation was not successful (Promise.all(promArray)). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
582
627
|
}
|
|
583
628
|
const retVal = {
|
|
584
629
|
status: StatusCodes.OK,
|
|
585
630
|
detail: [],
|
|
586
631
|
options: {},
|
|
587
|
-
operation: operation
|
|
632
|
+
operation: operation,
|
|
588
633
|
};
|
|
589
|
-
promRetVal.forEach(prv => {
|
|
590
|
-
if (!(prv.status === StatusCodes.OK ||
|
|
591
|
-
|
|
634
|
+
promRetVal.forEach((prv) => {
|
|
635
|
+
if (!(prv.status === StatusCodes.OK ||
|
|
636
|
+
prv.status === StatusCodes.CREATED)) {
|
|
637
|
+
if (retVal.status === StatusCodes.OK) {
|
|
638
|
+
// only set the first error
|
|
592
639
|
const message = `pgaccesslayer:#__UpdateOrPatchResources(): Operation was not successful. Check array for specific details.`;
|
|
593
640
|
retVal.status = StatusCodes.INTERNAL_SERVER_ERROR;
|
|
594
641
|
retVal.options = prv.options;
|
|
@@ -597,25 +644,25 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
597
644
|
error: new Error(message),
|
|
598
645
|
errorMessage: message,
|
|
599
646
|
operation: prv.operation,
|
|
600
|
-
status: StatusCodes.INTERNAL_SERVER_ERROR
|
|
647
|
+
status: StatusCodes.INTERNAL_SERVER_ERROR,
|
|
601
648
|
};
|
|
602
649
|
}
|
|
603
650
|
}
|
|
604
651
|
retVal.detail.push(prv);
|
|
605
652
|
});
|
|
606
653
|
if (retVal.status === StatusCodes.OK) {
|
|
607
|
-
await client.query(
|
|
654
|
+
await client.query("COMMIT");
|
|
608
655
|
}
|
|
609
656
|
else {
|
|
610
|
-
retVal.detail.forEach(detail => {
|
|
657
|
+
retVal.detail.forEach((detail) => {
|
|
611
658
|
detail.detail = null;
|
|
612
659
|
});
|
|
613
|
-
await client.query(
|
|
660
|
+
await client.query("ROLLBACK");
|
|
614
661
|
}
|
|
615
662
|
return retVal;
|
|
616
663
|
}
|
|
617
664
|
catch (error) {
|
|
618
|
-
await client.query(
|
|
665
|
+
await client.query("ROLLBACK");
|
|
619
666
|
return this.#LogAndGetErrorMessage({}, StatusCodes.INTERNAL_SERVER_ERROR, operation, `pgaccesslayer:__#UpdateOrPatchResources(): Operation was not successful (Promise processing). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
620
667
|
}
|
|
621
668
|
finally {
|
|
@@ -649,7 +696,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
649
696
|
const createQuery = `select * from delete_stsresource_latest($1, $2)`;
|
|
650
697
|
const values = [
|
|
651
698
|
options.filters?.dbactionuser,
|
|
652
|
-
options.filters?.resname
|
|
699
|
+
options.filters?.resname,
|
|
653
700
|
];
|
|
654
701
|
try {
|
|
655
702
|
const { rows } = await client.query(createQuery, values);
|
|
@@ -659,11 +706,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
659
706
|
status: StatusCodes.OK,
|
|
660
707
|
detail: dbResponse,
|
|
661
708
|
options,
|
|
662
|
-
operation
|
|
709
|
+
operation,
|
|
663
710
|
};
|
|
664
711
|
}
|
|
665
712
|
catch (error) {
|
|
666
|
-
if (error.code ===
|
|
713
|
+
if (error.code === "P0002") {
|
|
667
714
|
return this.#LogAndGetErrorMessage(options, StatusCodes.NOT_FOUND, eOperations.DeleteResource, `pgaccesslayer:DeleteResource(): resourceid [${options.filters?.resname}] not found or not current. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
668
715
|
}
|
|
669
716
|
else {
|
|
@@ -677,20 +724,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
677
724
|
}
|
|
678
725
|
async DeleteResource(options) {
|
|
679
726
|
try {
|
|
680
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
727
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
681
728
|
try {
|
|
682
|
-
await client.query(
|
|
729
|
+
await client.query("BEGIN");
|
|
683
730
|
const retVal = await this.#__DeleteResource(client, options, eOperations.DeleteResource);
|
|
684
731
|
if (retVal.status === StatusCodes.OK) {
|
|
685
|
-
await client.query(
|
|
732
|
+
await client.query("COMMIT");
|
|
686
733
|
}
|
|
687
734
|
else {
|
|
688
|
-
await client.query(
|
|
735
|
+
await client.query("ROLLBACK");
|
|
689
736
|
}
|
|
690
737
|
return retVal;
|
|
691
738
|
}
|
|
692
739
|
catch (error) {
|
|
693
|
-
await client.query(
|
|
740
|
+
await client.query("ROLLBACK");
|
|
694
741
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.DeleteResource, `pgaccesslayer:DeleteResource(): Operation was not successful (__GetResource). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
695
742
|
}
|
|
696
743
|
finally {
|
|
@@ -702,18 +749,18 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
702
749
|
}
|
|
703
750
|
}
|
|
704
751
|
async #__CreateEntity(client, options, operation, entity) {
|
|
705
|
-
const requiredFields = [
|
|
706
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
752
|
+
const requiredFields = ["dbactionuser", "resname", "entname"];
|
|
753
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
707
754
|
if (checkAllKeys) {
|
|
708
755
|
const createQuery = `select * from create_stsentity_latest($1, $2, $3, $4)`;
|
|
709
756
|
const values = [
|
|
710
757
|
options.filters?.dbactionuser,
|
|
711
758
|
options.filters?.resname,
|
|
712
759
|
options.filters?.entname,
|
|
713
|
-
JSON.stringify(entity)
|
|
760
|
+
JSON.stringify(entity),
|
|
714
761
|
];
|
|
715
762
|
try {
|
|
716
|
-
const { rows } =
|
|
763
|
+
const { rows } = await client.query(createQuery, values);
|
|
717
764
|
const dbResponse = rows[0];
|
|
718
765
|
// Convert the resourceoid to a string
|
|
719
766
|
dbResponse.resourceoid = dbResponse.resourceoid.toString();
|
|
@@ -722,11 +769,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
722
769
|
status: StatusCodes.CREATED,
|
|
723
770
|
detail: dbResponse,
|
|
724
771
|
options,
|
|
725
|
-
operation
|
|
772
|
+
operation,
|
|
726
773
|
};
|
|
727
774
|
}
|
|
728
775
|
catch (error) {
|
|
729
|
-
if (error.code ===
|
|
776
|
+
if (error.code === "23505") {
|
|
730
777
|
return this.#LogAndGetErrorMessage(options, StatusCodes.CONFLICT, eOperations.CreateEntity, `pgaccesslayer:CreateEntity(): entityid [${options.filters?.entname}] already exists. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
731
778
|
}
|
|
732
779
|
else {
|
|
@@ -740,20 +787,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
740
787
|
}
|
|
741
788
|
async CreateEntity(options, entity) {
|
|
742
789
|
try {
|
|
743
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
790
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
744
791
|
try {
|
|
745
|
-
await client.query(
|
|
792
|
+
await client.query("BEGIN");
|
|
746
793
|
const retVal = await this.#__CreateEntity(client, options, eOperations.CreateEntity, entity);
|
|
747
794
|
if (retVal.status === StatusCodes.CREATED) {
|
|
748
|
-
await client.query(
|
|
795
|
+
await client.query("COMMIT");
|
|
749
796
|
}
|
|
750
797
|
else {
|
|
751
|
-
await client.query(
|
|
798
|
+
await client.query("ROLLBACK");
|
|
752
799
|
}
|
|
753
800
|
return retVal;
|
|
754
801
|
}
|
|
755
802
|
catch (error) {
|
|
756
|
-
await client.query(
|
|
803
|
+
await client.query("ROLLBACK");
|
|
757
804
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.CreateEntity, `pgaccesslayer:CreateEntity(): Operation was not successful. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
758
805
|
}
|
|
759
806
|
finally {
|
|
@@ -766,15 +813,15 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
766
813
|
}
|
|
767
814
|
async #__GetEntity(client, options) {
|
|
768
815
|
try {
|
|
769
|
-
const requiredFields = [
|
|
770
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
816
|
+
const requiredFields = ["resname", "entname"];
|
|
817
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
771
818
|
if (checkAllKeys) {
|
|
772
|
-
let query =
|
|
819
|
+
let query = "select e.* from stsentity e join stsresource r on e.resourceoid = r.oid";
|
|
773
820
|
let values = [];
|
|
774
821
|
const qs = this.#buildQueryString({
|
|
775
822
|
resenddate: null,
|
|
776
|
-
...options.filters
|
|
777
|
-
},
|
|
823
|
+
...options.filters,
|
|
824
|
+
}, "e");
|
|
778
825
|
//let entityid = filters.entname;
|
|
779
826
|
if (qs !== null) {
|
|
780
827
|
query += qs.qstring;
|
|
@@ -797,7 +844,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
797
844
|
status: StatusCodes.OK,
|
|
798
845
|
detail: dbResponse,
|
|
799
846
|
options,
|
|
800
|
-
operation: eOperations.GetEntity
|
|
847
|
+
operation: eOperations.GetEntity,
|
|
801
848
|
};
|
|
802
849
|
}
|
|
803
850
|
catch (error) {
|
|
@@ -814,7 +861,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
814
861
|
}
|
|
815
862
|
async GetEntity(options) {
|
|
816
863
|
try {
|
|
817
|
-
const client = await this.#poolManager?.connectReadOnly();
|
|
864
|
+
const client = (await this.#poolManager?.connectReadOnly());
|
|
818
865
|
const retVal = await this.#__GetEntity(client, options);
|
|
819
866
|
client.release();
|
|
820
867
|
return retVal;
|
|
@@ -830,7 +877,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
830
877
|
options.filters?.dbactionuser,
|
|
831
878
|
options.filters?.resname,
|
|
832
879
|
options.filters?.entname,
|
|
833
|
-
JSON.stringify(entity)
|
|
880
|
+
JSON.stringify(entity),
|
|
834
881
|
];
|
|
835
882
|
try {
|
|
836
883
|
const { rows } = await client.query(createQuery, values);
|
|
@@ -842,11 +889,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
842
889
|
status: StatusCodes.OK,
|
|
843
890
|
detail: dbResponse,
|
|
844
891
|
options,
|
|
845
|
-
operation
|
|
892
|
+
operation,
|
|
846
893
|
};
|
|
847
894
|
}
|
|
848
895
|
catch (error) {
|
|
849
|
-
if (error.code ===
|
|
896
|
+
if (error.code === "P0002") {
|
|
850
897
|
return this.#LogAndGetErrorMessage(options, StatusCodes.NOT_FOUND, eOperations.UpdateEntity, `resname: [${options.filters?.resname}], entname: [${options.filters?.entname}] not found or not current. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
851
898
|
}
|
|
852
899
|
else {
|
|
@@ -860,20 +907,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
860
907
|
}
|
|
861
908
|
async UpdateEntity(options, entity) {
|
|
862
909
|
try {
|
|
863
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
910
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
864
911
|
try {
|
|
865
|
-
await client.query(
|
|
912
|
+
await client.query("BEGIN");
|
|
866
913
|
const retVal = await this.#__UpdateEntity(client, options, eOperations.UpdateEntity, entity);
|
|
867
914
|
if (retVal.status === StatusCodes.OK) {
|
|
868
|
-
await client.query(
|
|
915
|
+
await client.query("COMMIT");
|
|
869
916
|
}
|
|
870
917
|
else {
|
|
871
|
-
await client.query(
|
|
918
|
+
await client.query("ROLLBACK");
|
|
872
919
|
}
|
|
873
920
|
return retVal;
|
|
874
921
|
}
|
|
875
922
|
catch (error) {
|
|
876
|
-
await client.query(
|
|
923
|
+
await client.query("ROLLBACK");
|
|
877
924
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.UpdateEntity, `pgaccesslayer:GetEntity(): Operation was not successful (__GetEntity). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
878
925
|
}
|
|
879
926
|
finally {
|
|
@@ -886,28 +933,31 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
886
933
|
}
|
|
887
934
|
async PatchEntity(options, entity) {
|
|
888
935
|
try {
|
|
889
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
936
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
890
937
|
try {
|
|
891
|
-
await client.query(
|
|
938
|
+
await client.query("BEGIN");
|
|
892
939
|
const currentEntity = await this.#__GetEntity(client, options);
|
|
893
940
|
if (currentEntity.status === StatusCodes.OK) {
|
|
894
|
-
const updatedRecord = {
|
|
941
|
+
const updatedRecord = {
|
|
942
|
+
...currentEntity.detail.entvalue,
|
|
943
|
+
...entity,
|
|
944
|
+
};
|
|
895
945
|
const retVal = await this.#__UpdateEntity(client, options, eOperations.PatchEntity, updatedRecord);
|
|
896
946
|
if (retVal.status === StatusCodes.OK) {
|
|
897
|
-
await client.query(
|
|
947
|
+
await client.query("COMMIT");
|
|
898
948
|
}
|
|
899
949
|
else {
|
|
900
|
-
await client.query(
|
|
950
|
+
await client.query("ROLLBACK");
|
|
901
951
|
}
|
|
902
952
|
return retVal;
|
|
903
953
|
}
|
|
904
954
|
else {
|
|
905
|
-
await client.query(
|
|
955
|
+
await client.query("ROLLBACK");
|
|
906
956
|
return currentEntity;
|
|
907
957
|
}
|
|
908
958
|
}
|
|
909
959
|
catch (error) {
|
|
910
|
-
await client.query(
|
|
960
|
+
await client.query("ROLLBACK");
|
|
911
961
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.PatchEntity, `pgaccesslayer:PatchEntity(): Operation was not successful (__GetEntity). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
912
962
|
}
|
|
913
963
|
finally {
|
|
@@ -924,7 +974,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
924
974
|
const values = [
|
|
925
975
|
options.filters?.dbactionuser,
|
|
926
976
|
options.filters?.resname,
|
|
927
|
-
options.filters?.entname
|
|
977
|
+
options.filters?.entname,
|
|
928
978
|
];
|
|
929
979
|
try {
|
|
930
980
|
const { rows } = await client.query(createQuery, values);
|
|
@@ -936,11 +986,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
936
986
|
status: StatusCodes.OK,
|
|
937
987
|
detail: dbResponse,
|
|
938
988
|
options,
|
|
939
|
-
operation
|
|
989
|
+
operation,
|
|
940
990
|
};
|
|
941
991
|
}
|
|
942
992
|
catch (error) {
|
|
943
|
-
if (error.code ===
|
|
993
|
+
if (error.code === "P0002") {
|
|
944
994
|
return this.#LogAndGetErrorMessage(options, StatusCodes.NOT_FOUND, eOperations.DeleteEntity, `resname: [${options.filters?.resname}], entname: [${options.filters?.entname}] not found or not current. Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
945
995
|
}
|
|
946
996
|
else {
|
|
@@ -954,20 +1004,20 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
954
1004
|
}
|
|
955
1005
|
async DeleteEntity(options) {
|
|
956
1006
|
try {
|
|
957
|
-
const client = await this.#poolManager?.connectReadWrite();
|
|
1007
|
+
const client = (await this.#poolManager?.connectReadWrite());
|
|
958
1008
|
try {
|
|
959
|
-
await client.query(
|
|
1009
|
+
await client.query("BEGIN");
|
|
960
1010
|
const retVal = await this.#__DeleteEntity(client, options, eOperations.DeleteEntity);
|
|
961
1011
|
if (retVal.status === StatusCodes.OK) {
|
|
962
|
-
await client.query(
|
|
1012
|
+
await client.query("COMMIT");
|
|
963
1013
|
}
|
|
964
1014
|
else {
|
|
965
|
-
await client.query(
|
|
1015
|
+
await client.query("ROLLBACK");
|
|
966
1016
|
}
|
|
967
1017
|
return retVal;
|
|
968
1018
|
}
|
|
969
1019
|
catch (error) {
|
|
970
|
-
await client.query(
|
|
1020
|
+
await client.query("ROLLBACK");
|
|
971
1021
|
return this.#LogAndGetErrorMessage(options, StatusCodes.INTERNAL_SERVER_ERROR, eOperations.DeleteEntity, `pgaccesslayer:DeleteEntity(): Operation was not successful (__GetEntity). Error: [${this.#ToErrorWithMessage(error).message}]`);
|
|
972
1022
|
}
|
|
973
1023
|
finally {
|
|
@@ -979,11 +1029,11 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
979
1029
|
}
|
|
980
1030
|
}
|
|
981
1031
|
async GetResources(options) {
|
|
982
|
-
const useOptions =
|
|
1032
|
+
const useOptions = options ? options : {};
|
|
983
1033
|
try {
|
|
984
|
-
let query =
|
|
1034
|
+
let query = "select r.* from stsresource r";
|
|
985
1035
|
let values = [];
|
|
986
|
-
const qs = this.#buildQueryString((options ? options.filters : {}),
|
|
1036
|
+
const qs = this.#buildQueryString((options ? options.filters : {}), "r");
|
|
987
1037
|
if (qs !== null) {
|
|
988
1038
|
query += qs.qstring;
|
|
989
1039
|
values = qs.qparams;
|
|
@@ -992,21 +1042,21 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
992
1042
|
if (options && options.filters && options.filters.limit) {
|
|
993
1043
|
query += ` limit ${options.filters.limit}`;
|
|
994
1044
|
}
|
|
995
|
-
const client = await this.#poolManager?.connectReadOnly();
|
|
1045
|
+
const client = (await this.#poolManager?.connectReadOnly());
|
|
996
1046
|
try {
|
|
997
1047
|
//const start = performance.now();
|
|
998
1048
|
const { rows } = await client.query(query, values);
|
|
999
1049
|
const dbResponse = rows;
|
|
1000
1050
|
//const end = performance.now();
|
|
1001
1051
|
//console.log(chalk.green(`QQQ: [${query}] [${values}] ${end - start}`));
|
|
1002
|
-
dbResponse.forEach(r => {
|
|
1052
|
+
dbResponse.forEach((r) => {
|
|
1003
1053
|
r.resdesc = this.#JSONParse(r.resdesc);
|
|
1004
1054
|
});
|
|
1005
1055
|
return {
|
|
1006
1056
|
status: StatusCodes.OK,
|
|
1007
1057
|
detail: dbResponse,
|
|
1008
1058
|
options: useOptions,
|
|
1009
|
-
operation: eOperations.GetResources
|
|
1059
|
+
operation: eOperations.GetResources,
|
|
1010
1060
|
};
|
|
1011
1061
|
}
|
|
1012
1062
|
catch (error) {
|
|
@@ -1022,15 +1072,17 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1022
1072
|
}
|
|
1023
1073
|
async GetEntities(options) {
|
|
1024
1074
|
try {
|
|
1025
|
-
const requiredFields = [
|
|
1026
|
-
const checkAllKeys = requiredFields.every(f => Object.hasOwn(options.filters, f));
|
|
1075
|
+
const requiredFields = ["resname"];
|
|
1076
|
+
const checkAllKeys = requiredFields.every((f) => Object.hasOwn(options.filters, f));
|
|
1027
1077
|
if (checkAllKeys) {
|
|
1028
1078
|
let query = `select e.* from stsentity e join stsresource r on e.resourceoid = r.oid`;
|
|
1029
1079
|
let values = [];
|
|
1030
|
-
const qs = this.#buildQueryString((options
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1080
|
+
const qs = this.#buildQueryString((options
|
|
1081
|
+
? {
|
|
1082
|
+
resenddate: null,
|
|
1083
|
+
...options.filters,
|
|
1084
|
+
}
|
|
1085
|
+
: {}), "e");
|
|
1034
1086
|
if (qs !== null) {
|
|
1035
1087
|
query += qs.qstring;
|
|
1036
1088
|
values = qs.qparams;
|
|
@@ -1039,14 +1091,14 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1039
1091
|
if (options && options.filters && options.filters.limit) {
|
|
1040
1092
|
query += ` limit ${options.filters.limit}`;
|
|
1041
1093
|
}
|
|
1042
|
-
const client = await this.#poolManager?.connectReadOnly();
|
|
1094
|
+
const client = (await this.#poolManager?.connectReadOnly());
|
|
1043
1095
|
try {
|
|
1044
1096
|
//const start = performance.now();
|
|
1045
1097
|
const { rows } = await client.query(query, values);
|
|
1046
1098
|
const dbResponse = rows;
|
|
1047
1099
|
//const end = performance.now();
|
|
1048
1100
|
//console.log(chalk.green(`YYY: [${query}] [${values}] ${end - start}`));
|
|
1049
|
-
dbResponse.forEach(r => {
|
|
1101
|
+
dbResponse.forEach((r) => {
|
|
1050
1102
|
// Convert the resourceoid to a string
|
|
1051
1103
|
r.resourceoid = r.resourceoid.toString();
|
|
1052
1104
|
r.entvalue = this.#JSONParse(r.entvalue);
|
|
@@ -1055,7 +1107,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1055
1107
|
status: StatusCodes.OK,
|
|
1056
1108
|
detail: dbResponse,
|
|
1057
1109
|
options,
|
|
1058
|
-
operation: eOperations.GetEntities
|
|
1110
|
+
operation: eOperations.GetEntities,
|
|
1059
1111
|
};
|
|
1060
1112
|
}
|
|
1061
1113
|
catch (error) {
|
|
@@ -1075,14 +1127,14 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1075
1127
|
}
|
|
1076
1128
|
async #__SearchResources(client, options, searchOptions) {
|
|
1077
1129
|
try {
|
|
1078
|
-
const useOptions =
|
|
1079
|
-
let paramList =
|
|
1080
|
-
let paramSep =
|
|
1130
|
+
const useOptions = options ? options : {};
|
|
1131
|
+
let paramList = "(";
|
|
1132
|
+
let paramSep = "";
|
|
1081
1133
|
for (let i = 0; i < Object.values(searchOptions.searchParameters).length; i++) {
|
|
1082
|
-
paramList = paramList + paramSep +
|
|
1083
|
-
paramSep =
|
|
1134
|
+
paramList = paramList + paramSep + "$" + (i + 1).toString();
|
|
1135
|
+
paramSep = ", ";
|
|
1084
1136
|
}
|
|
1085
|
-
paramList = paramList +
|
|
1137
|
+
paramList = paramList + ")";
|
|
1086
1138
|
let query = `select * from ${searchOptions.queryFunctionName}${paramList}`;
|
|
1087
1139
|
let values = Object.values(searchOptions.searchParameters);
|
|
1088
1140
|
try {
|
|
@@ -1090,10 +1142,10 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1090
1142
|
let dbResponse;
|
|
1091
1143
|
if (searchOptions.returnsResourceList === true) {
|
|
1092
1144
|
dbResponse = rows;
|
|
1093
|
-
dbResponse.forEach(r => {
|
|
1145
|
+
dbResponse.forEach((r) => {
|
|
1094
1146
|
try {
|
|
1095
1147
|
r.resdesc = this.#JSONParse(r.resdesc);
|
|
1096
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1148
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1097
1149
|
}
|
|
1098
1150
|
catch (error) {
|
|
1099
1151
|
// Do nothing
|
|
@@ -1107,7 +1159,7 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1107
1159
|
status: StatusCodes.OK,
|
|
1108
1160
|
detail: dbResponse,
|
|
1109
1161
|
options: useOptions,
|
|
1110
|
-
operation: eOperations.GetResources
|
|
1162
|
+
operation: eOperations.GetResources,
|
|
1111
1163
|
};
|
|
1112
1164
|
}
|
|
1113
1165
|
catch (error) {
|
|
@@ -1122,10 +1174,12 @@ export class PGAccessLayer extends TinyEmitter {
|
|
|
1122
1174
|
try {
|
|
1123
1175
|
let client;
|
|
1124
1176
|
if (options.useMultipleDatabases) {
|
|
1125
|
-
client =
|
|
1177
|
+
client =
|
|
1178
|
+
(await this.#poolManager?.connectReadOnly());
|
|
1126
1179
|
}
|
|
1127
1180
|
else {
|
|
1128
|
-
client =
|
|
1181
|
+
client =
|
|
1182
|
+
(await this.#poolManager?.connectReadWrite());
|
|
1129
1183
|
}
|
|
1130
1184
|
const retVal = await this.#__SearchResources(client, options, searchOptions);
|
|
1131
1185
|
client.release();
|