@nymphjs/driver-postgresql 1.0.0-beta.77 → 1.0.0-beta.78

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 CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.0.0-beta.78](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.77...v1.0.0-beta.78) (2024-09-27)
7
+
8
+ ### Bug Fixes
9
+
10
+ - don't use transactions for import, to avoid issues when creating tables ([2f8f715](https://github.com/sciactive/nymphjs/commit/2f8f71545de6ca2f3235a9f3a3c91107f58129bf))
11
+ - potential bug with nulls in postgres ([1d8bc50](https://github.com/sciactive/nymphjs/commit/1d8bc500d752b1ef59d6591f3045bf4976eb7c00))
12
+
13
+ ### Features
14
+
15
+ - add method to detect if migration is needed ([274f7c3](https://github.com/sciactive/nymphjs/commit/274f7c39aa4e0d251a38c01593775e1270fc9621))
16
+ - move comparison fields to data table and remove comparison table ([3d7fe7e](https://github.com/sciactive/nymphjs/commit/3d7fe7e614327ecf8903ee7143e559549793e8fc))
17
+
18
+ ### BREAKING CHANGES
19
+
20
+ - This is a breaking change, and requires export and
21
+ import of the database.
22
+
6
23
  # [1.0.0-beta.77](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.76...v1.0.0-beta.77) (2024-09-26)
7
24
 
8
25
  ### Bug Fixes
@@ -112,5 +112,6 @@ export default class PostgreSQLDriver extends NymphDriver {
112
112
  setUID(name: string, curUid: number): Promise<boolean>;
113
113
  protected internalTransaction(name: string): Promise<PostgreSQLDriverTransaction>;
114
114
  startTransaction(name: string): Promise<import("@nymphjs/nymph").Nymph>;
115
+ needsMigration(): Promise<boolean>;
115
116
  }
116
117
  export {};
@@ -50,8 +50,8 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
50
50
  }
51
51
  static unescapeNulls(input) {
52
52
  return input
53
- .replace(/\uFFFD\uFFFD/g, () => '\uFFFD')
54
- .replace(/-\uFFFD-/g, () => '\x00');
53
+ .replace(/-\uFFFD-/g, () => '\x00')
54
+ .replace(/\uFFFD\uFFFD/g, () => '\uFFFD');
55
55
  }
56
56
  constructor(config, link, transaction) {
57
57
  super();
@@ -195,6 +195,9 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
195
195
  "name" TEXT NOT NULL,
196
196
  "value" CHARACTER(1) NOT NULL,
197
197
  "json" JSONB,
198
+ "string" TEXT,
199
+ "number" DOUBLE PRECISION,
200
+ "truthy" BOOLEAN,
198
201
  PRIMARY KEY ("guid", "name"),
199
202
  FOREIGN KEY ("guid")
200
203
  REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
@@ -202,41 +205,26 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
202
205
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
203
206
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)};`, { connection });
204
207
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid");`, { connection });
205
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)};`, { connection });
206
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name");`, { connection });
208
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name`)};`, { connection });
209
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name");`, { connection });
207
210
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__user`)};`, { connection });
208
211
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__user`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name" = 'user'::text;`, { connection });
209
212
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__group`)};`, { connection });
210
213
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name__group`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid") WHERE "name" = 'group'::text;`, { connection });
211
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_value`)};`, { connection });
212
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_value`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "value");`, { connection });
214
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)};`, { connection });
215
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name");`, { connection });
216
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string`)};`, { connection });
217
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", LEFT("string", 512));`, { connection });
218
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number`)};`, { connection });
219
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "number");`, { connection });
220
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)};`, { connection });
221
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name") WHERE "truthy" = TRUE;`, { connection });
222
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_falsy`)};`, { connection });
223
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_falsy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name") WHERE "truthy" <> TRUE;`, { connection });
224
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_string`)};`, { connection });
225
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_string`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("string" gin_trgm_ops);`, { connection });
213
226
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_json`)};`, { connection });
214
227
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_json`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("json");`, { connection });
215
- // Create the data comparisons table.
216
- await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} (
217
- "guid" BYTEA NOT NULL,
218
- "name" TEXT NOT NULL,
219
- "truthy" BOOLEAN,
220
- "string" TEXT,
221
- "number" DOUBLE PRECISION,
222
- PRIMARY KEY ("guid", "name"),
223
- FOREIGN KEY ("guid")
224
- REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
225
- ) WITH ( OIDS=FALSE );`, { connection });
226
- await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
227
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_guid`)};`, { connection });
228
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("guid");`, { connection });
229
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name`)};`, { connection });
230
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("name");`, { connection });
231
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_truthy`)};`, { connection });
232
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("name") WHERE "truthy" = TRUE;`, { connection });
233
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_falsy`)};`, { connection });
234
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_falsy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("name") WHERE "truthy" <> TRUE;`, { connection });
235
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_string`)};`, { connection });
236
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_string`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("name", LEFT("string", 512));`, { connection });
237
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_stringgin`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING gin ("string" gin_trgm_ops);`, { connection });
238
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_number`)};`, { connection });
239
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}_id_name_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} USING btree ("name", "number");`, { connection });
240
228
  // Create the references table.
