diff --git a/Cargo.lock b/Cargo.lock index 0501f5a..ad44098 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,9 +223,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -253,9 +253,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.81" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "libsqlite3-sys" @@ -339,9 +339,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -490,9 +490,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29" dependencies = [ "itoa", "ryu", @@ -531,9 +531,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ "proc-macro2", "quote", @@ -576,18 +576,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -619,12 +619,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "wasi", "winapi", ] @@ -639,9 +638,9 @@ dependencies = [ [[package]] name = "unicode-linebreak" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a31f45d18a3213b918019f78fe6a73a14ab896807f0aaf5622aa0684749455" +checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" dependencies = [ "regex", ] @@ -660,9 +659,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "vcpkg" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -678,9 +677,9 @@ checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" diff --git a/src/commands/out.rs b/src/commands/out.rs index 3488632..315dd5d 100644 --- a/src/commands/out.rs +++ b/src/commands/out.rs @@ -42,7 +42,6 @@ impl<'a> Command<'a> for OutCommand { writeln!(out, "Checked out of sheet \"{}\".", sheet)?; db.entry_update(entry.id, entry.start, Some(end), entry.note, &entry.sheet)?; - db.set_last_checkout_id(entry.id)?; } else { writeln!(out, "No running entry on sheet \"{}\".", sheet)?; } @@ -84,7 +83,6 @@ mod tests { assert_eq!(PrettyString(&String::from_utf8_lossy(&out)), PrettyString("Checked out of sheet \"default\".\n")); assert_eq!(PrettyString(&String::from_utf8_lossy(&err)), PrettyString("")); - assert_eq!(db.last_checkout_id().unwrap().unwrap(), 1); } #[test] diff --git a/src/commands/resume.rs b/src/commands/resume.rs index 8ed8e7b..539dcc1 100644 --- a/src/commands/resume.rs +++ b/src/commands/resume.rs @@ -8,8 +8,9 @@ use crate::error::{Error, Result}; use crate::timeparse::parse_time; use crate::config::Config; use crate::database::Database; +use crate::models::Entry; -use super::{Command, r#in}; +use super::{Command, r#in, sheet}; #[derive(Default)] pub struct Args { @@ -28,6 +29,24 @@ impl<'a> TryFrom<&'a ArgMatches<'a>> for Args { } } +fn resume(args: Args, db: &mut D, out: &mut O, err: &mut E, config: &Config, entry: Entry, now: DateTime) -> Result<()> +where + D: Database, + O: Write, + E: Write, +{ + writeln!( + out, + "Resuming \"{}\" from entry #{}", + entry.note.as_ref().unwrap_or(&"".to_owned()), entry.id + )?; + + r#in::InCommand::handle(r#in::Args { + at: args.at, + note: entry.note, + }, db, out, err, config, now) +} + pub struct ResumeCommand; impl<'a> Command<'a> for ResumeCommand { @@ -39,24 +58,33 @@ impl<'a> Command<'a> for ResumeCommand { O: Write, E: Write, { - let entry_id = args.id.or(db.last_checkout_id()?); + let current_sheet = db.current_sheet()?.unwrap_or("default".to_owned()); - if let Some(entry_id) = entry_id { + // First try to process using the given id + if let Some(entry_id) = args.id { if let Some(entry) = db.entry_by_id(entry_id)? { - writeln!(out, "Resuming \"{}\" from entry #{}", entry.note.as_ref().unwrap_or(&"".to_owned()), entry.id)?; + if entry.sheet != current_sheet { + // first swith to the sheet + sheet::SheetCommand::handle(sheet::Args { + sheet: Some(entry.sheet.clone()), + }, db, out, err, config, now)?; + } - r#in::InCommand::handle(r#in::Args { - at: args.at, - note: entry.note, - }, db, out, err, config, now) + return resume(args, db, out, err, config, entry, now); } else { writeln!(out, "The entry with id '{}' could not be found to be resumed. Perhaps it was deleted?", entry_id)?; - Ok(()) + return Ok(()); } + } + + // No id specified, try to find something suitable to switch to in the + // database + if let Some(entry) = db.last_checkout_of_sheet(¤t_sheet)? { + resume(args ,db, out, err, config, entry, now) } else { - writeln!(out, "No entry to resume. Either no --id was given or no last_checkout_id was found in the database. -Perhaps start an entry with t in")?; + writeln!(out, "No entry to resume in the sheet '{}'. Perhaps start a new one? +Hint: use t in", current_sheet)?; Ok(()) } @@ -66,6 +94,7 @@ Perhaps start an entry with t in")?; #[cfg(test)] mod tests { use chrono::Duration; + use pretty_assertions::assert_eq; use crate::test_utils::PrettyString; use crate::database::SqliteDatabase; @@ -85,7 +114,6 @@ mod tests { db.init().unwrap(); db.entry_insert(two_hours_ago, Some(one_hour_ago), Some("fake note".into()), "default").unwrap(); - db.set_last_checkout_id(1).unwrap(); assert_eq!(db.entries_full(None, None).unwrap().len(), 1); @@ -119,27 +147,8 @@ Checked into sheet \"default\".\n")); ResumeCommand::handle(args, &mut db, &mut out, &mut err, &Default::default(), now).unwrap(); assert_eq!(PrettyString(&String::from_utf8_lossy(&out)), PrettyString("\ -No entry to resume. Either no --id was given or no last_checkout_id was found in the database. -Perhaps start an entry with t in -")); - } - - #[test] - fn last_checkout_id_does_not_exist() { - let args = Default::default(); - let mut db = SqliteDatabase::from_memory().unwrap(); - let mut out = Vec::new(); - let mut err = Vec::new(); - let now = Utc::now(); - - db.init().unwrap(); - - db.set_last_checkout_id(23).unwrap(); - - ResumeCommand::handle(args, &mut db, &mut out, &mut err, &Default::default(), now).unwrap(); - - assert_eq!(PrettyString(&String::from_utf8_lossy(&out)), PrettyString("\ -The entry with id '23' could not be found to be resumed. Perhaps it was deleted? +No entry to resume in the sheet 'default'. Perhaps start a new one? +Hint: use t in ")); } } diff --git a/src/commands/sheet.rs b/src/commands/sheet.rs index d10942a..bc479b6 100644 --- a/src/commands/sheet.rs +++ b/src/commands/sheet.rs @@ -12,7 +12,7 @@ use crate::commands::list::ListCommand; #[derive(Default)] pub struct Args { - sheet: Option, + pub sheet: Option, } impl<'a> TryFrom<&'a ArgMatches<'a>> for Args { @@ -62,10 +62,6 @@ Hint: remember that giving - (a dash) as argument to t sheet switches to the las db.set_last_sheet(¤t_sheet)?; db.set_current_sheet(&move_to)?; - if let Some(entry) = db.last_checkout_of_sheet(&move_to)? { - db.set_last_checkout_id(entry.id)?; - } - writeln!(out, "Switching to sheet '{}'", move_to)?; Ok(()) diff --git a/src/database.rs b/src/database.rs index 546b04f..a5a3d23 100644 --- a/src/database.rs +++ b/src/database.rs @@ -196,24 +196,6 @@ pub trait Database { Ok(()) } - fn last_checkout_id(&self) -> Result> { - let results = self.meta_query("select * from meta where key='last_checkout_id'", &[])?; - - Ok(results.into_iter().next().map(|m| m.value.parse().map_err(|_| { - Error::CorruptedData(format!( - "Found value '{}' for key 'last_checkout_id' in meta table which is not a valid integer", - m.value - )) - })).transpose()?) - } - - fn set_last_checkout_id(&mut self, id: u64) -> Result<()> { - self.execute("DELETE FROM meta WHERE key='last_checkout_id'", &[])?; - self.execute("INSERT INTO meta (key, value) VALUES ('last_checkout_id', ?1)", &[&id])?; - - Ok(()) - } - fn version(&self) -> Result { let results = self.meta_query("select * from meta where key='database_version'", &[])?;