@nymphjs/driver-sqlite3 1.0.0-beta.3 → 1.0.0-beta.30
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 +122 -0
- package/dist/SQLite3Driver.d.ts +13 -6
- package/dist/SQLite3Driver.js +176 -59
- package/dist/SQLite3Driver.js.map +1 -1
- package/dist/SQLite3Driver.test.js +39 -5
- package/dist/SQLite3Driver.test.js.map +1 -1
- package/dist/conf/d.d.ts +2 -1
- package/dist/conf/defaults.js +2 -1
- package/dist/conf/defaults.js.map +1 -1
- package/package.json +11 -11
- package/src/SQLite3Driver.test.ts +41 -6
- package/src/SQLite3Driver.ts +236 -88
- package/src/conf/d.ts +21 -2
- package/src/conf/defaults.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,128 @@
|
|
|
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.30](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.29...v1.0.0-beta.30) (2023-05-12)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
9
|
+
|
|
10
|
+
# [1.0.0-beta.29](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.28...v1.0.0-beta.29) (2023-05-08)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
13
|
+
|
|
14
|
+
# [1.0.0-beta.28](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.27...v1.0.0-beta.28) (2023-05-05)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
17
|
+
|
|
18
|
+
# [1.0.0-beta.27](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.26...v1.0.0-beta.27) (2023-05-04)
|
|
19
|
+
|
|
20
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
21
|
+
|
|
22
|
+
# [1.0.0-beta.26](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.25...v1.0.0-beta.26) (2023-05-04)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
25
|
+
|
|
26
|
+
# [1.0.0-beta.25](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.24...v1.0.0-beta.25) (2023-05-04)
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
- don't create empty entities ([1d4d2e9](https://github.com/sciactive/nymphjs/commit/1d4d2e99af2e9cdc647bcf58ac34572836f41176))
|
|
31
|
+
|
|
32
|
+
# [1.0.0-beta.24](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.23...v1.0.0-beta.24) (2023-05-02)
|
|
33
|
+
|
|
34
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
35
|
+
|
|
36
|
+
# [1.0.0-beta.23](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.22...v1.0.0-beta.23) (2023-05-02)
|
|
37
|
+
|
|
38
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
39
|
+
|
|
40
|
+
# [1.0.0-beta.22](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.21...v1.0.0-beta.22) (2023-05-01)
|
|
41
|
+
|
|
42
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
43
|
+
|
|
44
|
+
# [1.0.0-beta.21](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.20...v1.0.0-beta.21) (2023-05-01)
|
|
45
|
+
|
|
46
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
47
|
+
|
|
48
|
+
# [1.0.0-beta.20](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.19...v1.0.0-beta.20) (2023-04-30)
|
|
49
|
+
|
|
50
|
+
### Features
|
|
51
|
+
|
|
52
|
+
- let the user revoke all current auth tokens ([63af3b9](https://github.com/sciactive/nymphjs/commit/63af3b9a31c6c221ab40c2c8a69231675f4634a2))
|
|
53
|
+
|
|
54
|
+
# [1.0.0-beta.19](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.18...v1.0.0-beta.19) (2023-04-29)
|
|
55
|
+
|
|
56
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
57
|
+
|
|
58
|
+
# [1.0.0-beta.18](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.17...v1.0.0-beta.18) (2023-04-27)
|
|
59
|
+
|
|
60
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
61
|
+
|
|
62
|
+
# [1.0.0-beta.17](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.16...v1.0.0-beta.17) (2023-04-24)
|
|
63
|
+
|
|
64
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
65
|
+
|
|
66
|
+
# [1.0.0-beta.16](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.15...v1.0.0-beta.16) (2023-03-31)
|
|
67
|
+
|
|
68
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
69
|
+
|
|
70
|
+
# [1.0.0-beta.15](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.14...v1.0.0-beta.15) (2023-03-23)
|
|
71
|
+
|
|
72
|
+
### Features
|
|
73
|
+
|
|
74
|
+
- add option to sort results by a property ([16384e7](https://github.com/sciactive/nymphjs/commit/16384e7bdab88abb55ccccabb06ac09f92fa8a03))
|
|
75
|
+
|
|
76
|
+
# [1.0.0-beta.14](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.13...v1.0.0-beta.14) (2023-03-17)
|
|
77
|
+
|
|
78
|
+
### Bug Fixes
|
|
79
|
+
|
|
80
|
+
- run pragma and function on write link on new sqlite3 db ([6c28ba1](https://github.com/sciactive/nymphjs/commit/6c28ba1a396f7cec098d4e550c7b82c93979eaec))
|
|
81
|
+
|
|
82
|
+
# [1.0.0-beta.13](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.12...v1.0.0-beta.13) (2023-03-16)
|
|
83
|
+
|
|
84
|
+
### Features
|
|
85
|
+
|
|
86
|
+
- open sqlite in readonly unless actively writing to db ([0443b91](https://github.com/sciactive/nymphjs/commit/0443b9188df3ebd557b96baf873abc4e4ddd9137))
|
|
87
|
+
|
|
88
|
+
# [1.0.0-beta.12](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.11...v1.0.0-beta.12) (2023-03-04)
|
|
89
|
+
|
|
90
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
91
|
+
|
|
92
|
+
# [1.0.0-beta.11](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.10...v1.0.0-beta.11) (2023-02-27)
|
|
93
|
+
|
|
94
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
95
|
+
|
|
96
|
+
# [1.0.0-beta.10](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.9...v1.0.0-beta.10) (2023-01-19)
|
|
97
|
+
|
|
98
|
+
### Features
|
|
99
|
+
|
|
100
|
+
- add wal mode setting to sqlite driver ([0071d66](https://github.com/sciactive/nymphjs/commit/0071d6628534b8b35d49c0238a99fe143fd03207))
|
|
101
|
+
|
|
102
|
+
# [1.0.0-beta.9](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.8...v1.0.0-beta.9) (2023-01-09)
|
|
103
|
+
|
|
104
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
105
|
+
|
|
106
|
+
# [1.0.0-beta.8](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2023-01-09)
|
|
107
|
+
|
|
108
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
109
|
+
|
|
110
|
+
# [1.0.0-beta.7](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2023-01-05)
|
|
111
|
+
|
|
112
|
+
### Bug Fixes
|
|
113
|
+
|
|
114
|
+
- sqlite transaction returns wrong instance of nymph if it has been cloned ([b278c76](https://github.com/sciactive/nymphjs/commit/b278c7633722cb1cca7a941187ae2f1ff8ebdc7b))
|
|
115
|
+
|
|
116
|
+
# [1.0.0-beta.6](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.5...v1.0.0-beta.6) (2023-01-05)
|
|
117
|
+
|
|
118
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
119
|
+
|
|
120
|
+
# [1.0.0-beta.5](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2022-11-24)
|
|
121
|
+
|
|
122
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
123
|
+
|
|
124
|
+
# [1.0.0-beta.4](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.3...v1.0.0-beta.4) (2022-11-23)
|
|
125
|
+
|
|
126
|
+
**Note:** Version bump only for package @nymphjs/driver-sqlite3
|
|
127
|
+
|
|
6
128
|
# [1.0.0-beta.3](https://github.com/sciactive/nymphjs/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2022-11-21)
|
|
7
129
|
|
|
8
130
|
### Bug Fixes
|
package/dist/SQLite3Driver.d.ts
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import SQLite3 from 'better-sqlite3';
|
|
2
2
|
import { NymphDriver, EntityConstructor, EntityInterface, FormattedSelector, Options, Selector } from '@nymphjs/nymph';
|
|
3
3
|
import { SQLite3DriverConfig } from './conf';
|
|
4
|
+
declare class InternalStore {
|
|
5
|
+
link: SQLite3.Database;
|
|
6
|
+
linkWrite?: SQLite3.Database;
|
|
7
|
+
connected: boolean;
|
|
8
|
+
transactionsStarted: number;
|
|
9
|
+
constructor(link: SQLite3.Database);
|
|
10
|
+
}
|
|
4
11
|
export default class SQLite3Driver extends NymphDriver {
|
|
5
12
|
config: SQLite3DriverConfig;
|
|
6
13
|
protected prefix: string;
|
|
7
|
-
protected
|
|
8
|
-
protected link: SQLite3.Database;
|
|
9
|
-
protected transactionsStarted: number;
|
|
14
|
+
protected store: InternalStore;
|
|
10
15
|
static escape(input: string): string;
|
|
11
|
-
constructor(config: Partial<SQLite3DriverConfig
|
|
12
|
-
|
|
16
|
+
constructor(config: Partial<SQLite3DriverConfig>, store?: InternalStore);
|
|
17
|
+
clone(): SQLite3Driver;
|
|
18
|
+
connect(): Promise<boolean>;
|
|
19
|
+
private _connect;
|
|
13
20
|
disconnect(): Promise<false>;
|
|
14
21
|
inTransaction(): Promise<boolean>;
|
|
15
22
|
isConnected(): boolean;
|
|
16
|
-
private checkReadOnlyMode;
|
|
17
23
|
private createTables;
|
|
18
24
|
private query;
|
|
19
25
|
private queryIter;
|
|
@@ -50,3 +56,4 @@ export default class SQLite3Driver extends NymphDriver {
|
|
|
50
56
|
setUID(name: string, curUid: number): Promise<boolean>;
|
|
51
57
|
startTransaction(name: string): Promise<import("@nymphjs/nymph").Nymph>;
|
|
52
58
|
}
|
|
59
|
+
export {};
|
package/dist/SQLite3Driver.js
CHANGED
|
@@ -7,6 +7,13 @@ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
|
7
7
|
const nymph_1 = require("@nymphjs/nymph");
|
|
8
8
|
const guid_1 = require("@nymphjs/guid");
|
|
9
9
|
const conf_1 = require("./conf");
|
|
10
|
+
class InternalStore {
|
|
11
|
+
constructor(link) {
|
|
12
|
+
this.connected = false;
|
|
13
|
+
this.transactionsStarted = 0;
|
|
14
|
+
this.link = link;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
10
17
|
class SQLite3Driver extends nymph_1.NymphDriver {
|
|
11
18
|
static escape(input) {
|
|
12
19
|
if (input.indexOf('\x00') !== -1) {
|
|
@@ -14,63 +21,126 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
14
21
|
}
|
|
15
22
|
return '"' + input.replace(/"/g, () => '""') + '"';
|
|
16
23
|
}
|
|
17
|
-
constructor(config) {
|
|
24
|
+
constructor(config, store) {
|
|
18
25
|
super();
|
|
19
|
-
this.connected = false;
|
|
20
|
-
this.transactionsStarted = 0;
|
|
21
26
|
this.config = { ...conf_1.SQLite3DriverConfigDefaults, ...config };
|
|
27
|
+
if (this.config.filename === ':memory:') {
|
|
28
|
+
this.config.explicitWrite = true;
|
|
29
|
+
}
|
|
22
30
|
this.prefix = this.config.prefix;
|
|
23
|
-
|
|
31
|
+
if (store) {
|
|
32
|
+
this.store = store;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.connect();
|
|
36
|
+
}
|
|
24
37
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
clone() {
|
|
39
|
+
return new SQLite3Driver(this.config, this.store);
|
|
40
|
+
}
|
|
41
|
+
connect() {
|
|
42
|
+
if (this.store && this.store.connected) {
|
|
43
|
+
return Promise.resolve(true);
|
|
44
|
+
}
|
|
45
|
+
this._connect(false);
|
|
46
|
+
return Promise.resolve(this.store.connected);
|
|
47
|
+
}
|
|
48
|
+
_connect(write) {
|
|
49
|
+
const { filename, fileMustExist, timeout, explicitWrite, wal, verbose } = this.config;
|
|
50
|
+
try {
|
|
51
|
+
const setOptions = (link) => {
|
|
52
|
+
if (wal) {
|
|
53
|
+
link.pragma('journal_mode = WAL;');
|
|
54
|
+
}
|
|
55
|
+
link.pragma('encoding = "UTF-8";');
|
|
56
|
+
link.pragma('foreign_keys = 1;');
|
|
57
|
+
link.pragma('case_sensitive_like = 1;');
|
|
58
|
+
link.function('regexp', { deterministic: true }, ((pattern, subject) => (this.posixRegexMatch(pattern, subject) ? 1 : 0)));
|
|
59
|
+
};
|
|
60
|
+
let link;
|
|
28
61
|
try {
|
|
29
|
-
|
|
30
|
-
readonly,
|
|
62
|
+
link = new better_sqlite3_1.default(filename, {
|
|
63
|
+
readonly: !explicitWrite && !write,
|
|
31
64
|
fileMustExist,
|
|
32
65
|
timeout,
|
|
33
66
|
verbose,
|
|
34
67
|
});
|
|
35
|
-
this.connected = true;
|
|
36
|
-
this.link.pragma('encoding = "UTF-8";');
|
|
37
|
-
this.link.pragma('foreign_keys = 1;');
|
|
38
|
-
this.link.pragma('case_sensitive_like = 1;');
|
|
39
|
-
this.link.function('regexp', { deterministic: true }, (pattern, subject) => this.posixRegexMatch(pattern, subject) ? 1 : 0);
|
|
40
68
|
}
|
|
41
69
|
catch (e) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
70
|
+
if (e.code === 'SQLITE_CANTOPEN' &&
|
|
71
|
+
!explicitWrite &&
|
|
72
|
+
!write &&
|
|
73
|
+
!this.config.fileMustExist) {
|
|
74
|
+
const writeLink = new better_sqlite3_1.default(filename, {
|
|
75
|
+
readonly: false,
|
|
76
|
+
fileMustExist,
|
|
77
|
+
timeout,
|
|
78
|
+
verbose,
|
|
79
|
+
});
|
|
80
|
+
setOptions(writeLink);
|
|
81
|
+
writeLink.close();
|
|
82
|
+
link = new better_sqlite3_1.default(filename, {
|
|
83
|
+
readonly: true,
|
|
84
|
+
fileMustExist,
|
|
85
|
+
timeout,
|
|
86
|
+
verbose,
|
|
87
|
+
});
|
|
45
88
|
}
|
|
46
89
|
else {
|
|
47
|
-
throw
|
|
90
|
+
throw e;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!this.store) {
|
|
94
|
+
if (write) {
|
|
95
|
+
throw new Error('Tried to open in write without opening in read first.');
|
|
48
96
|
}
|
|
97
|
+
this.store = new InternalStore(link);
|
|
98
|
+
}
|
|
99
|
+
else if (write) {
|
|
100
|
+
this.store.linkWrite = link;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.store.link = link;
|
|
104
|
+
}
|
|
105
|
+
this.store.connected = true;
|
|
106
|
+
setOptions(link);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
if (this.store) {
|
|
110
|
+
this.store.connected = false;
|
|
111
|
+
}
|
|
112
|
+
if (filename === ':memory:') {
|
|
113
|
+
throw new nymph_1.NotConfiguredError("It seems the config hasn't been set up correctly. Could not connect: " +
|
|
114
|
+
e?.message);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
throw new nymph_1.UnableToConnectError('Could not connect: ' + e?.message);
|
|
49
118
|
}
|
|
50
119
|
}
|
|
51
|
-
return this.connected;
|
|
52
120
|
}
|
|
53
121
|
async disconnect() {
|
|
54
|
-
if (this.connected) {
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
122
|
+
if (this.store.connected) {
|
|
123
|
+
if (this.store.linkWrite && !this.config.explicitWrite) {
|
|
124
|
+
this.store.linkWrite.exec('PRAGMA optimize;');
|
|
125
|
+
this.store.linkWrite.close();
|
|
126
|
+
this.store.linkWrite = undefined;
|
|
127
|
+
}
|
|
128
|
+
if (this.config.explicitWrite) {
|
|
129
|
+
this.store.link.exec('PRAGMA optimize;');
|
|
130
|
+
}
|
|
131
|
+
this.store.link.close();
|
|
132
|
+
this.store.transactionsStarted = 0;
|
|
133
|
+
this.store.connected = false;
|
|
58
134
|
}
|
|
59
|
-
return this.connected;
|
|
135
|
+
return this.store.connected;
|
|
60
136
|
}
|
|
61
137
|
async inTransaction() {
|
|
62
|
-
return this.transactionsStarted > 0;
|
|
138
|
+
return this.store.transactionsStarted > 0;
|
|
63
139
|
}
|
|
64
140
|
isConnected() {
|
|
65
|
-
return this.connected;
|
|
66
|
-
}
|
|
67
|
-
checkReadOnlyMode() {
|
|
68
|
-
if (this.config.readonly) {
|
|
69
|
-
throw new nymph_1.InvalidParametersError('Attempt to write to SQLite3 DB in read only mode.');
|
|
70
|
-
}
|
|
141
|
+
return this.store.connected;
|
|
71
142
|
}
|
|
72
143
|
createTables(etype = null) {
|
|
73
|
-
this.checkReadOnlyMode();
|
|
74
144
|
this.startTransaction('nymph-tablecreation');
|
|
75
145
|
try {
|
|
76
146
|
if (etype != null) {
|
|
@@ -130,23 +200,32 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
130
200
|
}
|
|
131
201
|
}
|
|
132
202
|
queryIter(query, { etypes = [], params = {}, } = {}) {
|
|
133
|
-
return this.query(() => this.
|
|
203
|
+
return this.query(() => (this.store.linkWrite || this.store.link)
|
|
204
|
+
.prepare(query)
|
|
205
|
+
.iterate(params), `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
134
206
|
}
|
|
135
207
|
queryGet(query, { etypes = [], params = {}, } = {}) {
|
|
136
|
-
return this.query(() => this.link.prepare(query).get(params), `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
208
|
+
return this.query(() => (this.store.linkWrite || this.store.link).prepare(query).get(params), `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
137
209
|
}
|
|
138
210
|
queryRun(query, { etypes = [], params = {}, } = {}) {
|
|
139
|
-
return this.query(() => this.link.prepare(query).run(params), `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
211
|
+
return this.query(() => (this.store.linkWrite || this.store.link).prepare(query).run(params), `${query} -- ${JSON.stringify(params)}`, etypes);
|
|
140
212
|
}
|
|
141
213
|
async commit(name) {
|
|
142
214
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
143
215
|
throw new nymph_1.InvalidParametersError('Transaction commit attempted without a name.');
|
|
144
216
|
}
|
|
145
|
-
if (this.transactionsStarted === 0) {
|
|
217
|
+
if (this.store.transactionsStarted === 0) {
|
|
146
218
|
return true;
|
|
147
219
|
}
|
|
148
220
|
this.queryRun(`RELEASE SAVEPOINT ${SQLite3Driver.escape(name)};`);
|
|
149
|
-
this.transactionsStarted--;
|
|
221
|
+
this.store.transactionsStarted--;
|
|
222
|
+
if (this.store.transactionsStarted === 0 &&
|
|
223
|
+
this.store.linkWrite &&
|
|
224
|
+
!this.config.explicitWrite) {
|
|
225
|
+
this.store.linkWrite.exec('PRAGMA optimize;');
|
|
226
|
+
this.store.linkWrite.close();
|
|
227
|
+
this.store.linkWrite = undefined;
|
|
228
|
+
}
|
|
150
229
|
return true;
|
|
151
230
|
}
|
|
152
231
|
async deleteEntityByID(guid, className) {
|
|
@@ -159,7 +238,6 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
159
238
|
EntityClass = className;
|
|
160
239
|
}
|
|
161
240
|
const etype = EntityClass.ETYPE;
|
|
162
|
-
this.checkReadOnlyMode();
|
|
163
241
|
await this.startTransaction('nymph-delete');
|
|
164
242
|
try {
|
|
165
243
|
this.queryRun(`DELETE FROM ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=@guid;`, {
|
|
@@ -201,12 +279,13 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
201
279
|
if (!name) {
|
|
202
280
|
throw new nymph_1.InvalidParametersError('Name not given for UID');
|
|
203
281
|
}
|
|
204
|
-
this.
|
|
282
|
+
await this.startTransaction('nymph-delete-uid');
|
|
205
283
|
this.queryRun(`DELETE FROM ${SQLite3Driver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
206
284
|
params: {
|
|
207
285
|
name,
|
|
208
286
|
},
|
|
209
287
|
});
|
|
288
|
+
await this.commit('nymph-delete-uid');
|
|
210
289
|
return true;
|
|
211
290
|
}
|
|
212
291
|
async exportEntities(writeLine) {
|
|
@@ -274,6 +353,7 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
274
353
|
const cTable = `c${tableSuffix}`;
|
|
275
354
|
const fTable = `f${tableSuffix}`;
|
|
276
355
|
const ieTable = `ie${tableSuffix}`;
|
|
356
|
+
const sTable = `s${tableSuffix}`;
|
|
277
357
|
const sort = options.sort ?? 'cdate';
|
|
278
358
|
const queryParts = this.iterateSelectorsForQuery(formattedSelectors, (key, value, typeIsOr, typeIsNot) => {
|
|
279
359
|
const clauseNot = key.startsWith('!');
|
|
@@ -1019,18 +1099,31 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1019
1099
|
return curQuery;
|
|
1020
1100
|
});
|
|
1021
1101
|
let sortBy;
|
|
1102
|
+
let sortByInner;
|
|
1103
|
+
let sortJoin = '';
|
|
1104
|
+
const order = options.reverse ? ' DESC' : '';
|
|
1022
1105
|
switch (sort) {
|
|
1023
1106
|
case 'mdate':
|
|
1024
|
-
sortBy =
|
|
1107
|
+
sortBy = `${eTable}."mdate"${order}`;
|
|
1108
|
+
sortByInner = `${ieTable}."mdate"${order}`;
|
|
1025
1109
|
break;
|
|
1026
1110
|
case 'cdate':
|
|
1111
|
+
sortBy = `${eTable}."cdate"${order}`;
|
|
1112
|
+
sortByInner = `${ieTable}."cdate"${order}`;
|
|
1113
|
+
break;
|
|
1027
1114
|
default:
|
|
1028
|
-
|
|
1115
|
+
const name = `param${++count.i}`;
|
|
1116
|
+
sortJoin = `LEFT JOIN (
|
|
1117
|
+
SELECT "guid", "string", "number"
|
|
1118
|
+
FROM ${SQLite3Driver.escape(this.prefix + 'comparisons_' + etype)}
|
|
1119
|
+
WHERE "name"=@${name}
|
|
1120
|
+
ORDER BY "number"${order}, "string"${order}
|
|
1121
|
+
) ${sTable} USING ("guid")`;
|
|
1122
|
+
sortBy = `${sTable}."number"${order}, ${sTable}."string"${order}`;
|
|
1123
|
+
sortByInner = sortBy;
|
|
1124
|
+
params[name] = sort;
|
|
1029
1125
|
break;
|
|
1030
1126
|
}
|
|
1031
|
-
if (options.reverse) {
|
|
1032
|
-
sortBy += ' DESC';
|
|
1033
|
-
}
|
|
1034
1127
|
let query;
|
|
1035
1128
|
if (queryParts.length) {
|
|
1036
1129
|
if (subquery) {
|
|
@@ -1063,8 +1156,9 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1063
1156
|
else if (options.return === 'guid') {
|
|
1064
1157
|
query = `SELECT "guid"
|
|
1065
1158
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${ieTable}
|
|
1159
|
+
${sortJoin}
|
|
1066
1160
|
WHERE (${whereClause})
|
|
1067
|
-
ORDER BY ${
|
|
1161
|
+
ORDER BY ${sortByInner}, "guid"${limit}${offset}`;
|
|
1068
1162
|
}
|
|
1069
1163
|
else {
|
|
1070
1164
|
query = `SELECT
|
|
@@ -1079,13 +1173,15 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1079
1173
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${eTable}
|
|
1080
1174
|
LEFT JOIN ${SQLite3Driver.escape(this.prefix + 'data_' + etype)} ${dTable} USING ("guid")
|
|
1081
1175
|
INNER JOIN ${SQLite3Driver.escape(this.prefix + 'comparisons_' + etype)} ${cTable} USING ("guid", "name")
|
|
1176
|
+
${sortJoin}
|
|
1082
1177
|
INNER JOIN (
|
|
1083
1178
|
SELECT "guid"
|
|
1084
1179
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${ieTable}
|
|
1180
|
+
${sortJoin}
|
|
1085
1181
|
WHERE (${whereClause})
|
|
1086
|
-
ORDER BY ${
|
|
1182
|
+
ORDER BY ${sortByInner}${limit}${offset}
|
|
1087
1183
|
) ${fTable} USING ("guid")
|
|
1088
|
-
ORDER BY ${
|
|
1184
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1089
1185
|
}
|
|
1090
1186
|
}
|
|
1091
1187
|
}
|
|
@@ -1117,7 +1213,8 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1117
1213
|
else if (options.return === 'guid') {
|
|
1118
1214
|
query = `SELECT "guid"
|
|
1119
1215
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${ieTable}
|
|
1120
|
-
|
|
1216
|
+
${sortJoin}
|
|
1217
|
+
ORDER BY ${sortByInner}, "guid"${limit}${offset}`;
|
|
1121
1218
|
}
|
|
1122
1219
|
else {
|
|
1123
1220
|
if (limit || offset) {
|
|
@@ -1133,12 +1230,14 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1133
1230
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${eTable}
|
|
1134
1231
|
LEFT JOIN ${SQLite3Driver.escape(this.prefix + 'data_' + etype)} ${dTable} USING ("guid")
|
|
1135
1232
|
INNER JOIN ${SQLite3Driver.escape(this.prefix + 'comparisons_' + etype)} c USING ("guid", "name")
|
|
1233
|
+
${sortJoin}
|
|
1136
1234
|
INNER JOIN (
|
|
1137
1235
|
SELECT "guid"
|
|
1138
1236
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${ieTable}
|
|
1139
|
-
|
|
1237
|
+
${sortJoin}
|
|
1238
|
+
ORDER BY ${sortByInner}${limit}${offset}
|
|
1140
1239
|
) ${fTable} USING ("guid")
|
|
1141
|
-
ORDER BY ${
|
|
1240
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1142
1241
|
}
|
|
1143
1242
|
else {
|
|
1144
1243
|
query = `SELECT
|
|
@@ -1153,7 +1252,8 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1153
1252
|
FROM ${SQLite3Driver.escape(this.prefix + 'entities_' + etype)} ${eTable}
|
|
1154
1253
|
LEFT JOIN ${SQLite3Driver.escape(this.prefix + 'data_' + etype)} ${dTable} USING ("guid")
|
|
1155
1254
|
INNER JOIN ${SQLite3Driver.escape(this.prefix + 'comparisons_' + etype)} ${cTable} USING ("guid", "name")
|
|
1156
|
-
|
|
1255
|
+
${sortJoin}
|
|
1256
|
+
ORDER BY ${sortBy}, ${eTable}."guid"`;
|
|
1157
1257
|
}
|
|
1158
1258
|
}
|
|
1159
1259
|
}
|
|
@@ -1211,7 +1311,6 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1211
1311
|
return result?.cur_uid ?? null;
|
|
1212
1312
|
}
|
|
1213
1313
|
async import(filename) {
|
|
1214
|
-
this.checkReadOnlyMode();
|
|
1215
1314
|
try {
|
|
1216
1315
|
return this.importFromFile(filename, async (guid, tags, sdata, etype) => {
|
|
1217
1316
|
this.queryRun(`DELETE FROM ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} WHERE "guid"=@guid;`, {
|
|
@@ -1317,7 +1416,6 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1317
1416
|
if (name == null) {
|
|
1318
1417
|
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1319
1418
|
}
|
|
1320
|
-
this.checkReadOnlyMode();
|
|
1321
1419
|
await this.startTransaction('nymph-newuid');
|
|
1322
1420
|
try {
|
|
1323
1421
|
let curUid = this.queryGet(`SELECT "cur_uid" FROM ${SQLite3Driver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
@@ -1355,28 +1453,35 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1355
1453
|
if (oldName == null || newName == null) {
|
|
1356
1454
|
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1357
1455
|
}
|
|
1358
|
-
this.
|
|
1456
|
+
await this.startTransaction('nymph-rename-uid');
|
|
1359
1457
|
this.queryRun(`UPDATE ${SQLite3Driver.escape(`${this.prefix}uids`)} SET "name"=@newName WHERE "name"=@oldName;`, {
|
|
1360
1458
|
params: {
|
|
1361
1459
|
newName,
|
|
1362
1460
|
oldName,
|
|
1363
1461
|
},
|
|
1364
1462
|
});
|
|
1463
|
+
await this.commit('nymph-rename-uid');
|
|
1365
1464
|
return true;
|
|
1366
1465
|
}
|
|
1367
1466
|
async rollback(name) {
|
|
1368
1467
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
1369
1468
|
throw new nymph_1.InvalidParametersError('Transaction rollback attempted without a name.');
|
|
1370
1469
|
}
|
|
1371
|
-
if (this.transactionsStarted === 0) {
|
|
1470
|
+
if (this.store.transactionsStarted === 0) {
|
|
1372
1471
|
return true;
|
|
1373
1472
|
}
|
|
1374
1473
|
this.queryRun(`ROLLBACK TO SAVEPOINT ${SQLite3Driver.escape(name)};`);
|
|
1375
|
-
this.transactionsStarted--;
|
|
1474
|
+
this.store.transactionsStarted--;
|
|
1475
|
+
if (this.store.transactionsStarted === 0 &&
|
|
1476
|
+
this.store.linkWrite &&
|
|
1477
|
+
!this.config.explicitWrite) {
|
|
1478
|
+
this.store.linkWrite.exec('PRAGMA optimize;');
|
|
1479
|
+
this.store.linkWrite.close();
|
|
1480
|
+
this.store.linkWrite = undefined;
|
|
1481
|
+
}
|
|
1376
1482
|
return true;
|
|
1377
1483
|
}
|
|
1378
1484
|
async saveEntity(entity) {
|
|
1379
|
-
this.checkReadOnlyMode();
|
|
1380
1485
|
const insertData = (guid, data, sdata, etype) => {
|
|
1381
1486
|
const runInsertQuery = (name, value, svalue) => {
|
|
1382
1487
|
if (value === undefined) {
|
|
@@ -1426,6 +1531,10 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1426
1531
|
};
|
|
1427
1532
|
try {
|
|
1428
1533
|
return this.saveEntityRowLike(entity, async (_entity, guid, tags, data, sdata, cdate, etype) => {
|
|
1534
|
+
if (Object.keys(data).length === 0 &&
|
|
1535
|
+
Object.keys(sdata).length === 0) {
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1429
1538
|
this.queryRun(`INSERT INTO ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} ("guid", "tags", "cdate", "mdate") VALUES (@guid, @tags, @cdate, @cdate);`, {
|
|
1430
1539
|
etypes: [etype],
|
|
1431
1540
|
params: {
|
|
@@ -1437,6 +1546,10 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1437
1546
|
insertData(guid, data, sdata, etype);
|
|
1438
1547
|
return true;
|
|
1439
1548
|
}, async (entity, guid, tags, data, sdata, mdate, etype) => {
|
|
1549
|
+
if (Object.keys(data).length === 0 &&
|
|
1550
|
+
Object.keys(sdata).length === 0) {
|
|
1551
|
+
return false;
|
|
1552
|
+
}
|
|
1440
1553
|
const info = this.queryRun(`UPDATE ${SQLite3Driver.escape(`${this.prefix}entities_${etype}`)} SET "tags"=@tags, "mdate"=@mdate WHERE "guid"=@guid AND "mdate" <= @emdate;`, {
|
|
1441
1554
|
etypes: [etype],
|
|
1442
1555
|
params: {
|
|
@@ -1491,7 +1604,7 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1491
1604
|
if (name == null) {
|
|
1492
1605
|
throw new nymph_1.InvalidParametersError('Name not given for UID.');
|
|
1493
1606
|
}
|
|
1494
|
-
this.
|
|
1607
|
+
await this.startTransaction('nymph-set-uid');
|
|
1495
1608
|
this.queryRun(`DELETE FROM ${SQLite3Driver.escape(`${this.prefix}uids`)} WHERE "name"=@name;`, {
|
|
1496
1609
|
params: {
|
|
1497
1610
|
name,
|
|
@@ -1503,14 +1616,18 @@ class SQLite3Driver extends nymph_1.NymphDriver {
|
|
|
1503
1616
|
curUid,
|
|
1504
1617
|
},
|
|
1505
1618
|
});
|
|
1619
|
+
await this.commit('nymph-set-uid');
|
|
1506
1620
|
return true;
|
|
1507
1621
|
}
|
|
1508
1622
|
async startTransaction(name) {
|
|
1509
1623
|
if (name == null || typeof name !== 'string' || name.length === 0) {
|
|
1510
1624
|
throw new nymph_1.InvalidParametersError('Transaction start attempted without a name.');
|
|
1511
1625
|
}
|
|
1626
|
+
if (!this.config.explicitWrite && !this.store.linkWrite) {
|
|
1627
|
+
this._connect(true);
|
|
1628
|
+
}
|
|
1512
1629
|
this.queryRun(`SAVEPOINT ${SQLite3Driver.escape(name)};`);
|
|
1513
|
-
this.transactionsStarted++;
|
|
1630
|
+
this.store.transactionsStarted++;
|
|
1514
1631
|
return this.nymph;
|
|
1515
1632
|
}
|
|
1516
1633
|
}
|