pogi 2.11.0

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.
Files changed (82) hide show
  1. package/.vscode/launch.json +35 -0
  2. package/CHANGELOG.md +277 -0
  3. package/LICENSE +21 -0
  4. package/README.md +85 -0
  5. package/docs/API/PgDb.md +218 -0
  6. package/docs/API/PgSchema.md +91 -0
  7. package/docs/API/PgTable.md +365 -0
  8. package/docs/API/QueryOptions.md +77 -0
  9. package/docs/API/condition.md +133 -0
  10. package/docs/connection.md +91 -0
  11. package/docs/css/docs.css +164 -0
  12. package/docs/executingSqlFile.md +44 -0
  13. package/docs/faq.md +15 -0
  14. package/docs/functions.md +19 -0
  15. package/docs/generatingInterfaceForTables.md +35 -0
  16. package/docs/index.md +48 -0
  17. package/docs/logger.md +40 -0
  18. package/docs/mappingDatabaseTypes.md +89 -0
  19. package/docs/notification.md +19 -0
  20. package/docs/pitfalls.md +73 -0
  21. package/docs/streams.md +68 -0
  22. package/docs/transaction.md +65 -0
  23. package/lib/bin/generateInterface.d.ts +1 -0
  24. package/lib/bin/generateInterface.js +53 -0
  25. package/lib/bin/generateInterface.js.map +1 -0
  26. package/lib/connectionOptions.d.ts +25 -0
  27. package/lib/connectionOptions.js +3 -0
  28. package/lib/connectionOptions.js.map +1 -0
  29. package/lib/index.d.ts +6 -0
  30. package/lib/index.js +10 -0
  31. package/lib/index.js.map +1 -0
  32. package/lib/pgConverters.d.ts +10 -0
  33. package/lib/pgConverters.js +66 -0
  34. package/lib/pgConverters.js.map +1 -0
  35. package/lib/pgDb.d.ts +86 -0
  36. package/lib/pgDb.js +745 -0
  37. package/lib/pgDb.js.map +1 -0
  38. package/lib/pgDbLogger.d.ts +5 -0
  39. package/lib/pgDbLogger.js +3 -0
  40. package/lib/pgDbLogger.js.map +1 -0
  41. package/lib/pgDbOperators.d.ts +113 -0
  42. package/lib/pgDbOperators.js +44 -0
  43. package/lib/pgDbOperators.js.map +1 -0
  44. package/lib/pgSchema.d.ts +16 -0
  45. package/lib/pgSchema.js +16 -0
  46. package/lib/pgSchema.js.map +1 -0
  47. package/lib/pgTable.d.ts +131 -0
  48. package/lib/pgTable.js +322 -0
  49. package/lib/pgTable.js.map +1 -0
  50. package/lib/pgUtils.d.ts +31 -0
  51. package/lib/pgUtils.js +157 -0
  52. package/lib/pgUtils.js.map +1 -0
  53. package/lib/queryAble.d.ts +76 -0
  54. package/lib/queryAble.js +330 -0
  55. package/lib/queryAble.js.map +1 -0
  56. package/lib/queryWhere.d.ts +8 -0
  57. package/lib/queryWhere.js +249 -0
  58. package/lib/queryWhere.js.map +1 -0
  59. package/mkdocs.yml +25 -0
  60. package/package.json +65 -0
  61. package/spec/resources/init.sql +122 -0
  62. package/spec/resources/throw_exception.sql +5 -0
  63. package/spec/resources/tricky.sql +13 -0
  64. package/spec/run.js +5 -0
  65. package/spec/support/jasmine.json +9 -0
  66. package/src/bin/generateInterface.ts +54 -0
  67. package/src/connectionOptions.ts +42 -0
  68. package/src/index.ts +6 -0
  69. package/src/pgConverters.ts +55 -0
  70. package/src/pgDb.ts +820 -0
  71. package/src/pgDbLogger.ts +13 -0
  72. package/src/pgDbOperators.ts +62 -0
  73. package/src/pgSchema.ts +15 -0
  74. package/src/pgTable.ts +401 -0
  75. package/src/pgUtils.ts +176 -0
  76. package/src/queryAble.ts +393 -0
  77. package/src/queryWhere.ts +326 -0
  78. package/src/test/pgDbOperatorSpec.ts +492 -0
  79. package/src/test/pgDbSpec.ts +1339 -0
  80. package/src/test/pgServiceRestartTest.ts +1500 -0
  81. package/src/tsconfig.json +33 -0
  82. package/utils_sql/lower.sql +4 -0
@@ -0,0 +1,1500 @@
1
+ import { Notification, PgDb } from "../pgDb";
2
+ import * as yargs from 'yargs';
3
+ import * as shell from "shelljs";
4
+
5
+ // cd ~/labcup/ ; docker-compose start
6
+ // cd ~/labcup/ ; docker-compose stop
7
+ let argv: any = yargs
8
+ .usage('node pgServiceRestartTest.js\n Usage: $0')
9
+ .option('postgresOn', {
10
+ describe: 'the command line command which switches on the postgresql server',
11
+ type: "string"
12
+ })
13
+ .option('postgresOff', {
14
+ describe: 'the command line command which switches off the postgresql server',
15
+ type: "string"
16
+ })
17
+ .option('testParams', {
18
+ describe: 'check postgres Off & On params',
19
+ type: "boolean"
20
+ })
21
+ .argv;
22
+
23
+ async function runCommand(command: string, options?: { silent: boolean }): Promise<{ stdout: string, stderr: string }> {
24
+ return new Promise((resolve, reject) => {
25
+ shell.exec(command, { silent: options ? options.silent : true }, (code: number, stdout: string, stderr: string) => {
26
+ resolve({ stdout, stderr });
27
+ });
28
+ });
29
+ }
30
+
31
+ async function asyncWaitMs(ms: number) {
32
+ await new Promise(r => setTimeout(r, ms));
33
+ }
34
+
35
+ function syncWaitMs(ms: number) {
36
+ let origDate = +new Date();
37
+ let actDate = origDate;
38
+ while (origDate + ms > actDate) {
39
+ actDate = +new Date();
40
+ }
41
+ }
42
+
43
+ async function postgresOff() {
44
+ console.log('Kill postgres server.');
45
+ await runCommand(argv.postgresOff);
46
+ }
47
+
48
+ async function postgresOn() {
49
+ console.log('Start postgres server.');
50
+ await runCommand(argv.postgresOn);
51
+ await asyncWaitMs(500);
52
+ }
53
+
54
+ const poolSize = 3;
55
+
56
+ async function testSchemaClear(db: PgDb) {
57
+ await db.run(`drop table if exists pgdb_test.names`);
58
+
59
+ await db.run(`DROP TYPE IF EXISTS pgdb_test.mood CASCADE`);
60
+ await db.run(`DROP TABLE IF EXISTS pgdb_test."enumArrayTable"`);
61
+ }
62
+
63
+ async function testSchemaInit(db: PgDb) {
64
+ await testSchemaClear(db);
65
+ await db.run(`create table pgdb_test.names (name varchar null)`);
66
+ await db.run(`insert into pgdb_test.names (name) values ('Kuka'), ('Hapci')`);
67
+
68
+ await db.run(`CREATE TYPE pgdb_test.mood AS ENUM('sad', 'ok', 'happy')`);
69
+ await db.run(`CREATE TABLE pgdb_test."enumArrayTable"(m pgdb_test.mood[] NULL)`);
70
+ await db.run(`INSERT INTO pgdb_test."enumArrayTable"(m) values (ARRAY['sad'::pgdb_test.mood, 'happy'::pgdb_test.mood])`);
71
+ }
72
+
73
+ async function testDbFreeConnections(db: PgDb): Promise<Error> {
74
+ let dedicatedConnections: PgDb[] = new Array(poolSize).fill(null);
75
+
76
+ await Promise.race([
77
+ asyncWaitMs(1000),
78
+ (async () => {
79
+ for (let i = 0; i < dedicatedConnections.length; ++i) {
80
+ dedicatedConnections[i] = await db.dedicatedConnectionBegin();
81
+ }
82
+ })()
83
+ ]);
84
+ if (dedicatedConnections.some(v => !v)) {
85
+ return new Error('Some of the connections are not free!');
86
+ }
87
+ for (let conn of dedicatedConnections) {
88
+ await conn.dedicatedConnectionEnd();
89
+ }
90
+ return null;
91
+ }
92
+
93
+ async function testInsertQuery(db: PgDb): Promise<Error> {
94
+ let tableContents = await db.query(`select * from pgdb_test.names`);
95
+ if (tableContents.length != 2) {
96
+ return new Error('Simple query fails');
97
+ }
98
+ let callbackCounter1 = 0;
99
+ await db.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, (data) => {
100
+ ++callbackCounter1;
101
+ });
102
+ if (callbackCounter1 != 2) {
103
+ return new Error('Query with cursor callback fails');
104
+ }
105
+
106
+ let callbackCounter2 = 0;
107
+ let stream = await db.queryAsStream(`select * from pgdb_test.names`);
108
+ await new Promise<any>((resolve, reject) => {
109
+ stream.on("data", (data) => {
110
+ ++callbackCounter2;
111
+ });
112
+ stream.on('error', reject);
113
+ stream.on('close', resolve);
114
+ });
115
+ if (callbackCounter2 != 2) {
116
+ return new Error('Query as stream fails');
117
+ }
118
+ return null;
119
+ }
120
+
121
+ async function testNotificationSystem(db: PgDb): Promise<Error> {
122
+ let result: string;
123
+ await db.listen('testChannel', (data) => { result = data.payload; });
124
+ await db.notify('testChannel', 'newData');
125
+ await asyncWaitMs(1000);
126
+ if (result != 'newData') {
127
+ return new Error('Notification not working...');
128
+ }
129
+ await db.unlisten('testChannel');
130
+ }
131
+
132
+ async function testDbUsability(db: PgDb): Promise<Error> {
133
+ try {
134
+ console.log('TestSchemaInit');
135
+ await testSchemaInit(db);
136
+ console.log('TestFreeConnections');
137
+ let error = await testDbFreeConnections(db);
138
+ if (!error) {
139
+ console.log('TestInsertQueries');
140
+ error = await testInsertQuery(db);
141
+ }
142
+ if (!error) {
143
+ console.log('TestNotifications');
144
+ error = await testNotificationSystem(db);
145
+ }
146
+ await testSchemaClear(db);
147
+ return error;
148
+ } catch (e) {
149
+ return e;
150
+ }
151
+ }
152
+
153
+ interface TestDescriptor {
154
+ name: string,
155
+ fn: (db: PgDb, isTrue: (value: boolean) => void) => Promise<void>,
156
+ skipTestDb?: boolean
157
+ }
158
+
159
+ async function runTestInternal(db: PgDb, test: TestDescriptor): Promise<Error> {
160
+ let callCounter = 0;
161
+
162
+ let errorResult: Error = null;
163
+ try {
164
+ await test.fn(db, (value: boolean) => {
165
+ ++callCounter;
166
+ if (!value && !errorResult) {
167
+ errorResult = new Error(`Error in test at the ${callCounter}. call.`);
168
+ }
169
+ });
170
+ } catch (err) {
171
+ if (!errorResult) {
172
+ errorResult = err;
173
+ }
174
+ }
175
+
176
+ await postgresOn();
177
+
178
+ if (!errorResult && !test.skipTestDb) {
179
+ errorResult = await testDbUsability(db);
180
+ }
181
+ return errorResult;
182
+ }
183
+
184
+ let actTestCounter: number = 0;
185
+ let errorMessages: { testName: string, err: Error }[] = [];
186
+
187
+ async function runTest(allTestCount: number, test: TestDescriptor) {
188
+ ++actTestCounter;
189
+ console.log('====================================================================================');
190
+ console.log(`${actTestCounter}/${allTestCount} Test starting: "${test.name}"`);
191
+ console.log('====================================================================================');
192
+
193
+ await postgresOn();
194
+ let db = await PgDb.connect({
195
+ poolSize,
196
+ logger: {
197
+ log: console.log,
198
+ error: console.error
199
+ }
200
+ });
201
+ await testSchemaInit(db);
202
+
203
+ let error = await runTestInternal(db, test);
204
+ if (error) {
205
+ errorMessages.push({ testName: test.name, err: error });
206
+ }
207
+
208
+ await db.close();
209
+ console.log('====================================================================================');
210
+ if (error) {
211
+ console.log(`${actTestCounter}/${allTestCount} Test errored: "${test.name}"`);
212
+ } else {
213
+ console.log(`${actTestCounter}/${allTestCount} Test passed: "${test.name}"`);
214
+ }
215
+ console.log('====================================================================================');
216
+ }
217
+
218
+ let newConnectionTests: TestDescriptor[] = [
219
+ {
220
+ name: 'simple query 1',
221
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
222
+ let stageCounter = 0;
223
+ await postgresOff();
224
+ try {
225
+ await db.query(`select * from pgdb_test.names`);
226
+ isTrue(false);
227
+ } catch (e) {
228
+ ++stageCounter;
229
+ }
230
+ try {
231
+ await db.query(`select * from pgdb_test.names`);
232
+ isTrue(false);
233
+ } catch (e) {
234
+ ++stageCounter;
235
+ }
236
+ isTrue(stageCounter == 2);
237
+ }
238
+ },
239
+ {
240
+ name: 'simple query 2',
241
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
242
+ let stageCounter = 0;
243
+ await postgresOff();
244
+ try {
245
+ await db.query(`select * from pgdb_test."enumArrayTable"`);
246
+ isTrue(false);
247
+ } catch (e) {
248
+ ++stageCounter;
249
+ }
250
+ try {
251
+ await db.query(`select * from pgdb_test."enumArrayTable"`);
252
+ isTrue(false);
253
+ } catch (e) {
254
+ ++stageCounter;
255
+ }
256
+ isTrue(stageCounter == 2);
257
+ }
258
+ },
259
+ {
260
+ name: 'queryWithCallback 1 - postgresOff before call',
261
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
262
+ let stageCounter = 0;
263
+ await postgresOff();
264
+ try {
265
+ await db.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, () => {
266
+ isTrue(false);
267
+ });
268
+ isTrue(false);
269
+ } catch (e) {
270
+ ++stageCounter;
271
+ }
272
+ isTrue(stageCounter == 1);
273
+ }
274
+ },
275
+ {
276
+ name: 'queryWithCallback 2 - postgresOff between calls',
277
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
278
+ let stageCounter = 0;
279
+
280
+ let params = new Array(2000).fill(null).map((v, i) => `'Smith${i}'`).map(v => `(${v})`).join(', ');
281
+ await db.run(`INSERT INTO pgdb_test.names(name) values ${params}`);
282
+ let i = 0;
283
+ let fn1 = async () => {
284
+ try {
285
+ await db.queryWithOnCursorCallback('select * from pgdb_test.names', {}, {}, (data) => {
286
+ syncWaitMs(20);
287
+ ++i;
288
+ if (i % 10 == 0) {
289
+ console.log('Record:', i);
290
+ }
291
+ });
292
+ isTrue(false);
293
+ } catch (e) {
294
+ ++stageCounter;
295
+ }
296
+ }
297
+ let fn2 = async () => {
298
+ console.log('Wait before postgres off...');
299
+ await asyncWaitMs(100);
300
+ await postgresOff();
301
+ }
302
+ await Promise.all([fn1(), fn2()]);
303
+ isTrue(i > 0 && i < 2000);
304
+ isTrue(stageCounter == 1);
305
+ },
306
+ },
307
+ {
308
+ name: 'queryWithCallback 3 - postgresOff between calls, unknown oid',
309
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
310
+ let stageCounter = 0;
311
+
312
+ let params = new Array(2000).fill(null).map((v) => `ARRAY['sad'::pgdb_test.mood, 'happy'::pgdb_test.mood]`).map(v => `(${v})`).join(', ');
313
+ await db.run(`INSERT INTO pgdb_test."enumArrayTable"(m) values ${params}`);
314
+
315
+ let i = 0;
316
+ let fn1 = async () => {
317
+ try {
318
+ await db.queryWithOnCursorCallback('select * from pgdb_test."enumArrayTable"', {}, {}, (data) => {
319
+ syncWaitMs(20);
320
+ ++i;
321
+ if (i % 10 == 0) {
322
+ console.log('Record:', i);
323
+ }
324
+ });
325
+ isTrue(false);
326
+ } catch (e) {
327
+ ++stageCounter;
328
+ }
329
+ }
330
+ let fn2 = async () => {
331
+ console.log('Wait before postgres off...');
332
+ await asyncWaitMs(100);
333
+ await postgresOff();
334
+ }
335
+ await Promise.all([fn1(), fn2()]);
336
+ isTrue(i > 0 && i < 2000);
337
+ isTrue(stageCounter == 1);
338
+ },
339
+ },
340
+ {
341
+ name: 'queryAsStream 1 - postgresOff before call',
342
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
343
+ let stageCounter = 0;
344
+ await postgresOff();
345
+ try {
346
+ let stream = await db.queryAsStream(`select * from pgdb_test.names`);
347
+ isTrue(false);
348
+ } catch (e) {
349
+ ++stageCounter;
350
+ }
351
+ isTrue(stageCounter == 1);
352
+ }
353
+ },
354
+ {
355
+ name: 'queryAsStream 2 - postgresOff between calls',
356
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
357
+ let stageCounter = 0;
358
+
359
+ let params = new Array(2000).fill(null).map((v, i) => `'Smith${i}'`).map(v => `(${v})`).join(', ');
360
+ await db.run(`INSERT INTO pgdb_test.names(name) values ${params}`);
361
+
362
+ let stream = await db.queryAsStream('select * from pgdb_test.names');
363
+
364
+ let i = 0;
365
+ let promise1 = new Promise<any>((resolve, reject) => {
366
+ stream.on("data", (data) => {
367
+ syncWaitMs(20);
368
+ ++i;
369
+ if (i % 10 == 0) {
370
+ console.log(data.name);
371
+ }
372
+ });
373
+ stream.on('error', (...params) => {
374
+ ++stageCounter;
375
+ reject(...params);
376
+ });
377
+ stream.on('close', resolve);
378
+ });
379
+
380
+ let fn2 = async () => {
381
+ await asyncWaitMs(100);
382
+ await postgresOff();
383
+ }
384
+ try {
385
+ await Promise.all([promise1, fn2()]);
386
+ isTrue(false);
387
+ } catch (e) {
388
+ ++stageCounter;
389
+ }
390
+ isTrue(i > 0 && i < 2000);
391
+ isTrue(stageCounter == 2);
392
+ }
393
+ },
394
+ {
395
+ name: 'queryAsStream 3 - postgresOff between calls, unknown oid',
396
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
397
+ let stageCounter = 0;
398
+
399
+ let params = new Array(2000).fill(null).map((v) => `ARRAY['sad'::pgdb_test.mood, 'happy'::pgdb_test.mood]`).map(v => `(${v})`).join(', ');
400
+ await db.run(`INSERT INTO pgdb_test."enumArrayTable"(m) values ${params}`);
401
+
402
+ let stream = await db.queryAsStream('select * from pgdb_test."enumArrayTable"');
403
+ let i = 0;
404
+ let promise1 = new Promise<any>((resolve, reject) => {
405
+ stream.on("data", (data) => {
406
+ syncWaitMs(20);
407
+ ++i;
408
+ if (i % 10 == 0) {
409
+ console.log(data.name);
410
+ }
411
+ });
412
+ stream.on('error', (...params) => {
413
+ ++stageCounter;
414
+ reject(...params);
415
+ });
416
+ stream.on('close', resolve);
417
+ });
418
+
419
+ let fn2 = async () => {
420
+ await asyncWaitMs(100);
421
+ await postgresOff();
422
+ }
423
+ try {
424
+ await Promise.all([promise1, fn2()]);
425
+ isTrue(false);
426
+ } catch (e) {
427
+ ++stageCounter;
428
+ }
429
+ isTrue(i == 0);
430
+ isTrue(stageCounter == 2);
431
+ await postgresOff(); // To ensure, that postgresql stopped perfectly.
432
+ }
433
+ },
434
+ ];
435
+
436
+ let dedicatedConnection_SimpleQueryTests: TestDescriptor[] = [
437
+ {
438
+ name: 'dedicated connection - empty 1',
439
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
440
+ let stageCounter = 0;
441
+ await postgresOff();
442
+ try {
443
+ let db0 = await db.dedicatedConnectionBegin();
444
+ isTrue(false);
445
+ } catch (e) {
446
+ ++stageCounter;
447
+ }
448
+ isTrue(stageCounter == 1);
449
+ }
450
+ },
451
+ {
452
+ name: 'dedicated connection - empty 2',
453
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
454
+ let stageCounter = 0;
455
+ let db0 = await db.dedicatedConnectionBegin();
456
+ await postgresOff();
457
+ try {
458
+ await db0.dedicatedConnectionEnd();
459
+ ++stageCounter;
460
+ } catch (e) {
461
+ isTrue(false);
462
+ }
463
+ isTrue(stageCounter == 1);
464
+ }
465
+ },
466
+ {
467
+ name: 'dedicated connection - simple query 1',
468
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
469
+ let stageCounter = 0;
470
+ let db0 = await db.dedicatedConnectionBegin();
471
+ await postgresOff();
472
+ try {
473
+ await db0.query(`select * from pgdb_test.names`);
474
+ isTrue(false);
475
+ } catch (e) {
476
+ ++stageCounter;
477
+ }
478
+ isTrue(stageCounter == 1);
479
+ }
480
+ },
481
+ {
482
+ name: 'dedicated connection - simple query 2',
483
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
484
+ let stageCounter = 0;
485
+ let db0 = await db.dedicatedConnectionBegin();
486
+ await postgresOff();
487
+ try {
488
+ await db0.query(`select * from pgdb_test.names`);
489
+ isTrue(false);
490
+ } catch (e) {
491
+ ++stageCounter;
492
+ }
493
+ try {
494
+ await db0.dedicatedConnectionEnd();
495
+ ++stageCounter;
496
+ } catch (e) {
497
+ isTrue(false);
498
+ }
499
+ isTrue(stageCounter == 2);
500
+ }
501
+ },
502
+ {
503
+ name: 'dedicated connection - simple query 3',
504
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
505
+ let stageCounter = 0;
506
+ let db0 = await db.dedicatedConnectionBegin();
507
+ await db0.run(`truncate pgdb_test.names`)
508
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
509
+ await postgresOff();
510
+ try {
511
+ await db0.dedicatedConnectionEnd();
512
+ ++stageCounter;
513
+ } catch (e) {
514
+ isTrue(false);
515
+ }
516
+ await postgresOn();
517
+ let result = await db.query(`select * from pgdb_test.names`);
518
+ isTrue(result[0].name == 'Morgo');
519
+ isTrue(stageCounter == 1);
520
+ }
521
+ },
522
+ {
523
+ name: 'dedicated connection - simple query 4',
524
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
525
+ let stageCounter = 0;
526
+ let db0 = await db.dedicatedConnectionBegin();
527
+ await db0.run(`truncate pgdb_test.names`)
528
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
529
+ await postgresOff();
530
+ try {
531
+ await db0.query(`select * from pgdb_test.names`);
532
+ isTrue(false);
533
+ } catch (e) {
534
+ ++stageCounter;
535
+ }
536
+ await postgresOn();
537
+ let result = await db.query(`select * from pgdb_test.names`);
538
+ isTrue(result[0].name == 'Morgo');
539
+ isTrue(stageCounter == 1);
540
+ }
541
+ },
542
+ {
543
+ name: 'dedicated connection - simple query 5',
544
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
545
+ let stageCounter = 0;
546
+ let db0 = await db.dedicatedConnectionBegin();
547
+ await db0.run(`truncate pgdb_test.names`)
548
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
549
+ await postgresOff();
550
+ try {
551
+ await db0.query(`select * from pgdb_test.names`);
552
+ isTrue(false);
553
+ } catch (e) {
554
+ ++stageCounter;
555
+ }
556
+ try {
557
+ await db0.dedicatedConnectionEnd();
558
+ ++stageCounter;
559
+ } catch (e) {
560
+ isTrue(false);
561
+ }
562
+ await postgresOn();
563
+ let result = await db.query(`select * from pgdb_test.names`);
564
+ isTrue(result[0].name == 'Morgo');
565
+ isTrue(stageCounter == 2);
566
+ }
567
+ },
568
+ {
569
+ name: 'dedicated connection - simple query 6',
570
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
571
+ let stageCounter = 0;
572
+ let db0 = await db.dedicatedConnectionBegin();
573
+ await db0.run(`truncate pgdb_test.names`)
574
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
575
+ await postgresOff();
576
+ try {
577
+ await db0.query(`select * from pgdb_test.names`);
578
+ isTrue(false);
579
+ } catch (e) {
580
+ ++stageCounter;
581
+ }
582
+ await postgresOn();
583
+ try {
584
+ await db0.dedicatedConnectionEnd();
585
+ ++stageCounter;
586
+ } catch (e) {
587
+ isTrue(false);
588
+ }
589
+ let result = await db.query(`select * from pgdb_test.names`);
590
+ isTrue(result[0].name == 'Morgo');
591
+ isTrue(stageCounter == 2);
592
+ }
593
+ },
594
+ {
595
+ name: 'transaction - simple query 7',
596
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
597
+ let stageCounter = 0;
598
+ await db.run(`truncate pgdb_test.names`)
599
+ let db0 = await db.transactionBegin();
600
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
601
+ await postgresOff();
602
+ try {
603
+ await db0.query(`select * from pgdb_test.names`);
604
+ isTrue(false);
605
+ } catch (e) {
606
+ ++stageCounter;
607
+ }
608
+ await postgresOn();
609
+ let result = await db.query(`select * from pgdb_test.names`);
610
+ isTrue(result.length == 0);
611
+ isTrue(stageCounter == 1);
612
+ }
613
+ },
614
+ {
615
+ name: 'transaction - simple query 8',
616
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
617
+ let stageCounter = 0;
618
+ await db.run(`truncate pgdb_test.names`)
619
+ let db0 = await db.transactionBegin();
620
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
621
+ await postgresOff();
622
+ try {
623
+ await db0.query(`select * from pgdb_test.names`);
624
+ isTrue(false);
625
+ } catch (e) {
626
+ ++stageCounter;
627
+ }
628
+ await postgresOn();
629
+ try {
630
+ await db0.transactionCommit();
631
+ isTrue(false);
632
+ } catch (e) {
633
+ ++stageCounter;
634
+ }
635
+ let result = await db.query(`select * from pgdb_test.names`);
636
+ isTrue(result.length == 0);
637
+ isTrue(stageCounter == 2);
638
+ }
639
+ },
640
+ {
641
+ name: 'transaction - simple query 9',
642
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
643
+ let stageCounter = 0;
644
+ await db.run(`truncate pgdb_test.names`)
645
+ let db0 = await db.transactionBegin();
646
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
647
+ await postgresOff();
648
+ try {
649
+ await db0.query(`select * from pgdb_test.names`);
650
+ isTrue(false);
651
+ } catch (e) {
652
+ ++stageCounter;
653
+ }
654
+ try {
655
+ await db0.transactionCommit();
656
+ isTrue(false);
657
+ } catch (e) {
658
+ ++stageCounter;
659
+ }
660
+ await postgresOn();
661
+ let result = await db.query(`select * from pgdb_test.names`);
662
+ isTrue(result.length == 0);
663
+ isTrue(stageCounter == 2);
664
+ }
665
+ },
666
+ {
667
+ name: 'transaction - simple query 10',
668
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
669
+ let stageCounter = 0;
670
+ await db.run(`truncate pgdb_test.names`)
671
+ let db0 = await db.transactionBegin();
672
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
673
+ await postgresOff();
674
+ try {
675
+ await db0.query(`select * from pgdb_test.names`);
676
+ isTrue(false);
677
+ } catch (e) {
678
+ ++stageCounter;
679
+ }
680
+ await postgresOn();
681
+ let result = await db.query(`select * from pgdb_test.names`);
682
+ isTrue(result.length == 0);
683
+ isTrue(stageCounter == 1);
684
+ }
685
+ },
686
+ {
687
+ name: 'transaction - simple query 11',
688
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
689
+ let stageCounter = 0;
690
+ await db.run(`truncate pgdb_test.names`)
691
+ let db0 = await db.transactionBegin();
692
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
693
+ await postgresOff();
694
+ try {
695
+ await db0.transactionCommit();
696
+ isTrue(false);
697
+ } catch (e) {
698
+ ++stageCounter;
699
+ }
700
+ await postgresOn();
701
+ let result = await db.query(`select * from pgdb_test.names`);
702
+ isTrue(result.length == 0);
703
+ isTrue(stageCounter == 1);
704
+ }
705
+ },
706
+ {
707
+ name: 'transaction - rollback 1',
708
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
709
+ let stageCounter = 0;
710
+ await db.run(`truncate pgdb_test.names`)
711
+ let db0 = await db.transactionBegin();
712
+ await postgresOff();
713
+ try {
714
+ await db0.transactionRollback();
715
+ isTrue(false);
716
+ } catch (e) {
717
+ ++stageCounter;
718
+ }
719
+ isTrue(stageCounter == 1);
720
+ }
721
+ },
722
+ {
723
+ name: 'transaction - rollback 2',
724
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
725
+ let stageCounter = 0;
726
+ await db.run(`truncate pgdb_test.names`)
727
+ let db0 = await db.transactionBegin();
728
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
729
+ await postgresOff();
730
+ try {
731
+ await db0.transactionRollback();
732
+ isTrue(false);
733
+ } catch (e) {
734
+ ++stageCounter;
735
+ }
736
+ isTrue(stageCounter == 1);
737
+ }
738
+ },
739
+ {
740
+ name: 'transaction - rollback 3',
741
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
742
+ let stageCounter = 0;
743
+ await db.run(`truncate pgdb_test.names`)
744
+ let db0 = await db.transactionBegin();
745
+ await postgresOff();
746
+ try {
747
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
748
+ isTrue(false);
749
+ } catch (e) {
750
+ ++stageCounter;
751
+ }
752
+ try {
753
+ await db0.transactionRollback();
754
+ isTrue(false);
755
+ } catch (e) {
756
+ ++stageCounter;
757
+ }
758
+ isTrue(stageCounter == 2);
759
+ }
760
+ },
761
+ {
762
+ name: 'transaction - rollback 4',
763
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
764
+ let stageCounter = 0;
765
+ await db.run(`truncate pgdb_test.names`)
766
+ let db0 = await db.transactionBegin();
767
+ await postgresOff();
768
+ try {
769
+ await db0.run(`insert into pgdb_test.names (name) values ('Morgo')`);
770
+ isTrue(false);
771
+ } catch (e) {
772
+ ++stageCounter;
773
+ }
774
+ await postgresOn();
775
+ try {
776
+ await db0.transactionRollback();
777
+ isTrue(false);
778
+ } catch (e) {
779
+ ++stageCounter;
780
+ }
781
+ isTrue(stageCounter == 2);
782
+ }
783
+ }
784
+ ];
785
+
786
+ let dedicatedConnection_StreamQueryTests: TestDescriptor[] = [
787
+ {
788
+ name: 'dedicated connection queryWithCallback - 1',
789
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
790
+ let stageCounter = 0;
791
+ let db0 = await db.dedicatedConnectionBegin();
792
+ await postgresOff();
793
+ let i = 0;
794
+ try {
795
+ await db0.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, (data) => { ++i });
796
+ isTrue(false);
797
+ } catch (e) {
798
+ ++stageCounter;
799
+ }
800
+ isTrue(i == 0);
801
+ isTrue(stageCounter == 1);
802
+ }
803
+ },
804
+ {
805
+ name: 'dedicated connection queryWithCallback - 1',
806
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
807
+ let stageCounter = 0;
808
+ let db0 = await db.dedicatedConnectionBegin();
809
+ await postgresOff();
810
+ let i = 0;
811
+ try {
812
+ await db0.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, (data) => { ++i });
813
+ isTrue(false);
814
+ } catch (e) {
815
+ ++stageCounter;
816
+ }
817
+ try {
818
+ await db0.dedicatedConnectionEnd();
819
+ ++stageCounter;
820
+ } catch (e) {
821
+ isTrue(false);
822
+ }
823
+ isTrue(i == 0);
824
+ isTrue(stageCounter == 2);
825
+ }
826
+ },
827
+ {
828
+ name: 'dedicated connection queryWithCallback - 3',
829
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
830
+ let stageCounter = 0;
831
+ let db0 = await db.dedicatedConnectionBegin();
832
+ await postgresOff();
833
+ try {
834
+ await db0.query(`select * from pgdb_test.names`);
835
+ isTrue(false);
836
+ } catch (e) {
837
+ ++stageCounter;
838
+ }
839
+ let i = 0;
840
+ try {
841
+ await db0.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, (data) => { ++i });
842
+ isTrue(false);
843
+ } catch (e) {
844
+ ++stageCounter;
845
+ }
846
+ isTrue(i == 0);
847
+ isTrue(stageCounter == 2);
848
+ }
849
+ },
850
+ {
851
+ name: 'dedicated connection queryWithCallback 4 - postgresOff between calls',
852
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
853
+ let stageCounter = 0;
854
+
855
+ let params = new Array(2000).fill(null).map((v, i) => `'Smith${i}'`).map(v => `(${v})`).join(', ');
856
+ await db.run(`INSERT INTO pgdb_test.names(name) values ${params}`);
857
+
858
+ let db0 = await db.dedicatedConnectionBegin();
859
+ let i = 0;
860
+ let fn1 = async () => {
861
+ try {
862
+ await db0.queryWithOnCursorCallback('select * from pgdb_test.names', {}, {}, (data) => {
863
+ syncWaitMs(20);
864
+ ++i;
865
+ if (i % 10 == 0) {
866
+ console.log('Record:', i);
867
+ }
868
+ });
869
+ isTrue(false);
870
+ } catch (e) {
871
+ ++stageCounter;
872
+ }
873
+ }
874
+ let fn2 = async () => {
875
+ console.log('Wait before postgres off...');
876
+ await asyncWaitMs(100);
877
+ await postgresOff();
878
+ }
879
+ await Promise.all([fn1(), fn2()]);
880
+ isTrue(i > 0 && i < 2000);
881
+ isTrue(stageCounter == 1);
882
+ },
883
+ },
884
+ {
885
+ name: 'dedicated connection queryWithCallback 5 - postgresOff between calls, unknown oid',
886
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
887
+ let stageCounter = 0;
888
+
889
+ let params = new Array(2000).fill(null).map((v) => `ARRAY['sad'::pgdb_test.mood, 'happy'::pgdb_test.mood]`).map(v => `(${v})`).join(', ');
890
+ await db.run(`INSERT INTO pgdb_test."enumArrayTable"(m) values ${params}`);
891
+
892
+ let db0 = await db.dedicatedConnectionBegin();
893
+ let i = 0;
894
+ let fn1 = async () => {
895
+ try {
896
+ await db0.queryWithOnCursorCallback('select * from pgdb_test."enumArrayTable"', {}, {}, (data) => {
897
+ syncWaitMs(20);
898
+ ++i;
899
+ if (i % 10 == 0) {
900
+ console.log('Record:', i);
901
+ }
902
+ });
903
+ isTrue(false);
904
+ } catch (e) {
905
+ ++stageCounter;
906
+ }
907
+ }
908
+ let fn2 = async () => {
909
+ console.log('Wait before postgres off...');
910
+ await asyncWaitMs(100);
911
+ await postgresOff();
912
+ }
913
+ await Promise.all([fn1(), fn2()]);
914
+ isTrue(i > 0 && i < 2000);
915
+ isTrue(stageCounter == 1);
916
+ },
917
+ },
918
+
919
+ {
920
+ name: 'dedicated connection queryAsStream - 1',
921
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
922
+ let stageCounter = 0;
923
+ let db0 = await db.dedicatedConnectionBegin();
924
+ await postgresOff();
925
+ let stream;
926
+ try {
927
+ stream = await db0.queryAsStream(`select * from pgdb_test.names`);
928
+ ++stageCounter;
929
+ } catch (e) {
930
+ isTrue(false);
931
+ }
932
+ try {
933
+ await new Promise<any>((resolve, reject) => {
934
+ stream.on("data", (data) => {
935
+ isTrue(false);
936
+ });
937
+ stream.on('error', (...params) => {
938
+ ++stageCounter;
939
+ reject(...params);
940
+ });
941
+ stream.on('close', resolve);
942
+ });
943
+ isTrue(false);
944
+ } catch (e) {
945
+ ++stageCounter;
946
+ }
947
+ isTrue(stageCounter == 3);
948
+ }
949
+ },
950
+ {
951
+ name: 'dedicated connection queryAsStream - 2',
952
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
953
+ let stageCounter = 0;
954
+ let db0 = await db.dedicatedConnectionBegin();
955
+ await postgresOff();
956
+ let stream;
957
+ try {
958
+ stream = await db0.queryAsStream(`select * from pgdb_test.names`);
959
+ ++stageCounter;
960
+ } catch (e) {
961
+ isTrue(false);
962
+ }
963
+ try {
964
+ await new Promise<any>((resolve, reject) => {
965
+ stream.on("data", (data) => {
966
+ isTrue(false);
967
+ });
968
+ stream.on('error', (...params) => {
969
+ ++stageCounter;
970
+ reject(...params);
971
+ });
972
+ stream.on('close', resolve);
973
+ });
974
+ isTrue(false);
975
+ } catch (e) {
976
+ ++stageCounter;
977
+ }
978
+ try {
979
+ await db0.dedicatedConnectionEnd();
980
+ ++stageCounter;
981
+ } catch (e) {
982
+ isTrue(false);
983
+ }
984
+ isTrue(stageCounter == 4);
985
+ }
986
+ },
987
+ {
988
+ name: 'dedicated connection queryAsStream - 3',
989
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
990
+ let stageCounter = 0;
991
+ let db0 = await db.dedicatedConnectionBegin();
992
+ await postgresOff();
993
+ try {
994
+ await db0.query(`select * from pgdb_test.names`);
995
+ isTrue(false);
996
+ } catch (e) {
997
+ ++stageCounter;
998
+ }
999
+ let stream;
1000
+ try {
1001
+ stream = await db0.queryAsStream(`select * from pgdb_test.names`);
1002
+ ++stageCounter;
1003
+ } catch (e) {
1004
+ isTrue(false);
1005
+ }
1006
+ try {
1007
+ await new Promise<any>((resolve, reject) => {
1008
+ stream.on("data", (data) => {
1009
+ isTrue(false);
1010
+ });
1011
+ stream.on('error', (...params) => {
1012
+ ++stageCounter;
1013
+ reject(...params);
1014
+ });
1015
+ stream.on('close', resolve);
1016
+ });
1017
+ isTrue(false);
1018
+ } catch (e) {
1019
+ ++stageCounter;
1020
+ }
1021
+ isTrue(stageCounter == 4);
1022
+ }
1023
+ },
1024
+ {
1025
+ name: 'dedicated connection queryAsStream 4 - postgresOff between calls',
1026
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1027
+ let stageCounter = 0;
1028
+
1029
+ let params = new Array(2000).fill(null).map((v, i) => `'Smith${i}'`).map(v => `(${v})`).join(', ');
1030
+ await db.run(`INSERT INTO pgdb_test.names(name) values ${params}`);
1031
+
1032
+ let db0 = await db.dedicatedConnectionBegin();
1033
+ let stream = await db0.queryAsStream('select * from pgdb_test.names');
1034
+
1035
+ let i = 0;
1036
+ let promise1 = new Promise<any>((resolve, reject) => {
1037
+ stream.on("data", (data) => {
1038
+ syncWaitMs(20);
1039
+ ++i;
1040
+ if (i % 10 == 0) {
1041
+ console.log(data.name);
1042
+ }
1043
+ });
1044
+ stream.on('error', (...params) => {
1045
+ ++stageCounter;
1046
+ reject(...params);
1047
+ });
1048
+ stream.on('close', resolve);
1049
+ });
1050
+
1051
+ let fn2 = async () => {
1052
+ await asyncWaitMs(100);
1053
+ await postgresOff();
1054
+ }
1055
+ try {
1056
+ await Promise.all([promise1, fn2()]);
1057
+ isTrue(false);
1058
+ } catch (e) {
1059
+ ++stageCounter;
1060
+ }
1061
+ isTrue(i > 0 && i < 2000);
1062
+ isTrue(stageCounter == 2);
1063
+ },
1064
+ },
1065
+ {
1066
+ name: 'dedicated connection queryAsStream 5 - postgresOff between calls, unknown oid',
1067
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1068
+ let stageCounter = 0;
1069
+
1070
+ let params = new Array(2000).fill(null).map((v) => `ARRAY['sad'::pgdb_test.mood, 'happy'::pgdb_test.mood]`).map(v => `(${v})`).join(', ');
1071
+ await db.run(`INSERT INTO pgdb_test."enumArrayTable"(m) values ${params}`);
1072
+
1073
+ let db0 = await db.dedicatedConnectionBegin();
1074
+ let stream = await db0.queryAsStream('select * from pgdb_test."enumArrayTable"');
1075
+ let i = 0;
1076
+ let promise1 = new Promise<any>((resolve, reject) => {
1077
+ stream.on("data", (data) => {
1078
+ syncWaitMs(20);
1079
+ ++i;
1080
+ if (i % 10 == 0) {
1081
+ console.log(data.name);
1082
+ }
1083
+ });
1084
+ stream.on('error', (...params) => {
1085
+ ++stageCounter;
1086
+ reject(...params);
1087
+ });
1088
+ stream.on('close', resolve);
1089
+ });
1090
+
1091
+ let fn2 = async () => {
1092
+ await asyncWaitMs(100);
1093
+ await postgresOff();
1094
+ }
1095
+ try {
1096
+ await Promise.all([promise1, fn2()]);
1097
+ isTrue(false);
1098
+ } catch (e) {
1099
+ ++stageCounter;
1100
+ }
1101
+ isTrue(i == 0);
1102
+ isTrue(stageCounter == 2);
1103
+ await postgresOff(); // To ensure, that postgresql stopped perfectly.
1104
+ },
1105
+ }
1106
+ ];
1107
+
1108
+ let postgresRestartTests: TestDescriptor[] = [
1109
+ {
1110
+ name: 'postgres restart 1',
1111
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1112
+ let stageCounter = 0;
1113
+ let db0 = await db.dedicatedConnectionBegin();
1114
+ await postgresOff();
1115
+ await postgresOn();
1116
+ try {
1117
+ await db0.dedicatedConnectionEnd();
1118
+ ++stageCounter;
1119
+ } catch (e) {
1120
+ isTrue(false);
1121
+ }
1122
+ isTrue(stageCounter == 1);
1123
+ }
1124
+ },
1125
+ {
1126
+ name: 'postgres restart 2',
1127
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1128
+ let stageCounter = 0;
1129
+ let db0 = await db.transactionBegin();
1130
+ await postgresOff();
1131
+ await postgresOn();
1132
+ try {
1133
+ await db0.transactionRollback();
1134
+ isTrue(false);
1135
+ } catch (e) {
1136
+ ++stageCounter;
1137
+
1138
+ }
1139
+ isTrue(stageCounter == 1);
1140
+ }
1141
+ },
1142
+ {
1143
+ name: 'postgres restart 3',
1144
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1145
+ let stageCounter = 0;
1146
+ let db0 = await db.dedicatedConnectionBegin();
1147
+ await postgresOff();
1148
+ await postgresOn();
1149
+ try {
1150
+ let result = await db0.query(`select * from pgdb_test.names`);
1151
+ isTrue(false);
1152
+ } catch (e) {
1153
+ ++stageCounter;
1154
+
1155
+ }
1156
+ isTrue(stageCounter == 1);
1157
+ }
1158
+ },
1159
+ {
1160
+ name: 'postgres restart 4',
1161
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1162
+ let stageCounter = 0;
1163
+ let db0 = await db.dedicatedConnectionBegin();
1164
+ await postgresOff();
1165
+ await postgresOn();
1166
+ try {
1167
+ let result = await db0.queryWithOnCursorCallback(`select * from pgdb_test.names`, {}, {}, (data) => {
1168
+ isTrue(false);
1169
+ });
1170
+ isTrue(false);
1171
+ } catch (e) {
1172
+ ++stageCounter;
1173
+
1174
+ }
1175
+ isTrue(stageCounter == 1);
1176
+ }
1177
+ },
1178
+ {
1179
+ name: 'postgres restart 5',
1180
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1181
+ let stageCounter = 0;
1182
+ let db0 = await db.dedicatedConnectionBegin();
1183
+ await postgresOff();
1184
+ await postgresOn();
1185
+ let stream;
1186
+ try {
1187
+ stream = await db0.queryAsStream(`select * from pgdb_test.names`);
1188
+ ++stageCounter;
1189
+ } catch (e) {
1190
+ isTrue(false);
1191
+ }
1192
+ try {
1193
+ await new Promise<any>((resolve, reject) => {
1194
+ stream.on("data", (data) => {
1195
+ isTrue(false);
1196
+ });
1197
+ stream.on('error', (...params) => {
1198
+ ++stageCounter;
1199
+ reject(...params);
1200
+ });
1201
+ stream.on('close', resolve);
1202
+ });
1203
+ isTrue(false);
1204
+ } catch (e) {
1205
+ ++stageCounter;
1206
+ }
1207
+ isTrue(stageCounter == 3);
1208
+ }
1209
+ },
1210
+ ];
1211
+
1212
+ let postgresEndTests: TestDescriptor[] = [
1213
+ {
1214
+ name: 'postgres end 1',
1215
+ skipTestDb: true,
1216
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1217
+ let stageCounter = 0;
1218
+ let db0 = await db.dedicatedConnectionBegin();
1219
+ await postgresOff();
1220
+ try {
1221
+ await db.close();
1222
+ ++stageCounter;
1223
+ } catch (e) {
1224
+ isTrue(false);
1225
+ }
1226
+ isTrue(stageCounter == 1);
1227
+ }
1228
+ }
1229
+ ]
1230
+
1231
+ let notifyTests: TestDescriptor[] = [
1232
+ {
1233
+ name: 'notification 1',
1234
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1235
+ let stageCounter = 0;
1236
+ await postgresOff();
1237
+ try {
1238
+ await db.listen('newChannel', (notif) => { });
1239
+ isTrue(false);
1240
+ } catch (e) {
1241
+ ++stageCounter;
1242
+ }
1243
+ isTrue(stageCounter == 1);
1244
+ }
1245
+ },
1246
+ {
1247
+ name: 'notification 2',
1248
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1249
+ await db.listen('newChannel', (notif) => { });
1250
+ await postgresOff();
1251
+ await postgresOn();
1252
+ await db.unlisten('newChannel');
1253
+ }
1254
+ },
1255
+ {
1256
+ name: 'notification 3',
1257
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1258
+ let result: string;
1259
+ await db.listen('newChannel', (notif) => { result = notif.payload });
1260
+ await postgresOff();
1261
+ await postgresOn();
1262
+ await db.notify('newChannel', 'newValue');
1263
+ await asyncWaitMs(1000);
1264
+ isTrue(result == 'newValue');
1265
+ await db.unlisten('newChannel'); //To empty the queue
1266
+ }
1267
+ },
1268
+ {
1269
+ name: 'notification 4',
1270
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1271
+ let result: string;
1272
+ await db.listen('newChannel', (notif) => { result = notif.payload });
1273
+ await postgresOff();
1274
+ await postgresOn();
1275
+ await db.run(`notify "newChannel", 'newValue'`);
1276
+ await asyncWaitMs(1000);
1277
+ isTrue(result == 'newValue');
1278
+ await db.unlisten('newChannel'); //To empty the queue
1279
+ }
1280
+ },
1281
+ {
1282
+ name: 'notification 5',
1283
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1284
+ let result: string;
1285
+ await db.listen('newChannel', (notif) => { result = notif.payload });
1286
+ await postgresOff();
1287
+ await postgresOn();
1288
+ let db0 = await db.dedicatedConnectionBegin();
1289
+ await db0.run(`notify "newChannel", 'newValue'`);
1290
+ await asyncWaitMs(1000);
1291
+ isTrue(result == 'newValue');
1292
+ await db.unlisten('newChannel'); //To empty the queue
1293
+ await db0.dedicatedConnectionEnd();
1294
+ }
1295
+ },
1296
+ {
1297
+ name: 'notification 6',
1298
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1299
+ let i = 0;
1300
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1301
+ let fn2 = (notif: Notification) => { i += 2 * (+notif.payload) };
1302
+ await db.listen('newChannel', fn1);
1303
+ await postgresOff();
1304
+ await db.listen('newChannel', fn2);
1305
+ await postgresOn();
1306
+ await db.notify('newChannel', '1');
1307
+ await asyncWaitMs(1000);
1308
+ isTrue(i == 3);
1309
+ await db.unlisten('newChannel'); //To empty the queue
1310
+ }
1311
+ },
1312
+ {
1313
+ name: 'notification 7',
1314
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1315
+ let i = 0;
1316
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1317
+ let fn2 = (notif: Notification) => { i += 2 * (+notif.payload) };
1318
+ await db.listen('newChannel', fn1);
1319
+ await postgresOff();
1320
+ await db.listen('newChannel', fn2);
1321
+ await db.unlisten('newChannel', fn1);
1322
+ await postgresOn();
1323
+ await db.notify('newChannel', '1');
1324
+ await asyncWaitMs(1000);
1325
+ isTrue(i == 2);
1326
+ await db.unlisten('newChannel'); //To empty the queue
1327
+ }
1328
+ },
1329
+ {
1330
+ name: 'notification 8',
1331
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1332
+ let i = 0;
1333
+ let j = 0;
1334
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1335
+ let fn2 = (notif: Notification) => { j += +notif.payload };
1336
+ await db.listen('newChannel', fn1);
1337
+ await postgresOff();
1338
+ try {
1339
+ await db.listen('newChannel2', fn2);
1340
+ isTrue(false);
1341
+ } catch (e) {
1342
+ }
1343
+ await postgresOn();
1344
+ await db.notify('newChannel', '1');
1345
+ await db.notify('newChannel2', '1');
1346
+ await asyncWaitMs(1000);
1347
+ isTrue(i == 1);
1348
+ isTrue(j == 0);
1349
+ await db.unlisten('newChannel'); //To empty the queue
1350
+ }
1351
+ },
1352
+ {
1353
+ name: 'notification 9',
1354
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1355
+ let i = 0;
1356
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1357
+ await db.listen('newChannel', fn1);
1358
+ await postgresOff();
1359
+ try {
1360
+ await db.unlisten('newChannel', fn1);
1361
+ isTrue(false);
1362
+ } catch (e) {
1363
+ }
1364
+ await postgresOn();
1365
+ await db.notify('newChannel', '1');
1366
+ await asyncWaitMs(1000);
1367
+ isTrue(i == 1);
1368
+ await db.unlisten('newChannel'); //To empty the queue
1369
+ }
1370
+ },
1371
+ {
1372
+ name: 'notification 10',
1373
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1374
+ let i = 0;
1375
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1376
+ await db.listen('newChannel', fn1);
1377
+ await postgresOff();
1378
+ try {
1379
+ await db.unlisten('newChannel');
1380
+ isTrue(false);
1381
+ } catch (e) {
1382
+ }
1383
+ await postgresOn();
1384
+ await db.notify('newChannel', '1');
1385
+ await asyncWaitMs(1000);
1386
+ isTrue(i == 1);
1387
+ await db.unlisten('newChannel'); //To empty the queue
1388
+ }
1389
+ },
1390
+ {
1391
+ name: 'notification 11 - automatic notification restart...',
1392
+ fn: async (db: PgDb, isTrue: (value: boolean) => void) => {
1393
+ let i = 0;
1394
+ let fn1 = (notif: Notification) => { i += +notif.payload };
1395
+ await db.listen('newChannel', fn1);
1396
+ await postgresOff();
1397
+ await postgresOn();
1398
+ await asyncWaitMs(3000);
1399
+ let db2 = await PgDb.connect({});
1400
+ await db2.notify('newChannel', '1');
1401
+ await db2.close();
1402
+ await asyncWaitMs(1000);
1403
+ isTrue(i == 1);
1404
+ await db.unlisten('newChannel'); //To empty the queue
1405
+ }
1406
+ }
1407
+ ];
1408
+
1409
+ async function testParams() {
1410
+ console.log('Start testing params');
1411
+
1412
+ let postgresOnCommandOk = true;
1413
+ let postgresOffCommandOk = false;
1414
+ let frameworkError = false;
1415
+ try {
1416
+ console.log('Postgres On test');
1417
+ await postgresOn();
1418
+ try {
1419
+ let db = await PgDb.connect({});
1420
+ } catch (e) {
1421
+ postgresOnCommandOk = false;
1422
+ }
1423
+ console.log('Postgres Off test');
1424
+ await postgresOff();
1425
+ try {
1426
+ let db = await PgDb.connect({});
1427
+ } catch (e) {
1428
+ postgresOffCommandOk = postgresOnCommandOk;
1429
+ }
1430
+ console.log('Postgres On test');
1431
+ await postgresOn();
1432
+ try {
1433
+ let db = await PgDb.connect({});
1434
+ } catch (e) {
1435
+ postgresOnCommandOk = false;
1436
+ }
1437
+ } catch (e) {
1438
+ console.log('Unknown exception has found', e);
1439
+ frameworkError = true;
1440
+ }
1441
+ if (!frameworkError) {
1442
+ if (postgresOffCommandOk && postgresOnCommandOk) {
1443
+ console.log('Postgres On/Off commands OK');
1444
+ } else {
1445
+ if (!postgresOnCommandOk) {
1446
+ console.log('Postgres On command NOT OK');
1447
+ }
1448
+ if (!postgresOffCommandOk) {
1449
+ console.log('Postgres Off command NOT OK');
1450
+ }
1451
+ }
1452
+ }
1453
+ console.log('Postgres On/Off test end');
1454
+ }
1455
+
1456
+ async function runTests() {
1457
+ console.log('Start tests');
1458
+
1459
+ let allTests = [
1460
+ ...newConnectionTests,
1461
+ ...dedicatedConnection_SimpleQueryTests,
1462
+ ...dedicatedConnection_StreamQueryTests,
1463
+ ...postgresRestartTests,
1464
+ ...notifyTests,
1465
+ ...postgresEndTests
1466
+ ];
1467
+ let testNamePrefix = '';
1468
+ try {
1469
+ if (testNamePrefix) {
1470
+ allTests = allTests.filter(v => v.name.startsWith(testNamePrefix));
1471
+ }
1472
+ for (let test of allTests) {
1473
+ await runTest(allTests.length, test);
1474
+ }
1475
+
1476
+ console.log('All tests: ', actTestCounter);
1477
+ console.log(`Problematic tests: ${errorMessages.length}`);
1478
+ for (let errorMessage of errorMessages) {
1479
+ console.log(`Error in "${errorMessage.testName}"`);
1480
+ console.log(errorMessage.err);
1481
+ }
1482
+ } catch (e) {
1483
+ console.log('Error has found in the test framework!');
1484
+ console.log(e);
1485
+ }
1486
+ console.log('All tests are finished');
1487
+ }
1488
+
1489
+ (async () => {
1490
+ if (!argv.postgresOn || !argv.postgresOff) {
1491
+ console.log('postgresOn or postgresOff parameter is missing!');
1492
+ return;
1493
+ }
1494
+
1495
+ if (argv.testParams) {
1496
+ await testParams();
1497
+ } else {
1498
+ await runTests();
1499
+ }
1500
+ })().catch(console.log);