@nymphjs/driver-mysql 1.0.0-beta.62 → 1.0.0-beta.63

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,17 @@
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.63](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.62...v1.0.0-beta.63) (2024-06-18)
7
+
8
+ ### Bug Fixes
9
+
10
+ - undo ts compilation to module change ([84be6d4](https://github.com/sciactive/nymphjs/commit/84be6d434be29f8afd53907d15be2eb77d1736ce))
11
+
12
+ ### Features
13
+
14
+ - allow importing from text and iterables ([9d766bd](https://github.com/sciactive/nymphjs/commit/9d766bdad4b0f17bc2dd68b0336a0064857eb4e9))
15
+ - export data iterator ([b86aa19](https://github.com/sciactive/nymphjs/commit/b86aa19fc77d744b5a683046dfb697fc4746df5c))
16
+
6
17
  # [1.0.0-beta.62](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.61...v1.0.0-beta.62) (2024-06-15)
7
18
 
8
19
  **Note:** Version bump only for package @nymphjs/driver-mysql
@@ -1,5 +1,5 @@
1
1
  import { Pool, PoolConnection } from 'mysql2';
2
- import { NymphDriver, type EntityConstructor, type EntityInterface, type EntityInstanceType, type FormattedSelector, type Options, type Selector } from '@nymphjs/nymph';
2
+ import { NymphDriver, type EntityConstructor, type EntityInterface, type EntityInstanceType, type SerializedEntityData, type FormattedSelector, type Options, type Selector } from '@nymphjs/nymph';
3
3
  import { MySQLDriverConfig } from './conf';
4
4
  type MySQLDriverTransaction = {
5
5
  connection: PoolConnection | null;
@@ -59,7 +59,10 @@ export default class MySQLDriver extends NymphDriver {
59
59
  commit(name: string): Promise<boolean>;
60
60
  deleteEntityByID(guid: string, className?: EntityConstructor | string | null): Promise<boolean>;
61
61
  deleteUID(name: string): Promise<boolean>;
62
- protected exportEntities(writeLine: (line: string) => void): Promise<void>;
62
+ exportDataIterator(): AsyncGenerator<{
63
+ type: 'comment' | 'uid' | 'entity';
64
+ content: string;
65
+ }, void, false | undefined>;
63
66
  /**
64
67
  * Generate the MySQL query.
65
68
  * @param options The options array.
@@ -82,13 +85,24 @@ export default class MySQLDriver extends NymphDriver {
82
85
  }, ...selectors: Selector[]): Promise<string[]>;
83
86
  getEntities<T extends EntityConstructor = EntityConstructor>(options?: Options<T>, ...selectors: Selector[]): Promise<EntityInstanceType<T>[]>;
84
87
  getUID(name: string): Promise<number | null>;
85
- import(filename: string, transaction?: boolean): Promise<boolean>;
88
+ importEntity({ guid, cdate, mdate, tags, sdata, etype, }: {
89
+ guid: string;
90
+ cdate: number;
91
+ mdate: number;
92
+ tags: string[];
93
+ sdata: SerializedEntityData;
94
+ etype: string;
95
+ }): Promise<void>;
96
+ importUID({ name, value }: {
97
+ name: string;
98
+ value: number;
99
+ }): Promise<void>;
86
100
  newUID(name: string): Promise<number | null>;
87
101
  renameUID(oldName: string, newName: string): Promise<boolean>;
88
102
  rollback(name: string): Promise<boolean>;
89
103
  saveEntity(entity: EntityInterface): Promise<boolean>;
90
104
  setUID(name: string, curUid: number): Promise<boolean>;
91
- private internalTransaction;
105
+ protected internalTransaction(name: string): Promise<MySQLDriverTransaction>;
92
106
  startTransaction(name: string): Promise<import("@nymphjs/nymph").Nymph>;
93
107
  }
94
108
  export {};
@@ -12,6 +12,13 @@ const conf_1 = require("./conf");
12
12
  * The MySQL Nymph database driver.
13
13
  */
14
14
  class MySQLDriver extends nymph_1.NymphDriver {
15
+ config;
16
+ mysqlConfig;
17
+ prefix;
18
+ connected = false;
19
+ // @ts-ignore: this is assigned in connect(), which is called by the constructor.
20
+ link;
21
+ transaction = null;
15
22
  static escape(input) {
16
23
  return sqlstring_1.default.escapeId(input, true);
17
24
  }
@@ -20,8 +27,6 @@ class MySQLDriver extends nymph_1.NymphDriver {
20
27
  }
21
28
  constructor(config, link, transaction) {
22
29
  super();
23
- this.connected = false;
24
- this.transaction = null;
25
30
  this.config = { ...conf_1.MySQLDriverConfigDefaults, ...config };
26
31
  const { host, user, password, database, port, customPoolConfig } = this.config;
27
32
  this.mysqlConfig = customPoolConfig ?? {
@@ -402,27 +407,49 @@ class MySQLDriver extends nymph_1.NymphDriver {
402
407
  });
403
408
  return true;
404
409
  }
405
- async exportEntities(writeLine) {
406
- writeLine('#nex2');
407
- writeLine('# Nymph Entity Exchange v2');
408
- writeLine('# http://nymph.io');
409
- writeLine('#');
410
- writeLine('# Generation Time: ' + new Date().toLocaleString());
411
- writeLine('');
412
- writeLine('#');
413
- writeLine('# UIDs');
414
- writeLine('#');
415
- writeLine('');
410
+ async *exportDataIterator() {
411
+ if (yield {
412
+ type: 'comment',
413
+ content: `#nex2
414
+ # Nymph Entity Exchange v2
415
+ # http://nymph.io
416
+ #
417
+ # Generation Time: ${new Date().toLocaleString()}
418
+ `,
419
+ }) {
420
+ return;
421
+ }
422
+ if (yield {
423
+ type: 'comment',
424
+ content: `
425
+
426
+ #
427
+ # UIDs
428
+ #
429
+
430
+ `,
431
+ }) {
432
+ return;
433
+ }
416
434
  // Export UIDs.
417
435
  let uids = await this.queryIter(`SELECT * FROM ${MySQLDriver.escape(`${this.prefix}uids`)} ORDER BY \`name\`;`);
418
436
  for (const uid of uids) {
419
- writeLine(`<${uid.name}>[${uid.cur_uid}]`);
437
+ if (yield { type: 'uid', content: `<${uid.name}>[${uid.cur_uid}]\n` }) {
438
+ return;
439
+ }
440
+ }
441
+ if (yield {
442
+ type: 'comment',
443
+ content: `
444
+
445
+ #
446
+ # Entities
447
+ #
448
+
449
+ `,
450
+ }) {
451
+ return;
420
452
  }
421
- writeLine('');
422
- writeLine('#');
423
- writeLine('# Entities');
424
- writeLine('#');
425
- writeLine('');
426
453
  // Get the etypes.
427
454
  const tables = await this.queryIter('SHOW TABLES;');
428
455
  const etypes = [];
@@ -445,9 +472,10 @@ class MySQLDriver extends nymph_1.NymphDriver {
445
472
  const tags = datum.value.tags.slice(1, -1).split(' ').join(',');
446
473
  const cdate = datum.value.cdate;
447
474
  const mdate = datum.value.mdate;
448
- writeLine(`{${guid}}<${etype}>[${tags}]`);
449
- writeLine(`\tcdate=${JSON.stringify(cdate)}`);
450
- writeLine(`\tmdate=${JSON.stringify(mdate)}`);
475
+ let currentEntityExport = [];
476
+ currentEntityExport.push(`{${guid}}<${etype}>[${tags}]`);
477
+ currentEntityExport.push(`\tcdate=${JSON.stringify(cdate)}`);
478
+ currentEntityExport.push(`\tmdate=${JSON.stringify(mdate)}`);
451
479
  if (datum.value.dname != null) {
452
480
  // This do will keep going and adding the data until the
453
481
  // next entity is reached. $row will end on the next entity.
@@ -457,7 +485,7 @@ class MySQLDriver extends nymph_1.NymphDriver {
457
485
  : datum.value.dvalue === 'S'
458
486
  ? JSON.stringify(datum.value.string)
459
487
  : datum.value.dvalue;
460
- writeLine(`\t${datum.value.dname}=${value}`);
488
+ currentEntityExport.push(`\t${datum.value.dname}=${value}`);
461
489
  datum = dataIterator.next();
462
490
  } while (!datum.done && datum.value.guid === guid);
463
491
  }
@@ -465,9 +493,12 @@ class MySQLDriver extends nymph_1.NymphDriver {
465
493
  // Make sure that datum is incremented :)
466
494
  datum = dataIterator.next();
467
495
  }
496
+ currentEntityExport.push('');
497
+ if (yield { type: 'entity', content: currentEntityExport.join('\n') }) {
498
+ return;
499
+ }
468
500
  }
469
501
  }
470
- return;
471
502
  }
472
503
  /**
473
504
  * Generate the MySQL query.
@@ -1507,150 +1538,127 @@ class MySQLDriver extends nymph_1.NymphDriver {
1507
1538
  });
1508
1539
  return result?.cur_uid ?? null;
1509
1540
  }
1510
- async import(filename, transaction) {
1541
+ async importEntity({ guid, cdate, mdate, tags, sdata, etype, }) {
1511
1542
  try {
1512
- const result = await this.importFromFile(filename, async (guid, tags, sdata, etype) => {
1513
- try {
1514
- await this.internalTransaction(`nymph-import-entity-${guid}`);
1515
- const cdate = Number(JSON.parse(sdata.cdate));
1516
- delete sdata.cdate;
1517
- const mdate = Number(JSON.parse(sdata.mdate));
1518
- delete sdata.mdate;
1519
- await this.queryRun(`REPLACE INTO ${MySQLDriver.escape(`${this.prefix}entities_${etype}`)} (\`guid\`, \`tags\`, \`cdate\`, \`mdate\`) VALUES (UNHEX(@guid), @tags, @cdate, @mdate);`, {
1520
- etypes: [etype],
1521
- params: {
1522
- guid,
1523
- tags: ' ' + tags.join(' ') + ' ',
1524
- cdate: isNaN(cdate) ? null : cdate,
1525
- mdate: isNaN(mdate) ? null : mdate,
1526
- },
1527
- });
1528
- const promises = [];
1529
- promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1530
- etypes: [etype],
1531
- params: {
1532
- guid,
1533
- },
1534
- }));
1535
- promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1536
- etypes: [etype],
1537
- params: {
1538
- guid,
1539
- },
1540
- }));
1541
- promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1542
- etypes: [etype],
1543
- params: {
1544
- guid,
1545
- },
1546
- }));
1547
- promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1543
+ await this.internalTransaction(`nymph-import-entity-${guid}`);
1544
+ await this.queryRun(`REPLACE INTO ${MySQLDriver.escape(`${this.prefix}entities_${etype}`)} (\`guid\`, \`tags\`, \`cdate\`, \`mdate\`) VALUES (UNHEX(@guid), @tags, @cdate, @mdate);`, {
1545
+ etypes: [etype],
1546
+ params: {
1547
+ guid,
1548
+ tags: ' ' + tags.join(' ') + ' ',
1549
+ cdate: isNaN(cdate) ? null : cdate,
1550
+ mdate: isNaN(mdate) ? null : mdate,
1551
+ },
1552
+ });
1553
+ const promises = [];
1554
+ promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}data_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1555
+ etypes: [etype],
1556
+ params: {
1557
+ guid,
1558
+ },
1559
+ }));
1560
+ promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}comparisons_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1561
+ etypes: [etype],
1562
+ params: {
1563
+ guid,
1564
+ },
1565
+ }));
1566
+ promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}references_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1567
+ etypes: [etype],
1568
+ params: {
1569
+ guid,
1570
+ },
1571
+ }));
1572
+ promises.push(this.queryRun(`DELETE FROM ${MySQLDriver.escape(`${this.prefix}uniques_${etype}`)} WHERE \`guid\`=UNHEX(@guid);`, {
1573
+ etypes: [etype],
1574
+ params: {
1575
+ guid,
1576
+ },
1577
+ }));
1578
+ await Promise.all(promises);
1579
+ for (const name in sdata) {
1580
+ const value = sdata[name];
1581
+ const uvalue = JSON.parse(value);
1582
+ if (value === undefined) {
1583
+ continue;
1584
+ }
1585
+ const storageValue = typeof uvalue === 'number'
1586
+ ? 'N'
1587
+ : typeof uvalue === 'string'
1588
+ ? 'S'
1589
+ : value;
1590
+ const promises = [];
1591
+ promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}data_${etype}`)} (\`guid\`, \`name\`, \`value\`) VALUES (UNHEX(@guid), @name, @storageValue);`, {
1592
+ etypes: [etype],
1593
+ params: {
1594
+ guid,
1595
+ name,
1596
+ storageValue,
1597
+ },
1598
+ }));
1599
+ promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}comparisons_${etype}`)} (\`guid\`, \`name\`, \`truthy\`, \`string\`, \`number\`) VALUES (UNHEX(@guid), @name, @truthy, @string, @number);`, {
1600
+ etypes: [etype],
1601
+ params: {
1602
+ guid,
1603
+ name,
1604
+ truthy: !!uvalue,
1605
+ string: `${uvalue}`,
1606
+ number: isNaN(Number(uvalue)) ? null : Number(uvalue),
1607
+ },
1608
+ }));
1609
+ const references = this.findReferences(value);
1610
+ for (const reference of references) {
1611
+ promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}references_${etype}`)} (\`guid\`, \`name\`, \`reference\`) VALUES (UNHEX(@guid), @name, UNHEX(@reference));`, {
1548
1612
  etypes: [etype],
1549
1613
  params: {
1550
1614
  guid,
1551
- },
1552
- }));
1553
- await Promise.all(promises);
1554
- for (const name in sdata) {
1555
- const value = sdata[name];
1556
- const uvalue = JSON.parse(value);
1557
- if (value === undefined) {
1558
- continue;
1559
- }
1560
- const storageValue = typeof uvalue === 'number'
1561
- ? 'N'
1562
- : typeof uvalue === 'string'
1563
- ? 'S'
1564
- : value;
1565
- const promises = [];
1566
- promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}data_${etype}`)} (\`guid\`, \`name\`, \`value\`) VALUES (UNHEX(@guid), @name, @storageValue);`, {
1567
- etypes: [etype],
1568
- params: {
1569
- guid,
1570
- name,
1571
- storageValue,
1572
- },
1573
- }));
1574
- promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}comparisons_${etype}`)} (\`guid\`, \`name\`, \`truthy\`, \`string\`, \`number\`) VALUES (UNHEX(@guid), @name, @truthy, @string, @number);`, {
1575
- etypes: [etype],
1576
- params: {
1577
- guid,
1578
- name,
1579
- truthy: !!uvalue,
1580
- string: `${uvalue}`,
1581
- number: isNaN(Number(uvalue)) ? null : Number(uvalue),
1582
- },
1583
- }));
1584
- const references = this.findReferences(value);
1585
- for (const reference of references) {
1586
- promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}references_${etype}`)} (\`guid\`, \`name\`, \`reference\`) VALUES (UNHEX(@guid), @name, UNHEX(@reference));`, {
1587
- etypes: [etype],
1588
- params: {
1589
- guid,
1590
- name,
1591
- reference,
1592
- },
1593
- }));
1594
- }
1595
- }
1596
- const uniques = await this.nymph
1597
- .getEntityClassByEtype(etype)
1598
- .getUniques({ guid, cdate, mdate, tags, data: {}, sdata });
1599
- for (const unique of uniques) {
1600
- promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}uniques_${etype}`)} (\`guid\`, \`unique\`) VALUES (UNHEX(@guid), @unique);`, {
1601
- etypes: [etype],
1602
- params: {
1603
- guid,
1604
- unique,
1605
- },
1606
- }).catch((e) => {
1607
- if (e instanceof nymph_1.EntityUniqueConstraintError) {
1608
- this.nymph.config.debugError('mysql', `Import entity unique constraint violation for GUID "${guid}" on etype "${etype}": "${unique}"`);
1609
- }
1610
- return e;
1611
- }));
1612
- }
1613
- await Promise.all(promises);
1614
- await this.commit(`nymph-import-entity-${guid}`);
1615
- }
1616
- catch (e) {
1617
- this.nymph.config.debugError('mysql', `Import entity error: "${e}"`);
1618
- await this.rollback(`nymph-import-entity-${guid}`);
1619
- throw e;
1620
- }
1621
- }, async (name, curUid) => {
1622
- try {
1623
- await this.internalTransaction(`nymph-import-uid-${name}`);
1624
- await this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}uids`)} (\`name\`, \`cur_uid\`) VALUES (@name, @curUid) ON DUPLICATE KEY UPDATE \`cur_uid\`=@curUid;`, {
1625
- params: {
1626
1615
  name,
1627
- curUid,
1616
+ reference,
1628
1617
  },
1629
- });
1630
- await this.commit(`nymph-import-uid-${name}`);
1631
- }
1632
- catch (e) {
1633
- this.nymph.config.debugError('mysql', `Import UID error: "${e}"`);
1634
- await this.rollback(`nymph-import-uid-${name}`);
1635
- throw e;
1636
- }
1637
- }, async () => {
1638
- if (transaction) {
1639
- await this.internalTransaction('nymph-import');
1640
- }
1641
- }, async () => {
1642
- if (transaction) {
1643
- await this.commit('nymph-import');
1618
+ }));
1644
1619
  }
1620
+ }
1621
+ const uniques = await this.nymph
1622
+ .getEntityClassByEtype(etype)
1623
+ .getUniques({ guid, cdate, mdate, tags, data: {}, sdata });
1624
+ for (const unique of uniques) {
1625
+ promises.push(this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}uniques_${etype}`)} (\`guid\`, \`unique\`) VALUES (UNHEX(@guid), @unique);`, {
1626
+ etypes: [etype],
1627
+ params: {
1628
+ guid,
1629
+ unique,
1630
+ },
1631
+ }).catch((e) => {
1632
+ if (e instanceof nymph_1.EntityUniqueConstraintError) {
1633
+ this.nymph.config.debugError('mysql', `Import entity unique constraint violation for GUID "${guid}" on etype "${etype}": "${unique}"`);
1634
+ }
1635
+ return e;
1636
+ }));
1637
+ }
1638
+ await Promise.all(promises);
1639
+ await this.commit(`nymph-import-entity-${guid}`);
1640
+ }
1641
+ catch (e) {
1642
+ this.nymph.config.debugError('mysql', `Import entity error: "${e}"`);
1643
+ await this.rollback(`nymph-import-entity-${guid}`);
1644
+ throw e;
1645
+ }
1646
+ }
1647
+ async importUID({ name, value }) {
1648
+ try {
1649
+ await this.internalTransaction(`nymph-import-uid-${name}`);
1650
+ await this.queryRun(`INSERT INTO ${MySQLDriver.escape(`${this.prefix}uids`)} (\`name\`, \`cur_uid\`) VALUES (@name, @value) ON DUPLICATE KEY UPDATE \`cur_uid\`=@value;`, {
1651
+ params: {
1652
+ name,
1653
+ value,
1654
+ },
1645
1655
  });
1646
- return result;
1656
+ await this.commit(`nymph-import-uid-${name}`);
1647
1657
  }
1648
1658
  catch (e) {
1649
- this.nymph.config.debugError('mysql', `Import error: "${e}"`);
1650
- if (transaction) {
1651
- await this.rollback('nymph-import');
1652
- }
1653
- return false;
1659
+ this.nymph.config.debugError('mysql', `Import UID error: "${e}"`);
1660
+ await this.rollback(`nymph-import-uid-${name}`);
1661
+ throw e;
1654
1662
  }
1655
1663
  }
1656
1664
  async newUID(name) {