MCPcopy Create free account
hub / github.com/ProtonDriveApps/sdk / SQLiteCache

Class SQLiteCache

cli/src/cache/sqliteCache.ts:5–71  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3import type { EntityResult, ProtonDriveCache } from '@protontech/drive-sdk';
4
5const SQLITE_BUSY_TIMEOUT_MS = 5000;
6
7export class SQLiteCache implements ProtonDriveCache<string> {
8 private db: Database;
9
10 constructor(cacheFile: string) {
11 this.db = new Database(cacheFile, { create: true });
12 this.db.run(`PRAGMA journal_mode = WAL`);
13 this.db.run(`PRAGMA synchronous = NORMAL`);
14 this.db.run(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
15 this.db.run('CREATE TABLE IF NOT EXISTS entities (key TEXT PRIMARY KEY, value TEXT)');
16 this.db.run('CREATE TABLE IF NOT EXISTS entities_labels (label TEXT, key TEXT, UNIQUE (label, key))');
17 }
18
19 async clear() {
20 this.db.run('DELETE FROM entities');
21 this.db.run('DELETE FROM entities_labels');
22 }
23
24 async setEntity(key: string, data: string, tags?: string[]) {
25 const query = this.db.query('INSERT OR REPLACE INTO entities (key, value) VALUES ($key, $data)');
26 query.run({ $key: key, $data: data });
27
28 // Remove previous tags.
29 const deleteQuery = this.db.query('DELETE FROM entities_labels WHERE key = $key');
30 deleteQuery.run({ $key: key });
31
32 for (const tag of tags || []) {
33 const insertQuery = this.db.query(
34 'INSERT OR REPLACE INTO entities_labels (label, key) VALUES ($tag, $key)',
35 );
36 insertQuery.run({ $tag: tag, $key: key });
37 }
38 }
39
40 async getEntity(key: string) {
41 const query = this.db.query('SELECT value FROM entities WHERE key = $key');
42 const result = query.get({ $key: key });
43 if (!result) {
44 throw Error(`Entity ${key} not found`);
45 }
46 // @ts-expect-error - SQLite returns unknown type.
47 return result['value'];
48 }
49
50 async *iterateEntities(keys: string[]): AsyncGenerator<EntityResult<string>> {
51 for (const key of keys) {
52 try {
53 const value = await this.getEntity(key);
54 yield { key, ok: true, value };
55 } catch (error) {
56 yield { key, ok: false, error: `${error}` };
57 }
58 }
59 }
60
61 async *iterateEntitiesByTag(tag: string): AsyncGenerator<EntityResult<string>> {
62 const query = this.db.query('SELECT key FROM entities_labels WHERE label = $tag');

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected