Newer
Older
TelosDB / src-tauri / src / db.rs
use rusqlite::{Connection, Result};
use std::path::Path;
use std::fs;

pub fn init_db(db_path: &Path, extension_path: &Path) -> Result<Connection> {
    // Ensure parent directory exists
    if let Some(parent) = db_path.parent() {
        if !parent.exists() {
            fs::create_dir_all(parent).map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        }
    }

    let conn = Connection::open(db_path)?;

    // Load sqlite-vec extension
    // IMPORTANT: This relies on vec0.dll being in a place where standard LoadLibrary can find it
    // OR we pass the absolute path.
    // Since build.rs copies it to the same dir as the exe, we can try loading by name "vec0" or full path.
    // If we use full path, we need to know where the exe is.
    // But passing extension_path allows flexibility from main.rs.
    unsafe {
        conn.load_extension_enable()?;
        conn.load_extension(extension_path, None)?;
        conn.load_extension_disable()?;
    }

    // Initialize Schema
    conn.execute_batch(
        "PRAGMA journal_mode = WAL;
         CREATE TABLE IF NOT EXISTS items (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            content TEXT NOT NULL,
            path TEXT,
            created_at TEXT DEFAULT (datetime('now', 'localtime')),
            updated_at TEXT DEFAULT (datetime('now', 'localtime'))
        );
        CREATE TRIGGER IF NOT EXISTS update_items_updated_at
        AFTER UPDATE ON items
        FOR EACH ROW
        BEGIN
            UPDATE items SET updated_at = datetime('now', 'localtime') WHERE id = OLD.id;
        END;
        CREATE VIRTUAL TABLE IF NOT EXISTS vec_items USING vec0(
            id INTEGER PRIMARY KEY,
            embedding FLOAT[640]
        );"
    )?;

    Ok(conn)
}

use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use std::str::FromStr;
use std::borrow::Cow;

pub async fn init_pool(db_path: &str, extension_path: impl Into<Cow<'static, str>>) -> Result<sqlx::SqlitePool, sqlx::Error> {
    let opts = SqliteConnectOptions::from_str(&format!("sqlite://{}?mode=rwc", db_path))?
        .extension(extension_path);

    let pool = SqlitePoolOptions::new()
        .connect_with(opts)
        .await?;
    Ok(pool)
}