simplify and stabilize t resume
This commit is contained in:
parent
9832945005
commit
abd40dea83
|
@ -223,9 +223,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.17"
|
version = "0.1.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
@ -253,9 +253,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.81"
|
version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
|
@ -339,9 +339,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.27"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
@ -490,9 +490,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.64"
|
version = "1.0.65"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -531,9 +531,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.73"
|
version = "1.0.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -576,18 +576,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.25"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
|
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.25"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
|
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -619,12 +619,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.44"
|
version = "0.1.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -639,9 +638,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-linebreak"
|
name = "unicode-linebreak"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05a31f45d18a3213b918019f78fe6a73a14ab896807f0aaf5622aa0684749455"
|
checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
@ -660,9 +659,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.13"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
|
@ -678,9 +677,9 @@ checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
|
|
@ -42,7 +42,6 @@ impl<'a> Command<'a> for OutCommand {
|
||||||
writeln!(out, "Checked out of sheet \"{}\".", sheet)?;
|
writeln!(out, "Checked out of sheet \"{}\".", sheet)?;
|
||||||
|
|
||||||
db.entry_update(entry.id, entry.start, Some(end), entry.note, &entry.sheet)?;
|
db.entry_update(entry.id, entry.start, Some(end), entry.note, &entry.sheet)?;
|
||||||
db.set_last_checkout_id(entry.id)?;
|
|
||||||
} else {
|
} else {
|
||||||
writeln!(out, "No running entry on sheet \"{}\".", sheet)?;
|
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(&out)), PrettyString("Checked out of sheet \"default\".\n"));
|
||||||
assert_eq!(PrettyString(&String::from_utf8_lossy(&err)), PrettyString(""));
|
assert_eq!(PrettyString(&String::from_utf8_lossy(&err)), PrettyString(""));
|
||||||
assert_eq!(db.last_checkout_id().unwrap().unwrap(), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -8,8 +8,9 @@ use crate::error::{Error, Result};
|
||||||
use crate::timeparse::parse_time;
|
use crate::timeparse::parse_time;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
|
use crate::models::Entry;
|
||||||
|
|
||||||
use super::{Command, r#in};
|
use super::{Command, r#in, sheet};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
|
@ -28,6 +29,24 @@ impl<'a> TryFrom<&'a ArgMatches<'a>> for Args {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resume<D, O, E>(args: Args, db: &mut D, out: &mut O, err: &mut E, config: &Config, entry: Entry, now: DateTime<Utc>) -> 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;
|
pub struct ResumeCommand;
|
||||||
|
|
||||||
impl<'a> Command<'a> for ResumeCommand {
|
impl<'a> Command<'a> for ResumeCommand {
|
||||||
|
@ -39,24 +58,33 @@ impl<'a> Command<'a> for ResumeCommand {
|
||||||
O: Write,
|
O: Write,
|
||||||
E: 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)? {
|
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 {
|
return resume(args, db, out, err, config, entry, now);
|
||||||
at: args.at,
|
|
||||||
note: entry.note,
|
|
||||||
}, db, out, err, config, now)
|
|
||||||
} else {
|
} else {
|
||||||
writeln!(out, "The entry with id '{}' could not be found to be resumed. Perhaps it was deleted?", entry_id)?;
|
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 {
|
} else {
|
||||||
writeln!(out, "No entry to resume. Either no --id was given or no last_checkout_id was found in the database.
|
writeln!(out, "No entry to resume in the sheet '{}'. Perhaps start a new one?
|
||||||
Perhaps start an entry with t in")?;
|
Hint: use t in", current_sheet)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -66,6 +94,7 @@ Perhaps start an entry with t in")?;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
use crate::test_utils::PrettyString;
|
use crate::test_utils::PrettyString;
|
||||||
use crate::database::SqliteDatabase;
|
use crate::database::SqliteDatabase;
|
||||||
|
@ -85,7 +114,6 @@ mod tests {
|
||||||
db.init().unwrap();
|
db.init().unwrap();
|
||||||
|
|
||||||
db.entry_insert(two_hours_ago, Some(one_hour_ago), Some("fake note".into()), "default").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);
|
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();
|
ResumeCommand::handle(args, &mut db, &mut out, &mut err, &Default::default(), now).unwrap();
|
||||||
|
|
||||||
assert_eq!(PrettyString(&String::from_utf8_lossy(&out)), PrettyString("\
|
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.
|
No entry to resume in the sheet 'default'. Perhaps start a new one?
|
||||||
Perhaps start an entry with t in
|
Hint: use 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?
|
|
||||||
"));
|
"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::commands::list::ListCommand;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
sheet: Option<String>,
|
pub sheet: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a ArgMatches<'a>> for Args {
|
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_last_sheet(¤t_sheet)?;
|
||||||
db.set_current_sheet(&move_to)?;
|
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)?;
|
writeln!(out, "Switching to sheet '{}'", move_to)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -196,24 +196,6 @@ pub trait Database {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last_checkout_id(&self) -> Result<Option<u64>> {
|
|
||||||
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<DBVersion> {
|
fn version(&self) -> Result<DBVersion> {
|
||||||
let results = self.meta_query("select * from meta where key='database_version'", &[])?;
|
let results = self.meta_query("select * from meta where key='database_version'", &[])?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue