"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.dbOps = void 0;
exports.initDb = initDb;
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const os_1 = __importDefault(require("os"));
// Use a path relative to the built script (dist/src/db.js -> ../../antigravity.db)
// This puts it in the project root.
const DB_PATH = path_1.default.resolve(__dirname, "../../antigravity.db");
// Debug logging to help diagnose startup issues
const DEBUG_LOG = path_1.default.join(os_1.default.tmpdir(), "antigravity_debug.log");
function log(msg) {
try {
fs_1.default.appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`);
}
catch (e) {
// ignore
}
}
let db;
function initDb() {
log(`Initializing DB at ${DB_PATH}`);
if (!db) {
try {
db = new better_sqlite3_1.default(DB_PATH);
db.pragma("journal_mode = WAL");
log("DB connection established");
}
catch (e) {
log(`Failed to connect to DB: ${e.message}`);
throw e;
}
}
db.exec(`
CREATE TABLE IF NOT EXISTS documents (
id TEXT PRIMARY KEY,
path TEXT NOT NULL,
filename TEXT NOT NULL,
added_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS chunks (
id TEXT PRIMARY KEY,
document_id TEXT NOT NULL,
text TEXT NOT NULL,
page_number INTEGER, -- Added page_number column
embedding TEXT, -- JSON string
tfidf_vector TEXT, -- JSON string
FOREIGN KEY(document_id) REFERENCES documents(id) ON DELETE CASCADE
);
`);
// Migration: Add page_number column if it doesn't exist (for existing DBs)
try {
db.exec("ALTER TABLE chunks ADD COLUMN page_number INTEGER");
}
catch (e) {
// Column likely already exists, ignore if the error is about column existence
if (!e.message.includes("duplicate column name")) {
throw e; // Re-throw other errors
}
}
}
function getDb() {
if (!db) {
log(`Lazy initializing DB at ${DB_PATH}`);
try {
db = new better_sqlite3_1.default(DB_PATH);
db.pragma("journal_mode = WAL");
log("DB connection established (lazy)");
}
catch (e) {
log(`Failed to connect to DB (lazy): ${e.message}`);
throw e;
}
}
return db;
}
exports.dbOps = {
addDocument: (doc) => {
const stmt = getDb().prepare("INSERT INTO documents (id, path, filename, added_at) VALUES (?, ?, ?, ?)");
stmt.run(doc.id, doc.path, doc.filename, new Date().toISOString());
},
getDocumentByPath: (path) => {
const stmt = getDb().prepare("SELECT * FROM documents WHERE path = ?");
return stmt.get(path);
},
listDocuments: () => {
const stmt = getDb().prepare("SELECT * FROM documents ORDER BY added_at DESC");
return stmt.all();
},
addChunk: (chunk) => {
const stmt = getDb().prepare("INSERT INTO chunks (id, document_id, text, page_number, embedding, tfidf_vector) VALUES (?, ?, ?, ?, ?, ?)");
stmt.run(chunk.id, chunk.document_id, chunk.text, chunk.page_number || null, // Handle optional page_number
chunk.embedding ? JSON.stringify(chunk.embedding) : null, chunk.tfidf ? JSON.stringify(chunk.tfidf) : null);
},
addChunksBatch: (chunks) => {
const database = getDb();
const insert = database.prepare("INSERT INTO chunks (id, document_id, text, page_number, embedding, tfidf_vector) VALUES (?, ?, ?, ?, ?, ?)");
const insertMany = database.transaction((chunks) => {
for (const chunk of chunks)
insert.run(chunk.id, chunk.document_id, chunk.text, chunk.page_number || null, // Handle optional page_number
chunk.embedding ? JSON.stringify(chunk.embedding) : null, chunk.tfidf ? JSON.stringify(chunk.tfidf) : null);
});
insertMany(chunks);
},
getAllChunks: () => {
const stmt = getDb().prepare("SELECT * FROM chunks");
const rows = stmt.all();
return rows.map(row => ({
id: row.id,
document_id: row.document_id,
text: row.text,
pageNumber: row.page_number,
embedding: row.embedding ? JSON.parse(row.embedding) : undefined,
tfidf: row.tfidf_vector ? JSON.parse(row.tfidf_vector) : undefined
}));
},
reset: () => {
getDb().exec("DELETE FROM chunks; DELETE FROM documents;");
}
};