diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index 6af5562..c8cce52 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -1,9 +1,13 @@ use clap::{Args, Parser, Subcommand}; +use tracing::trace; use std::io::{self, Read}; use std::path::PathBuf; use std::process; -use vanth::{ContentHash, store::Store, Ty}; use vanth::hash as vanth_hash; +use vanth::{ + ContentHash, Ty, + store::{Store, StoreParams}, +}; #[derive(Parser, Debug)] #[command(name = "vanth")] @@ -104,7 +108,7 @@ fn parse_hash(s: &str) -> ContentHash { } fn handle_write(args: &WriteArgs) { - let mut store = Store::sqlite_from_path(args.db.clone()).unwrap_or_else(|e| { + let mut store = Store::sqlite_from_path(args.db.clone(), StoreParams::default()).unwrap_or_else(|e| { eprintln!("Error opening store: {:?}", e); process::exit(1); }); @@ -119,6 +123,8 @@ fn handle_write(args: &WriteArgs) { process::exit(1); }); } + + trace!("Received JSON content: {}", content); let value: serde_json::Value = serde_json::from_str(&content).unwrap_or_else(|e| { eprintln!("Invalid JSON: {}", e); @@ -134,7 +140,14 @@ fn handle_write(args: &WriteArgs) { } fn handle_get(args: &GetArgs) { - let mut store = Store::sqlite_from_path(args.db.clone()).unwrap_or_else(|e| { + let mut store = Store::sqlite_from_path( + args.db.clone(), + StoreParams { + create_if_not_exists: false, + ..Default::default() + }, + ) + .unwrap_or_else(|e| { eprintln!("Error opening store: {:?}", e); process::exit(1); }); @@ -160,7 +173,14 @@ fn handle_get(args: &GetArgs) { } fn handle_get_all(args: &GetAllArgs) { - let mut store = Store::sqlite_from_path(args.db.clone()).unwrap_or_else(|e| { + let mut store = Store::sqlite_from_path( + args.db.clone(), + StoreParams { + create_if_not_exists: false, + ..Default::default() + }, + ) + .unwrap_or_else(|e| { eprintln!("Error opening store: {:?}", e); process::exit(1); }); @@ -180,7 +200,14 @@ fn handle_get_all(args: &GetAllArgs) { } fn handle_delete(args: &DeleteArgs) { - let mut store = Store::sqlite_from_path(args.db.clone()).unwrap_or_else(|e| { + let mut store = Store::sqlite_from_path( + args.db.clone(), + StoreParams { + create_if_not_exists: false, + ..Default::default() + }, + ) + .unwrap_or_else(|e| { eprintln!("Error opening store: {:?}", e); process::exit(1); }); @@ -188,7 +215,14 @@ fn handle_delete(args: &DeleteArgs) { } fn handle_delete_all(args: &DeleteAllArgs) { - let mut store = Store::sqlite_from_path(args.db.clone()).unwrap_or_else(|e| { + let mut store = Store::sqlite_from_path( + args.db.clone(), + StoreParams { + create_if_not_exists: false, + ..Default::default() + }, + ) + .unwrap_or_else(|e| { eprintln!("Error opening store: {:?}", e); process::exit(1); }); diff --git a/crates/vanth/src/store.rs b/crates/vanth/src/store.rs index f925743..b60b8b8 100644 --- a/crates/vanth/src/store.rs +++ b/crates/vanth/src/store.rs @@ -58,10 +58,27 @@ impl Default for StoreParams { impl Store { /// Use an SQLite backend with a database file at the provided path. - // TODO: Params - pub fn sqlite_from_path(path: PathBuf) -> Result { + pub fn sqlite_from_path(path: PathBuf, params: StoreParams) -> Result { + use rusqlite::OpenFlags; + // Base flags for URI handling and disabling mutexes. + let mut flags = OpenFlags::SQLITE_OPEN_URI | OpenFlags::SQLITE_OPEN_NO_MUTEX; + + // Read‑only takes precedence over read‑write. + if params.read_only { + flags |= OpenFlags::SQLITE_OPEN_READ_ONLY; + } else { + flags |= OpenFlags::SQLITE_OPEN_READ_WRITE; + } + + // Create the file if allowed. + if params.create_if_not_exists { + flags |= OpenFlags::SQLITE_OPEN_CREATE; + } + + // Open the SQLite connection with the computed flags. + let connection = rusqlite::Connection::open_with_flags(path, flags)?; Ok(Self { - backend: Box::new(Sqlite::new(path)?), + backend: Box::new(Sqlite { connection }), }) } @@ -154,6 +171,7 @@ pub struct Sqlite { } impl Sqlite { + // TODO: Use this instead of directly constructing the connection in `Store`. pub fn new(path: PathBuf) -> Result { use rusqlite::OpenFlags; // Remove the `SQLITE_OPEN_CREATE` flag because we do not want to create databases if they don't exist. diff --git a/crates/vanth/tests/integration/store.rs b/crates/vanth/tests/integration/store.rs index ff57d89..331ba64 100644 --- a/crates/vanth/tests/integration/store.rs +++ b/crates/vanth/tests/integration/store.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; use tempfile::TempDir; -use vanth::{Vanth, hash, store::Store}; +use vanth::{Vanth, hash, store::{Store, StoreParams}}; #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Vanth)] struct Foo { @@ -17,7 +17,7 @@ struct Bar { fn test_sqlite_store() { let dir = TempDir::new().unwrap(); let path = dir.path().join("test.db"); - let mut store = Store::sqlite_from_path(path.clone()).unwrap(); + let mut store = Store::sqlite_from_path(path.clone(), StoreParams::default()).unwrap(); let foo_1 = Foo { inner: 1 }; let foo_2 = Foo { inner: 2 };