import DB from "better-sqlite3";
import fs from "fs";
const applyPragmas = (db, pragmas) => {
    db.pragma("journal_mode = WAL");
    db.pragma("foreign_keys = on");
    db.pragma(`synchronous = ${(pragmas?.synchronous ?? "FULL").toUpperCase()}`);
    if (pragmas?.lockingMode) {
        db.pragma(`locking_mode = ${pragmas.lockingMode.toUpperCase()}`);
    }
    if (pragmas?.tempStore && pragmas.tempStore !== "DEFAULT") {
        db.pragma(`temp_store = ${pragmas.tempStore.toUpperCase()}`);
    }
    db.defaultSafeIntegers(true);
};
let create = async (directory, options) => {
    let db = undefined;
    let statements = new Map();
    let dbFileName;
    let close = () => {
        for (const stmt of statements.values()) {
            stmt.finalize?.();
        }
        statements.clear();
        if (db) {
            db.close();
            db = undefined;
        }
    };
    let drop = () => {
        if (db && !db?.memory) {
            fs.rmSync(dbFileName);
            db = undefined;
        }
        return close();
    };
    let open = () => {
        if (db?.open) {
            return db;
        }
        if (!db) {
            if (directory) {
                // if directory is provided, check if directory exist, if not create it
                if (!fs.existsSync(directory)) {
                    fs.mkdirSync(directory, { recursive: true });
                }
                dbFileName = `${directory}/db.sqlite`;
            }
            else {
                dbFileName = ":memory:";
            }
            db = new DB(dbFileName, {
                fileMustExist: false,
                readonly: false /* , verbose: (message) => console.log(message)  */,
            });
        }
        applyPragmas(db, options?.pragmas);
    };
    return {
        exec: (sql) => {
            if (!db)
                throw new Error("Database not open");
            return db.exec(sql);
        },
        async prepare(sql, id) {
            if (!db)
                throw new Error("Database not open");
            if (id != null) {
                let prev = statements.get(id);
                if (prev) {
                    await prev.reset?.();
                    return prev;
                }
            }
            const stmt = db.prepare(sql); // TODO types
            if (id != null) {
                statements.set(id, stmt);
            }
            return stmt;
        },
        statements,
        close,
        drop,
        open,
        status: () => (db ? "open" : "closed"),
    }; // TODO fix this
};
export { create };
//# sourceMappingURL=sqlite3.js.map