diff options
author | 2025-06-09 22:22:41 +0100 | |
---|---|---|
committer | 2025-06-09 22:22:41 +0100 | |
commit | cac9823d3b8889fe77f49397ffac79cdfd9f35eb (patch) | |
tree | b22619b1f8b0c656faf18caccee3ff5d79a79629 | |
parent | f487744505f8b391a345c659eb45034567d7bc0f (diff) | |
download | fj-cac9823d3b8889fe77f49397ffac79cdfd9f35eb.tar.gz fj-cac9823d3b8889fe77f49397ffac79cdfd9f35eb.tar.bz2 fj-cac9823d3b8889fe77f49397ffac79cdfd9f35eb.zip |
-rw-r--r-- | src/db.rs | 51 |
1 files changed, 44 insertions, 7 deletions
@@ -83,6 +83,10 @@ impl Db { "insert or ignore into categories ( id, name ) values ( ?1, ?2 )", (category_id, category), )?; + let category_id = self + .0 + .prepare("select id from categories where name = ?")? + .query_one([category], |row| Ok(row.get(0)?))?; self.0.execute( "insert into tasks_categories ( task_id, category_id ) values ( ?1, ?2 )", @@ -120,12 +124,31 @@ impl Db { Ok(task) } - // TODO: filter and ordering pub fn read_tasks(&self, filter: Vec<TaskFilter>) -> Result<Vec<Task>> { + let mut query = String::from("select name, cron, archived, description, id from tasks"); + + let where_clause = filter + .iter() + .filter_map(|filter| match filter { + TaskFilter::Archived(_) => Some("archived = ?"), + TaskFilter::Category(_) => None, + }) + .collect::<Vec<_>>() + .join(" and "); + if !where_clause.is_empty() { + query.push_str(" where "); + query.push_str(&where_clause); + } + + let archived = filter.iter().filter_map(|filter| match filter { + TaskFilter::Archived(b) => Some(b), + TaskFilter::Category(_) => None, + }); + let mut tasks = self .0 - .prepare("select name, cron, archived, description, id from tasks")? - .query_map([], |row| { + .prepare(&query)? + .query_map(params_from_iter(archived), |row| { Ok(( row.get::<_, Uuid>(4)?, Task { @@ -148,6 +171,19 @@ impl Db { task.categories = categories; } + // TODO: can i do this filtering within sqlite? + let category_filters = filter.iter().filter_map(|filter| match filter { + TaskFilter::Archived(_) => None, + TaskFilter::Category(c) => Some(Category::new(c.to_string())), + }); + + for category in category_filters { + tasks = tasks + .into_iter() + .filter(|(_id, task)| task.categories.contains(&category)) + .collect(); + } + Ok(tasks.into_iter().map(|(_id, task)| task).collect()) } @@ -196,7 +232,7 @@ impl Db { .iter() .map(|filter| filter.where_clause()) .collect::<Vec<_>>() - .join(", "), + .join(" and "), ); let logs = self @@ -214,11 +250,12 @@ impl Db { } pub fn delete_log(&self, log: &Log) -> Result<()> { - self.0.execute("delete from logs where id = ?1", [log.id])?; + self.0.execute("delete from log where id = ?1", [log.id])?; Ok(()) } } +// TODO: task filterings: if it's due or not: to be implemented separately pub enum TaskFilter { Archived(bool), Category(String), @@ -243,8 +280,8 @@ impl LogFilter { fn where_clause(&self) -> &'static str { match self { LogFilter::Task(_) => "task_id = (select id from tasks where name = ?)", - LogFilter::Before(naive_date_time) => "timestamp < ?", - LogFilter::After(naive_date_time) => "timestamp > ?", + LogFilter::Before(naive_date_time) => "timestamp <= ?", + LogFilter::After(naive_date_time) => "timestamp >= ?", } } } |