241
229
  await this.queryRun(`CREATE TABLE IF NOT EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} (
242
230
  "guid" BYTEA NOT NULL,
@@ -412,12 +400,6 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
412
400
  guid,
413
401
  },
414
402
  });
415
- await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
416
- etypes: [etype],
417
- params: {
418
- guid,
419
- },
420
- });
421
403
  await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
422
404
  etypes: [etype],
423
405
  params: {
@@ -498,20 +480,21 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
498
480
  return;
499
481
  }
500
482
  // Get the etypes.
501
- const tables = await this.queryIter('SELECT relname FROM pg_stat_user_tables ORDER BY relname;');
483
+ const tables = await this.queryIter('SELECT "table_name" AS "table_name" FROM "information_schema"."tables" WHERE "table_catalog"=@db AND "table_schema"=\'public\' AND "table_name" LIKE @prefix;', {
484
+ params: {
485
+ db: this.config.database,
486
+ prefix: this.prefix + 'entities_' + '%',
487
+ },
488
+ });
502
489
  const etypes = [];
503
- for (const tableRow of tables) {
504
- const table = tableRow.relname;
505
- if (table.startsWith(this.prefix + 'entities_')) {
506
- etypes.push(table.substr((this.prefix + 'entities_').length));
507
- }
490
+ for (const table of tables) {
491
+ etypes.push(table.table_name.substr((this.prefix + 'entities_').length));
508
492
  }
509
493
  for (const etype of etypes) {
510
494
  // Export entities.
511
- 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", d."json" AS "djson", c."string", c."number"
495
+ const dataIterator = (await this.queryIter(`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", d."name", d."value", d."json", d."string", d."number"
512
496
  FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} e
513
497
  LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} d ON e."guid"=d."guid"
