diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a708b7..645fc5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Procedure when bumping the version number: - Account login and logout - Authentication dialog for password-protected rooms - Error popups in rooms when something goes wrong +- `--ephemeral` flag that prevents cove from storing data permanently ### Changed - Reduced amount of unnecessary redraws diff --git a/src/main.rs b/src/main.rs index 36708dd..0d8115a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,28 +61,41 @@ struct Args { /// Path to a directory for cove to store its data in. #[clap(long, short)] data_dir: Option, + + /// If set, cove won't store data permanently. + #[clap(long, short, action)] + ephemeral: bool, + /// Measure the width of characters as displayed by the terminal emulator /// instead of guessing the width. #[clap(long, short, action)] measure_widths: bool, + #[clap(subcommand)] command: Option, } +fn data_dir(args_data_dir: Option) -> PathBuf { + if let Some(data_dir) = args_data_dir { + data_dir + } else { + let dirs = + ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories"); + dirs.data_dir().to_path_buf() + } +} + #[tokio::main] async fn main() -> anyhow::Result<()> { let args = Args::parse(); - let data_dir = if let Some(data_dir) = args.data_dir { - data_dir + let vault = if args.ephemeral { + vault::launch_in_memory()? } else { - let dirs = - ProjectDirs::from("de", "plugh", "cove").expect("unable to determine directories"); - dirs.data_dir().to_path_buf() + let data_dir = data_dir(args.data_dir); + println!("Data dir: {}", data_dir.to_string_lossy()); + vault::launch(&data_dir.join("vault.db"))? }; - println!("Data dir: {}", data_dir.to_string_lossy()); - - let vault = vault::launch(&data_dir.join("vault.db"))?; match args.command.unwrap_or_default() { Command::Run => run(&vault, args.measure_widths).await?, diff --git a/src/vault.rs b/src/vault.rs index abbaa49..66b52c2 100644 --- a/src/vault.rs +++ b/src/vault.rs @@ -20,9 +20,14 @@ enum Request { #[derive(Debug, Clone)] pub struct Vault { tx: mpsc::UnboundedSender, + ephemeral: bool, } impl Vault { + pub fn ephemeral(&self) -> bool { + self.ephemeral + } + pub async fn close(&self) { let (tx, rx) = oneshot::channel(); let _ = self.tx.send(Request::Close(tx)); @@ -64,12 +69,26 @@ fn run(mut conn: Connection, mut rx: mpsc::UnboundedReceiver) { } } +fn launch_from_connection(mut conn: Connection, ephemeral: bool) -> rusqlite::Result { + conn.pragma_update(None, "foreign_keys", true)?; + conn.pragma_update(None, "trusted_schema", false)?; + + println!("Opening vault"); + + migrate::migrate(&mut conn)?; + prepare::prepare(&mut conn)?; + + let (tx, rx) = mpsc::unbounded_channel(); + thread::spawn(move || run(conn, rx)); + Ok(Vault { tx, ephemeral }) +} + pub fn launch(path: &Path) -> rusqlite::Result { // If this fails, rusqlite will complain about not being able to open the db // file, which saves me from adding a separate vault error type. let _ = fs::create_dir_all(path.parent().expect("path to file")); - let mut conn = Connection::open(path)?; + let conn = Connection::open(path)?; // Setting locking mode before journal mode so no shared memory files // (*-shm) need to be created by sqlite. Apparently, setting the journal @@ -78,13 +97,11 @@ pub fn launch(path: &Path) -> rusqlite::Result { // https://sqlite.org/pragma.html#pragma_locking_mode conn.pragma_update(None, "locking_mode", "exclusive")?; conn.pragma_update(None, "journal_mode", "wal")?; - conn.pragma_update(None, "foreign_keys", true)?; - conn.pragma_update(None, "trusted_schema", false)?; - migrate::migrate(&mut conn)?; - prepare::prepare(&mut conn)?; - - let (tx, rx) = mpsc::unbounded_channel(); - thread::spawn(move || run(conn, rx)); - Ok(Vault { tx }) + launch_from_connection(conn, false) +} + +pub fn launch_in_memory() -> rusqlite::Result { + let conn = Connection::open_in_memory()?; + launch_from_connection(conn, true) } diff --git a/src/vault/prepare.rs b/src/vault/prepare.rs index fc45551..c990e26 100644 --- a/src/vault/prepare.rs +++ b/src/vault/prepare.rs @@ -1,8 +1,6 @@ use rusqlite::Connection; pub fn prepare(conn: &mut Connection) -> rusqlite::Result<()> { - println!("Opening vault"); - // Cache ids of tree roots. conn.execute_batch( "