@nymphjs/driver-sqlite3 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 +13 -0
- package/README.md +1 -1
- package/dist/SQLite3Driver.d.ts +6 -4
- package/dist/SQLite3Driver.js +121 -122
- package/dist/SQLite3Driver.js.map +1 -1
- package/dist/conf/defaults.js +0 -1
- package/dist/conf/defaults.js.map +1 -1
- package/dist/conf/index.d.ts +0 -4
- package/dist/conf/index.js.map +1 -1
- package/jest.config.js +1 -1
- package/package.json +6 -8
- package/src/SQLite3Driver.ts +159 -211
- package/src/conf/defaults.ts +0 -1
- package/src/conf/index.ts +0 -4
- package/tsconfig.json +2 -2
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-sqlite3
|
package/README.md
CHANGED
package/dist/SQLite3Driver.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
import { NymphDriver, type EntityConstructor, type EntityObjectType, type EntityInterface, type EntityInstanceType, type SerializedEntityData, type FormattedSelector, type Options, type Selector } from '@nymphjs/nymph';
|
|
3
3
|
import { SQLite3DriverConfig } from './conf/index.js';
|
|
4
4
|
declare class InternalStore {
|
|
5
|
-
link:
|
|
6
|
-
linkWrite?:
|
|
5
|
+
link: DatabaseSync;
|
|
6
|
+
linkWrite?: DatabaseSync;
|
|
7
7
|
connected: boolean;
|
|
8
8
|
transactionsStarted: number;
|
|
9
|
-
constructor(link:
|
|
9
|
+
constructor(link: DatabaseSync);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* The SQLite3 Nymph database driver.
|
|
@@ -80,6 +80,8 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
80
80
|
type: 'comment' | 'uid' | 'entity';
|
|
81
81
|
content: string;
|
|
82
82
|
}, void, false | undefined>;
|
|
83
|
+
exportEntity(etype: string, guid: string): Promise<string>;
|
|
84
|
+
private exportEntityInternal;
|
|
83
85
|
/**
|
|
84
86
|
* Generate the SQLite3 query.
|
|
85
87
|
* @param options The options array.
|
package/dist/SQLite3Driver.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
import { NymphDriver, EntityConflictError, EntityInvalidDataError, EntityUniqueConstraintError, InvalidParametersError, NotConfiguredError, QueryFailedError, UnableToConnectError, xor, } from '@nymphjs/nymph';
|
|
3
3
|
import { makeTableSuffix } from '@nymphjs/guid';
|
|
4
4
|
import { SQLite3DriverConfigDefaults as defaults, } from './conf/index.js';
|
|
@@ -64,53 +64,47 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
64
64
|
return Promise.resolve(this.store.connected);
|
|
65
65
|
}
|
|
66
66
|
_connect(write) {
|
|
67
|
-
const { filename, fileMustExist, timeout, explicitWrite, wal
|
|
67
|
+
const { filename, fileMustExist, timeout, explicitWrite, wal } = this.config;
|
|
68
68
|
try {
|
|
69
69
|
const setOptions = (link) => {
|
|
70
70
|
// Set database and connection options.
|
|
71
71
|
if (wal) {
|
|
72
|
-
link.
|
|
72
|
+
link.exec('PRAGMA journal_mode = WAL;');
|
|
73
73
|
}
|
|
74
|
-
link.
|
|
75
|
-
link.
|
|
76
|
-
link.
|
|
74
|
+
link.exec('PRAGMA encoding = "UTF-8";');
|
|
75
|
+
link.exec('PRAGMA foreign_keys = 1;');
|
|
76
|
+
link.exec('PRAGMA case_sensitive_like = 1;');
|
|
77
77
|
for (let pragma of this.config.pragmas) {
|
|
78
|
-
link.
|
|
78
|
+
link.exec(`PRAGMA ${pragma}`);
|
|
79
79
|
}
|
|
80
80
|
// Create the preg_match and regexp functions.
|
|
81
81
|
link.function('regexp', { deterministic: true }, ((pattern, subject) => (this.posixRegexMatch(pattern, subject) ? 1 : 0)));
|
|
82
82
|
};
|
|
83
83
|
let link;
|
|
84
84
|
try {
|
|
85
|
-
link = new
|
|
86
|
-
|
|
87
|
-
fileMustExist,
|
|
85
|
+
link = new DatabaseSync(filename, {
|
|
86
|
+
readOnly: !explicitWrite && !write,
|
|
88
87
|
timeout,
|
|
89
|
-
verbose,
|
|
90
88
|
});
|
|
91
89
|
}
|
|
92
90
|
catch (e) {
|
|
93
|
-
if (e.code === '
|
|
91
|
+
if (e.code === 'ERR_SQLITE_CANTOPEN' &&
|
|
94
92
|
!explicitWrite &&
|
|
95
93
|
!write &&
|
|
96
|
-
!
|
|
94
|
+
!fileMustExist) {
|
|
97
95
|
// This happens when the file doesn't exist and we attempt to open it
|
|
98
96
|
// readonly.
|
|
99
97
|
// First open it in write mode.
|
|
100
|
-
const writeLink = new
|
|
101
|
-
|
|
102
|
-
fileMustExist,
|
|
98
|
+
const writeLink = new DatabaseSync(filename, {
|
|
99
|
+
readOnly: false,
|
|
103
100
|
timeout,
|
|
104
|
-
verbose,
|
|
105
101
|
});
|
|
106
102
|
setOptions(writeLink);
|
|
107
103
|
writeLink.close();
|
|
108
104
|
// Now open in readonly.
|
|
109
|
-
link = new
|
|
110
|
-
|
|
111
|
-
fileMustExist,
|
|
105
|
+
link = new DatabaseSync(filename, {
|
|
106
|
+
readOnly: true,
|
|
112
107
|
timeout,
|
|
113
|
-
verbose,
|
|
114
108
|
});
|
|
115
109
|
}
|
|
116
110
|
else {
|
|
@@ -209,31 +203,21 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
209
203
|
createDataTable(etype) {
|
|
210
204
|
// Create the data table.
|
|
211
205
|
this.queryRun(`CREATE TABLE IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("guid" CHARACTER(24) NOT NULL REFERENCES ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} ("guid") ON DELETE CASCADE, "name" TEXT NOT NULL, "value" CHARACTER(1) NOT NULL, "json" BLOB, "string" TEXT, "number" REAL, "truthy" INTEGER, PRIMARY KEY("guid", "name"));`);
|
|
212
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}
|
|
213
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}
|
|
214
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}
|
|
215
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}
|
|
216
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}
|
|
217
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_guid_name_number`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "number");`);
|
|
218
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_truthy`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "truthy");`);
|
|
219
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_guid_name_truthy`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("guid", "name", "truthy");`);
|
|
206
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "guid");`);
|
|
207
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_string_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "string", "guid");`);
|
|
208
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_number_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "number", "guid");`);
|
|
209
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_truthy_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "truthy", "guid");`);
|
|
210
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_name_json_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("name", "json", "guid")`);
|
|
220
211
|
}
|
|
221
212
|
createReferencesTable(etype) {
|
|
222
213
|
// Create the references table.
|
|
223
214
|
this.queryRun(`CREATE TABLE IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("guid" CHARACTER(24) NOT NULL REFERENCES ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} ("guid") ON DELETE CASCADE, "name" TEXT NOT NULL, "reference" CHARACTER(24) NOT NULL, PRIMARY KEY("guid", "name", "reference"));`);
|
|
224
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}
|
|
225
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_name`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("name");`);
|
|
226
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_name_reference`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("name", "reference");`);
|
|
227
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_reference`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("reference");`);
|
|
228
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_guid_name`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("guid", "name");`);
|
|
229
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_guid_name_reference`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("guid", "name", "reference");`);
|
|
230
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_reference_name_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("reference", "name", "guid");`);
|
|
231
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_reference_guid_name`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("reference", "guid", "name");`);
|
|
215
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_name_reference_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("name", "reference", "guid");`);
|
|
232
216
|
}
|
|
233
217
|
createTokensTable(etype) {
|
|
234
218
|
// Create the tokens table.
|
|
235
219
|
this.queryRun(`CREATE TABLE IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}`)} ("guid" CHARACTER(24) NOT NULL REFERENCES ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} ("guid") ON DELETE CASCADE, "name" TEXT NOT NULL, "token" INTEGER NOT NULL, "position" INTEGER NOT NULL, "stem" INTEGER NOT NULL, PRIMARY KEY("guid", "name", "token", "position"));`);
|
|
236
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}
|
|
220
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}_id_name_token_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}`)} ("name", "token", "guid");`);
|
|
237
221
|
}
|
|
238
222
|
createUniquesTable(etype) {
|
|
239
223
|
// Create the unique strings table.
|
|
@@ -274,7 +258,7 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
274
258
|
catch (e) {
|
|
275
259
|
const errorCode = e?.code;
|
|
276
260
|
const errorMsg = e?.message;
|
|
277
|
-
if (errorCode === '
|
|
261
|
+
if (errorCode === 'ERR_SQLITE_ERROR' &&
|
|
278
262
|
errorMsg.match(/^no such table: /) &&
|
|
279
263
|
this.createTables()) {
|
|
280
264
|
for (let etype of etypes) {
|
|
@@ -287,7 +271,7 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
287
271
|
throw new QueryFailedError('Query failed: ' + e2?.code + ' - ' + e2?.message, query, e2?.code);
|
|
288
272
|
}
|
|
289
273
|
}
|
|
290
|
-
else if (errorCode === '
|
|
274
|
+
else if (errorCode === 'ERR_SQLITE_ERROR' &&
|
|
291
275
|
errorMsg.match(/^UNIQUE constraint failed: /)) {
|
|
292
276
|
throw new EntityUniqueConstraintError(`Unique constraint violation.`);
|
|
293
277
|
}
|
|
@@ -396,9 +380,9 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
396
380
|
async getIndexes(etype) {
|
|
397
381
|
const indexes = [];
|
|
398
382
|
for (let [scope, suffix] of [
|
|
399
|
-
['data', '
|
|
383
|
+
['data', '_string_guid'],
|
|
400
384
|
['references', '_reference_guid'],
|
|
401
|
-
['tokens', '
|
|
385
|
+
['tokens', '_token_guid'],
|
|
402
386
|
]) {
|
|
403
387
|
const indexDefinitions = this.queryArray(`SELECT "name", "sql" FROM "sqlite_master" WHERE "type"='index' AND "name" LIKE @pattern;`, {
|
|
404
388
|
params: {
|
|
@@ -419,37 +403,37 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
419
403
|
this.checkIndexName(definition.name);
|
|
420
404
|
await this.deleteIndex(etype, definition.scope, definition.name);
|
|
421
405
|
if (definition.scope === 'data') {
|
|
422
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}
|
|
423
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}
|
|
424
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}
|
|
425
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}
|
|
406
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_string_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("string", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
407
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_number_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("number", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
408
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_truthy_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("truthy", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
409
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${definition.name}_json_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} ("json", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
426
410
|
}
|
|
427
411
|
else if (definition.scope === 'references') {
|
|
428
412
|
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_custom_${definition.name}_reference_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}references_${etype}`)} ("reference", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
429
413
|
}
|
|
430
414
|
else if (definition.scope === 'tokens') {
|
|
431
|
-
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}_id_custom_${definition.name}
|
|
415
|
+
this.queryRun(`CREATE INDEX IF NOT EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}_id_custom_${definition.name}_token_guid`)} ON ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}`)} ("token", "guid") WHERE "name"=${SQLite3Driver.escapeValue(definition.property)};`);
|
|
432
416
|
}
|
|
433
417
|
return true;
|
|
434
418
|
}
|
|
435
419
|
async deleteIndex(etype, scope, name) {
|
|
436
420
|
this.checkIndexName(name);
|
|
437
421
|
if (scope === 'data') {
|
|
438
|
-
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}
|
|
439
|
-
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}
|
|
440
|
-
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}
|
|
441
|
-
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}
|
|
422
|
+
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}_string_guid`)};`);
|
|
423
|
+
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}_number_guid`)};`);
|
|
424
|
+
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}_truthy_guid`)};`);
|
|
425
|
+
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}data_${etype}_id_custom_${name}_json_guid`)};`);
|
|
442
426
|
}
|
|
443
427
|
else if (scope === 'references') {
|
|
444
428
|
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}references_${etype}_id_custom_${name}_reference_guid`)};`);
|
|
445
429
|
}
|
|
446
430
|
else if (scope === 'tokens') {
|
|
447
|
-
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}_id_custom_${name}
|
|
431
|
+
this.queryRun(`DROP INDEX IF EXISTS ${SQLite3Driver.escape(`${this.prefix}tokens_${etype}_id_custom_${name}_token_guid`)};`);
|
|
448
432
|
}
|
|
449
433
|
return true;
|
|
450
434
|
}
|
|
451
435
|
async getEtypes() {
|
|
452
|
-
const tables = this.queryArray(
|
|
436
|
+
const tables = this.queryArray(`SELECT "name" FROM "sqlite_master" WHERE "type"='table' AND "name" LIKE @prefix;`, {
|
|
453
437
|
params: {
|
|
454
438
|
prefix: this.prefix + 'entities_' + '%',
|
|
455
439
|
},
|
|
@@ -507,75 +491,90 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
507
491
|
const etypes = await this.getEtypes();
|
|
508
492
|
for (const etype of etypes) {
|
|
509
493
|
// Export entities.
|
|
510
|
-
const
|
|
511
|
-
let
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
if (acWrite != null) {
|
|
549
|
-
currentEntityExport.push(`\tacWrite=${JSON.stringify(acWrite)}`);
|
|
550
|
-
}
|
|
551
|
-
if (acFull != null) {
|
|
552
|
-
currentEntityExport.push(`\tacFull=${JSON.stringify(acFull)}`);
|
|
553
|
-
}
|
|
494
|
+
const entityIterator = this.exportEntityInternal(etype);
|
|
495
|
+
for await (let content of entityIterator) {
|
|
496
|
+
yield { type: 'entity', content };
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
async exportEntity(etype, guid) {
|
|
501
|
+
const entityIterator = this.exportEntityInternal(etype, guid);
|
|
502
|
+
let exportContent = '';
|
|
503
|
+
for await (let content of entityIterator) {
|
|
504
|
+
exportContent += content;
|
|
505
|
+
}
|
|
506
|
+
return exportContent;
|
|
507
|
+
}
|
|
508
|
+
async *exportEntityInternal(etype, guid) {
|
|
509
|
+
// Export entities.
|
|
510
|
+
const dataIterator = this.queryArray(`SELECT e."guid", e."tags", e."cdate", e."mdate", e."user", e."group", e."acUser", e."acGroup", e."acOther", e."acRead", e."acWrite", e."acFull", d."name", d."value", json(d."json") as "json", d."string", d."number" FROM ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} e LEFT JOIN ${SQLite3Driver.escape(`${this.prefix}data_${etype}`)} d USING ("guid")${guid == null ? '' : ` WHERE e."guid"=@guid`} ORDER BY e."guid";`, guid == null ? undefined : { params: { guid } })[Symbol.iterator]();
|
|
511
|
+
let datum = dataIterator.next();
|
|
512
|
+
while (!datum.done) {
|
|
513
|
+
const guid = datum.value.guid;
|
|
514
|
+
const tags = datum.value.tags.slice(1, -1);
|
|
515
|
+
const cdate = datum.value.cdate;
|
|
516
|
+
const mdate = datum.value.mdate;
|
|
517
|
+
const user = datum.value.user;
|
|
518
|
+
const group = datum.value.group;
|
|
519
|
+
const acUser = datum.value.acUser;
|
|
520
|
+
const acGroup = datum.value.acGroup;
|
|
521
|
+
const acOther = datum.value.acOther;
|
|
522
|
+
const acRead = datum.value.acRead?.slice(1, -1).split(',');
|
|
523
|
+
const acWrite = datum.value.acWrite?.slice(1, -1).split(',');
|
|
524
|
+
const acFull = datum.value.acFull?.slice(1, -1).split(',');
|
|
525
|
+
let currentEntityExport = [];
|
|
526
|
+
currentEntityExport.push(`{${guid}}<${etype}>[${tags}]`);
|
|
527
|
+
currentEntityExport.push(`\tcdate=${JSON.stringify(cdate)}`);
|
|
528
|
+
currentEntityExport.push(`\tmdate=${JSON.stringify(mdate)}`);
|
|
529
|
+
if (this.nymph.tilmeld != null) {
|
|
530
|
+
if (user != null) {
|
|
531
|
+
currentEntityExport.push(`\tuser=${JSON.stringify(['nymph_entity_reference', user, 'User'])}`);
|
|
554
532
|
}
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
// next entity is reached. datum will end on the next entity.
|
|
558
|
-
do {
|
|
559
|
-
const value = datum.value.value === 'N'
|
|
560
|
-
? JSON.stringify(datum.value.number)
|
|
561
|
-
: datum.value.value === 'S'
|
|
562
|
-
? JSON.stringify(datum.value.string)
|
|
563
|
-
: datum.value.value === 'J'
|
|
564
|
-
? datum.value.json
|
|
565
|
-
: datum.value.value;
|
|
566
|
-
currentEntityExport.push(`\t${datum.value.name}=${value}`);
|
|
567
|
-
datum = dataIterator.next();
|
|
568
|
-
} while (!datum.done && datum.value.guid === guid);
|
|
533
|
+
if (group != null) {
|
|
534
|
+
currentEntityExport.push(`\tgroup=${JSON.stringify(['nymph_entity_reference', group, 'Group'])}`);
|
|
569
535
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
datum = dataIterator.next();
|
|
536
|
+
if (acUser != null) {
|
|
537
|
+
currentEntityExport.push(`\tacUser=${JSON.stringify(acUser)}`);
|
|
573
538
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
539
|
+
if (acGroup != null) {
|
|
540
|
+
currentEntityExport.push(`\tacGroup=${JSON.stringify(acGroup)}`);
|
|
541
|
+
}
|
|
542
|
+
if (acOther != null) {
|
|
543
|
+
currentEntityExport.push(`\tacOther=${JSON.stringify(acOther)}`);
|
|
544
|
+
}
|
|
545
|
+
if (acRead != null) {
|
|
546
|
+
currentEntityExport.push(`\tacRead=${JSON.stringify(acRead)}`);
|
|
547
|
+
}
|
|
548
|
+
if (acWrite != null) {
|
|
549
|
+
currentEntityExport.push(`\tacWrite=${JSON.stringify(acWrite)}`);
|
|
550
|
+
}
|
|
551
|
+
if (acFull != null) {
|
|
552
|
+
currentEntityExport.push(`\tacFull=${JSON.stringify(acFull)}`);
|
|
577
553
|
}
|
|
578
554
|
}
|
|
555
|
+
if (datum.value.name != null) {
|
|
556
|
+
// This do will keep going and adding the data until the
|
|
557
|
+
// next entity is reached. datum will end on the next entity.
|
|
558
|
+
do {
|
|
559
|
+
const value = datum.value.value === 'N'
|
|
560
|
+
? JSON.stringify(datum.value.number)
|
|
561
|
+
: datum.value.value === 'S'
|
|
562
|
+
? JSON.stringify(datum.value.string)
|
|
563
|
+
: datum.value.value === 'J'
|
|
564
|
+
? datum.value.json
|
|
565
|
+
: datum.value.value;
|
|
566
|
+
currentEntityExport.push(`\t${datum.value.name}=${value}`);
|
|
567
|
+
datum = dataIterator.next();
|
|
568
|
+
} while (!datum.done && datum.value.guid === guid);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
// Make sure that datum is incremented :)
|
|
572
|
+
datum = dataIterator.next();
|
|
573
|
+
}
|
|
574
|
+
currentEntityExport.push('');
|
|
575
|
+
if (yield currentEntityExport.join('\n')) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
579
578
|
}
|
|
580
579
|
}
|
|
581
580
|
/**
|
|
@@ -2464,13 +2463,13 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
2464
2463
|
return true;
|
|
2465
2464
|
}
|
|
2466
2465
|
async needsMigration() {
|
|
2467
|
-
const table = this.queryGet(
|
|
2466
|
+
const table = this.queryGet(`SELECT "name" FROM "sqlite_master" WHERE "type"='table' AND "name" LIKE @prefix LIMIT 1;`, {
|
|
2468
2467
|
params: {
|
|
2469
2468
|
prefix: this.prefix + 'data_' + '%',
|
|
2470
2469
|
},
|
|
2471
2470
|
});
|
|
2472
2471
|
if (table?.name) {
|
|
2473
|
-
const result = this.queryGet(
|
|
2472
|
+
const result = this.queryGet(`SELECT 1 AS "exists" FROM pragma_table_info(@table) WHERE "name"='json';`, {
|
|
2474
2473
|
params: {
|
|
2475
2474
|
table: table.name,
|
|
2476
2475
|
},
|
|
@@ -2479,7 +2478,7 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
2479
2478
|
return 'json';
|
|
2480
2479
|
}
|
|
2481
2480
|
}
|
|
2482
|
-
const table2 = this.queryGet(
|
|
2481
|
+
const table2 = this.queryGet(`SELECT "name" FROM "sqlite_master" WHERE "type"='table' AND "name" LIKE @tokenTable LIMIT 1;`, {
|
|
2483
2482
|
params: {
|
|
2484
2483
|
tokenTable: this.prefix + 'tokens_' + '%',
|
|
2485
2484
|
},
|
|
@@ -2487,13 +2486,13 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
2487
2486
|
if (!table2 || !table2.name) {
|
|
2488
2487
|
return 'tokens';
|
|
2489
2488
|
}
|
|
2490
|
-
const table3 = this.queryGet(
|
|
2489
|
+
const table3 = this.queryGet(`SELECT "name" FROM "sqlite_master" WHERE "type"='table' AND "name" LIKE @prefix LIMIT 1;`, {
|
|
2491
2490
|
params: {
|
|
2492
2491
|
prefix: this.prefix + 'entities_' + '%',
|
|
2493
2492
|
},
|
|
2494
2493
|
});
|
|
2495
2494
|
if (table3?.name) {
|
|
2496
|
-
const result = this.queryGet(
|
|
2495
|
+
const result = this.queryGet(`SELECT 1 AS "exists" FROM pragma_table_info(@table) WHERE "name"='user';`, {
|
|
2497
2496
|
params: {
|
|
2498
2497
|
table: table3.name,
|
|
2499
2498
|
},
|