514
- INNER JOIN ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} c ON d."guid"=c."guid" AND d."name"=c."name"
515
498
  ORDER BY e."guid";`))[Symbol.iterator]();
516
499
  let datum = dataIterator.next();
517
500
  while (!datum.done) {
@@ -523,18 +506,18 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
523
506
  currentEntityExport.push(`{${guid}}<${etype}>[${tags}]`);
524
507
  currentEntityExport.push(`\tcdate=${JSON.stringify(cdate)}`);
525
508
  currentEntityExport.push(`\tmdate=${JSON.stringify(mdate)}`);
526
- if (datum.value.dname != null) {
509
+ if (datum.value.name != null) {
527
510
  // This do will keep going and adding the data until the
528
511
  // next entity is reached. $row will end on the next entity.
529
512
  do {
530
- const value = datum.value.dvalue === 'N'
513
+ const value = datum.value.value === 'N'
531
514
  ? JSON.stringify(Number(datum.value.number))
532
- : datum.value.dvalue === 'S'
515
+ : datum.value.value === 'S'
533
516
  ? JSON.stringify(PostgreSQLDriver.unescapeNulls(datum.value.string))
534
- : datum.value.dvalue === 'J'
535
- ? PostgreSQLDriver.unescapeNullSequences(JSON.stringify(datum.value.djson))
536
- : datum.value.dvalue;
537
- currentEntityExport.push(`\t${datum.value.dname}=${value}`);
517
+ : datum.value.value === 'J'
518
+ ? PostgreSQLDriver.unescapeNullSequences(JSON.stringify(datum.value.json))
519
+ : datum.value.value;
520
+ currentEntityExport.push(`\t${datum.value.name}=${value}`);
538
521
  datum = dataIterator.next();
539
522
  } while (!datum.done && datum.value.guid === guid);
540
523
  }
@@ -565,7 +548,6 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
565
548
  }
566
549
  const eTable = `e${tableSuffix}`;
567
550
  const dTable = `d${tableSuffix}`;
568
- const cTable = `c${tableSuffix}`;
569
551
  const fTable = `f${tableSuffix}`;
570
552
  const ieTable = `ie${tableSuffix}`;
571
553
  const countTable = `count${tableSuffix}`;
@@ -653,7 +635,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
653
635
  curQuery +=
654
636
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
655
637
  'EXISTS (SELECT "guid" FROM ' +
656
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
638
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
657
639
  ' WHERE "guid"=' +
658
640
  ieTable +
659
641
  '."guid" AND "name"=@' +
@@ -704,7 +686,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
704
686
  curQuery +=
705
687
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
706
688
  'EXISTS (SELECT "guid" FROM ' +
707
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
689
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
708
690
  ' WHERE "guid"=' +
709
691
  ieTable +
710
692
  '."guid" AND "name"=@' +
@@ -724,7 +706,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
724
706
  curQuery +=
725
707
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
726
708
  'EXISTS (SELECT "guid" FROM ' +
727
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
709
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
728
710
  ' WHERE "guid"=' +
729
711
  ieTable +
730
712
  '."guid" AND "name"=@' +
@@ -872,7 +854,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
872
854
  curQuery +=
873
855
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
874
856
  'EXISTS (SELECT "guid" FROM ' +
875
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
857
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
876
858
  ' WHERE "guid"=' +
877
859
  ieTable +
878
860
  '."guid" AND "name"=@' +
@@ -925,7 +907,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
925
907
  curQuery +=
926
908
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
927
909
  'EXISTS (SELECT "guid" FROM ' +
928
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
910
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
929
911
  ' WHERE "guid"=' +
930
912
  ieTable +
931
913
  '."guid" AND "name"=@' +
@@ -978,7 +960,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
978
960
  curQuery +=
979
961
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
980
962
  'EXISTS (SELECT "guid" FROM ' +
981
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
963
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
982
964
  ' WHERE "guid"=' +
983
965
  ieTable +
984
966
  '."guid" AND "name"=@' +
@@ -1031,7 +1013,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1031
1013
  curQuery +=
1032
1014
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
1033
1015
  'EXISTS (SELECT "guid" FROM ' +
1034
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
1016
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
1035
1017
  ' WHERE "guid"=' +
1036
1018
  ieTable +
1037
1019
  '."guid" AND "name"=@' +
@@ -1084,7 +1066,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1084
1066
  curQuery +=
1085
1067
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
1086
1068
  'EXISTS (SELECT "guid" FROM ' +
1087
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
1069
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
1088
1070
  ' WHERE "guid"=' +
1089
1071
  ieTable +
1090
1072
  '."guid" AND "name"=@' +
@@ -1139,7 +1121,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1139
1121
  curQuery +=
1140
1122
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
1141
1123
  'EXISTS (SELECT "guid" FROM ' +
1142
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
1124
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
1143
1125
  ' WHERE "guid"=' +
1144
1126
  ieTable +
1145
1127
  '."guid" AND "name"=@' +
@@ -1194,7 +1176,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1194
1176
  curQuery +=
1195
1177
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
1196
1178
  'EXISTS (SELECT "guid" FROM ' +
1197
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
1179
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
1198
1180
  ' WHERE "guid"=' +
1199
1181
  ieTable +
1200
1182
  '."guid" AND "name"=@' +
@@ -1249,7 +1231,7 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1249
1231
  curQuery +=
1250
1232
  ((0, nymph_1.xor)(typeIsNot, clauseNot) ? 'NOT ' : '') +
1251
1233
  'EXISTS (SELECT "guid" FROM ' +
1252
- PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype) +
1234
+ PostgreSQLDriver.escape(this.prefix + 'data_' + etype) +
1253
1235
  ' WHERE "guid"=' +
1254
1236
  ieTable +
1255
1237
  '."guid" AND "name"=@' +
@@ -1358,13 +1340,13 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1358
1340
  const name = `param${++count.i}`;
1359
1341
  sortJoin = `LEFT JOIN (
1360
1342
  SELECT "guid", "string", "number"
1361
- FROM ${PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype)}
1343
+ FROM ${PostgreSQLDriver.escape(this.prefix + 'data_' + etype)}
1362
1344
  WHERE "name"=@${name}
1363
1345
  ORDER BY "number"${order}, "string"${order}
