@nymphjs/driver-postgresql 1.0.0-beta.0 → 1.0.0-beta.2
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/CHANGELOG.md +10 -0
- package/dist/PostgreSQLDriver.js +536 -589
- package/dist/PostgreSQLDriver.js.map +1 -1
- package/dist/PostgreSQLDriver.test.js +3 -12
- package/dist/PostgreSQLDriver.test.js.map +1 -1
- package/package.json +4 -4
- package/tsconfig.json +2 -0
package/dist/PostgreSQLDriver.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -29,9 +20,9 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
29
20
|
super();
|
|
30
21
|
this.connected = false;
|
|
31
22
|
this.transaction = null;
|
|
32
|
-
this.config =
|
|
23
|
+
this.config = { ...conf_1.PostgreSQLDriverConfigDefaults, ...config };
|
|
33
24
|
const { host, user, password, database, port, customPoolConfig } = this.config;
|
|
34
|
-
this.postgresqlConfig = customPoolConfig
|
|
25
|
+
this.postgresqlConfig = customPoolConfig ?? {
|
|
35
26
|
host,
|
|
36
27
|
user,
|
|
37
28
|
password,
|
|
@@ -56,56 +47,50 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
56
47
|
}
|
|
57
48
|
return new Promise((resolve, reject) => this.link.connect((err, client, done) => err ? reject(err) : resolve({ client, done })));
|
|
58
49
|
}
|
|
59
|
-
connect() {
|
|
60
|
-
|
|
50
|
+
async connect() {
|
|
51
|
+
try {
|
|
52
|
+
if (this.connected) {
|
|
53
|
+
const connection = await new Promise((resolve, reject) => this.link.connect((err, client, done) => err ? reject(err) : resolve({ client, done })));
|
|
54
|
+
await new Promise((resolve, reject) => connection.client.query('SELECT 1;', [], (err, res) => {
|
|
55
|
+
if (err) {
|
|
56
|
+
reject(err);
|
|
57
|
+
}
|
|
58
|
+
resolve(0);
|
|
59
|
+
}));
|
|
60
|
+
connection.done();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
this.connected = false;
|
|
65
|
+
}
|
|
66
|
+
if (!this.connected) {
|
|
61
67
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
yield new Promise((resolve, reject) => connection.client.query('SELECT 1;', [], (err, res) => {
|
|
65
|
-
if (err) {
|
|
66
|
-
reject(err);
|
|
67
|
-
}
|
|
68
|
-
resolve(0);
|
|
69
|
-
}));
|
|
70
|
-
connection.done();
|
|
71
|
-
}
|
|
68
|
+
this.link = new pg_1.Pool(this.postgresqlConfig);
|
|
69
|
+
this.connected = true;
|
|
72
70
|
}
|
|
73
71
|
catch (e) {
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.connected = true;
|
|
72
|
+
if (this.postgresqlConfig.host === 'localhost' &&
|
|
73
|
+
this.postgresqlConfig.user === 'nymph' &&
|
|
74
|
+
this.postgresqlConfig.password === 'password' &&
|
|
75
|
+
this.postgresqlConfig.database === 'nymph') {
|
|
76
|
+
throw new nymph_1.NotConfiguredError("It seems the config hasn't been set up correctly.");
|
|
80
77
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.postgresqlConfig.user === 'nymph' &&
|
|
84
|
-
this.postgresqlConfig.password === 'password' &&
|
|
85
|
-
this.postgresqlConfig.database === 'nymph') {
|
|
86
|
-
throw new nymph_1.NotConfiguredError("It seems the config hasn't been set up correctly.");
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
throw new nymph_1.UnableToConnectError('Could not connect: ' + (e === null || e === void 0 ? void 0 : e.message));
|
|
90
|
-
}
|
|
78
|
+
else {
|
|
79
|
+
throw new nymph_1.UnableToConnectError('Could not connect: ' + e?.message);
|
|
91
80
|
}
|
|
92
81
|
}
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
}
|
|
83
|
+
return this.connected;
|
|
95
84
|
}
|
|
96
|
-
disconnect() {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return this.connected;
|
|
103
|
-
});
|
|
85
|
+
async disconnect() {
|
|
86
|
+
if (this.connected) {
|
|
87
|
+
await new Promise((resolve) => this.link.end(() => resolve(0)));
|
|
88
|
+
this.connected = false;
|
|
89
|
+
}
|
|
90
|
+
return this.connected;
|
|
104
91
|
}
|
|
105
|
-
inTransaction() {
|
|
106
|
-
return
|
|
107
|
-
return !!this.transaction;
|
|
108
|
-
});
|
|
92
|
+
async inTransaction() {
|
|
93
|
+
return !!this.transaction;
|
|
109
94
|
}
|
|
110
95
|
isConnected() {
|
|
111
96
|
return this.connected;
|
|
@@ -201,36 +186,34 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
201
186
|
}
|
|
202
187
|
return { query, params };
|
|
203
188
|
}
|
|
204
|
-
query(runQuery, query, etypes = []) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.createTables(etype);
|
|
214
|
-
}
|
|
215
|
-
try {
|
|
216
|
-
return yield runQuery();
|
|
217
|
-
}
|
|
218
|
-
catch (e2) {
|
|
219
|
-
throw new nymph_1.QueryFailedError('Query failed: ' + (e2 === null || e2 === void 0 ? void 0 : e2.code) + ' - ' + (e2 === null || e2 === void 0 ? void 0 : e2.message), query);
|
|
220
|
-
}
|
|
189
|
+
async query(runQuery, query, etypes = []) {
|
|
190
|
+
try {
|
|
191
|
+
return await runQuery();
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
const errorCode = e?.code;
|
|
195
|
+
if (errorCode === '42P01' && this.createTables()) {
|
|
196
|
+
for (let etype of etypes) {
|
|
197
|
+
this.createTables(etype);
|
|
221
198
|
}
|
|
222
|
-
|
|
223
|
-
|
|
199
|
+
try {
|
|
200
|
+
return await runQuery();
|
|
201
|
+
}
|
|
202
|
+
catch (e2) {
|
|
203
|
+
throw new nymph_1.QueryFailedError('Query failed: ' + e2?.code + ' - ' + e2?.message, query);
|
|
224
204
|
}
|
|
225
205
|
}
|
|
226
|
-
|
|
206
|
+
else {
|
|
207
|
+
throw e;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
227
210
|
}
|
|
228
211
|
querySync(runQuery, query, etypes = []) {
|
|
229
212
|
try {
|
|
230
213
|
return runQuery();
|
|
231
214
|
}
|
|
232
215
|
catch (e) {
|
|
233
|
-
const errorCode = e
|
|
216
|
+
const errorCode = e?.code;
|
|
234
217
|
if (errorCode === '42P01' && this.createTables()) {
|
|
235
218
|
for (let etype of etypes) {
|
|
236
219
|
this.createTables(etype);
|
|
@@ -239,7 +222,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
239
222
|
return runQuery();
|
|
240
223
|
}
|
|
241
224
|
catch (e2) {
|
|
242
|
-
throw new nymph_1.QueryFailedError('Query failed: ' +
|
|
225
|
+
throw new nymph_1.QueryFailedError('Query failed: ' + e2?.code + ' - ' + e2?.message, query);
|
|
243
226
|
}
|
|
244
227
|
}
|
|
245
228
|
else {
|
|
@@ -249,11 +232,10 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
249
232
|
}
|
|
250
233
|
queryIter(query, { etypes = [], params = {}, } = {}) {
|
|
251
234
|
const { query: newQuery, params: newParams } = this.translateQuery(query, params);
|
|
252
|
-
return this.query(() =>
|
|
253
|
-
const results =
|
|
254
|
-
var _a, _b, _c;
|
|
235
|
+
return this.query(async () => {
|
|
236
|
+
const results = await new Promise((resolve, reject) => {
|
|
255
237
|
try {
|
|
256
|
-
(
|
|
238
|
+
(this.transaction?.connection?.client ?? this.link)
|
|
257
239
|
.query(newQuery, newParams)
|
|
258
240
|
.then((results) => resolve(results), (error) => reject(error));
|
|
259
241
|
}
|
|
@@ -262,7 +244,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
262
244
|
}
|
|
263
245
|
});
|
|
264
246
|
return results.rows;
|
|
265
|
-
}
|
|
247
|
+
}, `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
266
248
|
}
|
|
267
249
|
queryIterSync(query, { etypes = [], params = {}, } = {}) {
|
|
268
250
|
const { query: newQuery, params: newParams } = this.translateQuery(query, params);
|
|
@@ -295,11 +277,10 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
295
277
|
}
|
|
296
278
|
queryGet(query, { etypes = [], params = {}, } = {}) {
|
|
297
279
|
const { query: newQuery, params: newParams } = this.translateQuery(query, params);
|
|
298
|
-
return this.query(() =>
|
|
299
|
-
const results =
|
|
300
|
-
var _a, _b, _c;
|
|
280
|
+
return this.query(async () => {
|
|
281
|
+
const results = await new Promise((resolve, reject) => {
|
|
301
282
|
try {
|
|
302
|
-
(
|
|
283
|
+
(this.transaction?.connection?.client ?? this.link)
|
|
303
284
|
.query(newQuery, newParams)
|
|
304
285
|
.then((results) => resolve(results), (error) => reject(error));
|
|
305
286
|
}
|
|
@@ -308,16 +289,14 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
308
289
|
}
|
|
309
290
|
});
|
|
310
291
|
return results.rows[0];
|
|
311
|
-
}
|
|
292
|
+
}, `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
312
293
|
}
|
|
313
294
|
queryRun(query, { etypes = [], params = {}, } = {}) {
|
|
314
295
|
const { query: newQuery, params: newParams } = this.translateQuery(query, params);
|
|
315
|
-
return this.query(() =>
|
|
316
|
-
|
|
317
|
-
const results = yield new Promise((resolve, reject) => {
|
|
318
|
-
var _a, _b, _c;
|
|
296
|
+
return this.query(async () => {
|
|
297
|
+
const results = await new Promise((resolve, reject) => {
|
|
319
298
|
try {
|
|
320
|
-
(
|
|
299
|
+
(this.transaction?.connection?.client ?? this.link)
|
|
321
300
|
.query(newQuery, newParams)
|
|
322
301
|
.then((results) => resolve(results), (error) => reject(error));
|
|
323
302
|
}
|
|
@@ -325,13 +304,12 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
325
304
|
reject(e);
|
|
326
305
|
}
|
|
327
306
|
});
|
|
328
|
-
return { rowCount:
|
|
329
|
-
}
|
|
307
|
+
return { rowCount: results.rowCount ?? 0 };
|
|
308
|
+
}, `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
330
309
|
}
|
|
331
310
|
queryRunSync(query, { etypes = [], params = {}, } = {}) {
|
|
332
311
|
const { query: newQuery, params: newParams } = this.translateQuery(query, params);
|
|
333
312
|
return this.querySync(() => {
|
|
334
|
-
var _a;
|
|
335
313
|
const output = child_process_1.default.spawnSync(process.argv0, [__dirname + '/runPostgresqlSync.js'], {
|
|
336
314
|
input: JSON.stringify({
|
|
337
315
|
postgresqlConfig: this.postgresqlConfig,
|
|
@@ -345,7 +323,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
345
323
|
});
|
|
346
324
|
try {
|
|
347
325
|
const results = JSON.parse(output.stdout);
|
|
348
|
-
return { rowCount:
|
|
326
|
+
return { rowCount: results.rowCount ?? 0 };
|
|
349
327
|
}
|
|
350
328
|
catch (e) {
|
|
351
329
|
}
|
|
@@ -359,155 +337,145 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
359
337
|
}
|
|
360
338
|
}, `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
361
339
|
}
|
|
362
|
-
commit(name) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (!this.transaction || this.transaction.count === 0) {
|
|
369
|
-
this.transaction = null;
|
|
370
|
-
return true;
|
|
371
|
-
}
|
|
372
|
-
yield this.queryRun(`RELEASE SAVEPOINT ${PostgreSQLDriver.escape(name)};`);
|
|
373
|
-
this.transaction.count--;
|
|
374
|
-
if (this.transaction.count === 0) {
|
|
375
|
-
yield this.queryRun('COMMIT;');
|
|
376
|
-
(_a = this.transaction.connection) === null || _a === void 0 ? void 0 : _a.done();
|
|
377
|
-
this.transaction.connection = null;
|
|
378
|
-
this.transaction = null;
|
|
379
|
-
}
|
|
340
|
+
async commit(name) {
|
|
341
|
+
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
342
|
+
throw new nymph_1.InvalidParametersError('Transaction commit attempted without a name.');
|
|
343
|
+
}
|
|
344
|
+
if (!this.transaction || this.transaction.count === 0) {
|
|
345
|
+
this.transaction = null;
|
|
380
346
|
return true;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
EntityClass = className;
|
|
392
|
-
}
|
|
393
|
-
const etype = EntityClass.ETYPE;
|
|
394
|
-
yield this.internalTransaction('nymph-delete');
|
|
395
|
-
try {
|
|
396
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
397
|
-
etypes: [etype],
|
|
398
|
-
params: {
|
|
399
|
-
guid,
|
|
400
|
-
},
|
|
401
|
-
});
|
|
402
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
403
|
-
etypes: [etype],
|
|
404
|
-
params: {
|
|
405
|
-
guid,
|
|
406
|
-
},
|
|
407
|
-
});
|
|
408
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
409
|
-
etypes: [etype],
|
|
410
|
-
params: {
|
|
411
|
-
guid,
|
|
412
|
-
},
|
|
413
|
-
});
|
|
414
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
415
|
-
etypes: [etype],
|
|
416
|
-
params: {
|
|
417
|
-
guid,
|
|
418
|
-
},
|
|
419
|
-
});
|
|
420
|
-
yield this.commit('nymph-delete');
|
|
421
|
-
if (this.nymph.config.cache) {
|
|
422
|
-
this.cleanCache(guid);
|
|
423
|
-
}
|
|
424
|
-
return true;
|
|
425
|
-
}
|
|
426
|
-
catch (e) {
|
|
427
|
-
yield this.rollback('nymph-delete');
|
|
428
|
-
throw e;
|
|
429
|
-
}
|
|
430
|
-
});
|
|
347
|
+
}
|
|
348
|
+
await this.queryRun(`RELEASE SAVEPOINT ${PostgreSQLDriver.escape(name)};`);
|
|
349
|
+
this.transaction.count--;
|
|
350
|
+
if (this.transaction.count === 0) {
|
|
351
|
+
await this.queryRun('COMMIT;');
|
|
352
|
+
this.transaction.connection?.done();
|
|
353
|
+
this.transaction.connection = null;
|
|
354
|
+
this.transaction = null;
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
431
357
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
358
|
+
async deleteEntityByID(guid, className) {
|
|
359
|
+
let EntityClass;
|
|
360
|
+
if (typeof className === 'string' || className == null) {
|
|
361
|
+
const GetEntityClass = this.nymph.getEntityClass(className ?? 'Entity');
|
|
362
|
+
EntityClass = GetEntityClass;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
EntityClass = className;
|
|
366
|
+
}
|
|
367
|
+
const etype = EntityClass.ETYPE;
|
|
368
|
+
await this.internalTransaction('nymph-delete');
|
|
369
|
+
try {
|
|
370
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
371
|
+
etypes: [etype],
|
|
438
372
|
params: {
|
|
439
|
-
|
|
373
|
+
guid,
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
377
|
+
etypes: [etype],
|
|
378
|
+
params: {
|
|
379
|
+
guid,
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
383
|
+
etypes: [etype],
|
|
384
|
+
params: {
|
|
385
|
+
guid,
|
|
440
386
|
},
|
|
441
387
|
});
|
|
388
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
389
|
+
etypes: [etype],
|
|
390
|
+
params: {
|
|
391
|
+
guid,
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
await this.commit('nymph-delete');
|
|
395
|
+
if (this.nymph.config.cache) {
|
|
396
|
+
this.cleanCache(guid);
|
|
397
|
+
}
|
|
442
398
|
return true;
|
|
399
|
+
}
|
|
400
|
+
catch (e) {
|
|
401
|
+
await this.rollback('nymph-delete');
|
|
402
|
+
throw e;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async deleteUID(name) {
|
|
406
|
+
if (!name) {
|
|
407
|
+
throw new nymph_1.InvalidParametersError('Name not given for UID');
|
|
408
|
+
}
|
|
409
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
410
|
+
params: {
|
|
411
|
+
name,
|
|
412
|
+
},
|
|
443
413
|
});
|
|
414
|
+
return true;
|
|
444
415
|
}
|
|
445
|
-
exportEntities(writeLine) {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
etypes.push(table.substr((this.prefix + 'entities_').length));
|
|
472
|
-
}
|
|
416
|
+
async exportEntities(writeLine) {
|
|
417
|
+
writeLine('#nex2');
|
|
418
|
+
writeLine('# Nymph Entity Exchange v2');
|
|
419
|
+
writeLine('# http://nymph.io');
|
|
420
|
+
writeLine('#');
|
|
421
|
+
writeLine('# Generation Time: ' + new Date().toLocaleString());
|
|
422
|
+
writeLine('');
|
|
423
|
+
writeLine('#');
|
|
424
|
+
writeLine('# UIDs');
|
|
425
|
+
writeLine('#');
|
|
426
|
+
writeLine('');
|
|
427
|
+
let uids = await this.queryIter(`SELECT * FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} ORDER BY "name";`);
|
|
428
|
+
for (const uid of uids) {
|
|
429
|
+
writeLine(`<${uid.name}>[${uid.cur_uid}]`);
|
|
430
|
+
}
|
|
431
|
+
writeLine('');
|
|
432
|
+
writeLine('#');
|
|
433
|
+
writeLine('# Entities');
|
|
434
|
+
writeLine('#');
|
|
435
|
+
writeLine('');
|
|
436
|
+
const tables = await this.queryIter('SELECT relname FROM pg_stat_user_tables ORDER BY relname;');
|
|
437
|
+
const etypes = [];
|
|
438
|
+
for (const tableRow of tables) {
|
|
439
|
+
const table = tableRow.relname;
|
|
440
|
+
if (table.startsWith(this.prefix + 'entities_')) {
|
|
441
|
+
etypes.push(table.substr((this.prefix + 'entities_').length));
|
|
473
442
|
}
|
|
474
|
-
|
|
475
|
-
|
|
443
|
+
}
|
|
444
|
+
for (const etype of etypes) {
|
|
445
|
+
const dataIterator = (await this.queryIter(`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", d."name" AS "dname", d."value" AS "dvalue", c."string", c."number"
|
|
476
446
|
FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} e
|
|
477
447
|
LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} d ON e."guid"=d."guid"
|
|
478
448
|
INNER JOIN ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} c ON d."guid"=c."guid" AND d."name"=c."name"
|
|
479
449
|
ORDER BY e."guid";`))[Symbol.iterator]();
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
datum = dataIterator.next();
|
|
498
|
-
} while (!datum.done && datum.value.guid === guid);
|
|
499
|
-
}
|
|
500
|
-
else {
|
|
450
|
+
let datum = dataIterator.next();
|
|
451
|
+
while (!datum.done) {
|
|
452
|
+
const guid = datum.value.guid;
|
|
453
|
+
const tags = datum.value.tags.join(',');
|
|
454
|
+
const cdate = datum.value.cdate;
|
|
455
|
+
const mdate = datum.value.mdate;
|
|
456
|
+
writeLine(`{${guid}}<${etype}>[${tags}]`);
|
|
457
|
+
writeLine(`\tcdate=${JSON.stringify(cdate)}`);
|
|
458
|
+
writeLine(`\tmdate=${JSON.stringify(mdate)}`);
|
|
459
|
+
if (datum.value.dname != null) {
|
|
460
|
+
do {
|
|
461
|
+
const value = datum.value.dvalue === 'N'
|
|
462
|
+
? JSON.stringify(Number(datum.value.number))
|
|
463
|
+
: datum.value.dvalue === 'S'
|
|
464
|
+
? JSON.stringify(datum.value.string)
|
|
465
|
+
: datum.value.dvalue;
|
|
466
|
+
writeLine(`\t${datum.value.dname}=${value}`);
|
|
501
467
|
datum = dataIterator.next();
|
|
502
|
-
}
|
|
468
|
+
} while (!datum.done && datum.value.guid === guid);
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
datum = dataIterator.next();
|
|
503
472
|
}
|
|
504
473
|
}
|
|
505
|
-
|
|
506
|
-
|
|
474
|
+
}
|
|
475
|
+
return;
|
|
507
476
|
}
|
|
508
477
|
makeEntityQuery(options, formattedSelectors, etype, count = { i: 0 }, params = {}, subquery = false, tableSuffix = '', etypes = []) {
|
|
509
|
-
|
|
510
|
-
if (typeof ((_a = options.class) === null || _a === void 0 ? void 0 : _a.alterOptions) === 'function') {
|
|
478
|
+
if (typeof options.class?.alterOptions === 'function') {
|
|
511
479
|
options = options.class.alterOptions(options);
|
|
512
480
|
}
|
|
513
481
|
const eTable = `e${tableSuffix}`;
|
|
@@ -516,7 +484,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
516
484
|
const fTable = `f${tableSuffix}`;
|
|
517
485
|
const ieTable = `ie${tableSuffix}`;
|
|
518
486
|
const countTable = `count${tableSuffix}`;
|
|
519
|
-
const sort =
|
|
487
|
+
const sort = options.sort ?? 'cdate';
|
|
520
488
|
const queryParts = this.iterateSelectorsForQuery(formattedSelectors, (key, value, typeIsOr, typeIsNot) => {
|
|
521
489
|
const clauseNot = key.startsWith('!');
|
|
522
490
|
let curQuery = '';
|
|
@@ -1265,7 +1233,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
1265
1233
|
const [qrefOptions, ...qrefSelectors] = curValue[1];
|
|
1266
1234
|
const QrefEntityClass = qrefOptions.class;
|
|
1267
1235
|
etypes.push(QrefEntityClass.ETYPE);
|
|
1268
|
-
const qrefQuery = this.makeEntityQuery(
|
|
1236
|
+
const qrefQuery = this.makeEntityQuery({ ...qrefOptions, return: 'guid', class: QrefEntityClass }, qrefSelectors, QrefEntityClass.ETYPE, count, params, false, (0, guid_1.makeTableSuffix)(), etypes);
|
|
1269
1237
|
if (curQuery) {
|
|
1270
1238
|
curQuery += typeIsOr ? ' OR ' : ' AND ';
|
|
1271
1239
|
}
|
|
@@ -1455,26 +1423,24 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
1455
1423
|
result,
|
|
1456
1424
|
};
|
|
1457
1425
|
}
|
|
1458
|
-
getEntities(options = {}, ...selectors) {
|
|
1459
|
-
|
|
1460
|
-
const
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
return process();
|
|
1477
|
-
});
|
|
1426
|
+
async getEntities(options = {}, ...selectors) {
|
|
1427
|
+
const { result: resultPromise, process } = this.getEntitesRowLike(options, selectors, (options, formattedSelectors, etype) => this.performQuery(options, formattedSelectors, etype), () => {
|
|
1428
|
+
const next = result.next();
|
|
1429
|
+
return next.done ? null : next.value;
|
|
1430
|
+
}, () => undefined, (row) => Number(row.count), (row) => row.guid, (row) => ({
|
|
1431
|
+
tags: row.tags,
|
|
1432
|
+
cdate: isNaN(Number(row.cdate)) ? null : Number(row.cdate),
|
|
1433
|
+
mdate: isNaN(Number(row.mdate)) ? null : Number(row.mdate),
|
|
1434
|
+
}), (row) => ({
|
|
1435
|
+
name: row.name,
|
|
1436
|
+
svalue: row.value === 'N'
|
|
1437
|
+
? JSON.stringify(Number(row.number))
|
|
1438
|
+
: row.value === 'S'
|
|
1439
|
+
? JSON.stringify(row.string)
|
|
1440
|
+
: row.value,
|
|
1441
|
+
}));
|
|
1442
|
+
const result = await resultPromise;
|
|
1443
|
+
return process();
|
|
1478
1444
|
}
|
|
1479
1445
|
getEntitiesSync(options = {}, ...selectors) {
|
|
1480
1446
|
const { result, process } = this.getEntitesRowLike(options, selectors, (options, formattedSelectors, etype) => this.performQuerySync(options, formattedSelectors, etype), () => {
|
|
@@ -1494,219 +1460,72 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
1494
1460
|
}));
|
|
1495
1461
|
return process();
|
|
1496
1462
|
}
|
|
1497
|
-
getUID(name) {
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
},
|
|
1506
|
-
});
|
|
1507
|
-
return (result === null || result === void 0 ? void 0 : result.cur_uid) == null ? null : Number(result.cur_uid);
|
|
1508
|
-
});
|
|
1509
|
-
}
|
|
1510
|
-
import(filename) {
|
|
1511
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1512
|
-
try {
|
|
1513
|
-
const result = yield this.importFromFile(filename, (guid, tags, sdata, etype) => __awaiter(this, void 0, void 0, function* () {
|
|
1514
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1515
|
-
etypes: [etype],
|
|
1516
|
-
params: {
|
|
1517
|
-
guid,
|
|
1518
|
-
},
|
|
1519
|
-
});
|
|
1520
|
-
yield this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`, {
|
|
1521
|
-
etypes: [etype],
|
|
1522
|
-
params: {
|
|
1523
|
-
guid,
|
|
1524
|
-
tags,
|
|
1525
|
-
cdate: isNaN(Number(JSON.parse(sdata.cdate)))
|
|
1526
|
-
? null
|
|
1527
|
-
: Number(JSON.parse(sdata.cdate)),
|
|
1528
|
-
mdate: isNaN(Number(JSON.parse(sdata.mdate)))
|
|
1529
|
-
? null
|
|
1530
|
-
: Number(JSON.parse(sdata.mdate)),
|
|
1531
|
-
},
|
|
1532
|
-
});
|
|
1533
|
-
const promises = [];
|
|
1534
|
-
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1535
|
-
etypes: [etype],
|
|
1536
|
-
params: {
|
|
1537
|
-
guid,
|
|
1538
|
-
},
|
|
1539
|
-
}));
|
|
1540
|
-
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1541
|
-
etypes: [etype],
|
|
1542
|
-
params: {
|
|
1543
|
-
guid,
|
|
1544
|
-
},
|
|
1545
|
-
}));
|
|
1546
|
-
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1547
|
-
etypes: [etype],
|
|
1548
|
-
params: {
|
|
1549
|
-
guid,
|
|
1550
|
-
},
|
|
1551
|
-
}));
|
|
1552
|
-
yield Promise.all(promises);
|
|
1553
|
-
delete sdata.cdate;
|
|
1554
|
-
delete sdata.mdate;
|
|
1555
|
-
for (const name in sdata) {
|
|
1556
|
-
const value = sdata[name];
|
|
1557
|
-
const uvalue = JSON.parse(value);
|
|
1558
|
-
if (value === undefined) {
|
|
1559
|
-
continue;
|
|
1560
|
-
}
|
|
1561
|
-
const storageValue = typeof uvalue === 'number'
|
|
1562
|
-
? 'N'
|
|
1563
|
-
: typeof uvalue === 'string'
|
|
1564
|
-
? 'S'
|
|
1565
|
-
: value;
|
|
1566
|
-
const promises = [];
|
|
1567
|
-
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value") VALUES (decode(@guid, 'hex'), @name, @storageValue);`, {
|
|
1568
|
-
etypes: [etype],
|
|
1569
|
-
params: {
|
|
1570
|
-
guid,
|
|
1571
|
-
name,
|
|
1572
|
-
storageValue,
|
|
1573
|
-
},
|
|
1574
|
-
}));
|
|
1575
|
-
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} ("guid", "name", "truthy", "string", "number") VALUES (decode(@guid, 'hex'), @name, @truthy, @string, @number);`, {
|
|
1576
|
-
etypes: [etype],
|
|
1577
|
-
params: {
|
|
1578
|
-
guid,
|
|
1579
|
-
name,
|
|
1580
|
-
truthy: !!uvalue,
|
|
1581
|
-
string: `${uvalue}`,
|
|
1582
|
-
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
1583
|
-
},
|
|
1584
|
-
}));
|
|
1585
|
-
const references = this.findReferences(value);
|
|
1586
|
-
for (const reference of references) {
|
|
1587
|
-
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`, {
|
|
1588
|
-
etypes: [etype],
|
|
1589
|
-
params: {
|
|
1590
|
-
guid,
|
|
1591
|
-
name,
|
|
1592
|
-
reference,
|
|
1593
|
-
},
|
|
1594
|
-
}));
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
yield Promise.all(promises);
|
|
1598
|
-
}), (name, curUid) => __awaiter(this, void 0, void 0, function* () {
|
|
1599
|
-
yield this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
1600
|
-
params: {
|
|
1601
|
-
name,
|
|
1602
|
-
},
|
|
1603
|
-
});
|
|
1604
|
-
yield this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}uids`)} ("name", "cur_uid") VALUES (@name, @curUid);`, {
|
|
1605
|
-
params: {
|
|
1606
|
-
name,
|
|
1607
|
-
curUid,
|
|
1608
|
-
},
|
|
1609
|
-
});
|
|
1610
|
-
}), () => __awaiter(this, void 0, void 0, function* () {
|
|
1611
|
-
yield this.internalTransaction('nymph-import');
|
|
1612
|
-
}), () => __awaiter(this, void 0, void 0, function* () {
|
|
1613
|
-
yield this.commit('nymph-import');
|
|
1614
|
-
}));
|
|
1615
|
-
return result;
|
|
1616
|
-
}
|
|
1617
|
-
catch (e) {
|
|
1618
|
-
yield this.rollback('nymph-import');
|
|
1619
|
-
return false;
|
|
1620
|
-
}
|
|
1463
|
+
async getUID(name) {
|
|
1464
|
+
if (name == null) {
|
|
1465
|
+
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1466
|
+
}
|
|
1467
|
+
const result = await this.queryGet(`SELECT "cur_uid" FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
1468
|
+
params: {
|
|
1469
|
+
name: name,
|
|
1470
|
+
},
|
|
1621
1471
|
});
|
|
1472
|
+
return result?.cur_uid == null ? null : Number(result.cur_uid);
|
|
1622
1473
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
yield this.internalTransaction('nymph-newuid');
|
|
1629
|
-
try {
|
|
1630
|
-
const lock = yield this.queryGet(`SELECT "cur_uid" FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name FOR UPDATE;`, {
|
|
1474
|
+
async import(filename) {
|
|
1475
|
+
try {
|
|
1476
|
+
const result = await this.importFromFile(filename, async (guid, tags, sdata, etype) => {
|
|
1477
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1478
|
+
etypes: [etype],
|
|
1631
1479
|
params: {
|
|
1632
|
-
|
|
1480
|
+
guid,
|
|
1633
1481
|
},
|
|
1634
1482
|
});
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
});
|
|
1674
|
-
return true;
|
|
1675
|
-
});
|
|
1676
|
-
}
|
|
1677
|
-
rollback(name) {
|
|
1678
|
-
var _a;
|
|
1679
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1680
|
-
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
1681
|
-
throw new nymph_1.InvalidParametersError('Transaction rollback attempted without a name.');
|
|
1682
|
-
}
|
|
1683
|
-
if (!this.transaction || this.transaction.count === 0) {
|
|
1684
|
-
this.transaction = null;
|
|
1685
|
-
return true;
|
|
1686
|
-
}
|
|
1687
|
-
yield this.queryRun(`ROLLBACK TO SAVEPOINT ${PostgreSQLDriver.escape(name)};`);
|
|
1688
|
-
this.transaction.count--;
|
|
1689
|
-
if (this.transaction.count === 0) {
|
|
1690
|
-
yield this.queryRun('ROLLBACK;');
|
|
1691
|
-
(_a = this.transaction.connection) === null || _a === void 0 ? void 0 : _a.done();
|
|
1692
|
-
this.transaction.connection = null;
|
|
1693
|
-
this.transaction = null;
|
|
1694
|
-
}
|
|
1695
|
-
return true;
|
|
1696
|
-
});
|
|
1697
|
-
}
|
|
1698
|
-
saveEntity(entity) {
|
|
1699
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1700
|
-
const insertData = (guid, data, sdata, etype) => __awaiter(this, void 0, void 0, function* () {
|
|
1701
|
-
const runInsertQuery = (name, value, svalue) => __awaiter(this, void 0, void 0, function* () {
|
|
1483
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`, {
|
|
1484
|
+
etypes: [etype],
|
|
1485
|
+
params: {
|
|
1486
|
+
guid,
|
|
1487
|
+
tags,
|
|
1488
|
+
cdate: isNaN(Number(JSON.parse(sdata.cdate)))
|
|
1489
|
+
? null
|
|
1490
|
+
: Number(JSON.parse(sdata.cdate)),
|
|
1491
|
+
mdate: isNaN(Number(JSON.parse(sdata.mdate)))
|
|
1492
|
+
? null
|
|
1493
|
+
: Number(JSON.parse(sdata.mdate)),
|
|
1494
|
+
},
|
|
1495
|
+
});
|
|
1496
|
+
const promises = [];
|
|
1497
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1498
|
+
etypes: [etype],
|
|
1499
|
+
params: {
|
|
1500
|
+
guid,
|
|
1501
|
+
},
|
|
1502
|
+
}));
|
|
1503
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1504
|
+
etypes: [etype],
|
|
1505
|
+
params: {
|
|
1506
|
+
guid,
|
|
1507
|
+
},
|
|
1508
|
+
}));
|
|
1509
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1510
|
+
etypes: [etype],
|
|
1511
|
+
params: {
|
|
1512
|
+
guid,
|
|
1513
|
+
},
|
|
1514
|
+
}));
|
|
1515
|
+
await Promise.all(promises);
|
|
1516
|
+
delete sdata.cdate;
|
|
1517
|
+
delete sdata.mdate;
|
|
1518
|
+
for (const name in sdata) {
|
|
1519
|
+
const value = sdata[name];
|
|
1520
|
+
const uvalue = JSON.parse(value);
|
|
1702
1521
|
if (value === undefined) {
|
|
1703
|
-
|
|
1522
|
+
continue;
|
|
1704
1523
|
}
|
|
1705
|
-
const storageValue = typeof
|
|
1524
|
+
const storageValue = typeof uvalue === 'number'
|
|
1706
1525
|
? 'N'
|
|
1707
|
-
: typeof
|
|
1526
|
+
: typeof uvalue === 'string'
|
|
1708
1527
|
? 'S'
|
|
1709
|
-
:
|
|
1528
|
+
: value;
|
|
1710
1529
|
const promises = [];
|
|
1711
1530
|
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value") VALUES (decode(@guid, 'hex'), @name, @storageValue);`, {
|
|
1712
1531
|
etypes: [etype],
|
|
@@ -1721,12 +1540,12 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
1721
1540
|
params: {
|
|
1722
1541
|
guid,
|
|
1723
1542
|
name,
|
|
1724
|
-
truthy: !!
|
|
1725
|
-
string: `${
|
|
1726
|
-
number: isNaN(Number(
|
|
1543
|
+
truthy: !!uvalue,
|
|
1544
|
+
string: `${uvalue}`,
|
|
1545
|
+
number: isNaN(Number(uvalue)) ? null : Number(uvalue),
|
|
1727
1546
|
},
|
|
1728
1547
|
}));
|
|
1729
|
-
const references = this.findReferences(
|
|
1548
|
+
const references = this.findReferences(value);
|
|
1730
1549
|
for (const reference of references) {
|
|
1731
1550
|
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`, {
|
|
1732
1551
|
etypes: [etype],
|
|
@@ -1737,165 +1556,293 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
|
|
|
1737
1556
|
},
|
|
1738
1557
|
}));
|
|
1739
1558
|
}
|
|
1740
|
-
yield Promise.all(promises);
|
|
1741
|
-
});
|
|
1742
|
-
for (const name in data) {
|
|
1743
|
-
yield runInsertQuery(name, data[name], JSON.stringify(data[name]));
|
|
1744
|
-
}
|
|
1745
|
-
for (const name in sdata) {
|
|
1746
|
-
yield runInsertQuery(name, JSON.parse(sdata[name]), sdata[name]);
|
|
1747
1559
|
}
|
|
1560
|
+
await Promise.all(promises);
|
|
1561
|
+
}, async (name, curUid) => {
|
|
1562
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
1563
|
+
params: {
|
|
1564
|
+
name,
|
|
1565
|
+
},
|
|
1566
|
+
});
|
|
1567
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}uids`)} ("name", "cur_uid") VALUES (@name, @curUid);`, {
|
|
1568
|
+
params: {
|
|
1569
|
+
name,
|
|
1570
|
+
curUid,
|
|
1571
|
+
},
|
|
1572
|
+
});
|
|
1573
|
+
}, async () => {
|
|
1574
|
+
await this.internalTransaction('nymph-import');
|
|
1575
|
+
}, async () => {
|
|
1576
|
+
await this.commit('nymph-import');
|
|
1748
1577
|
});
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1578
|
+
return result;
|
|
1579
|
+
}
|
|
1580
|
+
catch (e) {
|
|
1581
|
+
await this.rollback('nymph-import');
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
async newUID(name) {
|
|
1586
|
+
if (name == null) {
|
|
1587
|
+
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1588
|
+
}
|
|
1589
|
+
await this.internalTransaction('nymph-newuid');
|
|
1590
|
+
try {
|
|
1591
|
+
const lock = await this.queryGet(`SELECT "cur_uid" FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name FOR UPDATE;`, {
|
|
1592
|
+
params: {
|
|
1593
|
+
name,
|
|
1594
|
+
},
|
|
1595
|
+
});
|
|
1596
|
+
let curUid = lock?.cur_uid == null ? undefined : Number(lock.cur_uid);
|
|
1597
|
+
if (curUid == null) {
|
|
1598
|
+
curUid = 1;
|
|
1599
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}uids`)} ("name", "cur_uid") VALUES (@name, @curUid);`, {
|
|
1600
|
+
params: {
|
|
1601
|
+
name,
|
|
1602
|
+
curUid,
|
|
1603
|
+
},
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
else {
|
|
1607
|
+
curUid++;
|
|
1608
|
+
await this.queryRun(`UPDATE ${PostgreSQLDriver.escape(`${this.prefix}uids`)} SET "cur_uid"=@curUid WHERE "name"=@name;`, {
|
|
1609
|
+
params: {
|
|
1610
|
+
name,
|
|
1611
|
+
curUid,
|
|
1612
|
+
},
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
await this.commit('nymph-newuid');
|
|
1616
|
+
return curUid;
|
|
1617
|
+
}
|
|
1618
|
+
catch (e) {
|
|
1619
|
+
await this.rollback('nymph-newuid');
|
|
1620
|
+
throw e;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
async renameUID(oldName, newName) {
|
|
1624
|
+
if (oldName == null || newName == null) {
|
|
1625
|
+
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1626
|
+
}
|
|
1627
|
+
await this.queryRun(`UPDATE ${PostgreSQLDriver.escape(`${this.prefix}uids`)} SET "name"=@newName WHERE "name"=@oldName;`, {
|
|
1628
|
+
params: {
|
|
1629
|
+
newName,
|
|
1630
|
+
oldName,
|
|
1631
|
+
},
|
|
1632
|
+
});
|
|
1633
|
+
return true;
|
|
1634
|
+
}
|
|
1635
|
+
async rollback(name) {
|
|
1636
|
+
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
1637
|
+
throw new nymph_1.InvalidParametersError('Transaction rollback attempted without a name.');
|
|
1638
|
+
}
|
|
1639
|
+
if (!this.transaction || this.transaction.count === 0) {
|
|
1640
|
+
this.transaction = null;
|
|
1641
|
+
return true;
|
|
1642
|
+
}
|
|
1643
|
+
await this.queryRun(`ROLLBACK TO SAVEPOINT ${PostgreSQLDriver.escape(name)};`);
|
|
1644
|
+
this.transaction.count--;
|
|
1645
|
+
if (this.transaction.count === 0) {
|
|
1646
|
+
await this.queryRun('ROLLBACK;');
|
|
1647
|
+
this.transaction.connection?.done();
|
|
1648
|
+
this.transaction.connection = null;
|
|
1649
|
+
this.transaction = null;
|
|
1650
|
+
}
|
|
1651
|
+
return true;
|
|
1652
|
+
}
|
|
1653
|
+
async saveEntity(entity) {
|
|
1654
|
+
const insertData = async (guid, data, sdata, etype) => {
|
|
1655
|
+
const runInsertQuery = async (name, value, svalue) => {
|
|
1656
|
+
if (value === undefined) {
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
const storageValue = typeof value === 'number'
|
|
1660
|
+
? 'N'
|
|
1661
|
+
: typeof value === 'string'
|
|
1662
|
+
? 'S'
|
|
1663
|
+
: svalue;
|
|
1664
|
+
const promises = [];
|
|
1665
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value") VALUES (decode(@guid, 'hex'), @name, @storageValue);`, {
|
|
1666
|
+
etypes: [etype],
|
|
1667
|
+
params: {
|
|
1668
|
+
guid,
|
|
1669
|
+
name,
|
|
1670
|
+
storageValue,
|
|
1671
|
+
},
|
|
1672
|
+
}));
|
|
1673
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} ("guid", "name", "truthy", "string", "number") VALUES (decode(@guid, 'hex'), @name, @truthy, @string, @number);`, {
|
|
1674
|
+
etypes: [etype],
|
|
1675
|
+
params: {
|
|
1676
|
+
guid,
|
|
1677
|
+
name,
|
|
1678
|
+
truthy: !!value,
|
|
1679
|
+
string: `${value}`,
|
|
1680
|
+
number: isNaN(Number(value)) ? null : Number(value),
|
|
1681
|
+
},
|
|
1682
|
+
}));
|
|
1683
|
+
const references = this.findReferences(svalue);
|
|
1684
|
+
for (const reference of references) {
|
|
1685
|
+
promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} ("guid", "name", "reference") VALUES (decode(@guid, 'hex'), @name, decode(@reference, 'hex'));`, {
|
|
1764
1686
|
etypes: [etype],
|
|
1765
1687
|
params: {
|
|
1766
1688
|
guid,
|
|
1689
|
+
name,
|
|
1690
|
+
reference,
|
|
1767
1691
|
},
|
|
1768
1692
|
}));
|
|
1769
|
-
|
|
1693
|
+
}
|
|
1694
|
+
await Promise.all(promises);
|
|
1695
|
+
};
|
|
1696
|
+
for (const name in data) {
|
|
1697
|
+
await runInsertQuery(name, data[name], JSON.stringify(data[name]));
|
|
1698
|
+
}
|
|
1699
|
+
for (const name in sdata) {
|
|
1700
|
+
await runInsertQuery(name, JSON.parse(sdata[name]), sdata[name]);
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
try {
|
|
1704
|
+
const result = await this.saveEntityRowLike(entity, async (_entity, guid, tags, data, sdata, cdate, etype) => {
|
|
1705
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @cdate);`, {
|
|
1706
|
+
etypes: [etype],
|
|
1707
|
+
params: {
|
|
1708
|
+
guid,
|
|
1709
|
+
tags,
|
|
1710
|
+
cdate,
|
|
1711
|
+
},
|
|
1712
|
+
});
|
|
1713
|
+
await insertData(guid, data, sdata, etype);
|
|
1714
|
+
return true;
|
|
1715
|
+
}, async (entity, guid, tags, data, sdata, mdate, etype) => {
|
|
1716
|
+
const promises = [];
|
|
1717
|
+
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
1718
|
+
etypes: [etype],
|
|
1719
|
+
params: {
|
|
1720
|
+
guid,
|
|
1721
|
+
},
|
|
1722
|
+
}));
|
|
1723
|
+
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
1724
|
+
etypes: [etype],
|
|
1725
|
+
params: {
|
|
1726
|
+
guid,
|
|
1727
|
+
},
|
|
1728
|
+
}));
|
|
1729
|
+
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
1730
|
+
etypes: [etype],
|
|
1731
|
+
params: {
|
|
1732
|
+
guid,
|
|
1733
|
+
},
|
|
1734
|
+
}));
|
|
1735
|
+
promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
|
|
1736
|
+
etypes: [etype],
|
|
1737
|
+
params: {
|
|
1738
|
+
guid,
|
|
1739
|
+
},
|
|
1740
|
+
}));
|
|
1741
|
+
await Promise.all(promises);
|
|
1742
|
+
const info = await this.queryRun(`UPDATE ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} SET "tags"=@tags, "mdate"=@mdate WHERE "guid"=decode(@guid, 'hex') AND "mdate" <= @emdate;`, {
|
|
1743
|
+
etypes: [etype],
|
|
1744
|
+
params: {
|
|
1745
|
+
tags,
|
|
1746
|
+
mdate,
|
|
1747
|
+
guid,
|
|
1748
|
+
emdate: isNaN(Number(entity.mdate)) ? 0 : Number(entity.mdate),
|
|
1749
|
+
},
|
|
1750
|
+
});
|
|
1751
|
+
let success = false;
|
|
1752
|
+
if (info.rowCount === 1) {
|
|
1753
|
+
const promises = [];
|
|
1754
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1770
1755
|
etypes: [etype],
|
|
1771
1756
|
params: {
|
|
1772
1757
|
guid,
|
|
1773
1758
|
},
|
|
1774
1759
|
}));
|
|
1775
|
-
promises.push(this.queryRun(`
|
|
1760
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1776
1761
|
etypes: [etype],
|
|
1777
1762
|
params: {
|
|
1778
1763
|
guid,
|
|
1779
1764
|
},
|
|
1780
1765
|
}));
|
|
1781
|
-
promises.push(this.queryRun(`
|
|
1766
|
+
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1782
1767
|
etypes: [etype],
|
|
1783
1768
|
params: {
|
|
1784
1769
|
guid,
|
|
1785
1770
|
},
|
|
1786
1771
|
}));
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
guid,
|
|
1810
|
-
},
|
|
1811
|
-
}));
|
|
1812
|
-
promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
|
|
1813
|
-
etypes: [etype],
|
|
1814
|
-
params: {
|
|
1815
|
-
guid,
|
|
1816
|
-
},
|
|
1817
|
-
}));
|
|
1818
|
-
yield Promise.all(promises);
|
|
1819
|
-
yield insertData(guid, data, sdata, etype);
|
|
1820
|
-
success = true;
|
|
1821
|
-
}
|
|
1822
|
-
return success;
|
|
1823
|
-
}), () => __awaiter(this, void 0, void 0, function* () {
|
|
1824
|
-
yield this.internalTransaction('nymph-save');
|
|
1825
|
-
}), (success) => __awaiter(this, void 0, void 0, function* () {
|
|
1826
|
-
if (success) {
|
|
1827
|
-
yield this.commit('nymph-save');
|
|
1828
|
-
}
|
|
1829
|
-
else {
|
|
1830
|
-
yield this.rollback('nymph-save');
|
|
1831
|
-
}
|
|
1832
|
-
return success;
|
|
1833
|
-
}));
|
|
1834
|
-
return result;
|
|
1835
|
-
}
|
|
1836
|
-
catch (e) {
|
|
1837
|
-
yield this.rollback('nymph-save');
|
|
1838
|
-
throw e;
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1772
|
+
await Promise.all(promises);
|
|
1773
|
+
await insertData(guid, data, sdata, etype);
|
|
1774
|
+
success = true;
|
|
1775
|
+
}
|
|
1776
|
+
return success;
|
|
1777
|
+
}, async () => {
|
|
1778
|
+
await this.internalTransaction('nymph-save');
|
|
1779
|
+
}, async (success) => {
|
|
1780
|
+
if (success) {
|
|
1781
|
+
await this.commit('nymph-save');
|
|
1782
|
+
}
|
|
1783
|
+
else {
|
|
1784
|
+
await this.rollback('nymph-save');
|
|
1785
|
+
}
|
|
1786
|
+
return success;
|
|
1787
|
+
});
|
|
1788
|
+
return result;
|
|
1789
|
+
}
|
|
1790
|
+
catch (e) {
|
|
1791
|
+
await this.rollback('nymph-save');
|
|
1792
|
+
throw e;
|
|
1793
|
+
}
|
|
1841
1794
|
}
|
|
1842
|
-
setUID(name, curUid) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
}
|
|
1868
|
-
});
|
|
1795
|
+
async setUID(name, curUid) {
|
|
1796
|
+
if (name == null) {
|
|
1797
|
+
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1798
|
+
}
|
|
1799
|
+
await this.internalTransaction('nymph-setuid');
|
|
1800
|
+
try {
|
|
1801
|
+
await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
1802
|
+
params: {
|
|
1803
|
+
name,
|
|
1804
|
+
curUid,
|
|
1805
|
+
},
|
|
1806
|
+
});
|
|
1807
|
+
await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}uids`)} ("name", "cur_uid") VALUES (@name, @curUid);`, {
|
|
1808
|
+
params: {
|
|
1809
|
+
name,
|
|
1810
|
+
curUid,
|
|
1811
|
+
},
|
|
1812
|
+
});
|
|
1813
|
+
await this.commit('nymph-setuid');
|
|
1814
|
+
return true;
|
|
1815
|
+
}
|
|
1816
|
+
catch (e) {
|
|
1817
|
+
await this.rollback('nymph-setuid');
|
|
1818
|
+
throw e;
|
|
1819
|
+
}
|
|
1869
1820
|
}
|
|
1870
|
-
internalTransaction(name) {
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
return this.transaction;
|
|
1885
|
-
});
|
|
1821
|
+
async internalTransaction(name) {
|
|
1822
|
+
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
1823
|
+
throw new nymph_1.InvalidParametersError('Transaction start attempted without a name.');
|
|
1824
|
+
}
|
|
1825
|
+
if (!this.transaction || this.transaction.count === 0) {
|
|
1826
|
+
this.transaction = {
|
|
1827
|
+
count: 0,
|
|
1828
|
+
connection: await this.getConnection(),
|
|
1829
|
+
};
|
|
1830
|
+
await this.queryRun('BEGIN;');
|
|
1831
|
+
}
|
|
1832
|
+
await this.queryRun(`SAVEPOINT ${PostgreSQLDriver.escape(name)};`);
|
|
1833
|
+
this.transaction.count++;
|
|
1834
|
+
return this.transaction;
|
|
1886
1835
|
}
|
|
1887
|
-
startTransaction(name) {
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
return nymph;
|
|
1898
|
-
});
|
|
1836
|
+
async startTransaction(name) {
|
|
1837
|
+
const inTransaction = this.inTransaction();
|
|
1838
|
+
const transaction = await this.internalTransaction(name);
|
|
1839
|
+
if (!inTransaction) {
|
|
1840
|
+
this.transaction = null;
|
|
1841
|
+
}
|
|
1842
|
+
const nymph = this.nymph.clone();
|
|
1843
|
+
nymph.driver = new PostgreSQLDriver(this.config, this.link, transaction);
|
|
1844
|
+
nymph.driver.init(nymph);
|
|
1845
|
+
return nymph;
|
|
1899
1846
|
}
|
|
1900
1847
|
}
|
|
1901
1848
|
exports.default = PostgreSQLDriver;
|