deepbase-sqlite 3.5.1 → 3.6.0
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/README.md +2 -0
- package/package.json +2 -2
- package/src/SqliteDriver.js +26 -5
- package/test/test.js +15 -0
package/README.md
CHANGED
|
@@ -77,6 +77,8 @@ Efficiently stores nested objects using a key-value schema:
|
|
|
77
77
|
- Values are stored as JSON
|
|
78
78
|
- Fast lookups for both exact keys and partial paths
|
|
79
79
|
|
|
80
|
+
Each row also stores a monotonic `seq` so reads that rebuild objects use `ORDER BY seq, key`. That matches JavaScript insertion order for sibling keys and keeps `shift()` / `pop()` (via `DeepBase.keys()`) aligned with `JsonDriver`. Existing databases pick up `seq` via `ALTER TABLE` on connect (legacy rows default to `0`, then tie-break by `key`).
|
|
81
|
+
|
|
80
82
|
### ACID Compliance
|
|
81
83
|
|
|
82
84
|
SQLite provides:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepbase-sqlite",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "⚡ DeepBase SQLite - SQLite database driver",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.cjs",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"better-sqlite3": "^11.8.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"deepbase": "^3.
|
|
20
|
+
"deepbase": "^3.6.0"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"test": "mocha test/test.js"
|
package/src/SqliteDriver.js
CHANGED
|
@@ -52,7 +52,7 @@ export class SqliteDriver extends DeepBaseDriver {
|
|
|
52
52
|
SqliteDriver._instances[this.fileName] = this;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
_connectSync() {
|
|
56
56
|
if (this._connected) return;
|
|
57
57
|
|
|
58
58
|
if (!fs.existsSync(this.path)) {
|
|
@@ -75,15 +75,27 @@ export class SqliteDriver extends DeepBaseDriver {
|
|
|
75
75
|
this.db.exec(`
|
|
76
76
|
CREATE TABLE IF NOT EXISTS deepbase (
|
|
77
77
|
key TEXT PRIMARY KEY,
|
|
78
|
-
value TEXT NOT NULL
|
|
78
|
+
value TEXT NOT NULL,
|
|
79
|
+
seq INTEGER NOT NULL DEFAULT 0
|
|
79
80
|
)${withoutRowid}
|
|
80
81
|
`);
|
|
81
82
|
|
|
83
|
+
const tableCols = this.db.prepare('PRAGMA table_info(deepbase)').all();
|
|
84
|
+
if (!tableCols.some((c) => c.name === 'seq')) {
|
|
85
|
+
this.db.exec('ALTER TABLE deepbase ADD COLUMN seq INTEGER NOT NULL DEFAULT 0');
|
|
86
|
+
}
|
|
87
|
+
|
|
82
88
|
this.getStmt = this.db.prepare('SELECT value FROM deepbase WHERE key = ?');
|
|
83
|
-
this.setStmt = this.db.prepare(
|
|
89
|
+
this.setStmt = this.db.prepare(`
|
|
90
|
+
INSERT INTO deepbase (key, value, seq)
|
|
91
|
+
VALUES (?, ?, (SELECT IFNULL(MAX(seq), 0) + 1 FROM deepbase))
|
|
92
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
93
|
+
`);
|
|
84
94
|
this.delStmt = this.db.prepare('DELETE FROM deepbase WHERE key = ?');
|
|
85
|
-
this.getAllStmt = this.db.prepare('SELECT key, value FROM deepbase');
|
|
86
|
-
this.getKeysLikeStmt = this.db.prepare(
|
|
95
|
+
this.getAllStmt = this.db.prepare('SELECT key, value FROM deepbase ORDER BY seq, key');
|
|
96
|
+
this.getKeysLikeStmt = this.db.prepare(
|
|
97
|
+
"SELECT key, value FROM deepbase WHERE key LIKE ? ESCAPE '!' ORDER BY seq, key",
|
|
98
|
+
);
|
|
87
99
|
this.delChildrenStmt = this.db.prepare("DELETE FROM deepbase WHERE key LIKE ? ESCAPE '!'");
|
|
88
100
|
this.hasChildrenStmt = this.db.prepare("SELECT 1 FROM deepbase WHERE key LIKE ? ESCAPE '!' LIMIT 1");
|
|
89
101
|
|
|
@@ -116,6 +128,10 @@ export class SqliteDriver extends DeepBaseDriver {
|
|
|
116
128
|
this._connected = true;
|
|
117
129
|
}
|
|
118
130
|
|
|
131
|
+
async connect() {
|
|
132
|
+
this._connectSync();
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
async disconnect() {
|
|
120
136
|
if (this.db) {
|
|
121
137
|
this.db.close();
|
|
@@ -128,6 +144,11 @@ export class SqliteDriver extends DeepBaseDriver {
|
|
|
128
144
|
return this._getSync(args);
|
|
129
145
|
}
|
|
130
146
|
|
|
147
|
+
getSync(...args) {
|
|
148
|
+
this._connectSync();
|
|
149
|
+
return this._getSync(args);
|
|
150
|
+
}
|
|
151
|
+
|
|
131
152
|
_getSync(args) {
|
|
132
153
|
if (args.length === 0) {
|
|
133
154
|
return this._getRootObject();
|
package/test/test.js
CHANGED
|
@@ -85,6 +85,21 @@ for (const pragma of PRAGMA_MODES) {
|
|
|
85
85
|
await db.set('complex', complexObj);
|
|
86
86
|
assert.deepStrictEqual(await db.get('complex'), complexObj);
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
it('getSync returns same value as get (sync API)', async function () {
|
|
90
|
+
await db.set('syncKey', 'syncValue');
|
|
91
|
+
await db.set('syncNested', 'a', 1);
|
|
92
|
+
const driver = db.getDriver(0);
|
|
93
|
+
assert.strictEqual(driver.getSync('syncKey'), 'syncValue');
|
|
94
|
+
assert.strictEqual(driver.getSync('syncNested', 'a'), 1);
|
|
95
|
+
assert.strictEqual(driver.getSync('nonexistent'), null);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('getSync lazy-connects when not connected', function () {
|
|
99
|
+
const driver = new SqliteDriver({ name: 'getSync-lazy', path: testDataPath });
|
|
100
|
+
assert.strictEqual(driver.getSync('key'), null);
|
|
101
|
+
assert.ok(driver._connected);
|
|
102
|
+
});
|
|
88
103
|
});
|
|
89
104
|
|
|
90
105
|
describe('Keys with Dots', function () {
|