1364
1346
  ) ${sTable} ON ${eTable}."guid"=${sTable}."guid"`;
1365
1347
  sortJoinInner = `LEFT JOIN (
1366
1348
  SELECT "guid", "string", "number"
1367
- FROM ${PostgreSQLDriver.escape(this.prefix + 'comparisons_' + etype)}
1349
+ FROM ${PostgreSQLDriver.escape(this.prefix + 'data_' + etype)}
1368
1350
  WHERE "name"=@${name}
1369
1351
  ORDER BY "number"${order}, "string"${order}
1370
1352
  ) ${sTable} ON ${ieTable}."guid"=${sTable}."guid"`;
@@ -1424,11 +1406,10 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1424
1406
  ${dTable}."name",
1425
1407
  ${dTable}."value",
1426
1408
  ${dTable}."json",
1427
- ${cTable}."string",
1428
- ${cTable}."number"
1409
+ ${dTable}."string",
1410
+ ${dTable}."number"
1429
1411
  FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ${eTable}
1430
1412
  LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
1431
- INNER JOIN ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
1432
1413
  ${sortJoin}
1433
1414
  INNER JOIN (
1434
1415
  SELECT ${ieTable}."guid"
@@ -1489,11 +1470,10 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1489
1470
  ${dTable}."name",
1490
1471
  ${dTable}."value",
1491
1472
  ${dTable}."json",
1492
- ${cTable}."string",
1493
- ${cTable}."number"
1473
+ ${dTable}."string",
1474
+ ${dTable}."number"
1494
1475
  FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ${eTable}
1495
1476
  LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
1496
- INNER JOIN ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
1497
1477
  ${sortJoin}
1498
1478
  INNER JOIN (
1499
1479
  SELECT ${ieTable}."guid"
@@ -1513,11 +1493,10 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1513
1493
  ${dTable}."name",
1514
1494
  ${dTable}."value",
1515
1495
  ${dTable}."json",
1516
- ${cTable}."string",
1517
- ${cTable}."number"
1496
+ ${dTable}."string",
1497
+ ${dTable}."number"
1518
1498
  FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ${eTable}
1519
1499
  LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ${dTable} ON ${eTable}."guid"=${dTable}."guid"
1520
- INNER JOIN ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} ${cTable} ON ${dTable}."guid"=${cTable}."guid" AND ${dTable}."name"=${cTable}."name"
1521
1500
  ${sortJoin}
1522
1501
  ${guidSelector ? `WHERE ${eTable}."guid"=${guidSelector}` : ''}
1523
1502
  ORDER BY ${sortBy}, ${eTable}."guid"`;
@@ -1581,48 +1560,42 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1581
1560
  }
