@nymphjs/driver-postgresql 1.0.0-beta.127 → 1.0.0-beta.129

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,19 @@
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.129](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.128...v1.0.0-beta.129) (2026-10-05)
7
+
8
+ ### Features
9
+
10
+ - add method to export a single entity ([dac08cb](https://forge.sciactive.com/sciactive/nymphjs/commits/dac08cb39c1fe4473337d2c41c45252f1ed13dae))
11
+ - migrate to built in node sqlite, target es2024 ([d7c78c0](https://forge.sciactive.com/sciactive/nymphjs/commits/d7c78c06072d785b228ff790eb005ab4f84529e9))
12
+
13
+ # [1.0.0-beta.128](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.127...v1.0.0-beta.128) (2026-09-29)
14
+
15
+ ### Features
16
+
17
+ - fix indexes to properly optimize queries, requires full reimport ([0a54f5b](https://forge.sciactive.com/sciactive/nymphjs/commits/0a54f5baa663163f6876d17c5ef6bebefa4cd9fa))
18
+
6
19
  # [1.0.0-beta.127](https://forge.sciactive.com/sciactive/nymphjs/compare/v1.0.0-beta.126...v1.0.0-beta.127) (2026-09-24)
7
20
 
8
21
  **Note:** Version bump only for package @nymphjs/driver-postgresql
package/README.md CHANGED
@@ -34,7 +34,7 @@ const nymph = new Nymph({}, new PostgreSQLDriver(postgresqlConfig));
34
34
 
35
35
  ## Options
36
36
 
37
- See the [config declaration file](src/conf/d.ts).
37
+ See the [config declaration file](src/conf/index.ts).
38
38
 
39
39
  # License
40
40
 
@@ -92,6 +92,8 @@ export default class PostgreSQLDriver extends NymphDriver {
92
92
  type: 'comment' | 'uid' | 'entity';
93
93
  content: string;
94
94
  }, void, false | undefined>;
95
+ exportEntity(etype: string, guid: string): Promise<string>;
96
+ private exportEntityInternal;
95
97
  /**
96
98
  * Generate the PostgreSQL query.
97
99
  * @param options The options array.
@@ -235,22 +235,14 @@ export default class PostgreSQLDriver extends NymphDriver {
235
235
  REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
236
236
  ) WITH ( OIDS=FALSE );`, { connection });
237
237
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
238
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)};`, { connection });
239
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid");`, { connection });
240
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name`)};`, { connection });
241
- 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 });
242
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)};`, { connection });
243
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name");`, { connection });
244
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string`)};`, { connection });
245
- 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 });
246
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number`)};`, { connection });
247
- 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 });
248
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_number`)};`, { connection });
249
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name", "number");`, { connection });
250
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)};`, { connection });
251
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "truthy");`, { connection });
252
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_truthy`)};`, { connection });
253
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_guid_name_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("guid", "name", "truthy");`, { connection });
238
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_guid`)};`, { connection });
239
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "guid");`, { connection });
240
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string_guid`)};`, { connection });
241
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_string_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", LEFT("string", 512), "guid");`, { connection });
242
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number_guid`)};`, { connection });
243
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_number_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "number", "guid");`, { connection });
244
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy_guid`)};`, { connection });
245
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_name_truthy_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("name", "truthy", "guid");`, { connection });
254
246
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_string`)};`, { connection });
255
247
  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 });
256
248
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_json`)};`, { connection });
@@ -268,20 +260,8 @@ export default class PostgreSQLDriver extends NymphDriver {
268
260
  REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
269
261
  ) WITH ( OIDS=FALSE );`, { connection });
270
262
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
271
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid`)};`, { connection });
272
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid");`, { connection });
273
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name`)};`, { connection });
274
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("name");`, { connection });
275
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference`)};`, { connection });
276
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("name", "reference");`, { connection });
277
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference`)};`, { connection });
278
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference");`, { connection });
279
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_name_reference`)};`, { connection });
280
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_guid_name_reference`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("guid", "name", "reference");`, { connection });
281
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_name_guid`)};`, { connection });
282
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_name_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference", "name", "guid");`, { connection });
283
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_guid_name`)};`, { connection });
284
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_reference_guid_name`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference", "guid", "name");`, { connection });
263
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference_guid`)};`, { connection });
264
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_name_reference_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("name", "reference", "guid");`, { connection });
285
265
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
286
266
  }
287
267
  async createTokensTable(etype, connection) {
@@ -297,8 +277,8 @@ export default class PostgreSQLDriver extends NymphDriver {
297
277
  REFERENCES ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} ("guid") MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
298
278
  ) WITH ( OIDS=FALSE );`, { connection });
299
279
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} OWNER TO ${PostgreSQLDriver.escape(this.config.user)};`, { connection });
300
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token`)};`, { connection });
301
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token`)} ON ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} USING btree ("name", "token");`, { connection });
280
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token_guid`)};`, { connection });
281
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_name_token_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} USING btree ("name", "token", "guid");`, { connection });
302
282
  await this.queryRun(`ALTER TABLE ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} SET ( autovacuum_vacuum_scale_factor = 0.05, autovacuum_analyze_scale_factor = 0.05 );`, { connection });
303
283
  }
304
284
  async createUniquesTable(etype, connection) {
@@ -598,9 +578,9 @@ export default class PostgreSQLDriver extends NymphDriver {
598
578
  async getIndexes(etype) {
599
579
  const indexes = [];
600
580
  for (let [scope, suffix] of [
601
- ['data', '_json'],
581
+ ['data', '_string_guid'],
602
582
  ['references', '_reference_guid'],
603
- ['tokens', '_token_position_stem'],
583
+ ['tokens', '_token_guid'],
604
584
  ]) {
605
585
  const indexDefinitions = await this.queryArray(`SELECT * FROM "pg_indexes" WHERE "indexname" LIKE @pattern;`, {
606
586
  params: {
@@ -622,17 +602,17 @@ export default class PostgreSQLDriver extends NymphDriver {
622
602
  await this.deleteIndex(etype, definition.scope, definition.name);
623
603
  const connection = await this.getConnection(true);
624
604
  if (definition.scope === 'data') {
625
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_json`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("json") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
605
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_string_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree (LEFT("string", 1024), "guid") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
606
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_number_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("number", "guid") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
607
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_truthy_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("truthy", "guid") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
626
608
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_string_gin`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("string" gin_trgm_ops) WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
627
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_string_btree`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree (LEFT("string", 1024)) WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
628
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_number`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("number") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
629
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_truthy`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING btree ("truthy") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
609
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_json`)} ON ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} USING gin ("json") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
630
610
  }
631
611
  else if (definition.scope === 'references') {
632
612
  await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_custom_${definition.name}_reference_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}`)} USING btree ("reference", "guid") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
633
613
  }
634
614
  else if (definition.scope === 'tokens') {
635
- await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_custom_${definition.name}_token_position_stem`)} ON ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} USING btree ("token", "position", "stem") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
615
+ await this.queryRun(`CREATE INDEX ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_custom_${definition.name}_token_guid`)} ON ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}`)} USING btree ("token", "guid") WHERE "name"=${PostgreSQLDriver.escapeValue(definition.property)};`, { connection });
636
616
  }
637
617
  connection.done();
638
618
  return true;
@@ -641,17 +621,17 @@ export default class PostgreSQLDriver extends NymphDriver {
641
621
  this.checkIndexName(name);
642
622
  const connection = await this.getConnection(true);
643
623
  if (scope === 'data') {
644
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_json`)};`, { connection });
624
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_string_guid`)};`, { connection });
625
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_number_guid`)};`, { connection });
626
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_truthy_guid`)};`, { connection });
645
627
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_string_gin`)};`, { connection });
646
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_string_btree`)};`, { connection });
647
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_number`)};`, { connection });
648
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_truthy`)};`, { connection });
628
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}_id_custom_${name}_json`)};`, { connection });
649
629
  }
650
630
  else if (scope === 'references') {
651
631
  await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}references_${etype}_id_custom_${name}_reference_guid`)};`, { connection });
652
632
  }
653
633
  else if (scope === 'tokens') {
654
- await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_custom_${name}_token_position_stem`)};`, { connection });
634
+ await this.queryRun(`DROP INDEX IF EXISTS ${PostgreSQLDriver.escape(`${this.prefix}tokens_${etype}_id_custom_${name}_token_guid`)};`, { connection });
655
635
  }
656
636
  connection.done();
657
637
  return true;
@@ -716,77 +696,92 @@ export default class PostgreSQLDriver extends NymphDriver {
716
696
  const etypes = await this.getEtypes();
717
697
  for (const etype of etypes) {
718
698
  // Export entities.
719
- const dataIterator = await this.queryIter(`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", encode(e."user", 'hex') AS "user", encode(e."group", 'hex') AS "group", e."acUser", e."acGroup", e."acOther", array(SELECT encode(n, 'hex') FROM unnest(e."acRead") AS n) as "acRead", array(SELECT encode(n, 'hex') FROM unnest(e."acWrite") AS n) as "acWrite", array(SELECT encode(n, 'hex') FROM unnest(e."acFull") AS n) as "acFull", d."name", d."value", d."json", d."string", d."number"
699
+ const entityIterator = this.exportEntityInternal(etype);
700
+ for await (let content of entityIterator) {
701
+ yield { type: 'entity', content };
702
+ }
703
+ }
704
+ }
705
+ async exportEntity(etype, guid) {
706
+ const entityIterator = this.exportEntityInternal(etype, guid);
707
+ let exportContent = '';
708
+ for await (let content of entityIterator) {
709
+ exportContent += content;
710
+ }
711
+ return exportContent;
712
+ }
713
+ async *exportEntityInternal(etype, guid) {
714
+ // Export entities.
715
+ const dataIterator = await this.queryIter(`SELECT encode(e."guid", 'hex') AS "guid", e."tags", e."cdate", e."mdate", encode(e."user", 'hex') AS "user", encode(e."group", 'hex') AS "group", e."acUser", e."acGroup", e."acOther", array(SELECT encode(n, 'hex') FROM unnest(e."acRead") AS n) as "acRead", array(SELECT encode(n, 'hex') FROM unnest(e."acWrite") AS n) as "acWrite", array(SELECT encode(n, 'hex') FROM unnest(e."acFull") AS n) as "acFull", d."name", d."value", d."json", d."string", d."number"
720
716
  FROM ${PostgreSQLDriver.escape(`${this.prefix}entities_${etype}`)} e
721
- LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} d ON e."guid"=d."guid"
722
- ORDER BY e."guid";`);
723
- let datum = await dataIterator.next();
724
- while (!datum.done) {
725
- const guid = datum.value.guid;
726
- const tags = datum.value.tags.filter((tag) => tag).join(',');
727
- const cdate = datum.value.cdate;
728
- const mdate = datum.value.mdate;
729
- const user = datum.value.user;
730
- const group = datum.value.group;
731
- const acUser = datum.value.acUser;
732
- const acGroup = datum.value.acGroup;
733
- const acOther = datum.value.acOther;
734
- const acRead = datum.value.acRead?.filter((guid) => guid);
735
- const acWrite = datum.value.acWrite?.filter((guid) => guid);
736
- const acFull = datum.value.acFull?.filter((guid) => guid);
737
- let currentEntityExport = [];
738
- currentEntityExport.push(`{${guid}}<${etype}>[${tags}]`);
739
- currentEntityExport.push(`\tcdate=${JSON.stringify(cdate)}`);
740
- currentEntityExport.push(`\tmdate=${JSON.stringify(mdate)}`);
741
- if (this.nymph.tilmeld != null) {
742
- if (user != null) {
743
- currentEntityExport.push(`\tuser=${JSON.stringify(['nymph_entity_reference', user, 'User'])}`);
744
- }
745
- if (group != null) {
746
- currentEntityExport.push(`\tgroup=${JSON.stringify(['nymph_entity_reference', group, 'Group'])}`);
747
- }
748
- if (acUser != null) {
749
- currentEntityExport.push(`\tacUser=${JSON.stringify(acUser)}`);
750
- }
751
- if (acGroup != null) {
752
- currentEntityExport.push(`\tacGroup=${JSON.stringify(acGroup)}`);
753
- }
754
- if (acOther != null) {
755
- currentEntityExport.push(`\tacOther=${JSON.stringify(acOther)}`);
756
- }
757
- if (acRead != null) {
758
- currentEntityExport.push(`\tacRead=${JSON.stringify(acRead)}`);
759
- }
760
- if (acWrite != null) {
761
- currentEntityExport.push(`\tacWrite=${JSON.stringify(acWrite)}`);
762
- }
763
- if (acFull != null) {
764
- currentEntityExport.push(`\tacFull=${JSON.stringify(acFull)}`);
765
- }
717
+ LEFT JOIN ${PostgreSQLDriver.escape(`${this.prefix}data_${etype}`)} d ON e."guid"=d."guid"${guid == null ? '' : ` WHERE e."guid"=decode(@guid, 'hex')`}
718
+ ORDER BY e."guid";`, guid == null ? undefined : { params: { guid } });
719
+ let datum = await dataIterator.next();
720
+ while (!datum.done) {
721
+ const guid = datum.value.guid;
722
+ const tags = datum.value.tags.filter((tag) => tag).join(',');
723
+ const cdate = datum.value.cdate;
724
+ const mdate = datum.value.mdate;
725
+ const user = datum.value.user;
726
+ const group = datum.value.group;
727
+ const acUser = datum.value.acUser;
728
+ const acGroup = datum.value.acGroup;
729
+ const acOther = datum.value.acOther;
730
+ const acRead = datum.value.acRead?.filter((guid) => guid);
731
+ const acWrite = datum.value.acWrite?.filter((guid) => guid);
732
+ const acFull = datum.value.acFull?.filter((guid) => guid);
733
+ let currentEntityExport = [];
734
+ currentEntityExport.push(`{${guid}}<${etype}>[${tags}]`);
735
+ currentEntityExport.push(`\tcdate=${JSON.stringify(cdate)}`);
736
+ currentEntityExport.push(`\tmdate=${JSON.stringify(mdate)}`);
737
+ if (this.nymph.tilmeld != null) {
738
+ if (user != null) {
739
+ currentEntityExport.push(`\tuser=${JSON.stringify(['nymph_entity_reference', user, 'User'])}`);
766
740
  }
767
- if (datum.value.name != null) {
768
- // This do will keep going and adding the data until the
769
- // next entity is reached. $row will end on the next entity.
770
- do {
771
- const value = datum.value.value === 'N'
772
- ? JSON.stringify(Number(datum.value.number))
773
- : datum.value.value === 'S'
774
- ? JSON.stringify(PostgreSQLDriver.unescapeNulls(datum.value.string))
775
- : datum.value.value === 'J'
776
- ? PostgreSQLDriver.unescapeNullSequences(JSON.stringify(datum.value.json))
777
- : datum.value.value;
778
- currentEntityExport.push(`\t${datum.value.name}=${value}`);
779
- datum = await dataIterator.next();
780
- } while (!datum.done && datum.value.guid === guid);
741
+ if (group != null) {
742
+ currentEntityExport.push(`\tgroup=${JSON.stringify(['nymph_entity_reference', group, 'Group'])}`);
781
743
  }
782
- else {
783
- // Make sure that datum is incremented :)
784
- datum = await dataIterator.next();
744
+ if (acUser != null) {
745
+ currentEntityExport.push(`\tacUser=${JSON.stringify(acUser)}`);
785
746
  }
786
- currentEntityExport.push('');
787
- if (yield { type: 'entity', content: currentEntityExport.join('\n') }) {
788
- return;
747
+ if (acGroup != null) {
748
+ currentEntityExport.push(`\tacGroup=${JSON.stringify(acGroup)}`);
749
+ }
750
+ if (acOther != null) {
751
+ currentEntityExport.push(`\tacOther=${JSON.stringify(acOther)}`);
752
+ }
753
+ if (acRead != null) {
754
+ currentEntityExport.push(`\tacRead=${JSON.stringify(acRead)}`);
755
+ }
756
+ if (acWrite != null) {
757
+ currentEntityExport.push(`\tacWrite=${JSON.stringify(acWrite)}`);
789
758
  }
759
+ if (acFull != null) {
760
+ currentEntityExport.push(`\tacFull=${JSON.stringify(acFull)}`);
761
+ }
762
+ }
763
+ if (datum.value.name != null) {
764
+ // This do will keep going and adding the data until the
765
+ // next entity is reached. $row will end on the next entity.
766
+ do {
767
+ const value = datum.value.value === 'N'
768
+ ? JSON.stringify(Number(datum.value.number))
769
+ : datum.value.value === 'S'
770
+ ? JSON.stringify(PostgreSQLDriver.unescapeNulls(datum.value.string))
771
+ : datum.value.value === 'J'
772
+ ? PostgreSQLDriver.unescapeNullSequences(JSON.stringify(datum.value.json))
773
+ : datum.value.value;
774
+ currentEntityExport.push(`\t${datum.value.name}=${value}`);
775
+ datum = await dataIterator.next();
776
+ } while (!datum.done && datum.value.guid === guid);
777
+ }
778
+ else {
779
+ // Make sure that datum is incremented :)
780
+ datum = await dataIterator.next();
781
+ }
782
+ currentEntityExport.push('');
783
+ if (yield currentEntityExport.join('\n')) {
784
+ return;
790
785
  }
791
786
  }
792
787
  }