@stackmemoryai/stackmemory 0.5.29 → 0.5.31
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 +53 -32
- package/dist/core/database/batch-operations.js +29 -4
- package/dist/core/database/batch-operations.js.map +2 -2
- package/dist/core/database/connection-pool.js +13 -2
- package/dist/core/database/connection-pool.js.map +2 -2
- package/dist/core/database/migration-manager.js +130 -34
- package/dist/core/database/migration-manager.js.map +2 -2
- package/dist/core/database/paradedb-adapter.js +23 -7
- package/dist/core/database/paradedb-adapter.js.map +2 -2
- package/dist/core/database/query-router.js +8 -3
- package/dist/core/database/query-router.js.map +2 -2
- package/dist/core/database/sqlite-adapter.js +152 -33
- package/dist/core/database/sqlite-adapter.js.map +2 -2
- package/dist/integrations/linear/auth.js +34 -20
- package/dist/integrations/linear/auth.js.map +2 -2
- package/dist/integrations/linear/auto-sync.js +18 -8
- package/dist/integrations/linear/auto-sync.js.map +2 -2
- package/dist/integrations/linear/client.js +42 -9
- package/dist/integrations/linear/client.js.map +2 -2
- package/dist/integrations/linear/migration.js +94 -36
- package/dist/integrations/linear/migration.js.map +2 -2
- package/dist/integrations/linear/oauth-server.js +77 -34
- package/dist/integrations/linear/oauth-server.js.map +2 -2
- package/dist/integrations/linear/rest-client.js +13 -3
- package/dist/integrations/linear/rest-client.js.map +2 -2
- package/dist/integrations/linear/sync-service.js +18 -15
- package/dist/integrations/linear/sync-service.js.map +2 -2
- package/dist/integrations/linear/sync.js +12 -4
- package/dist/integrations/linear/sync.js.map +2 -2
- package/dist/integrations/linear/unified-sync.js +33 -8
- package/dist/integrations/linear/unified-sync.js.map +2 -2
- package/dist/integrations/linear/webhook-handler.js +5 -1
- package/dist/integrations/linear/webhook-handler.js.map +2 -2
- package/dist/integrations/linear/webhook-server.js +7 -7
- package/dist/integrations/linear/webhook-server.js.map +2 -2
- package/dist/integrations/linear/webhook.js +9 -2
- package/dist/integrations/linear/webhook.js.map +2 -2
- package/dist/integrations/mcp/schemas.js +147 -0
- package/dist/integrations/mcp/schemas.js.map +7 -0
- package/dist/integrations/mcp/server.js +19 -3
- package/dist/integrations/mcp/server.js.map +2 -2
- package/package.json +1 -1
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
FeatureAwareDatabaseAdapter
|
|
8
8
|
} from "./database-adapter.js";
|
|
9
9
|
import { logger } from "../monitoring/logger.js";
|
|
10
|
+
import { DatabaseError, ErrorCode, ValidationError } from "../errors/index.js";
|
|
10
11
|
import * as fs from "fs/promises";
|
|
11
12
|
import * as path from "path";
|
|
12
13
|
class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
@@ -76,7 +77,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
async initializeSchema() {
|
|
79
|
-
if (!this.db)
|
|
80
|
+
if (!this.db)
|
|
81
|
+
throw new DatabaseError(
|
|
82
|
+
"Database not connected",
|
|
83
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
84
|
+
);
|
|
80
85
|
this.db.exec(`
|
|
81
86
|
CREATE TABLE IF NOT EXISTS frames (
|
|
82
87
|
frame_id TEXT PRIMARY KEY,
|
|
@@ -149,8 +154,12 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
149
154
|
ensureCascadeConstraints() {
|
|
150
155
|
if (!this.db) return;
|
|
151
156
|
const needsCascade = (table) => {
|
|
152
|
-
const rows = this.db.prepare(
|
|
153
|
-
|
|
157
|
+
const rows = this.db.prepare(
|
|
158
|
+
`PRAGMA foreign_key_list(${table})`
|
|
159
|
+
).all();
|
|
160
|
+
return rows.some(
|
|
161
|
+
(r) => r.table === "frames" && String(r.on_delete).toUpperCase() !== "CASCADE"
|
|
162
|
+
);
|
|
154
163
|
};
|
|
155
164
|
const migrateTable = (table) => {
|
|
156
165
|
const createSql = table === "events" ? `CREATE TABLE events_new (
|
|
@@ -183,7 +192,9 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
183
192
|
this.db.exec("PRAGMA foreign_keys = OFF;");
|
|
184
193
|
this.db.exec("BEGIN;");
|
|
185
194
|
this.db.exec(createSql);
|
|
186
|
-
this.db.prepare(
|
|
195
|
+
this.db.prepare(
|
|
196
|
+
`INSERT INTO ${table === "events" ? "events_new" : "anchors_new"} (${cols}) SELECT ${cols} FROM ${table}`
|
|
197
|
+
).run();
|
|
187
198
|
this.db.exec(`DROP TABLE ${table};`);
|
|
188
199
|
this.db.exec(`ALTER TABLE ${table}_new RENAME TO ${table};`);
|
|
189
200
|
for (const stmt of idxSql) this.db.exec(stmt);
|
|
@@ -195,7 +206,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
195
206
|
if (needsCascade("anchors")) migrateTable("anchors");
|
|
196
207
|
}
|
|
197
208
|
async migrateSchema(targetVersion) {
|
|
198
|
-
if (!this.db)
|
|
209
|
+
if (!this.db)
|
|
210
|
+
throw new DatabaseError(
|
|
211
|
+
"Database not connected",
|
|
212
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
213
|
+
);
|
|
199
214
|
const currentVersion = await this.getSchemaVersion();
|
|
200
215
|
if (currentVersion >= targetVersion) {
|
|
201
216
|
logger.info("Schema already at target version", {
|
|
@@ -210,7 +225,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
210
225
|
}
|
|
211
226
|
}
|
|
212
227
|
async getSchemaVersion() {
|
|
213
|
-
if (!this.db)
|
|
228
|
+
if (!this.db)
|
|
229
|
+
throw new DatabaseError(
|
|
230
|
+
"Database not connected",
|
|
231
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
232
|
+
);
|
|
214
233
|
try {
|
|
215
234
|
const result = this.db.prepare("SELECT MAX(version) as version FROM schema_version").get();
|
|
216
235
|
return result?.version || 0;
|
|
@@ -220,7 +239,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
220
239
|
}
|
|
221
240
|
// Frame operations
|
|
222
241
|
async createFrame(frame) {
|
|
223
|
-
if (!this.db)
|
|
242
|
+
if (!this.db)
|
|
243
|
+
throw new DatabaseError(
|
|
244
|
+
"Database not connected",
|
|
245
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
246
|
+
);
|
|
224
247
|
const frameId = frame.frame_id || this.generateId();
|
|
225
248
|
this.db.prepare(
|
|
226
249
|
`
|
|
@@ -246,7 +269,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
246
269
|
return frameId;
|
|
247
270
|
}
|
|
248
271
|
async getFrame(frameId) {
|
|
249
|
-
if (!this.db)
|
|
272
|
+
if (!this.db)
|
|
273
|
+
throw new DatabaseError(
|
|
274
|
+
"Database not connected",
|
|
275
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
276
|
+
);
|
|
250
277
|
const row = this.db.prepare("SELECT * FROM frames WHERE frame_id = ?").get(frameId);
|
|
251
278
|
if (!row) return null;
|
|
252
279
|
return {
|
|
@@ -257,7 +284,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
257
284
|
};
|
|
258
285
|
}
|
|
259
286
|
async updateFrame(frameId, updates) {
|
|
260
|
-
if (!this.db)
|
|
287
|
+
if (!this.db)
|
|
288
|
+
throw new DatabaseError(
|
|
289
|
+
"Database not connected",
|
|
290
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
291
|
+
);
|
|
261
292
|
const fields = [];
|
|
262
293
|
const values = [];
|
|
263
294
|
if (updates.state !== void 0) {
|
|
@@ -289,13 +320,21 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
289
320
|
).run(...values);
|
|
290
321
|
}
|
|
291
322
|
async deleteFrame(frameId) {
|
|
292
|
-
if (!this.db)
|
|
323
|
+
if (!this.db)
|
|
324
|
+
throw new DatabaseError(
|
|
325
|
+
"Database not connected",
|
|
326
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
327
|
+
);
|
|
293
328
|
await this.deleteFrameAnchors(frameId);
|
|
294
329
|
await this.deleteFrameEvents(frameId);
|
|
295
330
|
this.db.prepare("DELETE FROM frames WHERE frame_id = ?").run(frameId);
|
|
296
331
|
}
|
|
297
332
|
async getActiveFrames(runId) {
|
|
298
|
-
if (!this.db)
|
|
333
|
+
if (!this.db)
|
|
334
|
+
throw new DatabaseError(
|
|
335
|
+
"Database not connected",
|
|
336
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
337
|
+
);
|
|
299
338
|
let query = "SELECT * FROM frames WHERE state = 'active'";
|
|
300
339
|
const params = [];
|
|
301
340
|
if (runId) {
|
|
@@ -320,7 +359,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
320
359
|
}
|
|
321
360
|
// Event operations
|
|
322
361
|
async createEvent(event) {
|
|
323
|
-
if (!this.db)
|
|
362
|
+
if (!this.db)
|
|
363
|
+
throw new DatabaseError(
|
|
364
|
+
"Database not connected",
|
|
365
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
366
|
+
);
|
|
324
367
|
const eventId = event.event_id || this.generateId();
|
|
325
368
|
this.db.prepare(
|
|
326
369
|
`
|
|
@@ -339,7 +382,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
339
382
|
return eventId;
|
|
340
383
|
}
|
|
341
384
|
async getFrameEvents(frameId, options) {
|
|
342
|
-
if (!this.db)
|
|
385
|
+
if (!this.db)
|
|
386
|
+
throw new DatabaseError(
|
|
387
|
+
"Database not connected",
|
|
388
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
389
|
+
);
|
|
343
390
|
let query = "SELECT * FROM events WHERE frame_id = ?";
|
|
344
391
|
query += this.buildOrderByClause(
|
|
345
392
|
options?.orderBy || "seq",
|
|
@@ -353,12 +400,20 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
353
400
|
}));
|
|
354
401
|
}
|
|
355
402
|
async deleteFrameEvents(frameId) {
|
|
356
|
-
if (!this.db)
|
|
403
|
+
if (!this.db)
|
|
404
|
+
throw new DatabaseError(
|
|
405
|
+
"Database not connected",
|
|
406
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
407
|
+
);
|
|
357
408
|
this.db.prepare("DELETE FROM events WHERE frame_id = ?").run(frameId);
|
|
358
409
|
}
|
|
359
410
|
// Anchor operations
|
|
360
411
|
async createAnchor(anchor) {
|
|
361
|
-
if (!this.db)
|
|
412
|
+
if (!this.db)
|
|
413
|
+
throw new DatabaseError(
|
|
414
|
+
"Database not connected",
|
|
415
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
416
|
+
);
|
|
362
417
|
const anchorId = anchor.anchor_id || this.generateId();
|
|
363
418
|
this.db.prepare(
|
|
364
419
|
`
|
|
@@ -377,7 +432,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
377
432
|
return anchorId;
|
|
378
433
|
}
|
|
379
434
|
async getFrameAnchors(frameId) {
|
|
380
|
-
if (!this.db)
|
|
435
|
+
if (!this.db)
|
|
436
|
+
throw new DatabaseError(
|
|
437
|
+
"Database not connected",
|
|
438
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
439
|
+
);
|
|
381
440
|
const rows = this.db.prepare(
|
|
382
441
|
`
|
|
383
442
|
SELECT * FROM anchors WHERE frame_id = ?
|
|
@@ -390,12 +449,20 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
390
449
|
}));
|
|
391
450
|
}
|
|
392
451
|
async deleteFrameAnchors(frameId) {
|
|
393
|
-
if (!this.db)
|
|
452
|
+
if (!this.db)
|
|
453
|
+
throw new DatabaseError(
|
|
454
|
+
"Database not connected",
|
|
455
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
456
|
+
);
|
|
394
457
|
this.db.prepare("DELETE FROM anchors WHERE frame_id = ?").run(frameId);
|
|
395
458
|
}
|
|
396
459
|
// Limited search (basic LIKE queries)
|
|
397
460
|
async search(options) {
|
|
398
|
-
if (!this.db)
|
|
461
|
+
if (!this.db)
|
|
462
|
+
throw new DatabaseError(
|
|
463
|
+
"Database not connected",
|
|
464
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
465
|
+
);
|
|
399
466
|
const sql = `
|
|
400
467
|
SELECT *,
|
|
401
468
|
CASE
|
|
@@ -425,16 +492,20 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
425
492
|
digest_json: JSON.parse(row.digest_json || "{}")
|
|
426
493
|
}));
|
|
427
494
|
}
|
|
428
|
-
async searchByVector(
|
|
495
|
+
async searchByVector(_embedding, _options) {
|
|
429
496
|
logger.warn("Vector search not supported in SQLite adapter");
|
|
430
497
|
return [];
|
|
431
498
|
}
|
|
432
|
-
async searchHybrid(textQuery,
|
|
499
|
+
async searchHybrid(textQuery, _embedding, weights) {
|
|
433
500
|
return this.search({ query: textQuery, ...weights });
|
|
434
501
|
}
|
|
435
502
|
// Basic aggregation
|
|
436
503
|
async aggregate(table, options) {
|
|
437
|
-
if (!this.db)
|
|
504
|
+
if (!this.db)
|
|
505
|
+
throw new DatabaseError(
|
|
506
|
+
"Database not connected",
|
|
507
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
508
|
+
);
|
|
438
509
|
const metrics = options.metrics.map(
|
|
439
510
|
(m) => `${m.operation}(${m.field}) AS ${m.alias || `${m.operation}_${m.field}`}`
|
|
440
511
|
).join(", ");
|
|
@@ -450,7 +521,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
450
521
|
}
|
|
451
522
|
// Pattern detection (basic)
|
|
452
523
|
async detectPatterns(timeRange) {
|
|
453
|
-
if (!this.db)
|
|
524
|
+
if (!this.db)
|
|
525
|
+
throw new DatabaseError(
|
|
526
|
+
"Database not connected",
|
|
527
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
528
|
+
);
|
|
454
529
|
let sql = `
|
|
455
530
|
SELECT type as pattern, type, COUNT(*) as frequency, MAX(created_at) as last_seen
|
|
456
531
|
FROM frames
|
|
@@ -474,7 +549,11 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
474
549
|
}
|
|
475
550
|
// Bulk operations
|
|
476
551
|
async executeBulk(operations) {
|
|
477
|
-
if (!this.db)
|
|
552
|
+
if (!this.db)
|
|
553
|
+
throw new DatabaseError(
|
|
554
|
+
"Database not connected",
|
|
555
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
556
|
+
);
|
|
478
557
|
await this.inTransaction(async () => {
|
|
479
558
|
for (const op of operations) {
|
|
480
559
|
switch (op.type) {
|
|
@@ -503,18 +582,30 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
503
582
|
});
|
|
504
583
|
}
|
|
505
584
|
async vacuum() {
|
|
506
|
-
if (!this.db)
|
|
585
|
+
if (!this.db)
|
|
586
|
+
throw new DatabaseError(
|
|
587
|
+
"Database not connected",
|
|
588
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
589
|
+
);
|
|
507
590
|
this.db.pragma("vacuum");
|
|
508
591
|
logger.info("SQLite database vacuumed");
|
|
509
592
|
}
|
|
510
593
|
async analyze() {
|
|
511
|
-
if (!this.db)
|
|
594
|
+
if (!this.db)
|
|
595
|
+
throw new DatabaseError(
|
|
596
|
+
"Database not connected",
|
|
597
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
598
|
+
);
|
|
512
599
|
this.db.pragma("analyze");
|
|
513
600
|
logger.info("SQLite database analyzed");
|
|
514
601
|
}
|
|
515
602
|
// Statistics
|
|
516
603
|
async getStats() {
|
|
517
|
-
if (!this.db)
|
|
604
|
+
if (!this.db)
|
|
605
|
+
throw new DatabaseError(
|
|
606
|
+
"Database not connected",
|
|
607
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
608
|
+
);
|
|
518
609
|
const stats = {
|
|
519
610
|
totalFrames: this.db.prepare("SELECT COUNT(*) as count FROM frames").get().count,
|
|
520
611
|
activeFrames: this.db.prepare(
|
|
@@ -537,17 +628,29 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
537
628
|
}
|
|
538
629
|
// Transaction support
|
|
539
630
|
async beginTransaction() {
|
|
540
|
-
if (!this.db)
|
|
631
|
+
if (!this.db)
|
|
632
|
+
throw new DatabaseError(
|
|
633
|
+
"Database not connected",
|
|
634
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
635
|
+
);
|
|
541
636
|
this.db.prepare("BEGIN").run();
|
|
542
637
|
this.inTransactionFlag = true;
|
|
543
638
|
}
|
|
544
639
|
async commitTransaction() {
|
|
545
|
-
if (!this.db)
|
|
640
|
+
if (!this.db)
|
|
641
|
+
throw new DatabaseError(
|
|
642
|
+
"Database not connected",
|
|
643
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
644
|
+
);
|
|
546
645
|
this.db.prepare("COMMIT").run();
|
|
547
646
|
this.inTransactionFlag = false;
|
|
548
647
|
}
|
|
549
648
|
async rollbackTransaction() {
|
|
550
|
-
if (!this.db)
|
|
649
|
+
if (!this.db)
|
|
650
|
+
throw new DatabaseError(
|
|
651
|
+
"Database not connected",
|
|
652
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
653
|
+
);
|
|
551
654
|
this.db.prepare("ROLLBACK").run();
|
|
552
655
|
this.inTransactionFlag = false;
|
|
553
656
|
}
|
|
@@ -563,9 +666,17 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
563
666
|
}
|
|
564
667
|
// Export/Import
|
|
565
668
|
async exportData(tables, format) {
|
|
566
|
-
if (!this.db)
|
|
669
|
+
if (!this.db)
|
|
670
|
+
throw new DatabaseError(
|
|
671
|
+
"Database not connected",
|
|
672
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
673
|
+
);
|
|
567
674
|
if (format !== "json") {
|
|
568
|
-
throw new
|
|
675
|
+
throw new ValidationError(
|
|
676
|
+
`Format ${format} not supported for SQLite export`,
|
|
677
|
+
ErrorCode.VALIDATION_FAILED,
|
|
678
|
+
{ format, supportedFormats: ["json"] }
|
|
679
|
+
);
|
|
569
680
|
}
|
|
570
681
|
const data = {};
|
|
571
682
|
for (const table of tables) {
|
|
@@ -574,9 +685,17 @@ class SQLiteAdapter extends FeatureAwareDatabaseAdapter {
|
|
|
574
685
|
return Buffer.from(JSON.stringify(data, null, 2));
|
|
575
686
|
}
|
|
576
687
|
async importData(data, format, options) {
|
|
577
|
-
if (!this.db)
|
|
688
|
+
if (!this.db)
|
|
689
|
+
throw new DatabaseError(
|
|
690
|
+
"Database not connected",
|
|
691
|
+
ErrorCode.DB_CONNECTION_FAILED
|
|
692
|
+
);
|
|
578
693
|
if (format !== "json") {
|
|
579
|
-
throw new
|
|
694
|
+
throw new ValidationError(
|
|
695
|
+
`Format ${format} not supported for SQLite import`,
|
|
696
|
+
ErrorCode.VALIDATION_FAILED,
|
|
697
|
+
{ format, supportedFormats: ["json"] }
|
|
698
|
+
);
|
|
580
699
|
}
|
|
581
700
|
const parsed = JSON.parse(data.toString());
|
|
582
701
|
await this.inTransaction(async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/database/sqlite-adapter.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * SQLite Database Adapter\n * Maintains backward compatibility with existing SQLite implementation\n */\n\nimport Database from 'better-sqlite3';\nimport {\n FeatureAwareDatabaseAdapter,\n DatabaseFeatures,\n SearchOptions,\n QueryOptions,\n AggregationOptions,\n BulkOperation,\n DatabaseStats,\n CountResult,\n VersionResult,\n FrameRow,\n EventRow,\n AnchorRow,\n} from './database-adapter.js';\nimport type { Frame, Event, Anchor } from '../context/frame-manager.js';\nimport { logger } from '../monitoring/logger.js';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nexport interface SQLiteConfig {\n dbPath: string;\n walMode?: boolean;\n busyTimeout?: number;\n cacheSize?: number;\n synchronous?: 'OFF' | 'NORMAL' | 'FULL' | 'EXTRA';\n}\n\nexport class SQLiteAdapter extends FeatureAwareDatabaseAdapter {\n private db: Database.Database | null = null;\n private readonly dbPath: string;\n private inTransactionFlag = false;\n\n constructor(projectId: string, config: SQLiteConfig) {\n super(projectId, config);\n this.dbPath = config.dbPath;\n }\n\n getFeatures(): DatabaseFeatures {\n return {\n supportsFullTextSearch: false, // Could enable with FTS5\n supportsVectorSearch: false,\n supportsPartitioning: false,\n supportsAnalytics: false,\n supportsCompression: false,\n supportsMaterializedViews: false,\n supportsParallelQueries: false,\n };\n }\n\n async connect(): Promise<void> {\n if (this.db) return;\n\n const config = this.config as SQLiteConfig;\n\n // Ensure directory exists\n const dir = path.dirname(this.dbPath);\n await fs.mkdir(dir, { recursive: true });\n\n this.db = new Database(this.dbPath);\n\n // Enforce referential integrity\n this.db.pragma('foreign_keys = ON');\n\n // Configure SQLite for better performance\n if (config.walMode !== false) {\n this.db.pragma('journal_mode = WAL');\n }\n\n if (config.busyTimeout) {\n this.db.pragma(`busy_timeout = ${config.busyTimeout}`);\n }\n\n if (config.cacheSize) {\n this.db.pragma(`cache_size = ${config.cacheSize}`);\n }\n\n if (config.synchronous) {\n this.db.pragma(`synchronous = ${config.synchronous}`);\n }\n\n logger.info('SQLite database connected', { dbPath: this.dbPath });\n }\n\n async disconnect(): Promise<void> {\n if (!this.db) return;\n\n this.db.close();\n this.db = null;\n logger.info('SQLite database disconnected');\n }\n\n /**\n * Get raw database handle for testing purposes\n * @internal\n */\n getRawDatabase(): Database.Database | null {\n return this.db;\n }\n\n isConnected(): boolean {\n return this.db !== null && this.db.open;\n }\n\n async ping(): Promise<boolean> {\n if (!this.db) return false;\n\n try {\n this.db.prepare('SELECT 1').get();\n return true;\n } catch {\n return false;\n }\n }\n\n async initializeSchema(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS frames (\n frame_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n parent_frame_id TEXT REFERENCES frames(frame_id),\n depth INTEGER NOT NULL DEFAULT 0,\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n state TEXT DEFAULT 'active',\n inputs TEXT DEFAULT '{}',\n outputs TEXT DEFAULT '{}',\n digest_text TEXT,\n digest_json TEXT DEFAULT '{}',\n created_at INTEGER DEFAULT (unixepoch()),\n closed_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS events (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS anchors (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at INTEGER DEFAULT (unixepoch())\n );\n\n -- Indexes for performance\n CREATE INDEX IF NOT EXISTS idx_frames_run ON frames(run_id);\n CREATE INDEX IF NOT EXISTS idx_frames_project ON frames(project_id);\n CREATE INDEX IF NOT EXISTS idx_frames_parent ON frames(parent_frame_id);\n CREATE INDEX IF NOT EXISTS idx_frames_state ON frames(state);\n CREATE INDEX IF NOT EXISTS idx_frames_created ON frames(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);\n CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);\n CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);\n\n -- Set initial schema version if not exists\n INSERT OR IGNORE INTO schema_version (version) VALUES (1);\n `);\n\n // Ensure cascade constraints exist on dependent tables for existing DBs\n try {\n this.ensureCascadeConstraints();\n } catch (e) {\n logger.warn('Failed to ensure cascade constraints', e as Error);\n }\n }\n\n /**\n * Ensure ON DELETE CASCADE exists for events/anchors referencing frames\n * Migrates existing tables in-place if needed without data loss.\n */\n private ensureCascadeConstraints(): void {\n if (!this.db) return;\n\n const needsCascade = (table: string): boolean => {\n const rows = this.db!.prepare(`PRAGMA foreign_key_list(${table})`).all() as any[];\n // If any FK points to frames without cascade, we need migration\n return rows.some((r) => r.table === 'frames' && String(r.on_delete).toUpperCase() !== 'CASCADE');\n };\n\n const migrateTable = (table: 'events' | 'anchors') => {\n const createSql =\n table === 'events'\n ? `CREATE TABLE events_new (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );`\n : `CREATE TABLE anchors_new (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );`;\n\n const cols = table === 'events'\n ? 'event_id, run_id, frame_id, seq, event_type, payload, ts'\n : 'anchor_id, frame_id, project_id, type, text, priority, created_at, metadata';\n\n const idxSql = table === 'events'\n ? [\n 'CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);',\n 'CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);',\n ]\n : [\n 'CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);',\n ];\n\n this.db!.exec('PRAGMA foreign_keys = OFF;');\n this.db!.exec('BEGIN;');\n this.db!.exec(createSql);\n this.db!.prepare(`INSERT INTO ${table === 'events' ? 'events_new' : 'anchors_new'} (${cols}) SELECT ${cols} FROM ${table}`).run();\n this.db!.exec(`DROP TABLE ${table};`);\n this.db!.exec(`ALTER TABLE ${table}_new RENAME TO ${table};`);\n for (const stmt of idxSql) this.db!.exec(stmt);\n this.db!.exec('COMMIT;');\n this.db!.exec('PRAGMA foreign_keys = ON;');\n logger.info(`Migrated ${table} to include ON DELETE CASCADE`);\n };\n\n if (needsCascade('events')) migrateTable('events');\n if (needsCascade('anchors')) migrateTable('anchors');\n }\n\n async migrateSchema(targetVersion: number): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n const currentVersion = await this.getSchemaVersion();\n\n if (currentVersion >= targetVersion) {\n logger.info('Schema already at target version', {\n currentVersion,\n targetVersion,\n });\n return;\n }\n\n // Apply migrations sequentially\n for (let v = currentVersion + 1; v <= targetVersion; v++) {\n logger.info(`Applying migration to version ${v}`);\n // Migration logic would go here\n this.db.prepare('UPDATE schema_version SET version = ?').run(v);\n }\n }\n\n async getSchemaVersion(): Promise<number> {\n if (!this.db) throw new Error('Database not connected');\n\n try {\n const result = this.db\n .prepare('SELECT MAX(version) as version FROM schema_version')\n .get() as VersionResult;\n return result?.version || 0;\n } catch {\n return 0;\n }\n }\n\n // Frame operations\n async createFrame(frame: Partial<Frame>): Promise<string> {\n if (!this.db) throw new Error('Database not connected');\n\n const frameId = frame.frame_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO frames (\n frame_id, run_id, project_id, parent_frame_id, depth,\n type, name, state, inputs, outputs, digest_text, digest_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n frameId,\n frame.run_id,\n frame.project_id || this.projectId,\n frame.parent_frame_id || null,\n frame.depth || 0,\n frame.type,\n frame.name,\n frame.state || 'active',\n JSON.stringify(frame.inputs || {}),\n JSON.stringify(frame.outputs || {}),\n frame.digest_text || null,\n JSON.stringify(frame.digest_json || {})\n );\n\n return frameId;\n }\n\n async getFrame(frameId: string): Promise<Frame | null> {\n if (!this.db) throw new Error('Database not connected');\n\n const row = this.db\n .prepare('SELECT * FROM frames WHERE frame_id = ?')\n .get(frameId) as FrameRow | undefined;\n\n if (!row) return null;\n\n return {\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n };\n }\n\n async updateFrame(frameId: string, updates: Partial<Frame>): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n const fields = [];\n const values = [];\n\n if (updates.state !== undefined) {\n fields.push('state = ?');\n values.push(updates.state);\n }\n\n if (updates.outputs !== undefined) {\n fields.push('outputs = ?');\n values.push(JSON.stringify(updates.outputs));\n }\n\n if (updates.digest_text !== undefined) {\n fields.push('digest_text = ?');\n values.push(updates.digest_text);\n }\n\n if (updates.digest_json !== undefined) {\n fields.push('digest_json = ?');\n values.push(JSON.stringify(updates.digest_json));\n }\n\n if (updates.closed_at !== undefined) {\n fields.push('closed_at = ?');\n values.push(updates.closed_at);\n }\n\n if (fields.length === 0) return;\n\n values.push(frameId);\n\n this.db\n .prepare(\n `\n UPDATE frames SET ${fields.join(', ')} WHERE frame_id = ?\n `\n )\n .run(...values);\n }\n\n async deleteFrame(frameId: string): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n // Delete in order due to foreign keys\n await this.deleteFrameAnchors(frameId);\n await this.deleteFrameEvents(frameId);\n\n this.db.prepare('DELETE FROM frames WHERE frame_id = ?').run(frameId);\n }\n\n async getActiveFrames(runId?: string): Promise<Frame[]> {\n if (!this.db) throw new Error('Database not connected');\n\n let query = \"SELECT * FROM frames WHERE state = 'active'\";\n const params = [];\n\n if (runId) {\n query += ' AND run_id = ?';\n params.push(runId);\n }\n\n query += ' ORDER BY depth ASC, created_at ASC';\n\n const rows = this.db.prepare(query).all(...params) as any[];\n\n return rows.map((row) => ({\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n }\n\n async closeFrame(frameId: string, outputs?: any): Promise<void> {\n await this.updateFrame(frameId, {\n state: 'closed',\n outputs,\n closed_at: Date.now(),\n });\n }\n\n // Event operations\n async createEvent(event: Partial<Event>): Promise<string> {\n if (!this.db) throw new Error('Database not connected');\n\n const eventId = event.event_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO events (event_id, run_id, frame_id, seq, event_type, payload, ts)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n eventId,\n event.run_id,\n event.frame_id,\n event.seq || 0,\n event.event_type,\n JSON.stringify(event.payload || {}),\n event.ts || Date.now()\n );\n\n return eventId;\n }\n\n async getFrameEvents(\n frameId: string,\n options?: QueryOptions\n ): Promise<Event[]> {\n if (!this.db) throw new Error('Database not connected');\n\n let query = 'SELECT * FROM events WHERE frame_id = ?';\n query += this.buildOrderByClause(\n options?.orderBy || 'seq',\n options?.orderDirection\n );\n query += this.buildLimitClause(options?.limit, options?.offset);\n\n const rows = this.db.prepare(query).all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n payload: JSON.parse(row.payload || '{}'),\n }));\n }\n\n async deleteFrameEvents(frameId: string): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.prepare('DELETE FROM events WHERE frame_id = ?').run(frameId);\n }\n\n // Anchor operations\n async createAnchor(anchor: Partial<Anchor>): Promise<string> {\n if (!this.db) throw new Error('Database not connected');\n\n const anchorId = anchor.anchor_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO anchors (anchor_id, frame_id, project_id, type, text, priority, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n anchorId,\n anchor.frame_id,\n anchor.project_id || this.projectId,\n anchor.type,\n anchor.text,\n anchor.priority || 0,\n JSON.stringify(anchor.metadata || {})\n );\n\n return anchorId;\n }\n\n async getFrameAnchors(frameId: string): Promise<Anchor[]> {\n if (!this.db) throw new Error('Database not connected');\n\n const rows = this.db\n .prepare(\n `\n SELECT * FROM anchors WHERE frame_id = ? \n ORDER BY priority DESC, created_at ASC\n `\n )\n .all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n metadata: JSON.parse(row.metadata || '{}'),\n }));\n }\n\n async deleteFrameAnchors(frameId: string): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.prepare('DELETE FROM anchors WHERE frame_id = ?').run(frameId);\n }\n\n // Limited search (basic LIKE queries)\n async search(\n options: SearchOptions\n ): Promise<Array<Frame & { score: number }>> {\n if (!this.db) throw new Error('Database not connected');\n\n // SQLite doesn't support HAVING on non-aggregate queries, so we filter in application\n const sql = `\n SELECT *, \n CASE \n WHEN name LIKE ? THEN 1.0\n WHEN digest_text LIKE ? THEN 0.8\n WHEN inputs LIKE ? THEN 0.6\n ELSE 0.5\n END as score\n FROM frames\n WHERE name LIKE ? OR digest_text LIKE ? OR inputs LIKE ?\n ORDER BY score DESC\n `;\n\n const params = Array(6).fill(`%${options.query}%`);\n\n let rows = this.db.prepare(sql).all(...params) as any[];\n\n // Apply score threshold in application layer\n if (options.scoreThreshold) {\n rows = rows.filter((row) => row.score >= options.scoreThreshold);\n }\n\n // Apply limit and offset in application layer if threshold is used\n if (options.limit || options.offset) {\n const start = options.offset || 0;\n const end = options.limit ? start + options.limit : rows.length;\n rows = rows.slice(start, end);\n }\n\n return rows.map((row) => ({\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n }\n\n async searchByVector(\n embedding: number[],\n options?: QueryOptions\n ): Promise<Array<Frame & { similarity: number }>> {\n // Not supported in SQLite\n logger.warn('Vector search not supported in SQLite adapter');\n return [];\n }\n\n async searchHybrid(\n textQuery: string,\n embedding: number[],\n weights?: { text: number; vector: number }\n ): Promise<Array<Frame & { score: number }>> {\n // Fall back to text search only\n return this.search({ query: textQuery, ...weights });\n }\n\n // Basic aggregation\n async aggregate(\n table: string,\n options: AggregationOptions\n ): Promise<Record<string, any>[]> {\n if (!this.db) throw new Error('Database not connected');\n\n const metrics = options.metrics\n .map(\n (m) =>\n `${m.operation}(${m.field}) AS ${m.alias || `${m.operation}_${m.field}`}`\n )\n .join(', ');\n\n let sql = `SELECT ${options.groupBy.join(', ')}, ${metrics} FROM ${table}`;\n sql += ` GROUP BY ${options.groupBy.join(', ')}`;\n\n if (options.having) {\n const havingClauses = Object.entries(options.having).map(\n ([key, value]) =>\n `${key} ${typeof value === 'object' ? value.op : '='} ?`\n );\n sql += ` HAVING ${havingClauses.join(' AND ')}`;\n }\n\n return this.db\n .prepare(sql)\n .all(...Object.values(options.having || {})) as any[];\n }\n\n // Pattern detection (basic)\n async detectPatterns(timeRange?: { start: Date; end: Date }): Promise<\n Array<{\n pattern: string;\n type: string;\n frequency: number;\n lastSeen: Date;\n }>\n > {\n if (!this.db) throw new Error('Database not connected');\n\n let sql = `\n SELECT type as pattern, type, COUNT(*) as frequency, MAX(created_at) as last_seen\n FROM frames\n `;\n\n const params = [];\n if (timeRange) {\n sql += ' WHERE created_at >= ? AND created_at <= ?';\n params.push(\n Math.floor(timeRange.start.getTime() / 1000),\n Math.floor(timeRange.end.getTime() / 1000)\n );\n }\n\n sql += ' GROUP BY type HAVING COUNT(*) > 1 ORDER BY frequency DESC';\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n\n return rows.map((row) => ({\n pattern: row.pattern,\n type: row.type,\n frequency: row.frequency,\n lastSeen: new Date(row.last_seen * 1000),\n }));\n }\n\n // Bulk operations\n async executeBulk(operations: BulkOperation[]): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n await this.inTransaction(async () => {\n for (const op of operations) {\n switch (op.type) {\n case 'insert':\n // Build insert dynamically based on data\n const insertCols = Object.keys(op.data);\n const insertPlaceholders = insertCols.map(() => '?').join(',');\n this.db!.prepare(\n `INSERT INTO ${op.table} (${insertCols.join(',')}) VALUES (${insertPlaceholders})`\n ).run(...Object.values(op.data));\n break;\n\n case 'update':\n const updateSets = Object.keys(op.data)\n .map((k) => `${k} = ?`)\n .join(',');\n const whereClause = this.buildWhereClause(op.where || {});\n this.db!.prepare(\n `UPDATE ${op.table} SET ${updateSets} ${whereClause}`\n ).run(...Object.values(op.data), ...Object.values(op.where || {}));\n break;\n\n case 'delete':\n const deleteWhere = this.buildWhereClause(op.where || {});\n this.db!.prepare(`DELETE FROM ${op.table} ${deleteWhere}`).run(\n ...Object.values(op.where || {})\n );\n break;\n }\n }\n });\n }\n\n async vacuum(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.pragma('vacuum');\n logger.info('SQLite database vacuumed');\n }\n\n async analyze(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.pragma('analyze');\n logger.info('SQLite database analyzed');\n }\n\n // Statistics\n async getStats(): Promise<DatabaseStats> {\n if (!this.db) throw new Error('Database not connected');\n\n const stats = {\n totalFrames: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM frames')\n .get() as CountResult\n ).count,\n activeFrames: (\n this.db\n .prepare(\n \"SELECT COUNT(*) as count FROM frames WHERE state = 'active'\"\n )\n .get() as CountResult\n ).count,\n totalEvents: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM events')\n .get() as CountResult\n ).count,\n totalAnchors: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM anchors')\n .get() as CountResult\n ).count,\n diskUsage: 0,\n };\n\n // Get file size\n try {\n const fileStats = await fs.stat(this.dbPath);\n stats.diskUsage = fileStats.size;\n } catch {}\n\n return stats;\n }\n\n async getQueryStats(): Promise<\n Array<{\n query: string;\n calls: number;\n meanTime: number;\n totalTime: number;\n }>\n > {\n // SQLite doesn't have built-in query stats\n logger.warn('Query stats not available for SQLite');\n return [];\n }\n\n // Transaction support\n async beginTransaction(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.prepare('BEGIN').run();\n this.inTransactionFlag = true;\n }\n\n async commitTransaction(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.prepare('COMMIT').run();\n this.inTransactionFlag = false;\n }\n\n async rollbackTransaction(): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n this.db.prepare('ROLLBACK').run();\n this.inTransactionFlag = false;\n }\n\n async inTransaction(\n callback: (adapter: DatabaseAdapter) => Promise<void>\n ): Promise<void> {\n await this.beginTransaction();\n\n try {\n await callback(this);\n await this.commitTransaction();\n } catch (error: unknown) {\n await this.rollbackTransaction();\n throw error;\n }\n }\n\n // Export/Import\n async exportData(\n tables: string[],\n format: 'json' | 'parquet' | 'csv'\n ): Promise<Buffer> {\n if (!this.db) throw new Error('Database not connected');\n\n if (format !== 'json') {\n throw new Error(`Format ${format} not supported for SQLite export`);\n }\n\n const data: Record<string, any[]> = {};\n\n for (const table of tables) {\n data[table] = this.db.prepare(`SELECT * FROM ${table}`).all();\n }\n\n return Buffer.from(JSON.stringify(data, null, 2));\n }\n\n async importData(\n data: Buffer,\n format: 'json' | 'parquet' | 'csv',\n options?: { truncate?: boolean; upsert?: boolean }\n ): Promise<void> {\n if (!this.db) throw new Error('Database not connected');\n\n if (format !== 'json') {\n throw new Error(`Format ${format} not supported for SQLite import`);\n }\n\n const parsed = JSON.parse(data.toString());\n\n await this.inTransaction(async () => {\n for (const [table, rows] of Object.entries(parsed)) {\n if (options?.truncate) {\n this.db!.prepare(`DELETE FROM ${table}`).run();\n }\n\n for (const row of rows as any[]) {\n const cols = Object.keys(row);\n const placeholders = cols.map(() => '?').join(',');\n\n if (options?.upsert) {\n const updates = cols.map((c) => `${c} = excluded.${c}`).join(',');\n this.db!.prepare(\n `INSERT INTO ${table} (${cols.join(',')}) VALUES (${placeholders})\n ON CONFLICT DO UPDATE SET ${updates}`\n ).run(...Object.values(row));\n } else {\n this.db!.prepare(\n `INSERT INTO ${table} (${cols.join(',')}) VALUES (${placeholders})`\n ).run(...Object.values(row));\n }\n }\n }\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * SQLite Database Adapter\n * Maintains backward compatibility with existing SQLite implementation\n */\n\nimport Database from 'better-sqlite3';\nimport {\n FeatureAwareDatabaseAdapter,\n DatabaseFeatures,\n SearchOptions,\n QueryOptions,\n AggregationOptions,\n BulkOperation,\n DatabaseStats,\n CountResult,\n VersionResult,\n FrameRow,\n} from './database-adapter.js';\nimport type { Frame, Event, Anchor } from '../context/frame-manager.js';\nimport { logger } from '../monitoring/logger.js';\nimport { DatabaseError, ErrorCode, ValidationError } from '../errors/index.js';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\nexport interface SQLiteConfig {\n dbPath: string;\n walMode?: boolean;\n busyTimeout?: number;\n cacheSize?: number;\n synchronous?: 'OFF' | 'NORMAL' | 'FULL' | 'EXTRA';\n}\n\nexport class SQLiteAdapter extends FeatureAwareDatabaseAdapter {\n private db: Database.Database | null = null;\n private readonly dbPath: string;\n private inTransactionFlag = false;\n\n constructor(projectId: string, config: SQLiteConfig) {\n super(projectId, config);\n this.dbPath = config.dbPath;\n }\n\n getFeatures(): DatabaseFeatures {\n return {\n supportsFullTextSearch: false, // Could enable with FTS5\n supportsVectorSearch: false,\n supportsPartitioning: false,\n supportsAnalytics: false,\n supportsCompression: false,\n supportsMaterializedViews: false,\n supportsParallelQueries: false,\n };\n }\n\n async connect(): Promise<void> {\n if (this.db) return;\n\n const config = this.config as SQLiteConfig;\n\n // Ensure directory exists\n const dir = path.dirname(this.dbPath);\n await fs.mkdir(dir, { recursive: true });\n\n this.db = new Database(this.dbPath);\n\n // Enforce referential integrity\n this.db.pragma('foreign_keys = ON');\n\n // Configure SQLite for better performance\n if (config.walMode !== false) {\n this.db.pragma('journal_mode = WAL');\n }\n\n if (config.busyTimeout) {\n this.db.pragma(`busy_timeout = ${config.busyTimeout}`);\n }\n\n if (config.cacheSize) {\n this.db.pragma(`cache_size = ${config.cacheSize}`);\n }\n\n if (config.synchronous) {\n this.db.pragma(`synchronous = ${config.synchronous}`);\n }\n\n logger.info('SQLite database connected', { dbPath: this.dbPath });\n }\n\n async disconnect(): Promise<void> {\n if (!this.db) return;\n\n this.db.close();\n this.db = null;\n logger.info('SQLite database disconnected');\n }\n\n /**\n * Get raw database handle for testing purposes\n * @internal\n */\n getRawDatabase(): Database.Database | null {\n return this.db;\n }\n\n isConnected(): boolean {\n return this.db !== null && this.db.open;\n }\n\n async ping(): Promise<boolean> {\n if (!this.db) return false;\n\n try {\n this.db.prepare('SELECT 1').get();\n return true;\n } catch {\n return false;\n }\n }\n\n async initializeSchema(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS frames (\n frame_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n parent_frame_id TEXT REFERENCES frames(frame_id),\n depth INTEGER NOT NULL DEFAULT 0,\n type TEXT NOT NULL,\n name TEXT NOT NULL,\n state TEXT DEFAULT 'active',\n inputs TEXT DEFAULT '{}',\n outputs TEXT DEFAULT '{}',\n digest_text TEXT,\n digest_json TEXT DEFAULT '{}',\n created_at INTEGER DEFAULT (unixepoch()),\n closed_at INTEGER\n );\n\n CREATE TABLE IF NOT EXISTS events (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS anchors (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );\n\n CREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at INTEGER DEFAULT (unixepoch())\n );\n\n -- Indexes for performance\n CREATE INDEX IF NOT EXISTS idx_frames_run ON frames(run_id);\n CREATE INDEX IF NOT EXISTS idx_frames_project ON frames(project_id);\n CREATE INDEX IF NOT EXISTS idx_frames_parent ON frames(parent_frame_id);\n CREATE INDEX IF NOT EXISTS idx_frames_state ON frames(state);\n CREATE INDEX IF NOT EXISTS idx_frames_created ON frames(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);\n CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);\n CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);\n\n -- Set initial schema version if not exists\n INSERT OR IGNORE INTO schema_version (version) VALUES (1);\n `);\n\n // Ensure cascade constraints exist on dependent tables for existing DBs\n try {\n this.ensureCascadeConstraints();\n } catch (e) {\n logger.warn('Failed to ensure cascade constraints', e as Error);\n }\n }\n\n /**\n * Ensure ON DELETE CASCADE exists for events/anchors referencing frames\n * Migrates existing tables in-place if needed without data loss.\n */\n private ensureCascadeConstraints(): void {\n if (!this.db) return;\n\n const needsCascade = (table: string): boolean => {\n const rows = this.db!.prepare(\n `PRAGMA foreign_key_list(${table})`\n ).all() as any[];\n // If any FK points to frames without cascade, we need migration\n return rows.some(\n (r) =>\n r.table === 'frames' &&\n String(r.on_delete).toUpperCase() !== 'CASCADE'\n );\n };\n\n const migrateTable = (table: 'events' | 'anchors') => {\n const createSql =\n table === 'events'\n ? `CREATE TABLE events_new (\n event_id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n frame_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n payload TEXT NOT NULL,\n ts INTEGER DEFAULT (unixepoch()),\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );`\n : `CREATE TABLE anchors_new (\n anchor_id TEXT PRIMARY KEY,\n frame_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n priority INTEGER DEFAULT 0,\n created_at INTEGER DEFAULT (unixepoch()),\n metadata TEXT DEFAULT '{}',\n FOREIGN KEY(frame_id) REFERENCES frames(frame_id) ON DELETE CASCADE\n );`;\n\n const cols =\n table === 'events'\n ? 'event_id, run_id, frame_id, seq, event_type, payload, ts'\n : 'anchor_id, frame_id, project_id, type, text, priority, created_at, metadata';\n\n const idxSql =\n table === 'events'\n ? [\n 'CREATE INDEX IF NOT EXISTS idx_events_frame ON events(frame_id);',\n 'CREATE INDEX IF NOT EXISTS idx_events_seq ON events(frame_id, seq);',\n ]\n : [\n 'CREATE INDEX IF NOT EXISTS idx_anchors_frame ON anchors(frame_id);',\n ];\n\n this.db!.exec('PRAGMA foreign_keys = OFF;');\n this.db!.exec('BEGIN;');\n this.db!.exec(createSql);\n this.db!.prepare(\n `INSERT INTO ${table === 'events' ? 'events_new' : 'anchors_new'} (${cols}) SELECT ${cols} FROM ${table}`\n ).run();\n this.db!.exec(`DROP TABLE ${table};`);\n this.db!.exec(`ALTER TABLE ${table}_new RENAME TO ${table};`);\n for (const stmt of idxSql) this.db!.exec(stmt);\n this.db!.exec('COMMIT;');\n this.db!.exec('PRAGMA foreign_keys = ON;');\n logger.info(`Migrated ${table} to include ON DELETE CASCADE`);\n };\n\n if (needsCascade('events')) migrateTable('events');\n if (needsCascade('anchors')) migrateTable('anchors');\n }\n\n async migrateSchema(targetVersion: number): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const currentVersion = await this.getSchemaVersion();\n\n if (currentVersion >= targetVersion) {\n logger.info('Schema already at target version', {\n currentVersion,\n targetVersion,\n });\n return;\n }\n\n // Apply migrations sequentially\n for (let v = currentVersion + 1; v <= targetVersion; v++) {\n logger.info(`Applying migration to version ${v}`);\n // Migration logic would go here\n this.db.prepare('UPDATE schema_version SET version = ?').run(v);\n }\n }\n\n async getSchemaVersion(): Promise<number> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n try {\n const result = this.db\n .prepare('SELECT MAX(version) as version FROM schema_version')\n .get() as VersionResult;\n return result?.version || 0;\n } catch {\n return 0;\n }\n }\n\n // Frame operations\n async createFrame(frame: Partial<Frame>): Promise<string> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const frameId = frame.frame_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO frames (\n frame_id, run_id, project_id, parent_frame_id, depth,\n type, name, state, inputs, outputs, digest_text, digest_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n frameId,\n frame.run_id,\n frame.project_id || this.projectId,\n frame.parent_frame_id || null,\n frame.depth || 0,\n frame.type,\n frame.name,\n frame.state || 'active',\n JSON.stringify(frame.inputs || {}),\n JSON.stringify(frame.outputs || {}),\n frame.digest_text || null,\n JSON.stringify(frame.digest_json || {})\n );\n\n return frameId;\n }\n\n async getFrame(frameId: string): Promise<Frame | null> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const row = this.db\n .prepare('SELECT * FROM frames WHERE frame_id = ?')\n .get(frameId) as FrameRow | undefined;\n\n if (!row) return null;\n\n return {\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n };\n }\n\n async updateFrame(frameId: string, updates: Partial<Frame>): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const fields = [];\n const values = [];\n\n if (updates.state !== undefined) {\n fields.push('state = ?');\n values.push(updates.state);\n }\n\n if (updates.outputs !== undefined) {\n fields.push('outputs = ?');\n values.push(JSON.stringify(updates.outputs));\n }\n\n if (updates.digest_text !== undefined) {\n fields.push('digest_text = ?');\n values.push(updates.digest_text);\n }\n\n if (updates.digest_json !== undefined) {\n fields.push('digest_json = ?');\n values.push(JSON.stringify(updates.digest_json));\n }\n\n if (updates.closed_at !== undefined) {\n fields.push('closed_at = ?');\n values.push(updates.closed_at);\n }\n\n if (fields.length === 0) return;\n\n values.push(frameId);\n\n this.db\n .prepare(\n `\n UPDATE frames SET ${fields.join(', ')} WHERE frame_id = ?\n `\n )\n .run(...values);\n }\n\n async deleteFrame(frameId: string): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n // Delete in order due to foreign keys\n await this.deleteFrameAnchors(frameId);\n await this.deleteFrameEvents(frameId);\n\n this.db.prepare('DELETE FROM frames WHERE frame_id = ?').run(frameId);\n }\n\n async getActiveFrames(runId?: string): Promise<Frame[]> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n let query = \"SELECT * FROM frames WHERE state = 'active'\";\n const params = [];\n\n if (runId) {\n query += ' AND run_id = ?';\n params.push(runId);\n }\n\n query += ' ORDER BY depth ASC, created_at ASC';\n\n const rows = this.db.prepare(query).all(...params) as any[];\n\n return rows.map((row) => ({\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n }\n\n async closeFrame(frameId: string, outputs?: any): Promise<void> {\n await this.updateFrame(frameId, {\n state: 'closed',\n outputs,\n closed_at: Date.now(),\n });\n }\n\n // Event operations\n async createEvent(event: Partial<Event>): Promise<string> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const eventId = event.event_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO events (event_id, run_id, frame_id, seq, event_type, payload, ts)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n eventId,\n event.run_id,\n event.frame_id,\n event.seq || 0,\n event.event_type,\n JSON.stringify(event.payload || {}),\n event.ts || Date.now()\n );\n\n return eventId;\n }\n\n async getFrameEvents(\n frameId: string,\n options?: QueryOptions\n ): Promise<Event[]> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n let query = 'SELECT * FROM events WHERE frame_id = ?';\n query += this.buildOrderByClause(\n options?.orderBy || 'seq',\n options?.orderDirection\n );\n query += this.buildLimitClause(options?.limit, options?.offset);\n\n const rows = this.db.prepare(query).all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n payload: JSON.parse(row.payload || '{}'),\n }));\n }\n\n async deleteFrameEvents(frameId: string): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.prepare('DELETE FROM events WHERE frame_id = ?').run(frameId);\n }\n\n // Anchor operations\n async createAnchor(anchor: Partial<Anchor>): Promise<string> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const anchorId = anchor.anchor_id || this.generateId();\n\n this.db\n .prepare(\n `\n INSERT INTO anchors (anchor_id, frame_id, project_id, type, text, priority, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n anchorId,\n anchor.frame_id,\n anchor.project_id || this.projectId,\n anchor.type,\n anchor.text,\n anchor.priority || 0,\n JSON.stringify(anchor.metadata || {})\n );\n\n return anchorId;\n }\n\n async getFrameAnchors(frameId: string): Promise<Anchor[]> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const rows = this.db\n .prepare(\n `\n SELECT * FROM anchors WHERE frame_id = ? \n ORDER BY priority DESC, created_at ASC\n `\n )\n .all(frameId) as any[];\n\n return rows.map((row) => ({\n ...row,\n metadata: JSON.parse(row.metadata || '{}'),\n }));\n }\n\n async deleteFrameAnchors(frameId: string): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.prepare('DELETE FROM anchors WHERE frame_id = ?').run(frameId);\n }\n\n // Limited search (basic LIKE queries)\n async search(\n options: SearchOptions\n ): Promise<Array<Frame & { score: number }>> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n // SQLite doesn't support HAVING on non-aggregate queries, so we filter in application\n const sql = `\n SELECT *, \n CASE \n WHEN name LIKE ? THEN 1.0\n WHEN digest_text LIKE ? THEN 0.8\n WHEN inputs LIKE ? THEN 0.6\n ELSE 0.5\n END as score\n FROM frames\n WHERE name LIKE ? OR digest_text LIKE ? OR inputs LIKE ?\n ORDER BY score DESC\n `;\n\n const params = Array(6).fill(`%${options.query}%`);\n\n let rows = this.db.prepare(sql).all(...params) as any[];\n\n // Apply score threshold in application layer\n if (options.scoreThreshold) {\n rows = rows.filter((row) => row.score >= options.scoreThreshold);\n }\n\n // Apply limit and offset in application layer if threshold is used\n if (options.limit || options.offset) {\n const start = options.offset || 0;\n const end = options.limit ? start + options.limit : rows.length;\n rows = rows.slice(start, end);\n }\n\n return rows.map((row) => ({\n ...row,\n inputs: JSON.parse(row.inputs || '{}'),\n outputs: JSON.parse(row.outputs || '{}'),\n digest_json: JSON.parse(row.digest_json || '{}'),\n }));\n }\n\n async searchByVector(\n _embedding: number[],\n _options?: QueryOptions\n ): Promise<Array<Frame & { similarity: number }>> {\n // Not supported in SQLite\n logger.warn('Vector search not supported in SQLite adapter');\n return [];\n }\n\n async searchHybrid(\n textQuery: string,\n _embedding: number[],\n weights?: { text: number; vector: number }\n ): Promise<Array<Frame & { score: number }>> {\n // Fall back to text search only\n return this.search({ query: textQuery, ...weights });\n }\n\n // Basic aggregation\n async aggregate(\n table: string,\n options: AggregationOptions\n ): Promise<Record<string, any>[]> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const metrics = options.metrics\n .map(\n (m) =>\n `${m.operation}(${m.field}) AS ${m.alias || `${m.operation}_${m.field}`}`\n )\n .join(', ');\n\n let sql = `SELECT ${options.groupBy.join(', ')}, ${metrics} FROM ${table}`;\n sql += ` GROUP BY ${options.groupBy.join(', ')}`;\n\n if (options.having) {\n const havingClauses = Object.entries(options.having).map(\n ([key, value]) =>\n `${key} ${typeof value === 'object' ? value.op : '='} ?`\n );\n sql += ` HAVING ${havingClauses.join(' AND ')}`;\n }\n\n return this.db\n .prepare(sql)\n .all(...Object.values(options.having || {})) as any[];\n }\n\n // Pattern detection (basic)\n async detectPatterns(timeRange?: { start: Date; end: Date }): Promise<\n Array<{\n pattern: string;\n type: string;\n frequency: number;\n lastSeen: Date;\n }>\n > {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n let sql = `\n SELECT type as pattern, type, COUNT(*) as frequency, MAX(created_at) as last_seen\n FROM frames\n `;\n\n const params = [];\n if (timeRange) {\n sql += ' WHERE created_at >= ? AND created_at <= ?';\n params.push(\n Math.floor(timeRange.start.getTime() / 1000),\n Math.floor(timeRange.end.getTime() / 1000)\n );\n }\n\n sql += ' GROUP BY type HAVING COUNT(*) > 1 ORDER BY frequency DESC';\n\n const rows = this.db.prepare(sql).all(...params) as any[];\n\n return rows.map((row) => ({\n pattern: row.pattern,\n type: row.type,\n frequency: row.frequency,\n lastSeen: new Date(row.last_seen * 1000),\n }));\n }\n\n // Bulk operations\n async executeBulk(operations: BulkOperation[]): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n await this.inTransaction(async () => {\n for (const op of operations) {\n switch (op.type) {\n case 'insert':\n // Build insert dynamically based on data\n const insertCols = Object.keys(op.data);\n const insertPlaceholders = insertCols.map(() => '?').join(',');\n this.db!.prepare(\n `INSERT INTO ${op.table} (${insertCols.join(',')}) VALUES (${insertPlaceholders})`\n ).run(...Object.values(op.data));\n break;\n\n case 'update':\n const updateSets = Object.keys(op.data)\n .map((k) => `${k} = ?`)\n .join(',');\n const whereClause = this.buildWhereClause(op.where || {});\n this.db!.prepare(\n `UPDATE ${op.table} SET ${updateSets} ${whereClause}`\n ).run(...Object.values(op.data), ...Object.values(op.where || {}));\n break;\n\n case 'delete':\n const deleteWhere = this.buildWhereClause(op.where || {});\n this.db!.prepare(`DELETE FROM ${op.table} ${deleteWhere}`).run(\n ...Object.values(op.where || {})\n );\n break;\n }\n }\n });\n }\n\n async vacuum(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.pragma('vacuum');\n logger.info('SQLite database vacuumed');\n }\n\n async analyze(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.pragma('analyze');\n logger.info('SQLite database analyzed');\n }\n\n // Statistics\n async getStats(): Promise<DatabaseStats> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n const stats = {\n totalFrames: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM frames')\n .get() as CountResult\n ).count,\n activeFrames: (\n this.db\n .prepare(\n \"SELECT COUNT(*) as count FROM frames WHERE state = 'active'\"\n )\n .get() as CountResult\n ).count,\n totalEvents: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM events')\n .get() as CountResult\n ).count,\n totalAnchors: (\n this.db\n .prepare('SELECT COUNT(*) as count FROM anchors')\n .get() as CountResult\n ).count,\n diskUsage: 0,\n };\n\n // Get file size\n try {\n const fileStats = await fs.stat(this.dbPath);\n stats.diskUsage = fileStats.size;\n } catch {}\n\n return stats;\n }\n\n async getQueryStats(): Promise<\n Array<{\n query: string;\n calls: number;\n meanTime: number;\n totalTime: number;\n }>\n > {\n // SQLite doesn't have built-in query stats\n logger.warn('Query stats not available for SQLite');\n return [];\n }\n\n // Transaction support\n async beginTransaction(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.prepare('BEGIN').run();\n this.inTransactionFlag = true;\n }\n\n async commitTransaction(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.prepare('COMMIT').run();\n this.inTransactionFlag = false;\n }\n\n async rollbackTransaction(): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n this.db.prepare('ROLLBACK').run();\n this.inTransactionFlag = false;\n }\n\n async inTransaction(\n callback: (adapter: DatabaseAdapter) => Promise<void>\n ): Promise<void> {\n await this.beginTransaction();\n\n try {\n await callback(this);\n await this.commitTransaction();\n } catch (error: unknown) {\n await this.rollbackTransaction();\n throw error;\n }\n }\n\n // Export/Import\n async exportData(\n tables: string[],\n format: 'json' | 'parquet' | 'csv'\n ): Promise<Buffer> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n if (format !== 'json') {\n throw new ValidationError(\n `Format ${format} not supported for SQLite export`,\n ErrorCode.VALIDATION_FAILED,\n { format, supportedFormats: ['json'] }\n );\n }\n\n const data: Record<string, any[]> = {};\n\n for (const table of tables) {\n data[table] = this.db.prepare(`SELECT * FROM ${table}`).all();\n }\n\n return Buffer.from(JSON.stringify(data, null, 2));\n }\n\n async importData(\n data: Buffer,\n format: 'json' | 'parquet' | 'csv',\n options?: { truncate?: boolean; upsert?: boolean }\n ): Promise<void> {\n if (!this.db)\n throw new DatabaseError(\n 'Database not connected',\n ErrorCode.DB_CONNECTION_FAILED\n );\n\n if (format !== 'json') {\n throw new ValidationError(\n `Format ${format} not supported for SQLite import`,\n ErrorCode.VALIDATION_FAILED,\n { format, supportedFormats: ['json'] }\n );\n }\n\n const parsed = JSON.parse(data.toString());\n\n await this.inTransaction(async () => {\n for (const [table, rows] of Object.entries(parsed)) {\n if (options?.truncate) {\n this.db!.prepare(`DELETE FROM ${table}`).run();\n }\n\n for (const row of rows as any[]) {\n const cols = Object.keys(row);\n const placeholders = cols.map(() => '?').join(',');\n\n if (options?.upsert) {\n const updates = cols.map((c) => `${c} = excluded.${c}`).join(',');\n this.db!.prepare(\n `INSERT INTO ${table} (${cols.join(',')}) VALUES (${placeholders})\n ON CONFLICT DO UPDATE SET ${updates}`\n ).run(...Object.values(row));\n } else {\n this.db!.prepare(\n `INSERT INTO ${table} (${cols.join(',')}) VALUES (${placeholders})`\n ).run(...Object.values(row));\n }\n }\n }\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|