1582
1561
  async importEntity({ guid, cdate, mdate, tags, sdata, etype, }) {
1583
1562
  try {
1584
- await this.internalTransaction(`nymph-import-entity-${guid}`);
1585
- await this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1586
- etypes: [etype],
1587
- params: {
1588
- guid,
1589
- },
1590
- });
1591
- await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`, {
1563
+ let promises = [];
1564
+ promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1592
1565
  etypes: [etype],
1593
1566
  params: {
1594
1567
  guid,
1595
- tags,
1596
- cdate: isNaN(cdate) ? null : cdate,
1597
- mdate: isNaN(mdate) ? null : mdate,
1598
1568
  },
1599
- });
1600
- const promises = [];
1569
+ }));
1601
1570
  promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1602
1571
  etypes: [etype],
1603
1572
  params: {
1604
1573
  guid,
1605
1574
  },
1606
1575
  }));
1607
- promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1576
+ promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1608
1577
  etypes: [etype],
1609
1578
  params: {
1610
1579
  guid,
1611
1580
  },
1612
1581
  }));
1613
- promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1582
+ promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1614
1583
  etypes: [etype],
1615
1584
  params: {
1616
1585
  guid,
1617
1586
  },
1618
1587
  }));
1619
- promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1588
+ await Promise.all(promises);
1589
+ promises = [];
1590
+ await this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (decode(@guid, 'hex'), @tags, @cdate, @mdate);`, {
1620
1591
  etypes: [etype],
1621
1592
  params: {
1622
1593
  guid,
1594
+ tags,
1595
+ cdate: isNaN(cdate) ? null : cdate,
1596
+ mdate: isNaN(mdate) ? null : mdate,
1623
1597
  },
1624
- }));
1625
- await Promise.all(promises);
1598
+ });
1626
1599
  for (const name in sdata) {
1627
1600
  const value = sdata[name];
1628
1601
  const uvalue = JSON.parse(value);
@@ -1637,26 +1610,18 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1637
1610
  const jsonValue = storageValue === 'J'
1638
1611
  ? PostgreSQLDriver.escapeNullSequences(value)
1639
1612
  : null;
1640
- const promises = [];
1641
- promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue);`, {
1613
+ promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json", "string", "number", "truthy") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue, @string, @number, @truthy);`, {
1642
1614
  etypes: [etype],
1643
1615
  params: {
1644
1616
  guid,
1645
1617
  name,
1646
1618
  storageValue,
1647
1619
  jsonValue,
1648
- },
1649
- }));
1650
- 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);`, {
1651
- etypes: [etype],
1652
- params: {
1653
- guid,
1654
- name,
1655
- truthy: !!uvalue,
1656
1620
  string: storageValue === 'J'
1657
1621
  ? null
1658
1622
  : PostgreSQLDriver.escapeNulls(`${uvalue}`),
1659
1623
  number: isNaN(Number(uvalue)) ? null : Number(uvalue),
1624
+ truthy: !!uvalue,
1660
1625
  },
1661
1626
  }));
1662
1627
  const references = this.findReferences(value);
@@ -1689,11 +1654,9 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1689
1654
  }));
1690
1655
  }
1691
1656
  await Promise.all(promises);
1692
- await this.commit(`nymph-import-entity-${guid}`);
1693
1657
  }
1694
1658
  catch (e) {
1695
1659
  this.nymph.config.debugError('postgresql', `Import entity error: "${e}"`);
1696
- await this.rollback(`nymph-import-entity-${guid}`);
1697
1660
  throw e;
1698
1661
  }
1699
1662
  }
@@ -1804,25 +1767,18 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1804
1767
  ? PostgreSQLDriver.escapeNullSequences(svalue)
1805
1768
  : null;
1806
1769
  const promises = [];
1807
- promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue);`, {
1770
+ promises.push(this.queryRun(`INSERT INTO ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "value", "json", "string", "number", "truthy") VALUES (decode(@guid, 'hex'), @name, @storageValue, @jsonValue, @string, @number, @truthy);`, {
1808
1771
  etypes: [etype],
1809
1772
  params: {
1810
1773
  guid,
1811
1774
  name,
1812
1775
  storageValue,
1813
1776
  jsonValue,
1814
- },
1815
- }));
1816
- 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);`, {
1817
- etypes: [etype],
1818
- params: {
1819
- guid,
1820
- name,
1821
- truthy: !!value,
1822
1777
  string: storageValue === 'J'
1823
1778
  ? null
1824
1779
  : PostgreSQLDriver.escapeNulls(`${value}`),
1825
1780
  number: isNaN(Number(value)) ? null : Number(value),
1781
+ truthy: !!value,
1826
1782
  },
1827
1783
  }));
1828
1784
  const references = this.findReferences(svalue);
@@ -1897,12 +1853,6 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1897
1853
  guid,
1898
1854
  },
1899
1855
  }));
1900
- promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
1901
- etypes: [etype],
1902
- params: {
1903
- guid,
1904
- },
1905
- }));
1906
1856
  promises.push(this.queryRun(`SELECT 1 FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex') FOR UPDATE;`, {
1907
1857
  etypes: [etype],
1908
1858
  params: {
@@ -1934,12 +1884,6 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
1934
1884
  guid,
1935
1885
  },
1936
1886
  }));
1937
- promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1938
- etypes: [etype],
1939
- params: {
1940
- guid,
1941
- },
1942
- }));
1943
1887
  promises.push(this.queryRun(`DELETE FROM ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE "guid"=decode(@guid, 'hex');`, {
1944
1888
  etypes: [etype],
1945
1889
  params: {
@@ -2035,6 +1979,24 @@ class PostgreSQLDriver extends nymph_1.NymphDriver {
2035
1979
  nymph.driver.transaction = transaction;
2036
1980
  return nymph;
2037
1981
  }
1982
+ async needsMigration() {
1983
+ const table = await this.queryGet('SELECT "table_name" AS "table_name" FROM "information_schema"."tables" WHERE "table_catalog"=@db AND "table_schema"=\'public\' AND "table_name" LIKE @prefix LIMIT 1;', {
1984
+ params: {
1985
+ db: this.config.database,
1986
+ prefix: this.prefix + 'data_' + '%',
1987
+ },
1988
+ });
1989
+ if (table?.table_name) {
1990
+ const result = await this.queryGet('SELECT 1 AS "exists" FROM "information_schema"."columns" WHERE "table_catalog"=@db AND "table_schema"=\'public\' AND "table_name"=@table AND "column_name"=\'json\';', {
1991
+ params: {
1992
+ db: this.config.database,
1993
+ table: table.table_name,
1994
+ },
1995
+ });
1996
+ return !result?.exists;
1997
+ }
1998
+ return false;
1999
+ }
2038
2000
  }
2039
2001
  exports.default = PostgreSQLDriver;
2040
2002
  //# sourceMappingURL=PostgreSQLDriver.js.map