deepbase-sqlite 3.6.7 → 3.6.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepbase-sqlite",
3
- "version": "3.6.7",
3
+ "version": "3.6.9",
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.6.7"
20
+ "deepbase": "^3.6.9"
21
21
  },
22
22
  "scripts": {
23
23
  "test": "mocha test/test.js"
@@ -49,6 +49,7 @@ export class SqliteDriver extends DeepBaseDriver {
49
49
  }
50
50
 
51
51
  this.db = null;
52
+ this._nextSeq = 1;
52
53
  SqliteDriver._instances[this.fileName] = this;
53
54
  }
54
55
 
@@ -102,9 +103,10 @@ export class SqliteDriver extends DeepBaseDriver {
102
103
  }
103
104
 
104
105
  this.getStmt = this.db.prepare('SELECT value FROM deepbase WHERE key = ?');
106
+ this.getMaxSeqStmt = this.db.prepare('SELECT IFNULL(MAX(seq), 0) AS maxSeq FROM deepbase');
105
107
  this.setStmt = this.db.prepare(`
106
108
  INSERT INTO deepbase (key, value, seq)
107
- VALUES (?, ?, (SELECT IFNULL(MAX(seq), 0) + 1 FROM deepbase))
109
+ VALUES (?, ?, ?)
108
110
  ON CONFLICT(key) DO UPDATE SET value = excluded.value
109
111
  `);
110
112
  this.delStmt = this.db.prepare('DELETE FROM deepbase WHERE key = ?');
@@ -123,7 +125,7 @@ export class SqliteDriver extends DeepBaseDriver {
123
125
 
124
126
  this._setTxn = this.db.transaction((key, jsonValue, keys) => {
125
127
  this._expandParentObjects(keys);
126
- this.setStmt.run(key, jsonValue);
128
+ this._replaceRow(key, jsonValue);
127
129
  });
128
130
 
129
131
  this._delTxn = this.db.transaction((key, likePattern, keys) => {
@@ -137,17 +139,19 @@ export class SqliteDriver extends DeepBaseDriver {
137
139
  const newValue = func(currentValue);
138
140
  const key = this._pathToKey(keys);
139
141
  this._expandParentObjects(keys);
140
- this.setStmt.run(key, JSON.stringify(newValue));
142
+ this._replaceRow(key, JSON.stringify(newValue));
141
143
  return keys;
142
144
  });
143
145
 
144
146
  this._setRootTxn = this.db.transaction((entries) => {
145
147
  this.db.exec('DELETE FROM deepbase');
148
+ this._nextSeq = 1;
146
149
  for (const [key, value] of entries) {
147
- this.setStmt.run(key, JSON.stringify(value));
150
+ this.setStmt.run(key, JSON.stringify(value), this._consumeSeq());
148
151
  }
149
152
  });
150
153
 
154
+ this._nextSeq = Number(this.getMaxSeqStmt.get()?.maxSeq || 0) + 1;
151
155
  this._connected = true;
152
156
  }
153
157
 
@@ -216,9 +220,15 @@ export class SqliteDriver extends DeepBaseDriver {
216
220
  return keys;
217
221
  }
218
222
 
223
+ _replaceRow(key, jsonValue) {
224
+ this.delChildrenStmt.run(this._likePrefix(key));
225
+ this.setStmt.run(key, jsonValue, this._consumeSeq());
226
+ }
227
+
219
228
  async del(...keys) {
220
229
  if (keys.length === 0) {
221
230
  this.db.exec('DELETE FROM deepbase');
231
+ this._nextSeq = 1;
222
232
  return;
223
233
  }
224
234
 
@@ -412,12 +422,18 @@ export class SqliteDriver extends DeepBaseDriver {
412
422
 
413
423
  const entries = this._flattenObject(parentValue, parentKey);
414
424
  for (const [key, value] of entries) {
415
- this.setStmt.run(key, JSON.stringify(value));
425
+ this.setStmt.run(key, JSON.stringify(value), this._consumeSeq());
416
426
  }
417
427
  }
418
428
  }
419
429
  }
420
430
  }
431
+
432
+ _consumeSeq() {
433
+ const seq = this._nextSeq;
434
+ this._nextSeq += 1;
435
+ return seq;
436
+ }
421
437
  }
422
438
 
423
439
  export default SqliteDriver;
package/test/test.js CHANGED
@@ -429,6 +429,32 @@ for (const pragma of PRAGMA_MODES) {
429
429
  assert.deepStrictEqual(await db.get('settings'), { a: 1, b: 99, c: 3, d: 4 });
430
430
  });
431
431
 
432
+ it('should replace stale child keys when setting a parent object', async function () {
433
+ await db.set('profile', 'chinchon:MZM3Z', 'remoteData', 'denounces', 1000);
434
+ await db.set('profile', 'chinchon:MZM3Z', {
435
+ game: 'chinchon',
436
+ remoteData: {
437
+ hid: 'MZM3Z',
438
+ denounces: 0,
439
+ },
440
+ });
441
+
442
+ const profile = await db.get('profile', 'chinchon:MZM3Z');
443
+ assert.strictEqual(profile.remoteData.denounces, 0);
444
+ assert.strictEqual(await db.get('profile', 'chinchon:MZM3Z', 'remoteData', 'denounces'), 0);
445
+ });
446
+
447
+ it('should keep sibling keys with similar prefixes when replacing a parent object', async function () {
448
+ await db.set('a', 'b', 'c', 1);
449
+ await db.set('a', 'bc', 'c', 2);
450
+ await db.set('a', 'b', { c: 0 });
451
+
452
+ assert.deepStrictEqual(await db.get('a'), {
453
+ b: { c: 0 },
454
+ bc: { c: 2 },
455
+ });
456
+ });
457
+
432
458
  it('should handle nested object then deeper nesting', async function () {
433
459
  await db.set('user', { name: 'Alice', meta: { role: 'admin' } });
434
460
  await db.set('user', 'meta', 'role', 'user');