use crate::errors::AppError;
use crate::pragmas::apply_connection_pragmas;
use rusqlite::Connection;
use sqlite_vec::sqlite3_vec_init;
use std::path::Path;
pub fn register_vec_extension() {
#[allow(clippy::missing_transmute_annotations)]
unsafe {
rusqlite::ffi::sqlite3_auto_extension(Some(std::mem::transmute(
sqlite3_vec_init as *const (),
)));
}
}
pub fn open_rw(path: &Path) -> Result<Connection, AppError> {
let conn = Connection::open(path)?;
apply_connection_pragmas(&conn)?;
apply_secure_permissions(path);
Ok(conn)
}
#[allow(unused_variables)]
fn apply_secure_permissions(path: &Path) {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let candidates = [
path.to_path_buf(),
path.with_extension(format!(
"{}-wal",
path.extension()
.and_then(|e| e.to_str())
.unwrap_or("sqlite")
)),
path.with_extension(format!(
"{}-shm",
path.extension()
.and_then(|e| e.to_str())
.unwrap_or("sqlite")
)),
];
for file in candidates.iter() {
if file.exists() {
if let Ok(meta) = std::fs::metadata(file) {
let mut perms = meta.permissions();
perms.set_mode(0o600);
let _ = std::fs::set_permissions(file, perms);
}
}
}
}
}
pub fn open_ro(path: &Path) -> Result<Connection, AppError> {
let conn = Connection::open_with_flags(
path,
rusqlite::OpenFlags::SQLITE_OPEN_READ_ONLY | rusqlite::OpenFlags::SQLITE_OPEN_URI,
)?;
conn.execute_batch("PRAGMA foreign_keys = ON;")?;
Ok(conn)
}