diff --git a/migrations/tables.sql b/migrations/tables.sql new file mode 100644 index 0000000..e38b52b --- /dev/null +++ b/migrations/tables.sql @@ -0,0 +1,25 @@ +PRAGMA foreign_keys = ON; + +create table if not exists task +( + id integer primary key autoincrement, + title text not null, + description text not null, + column_id integer, + foreign key (column_id) references kb_column(id) +); + +create table if not exists kb_column +( + id integer primary key autoincrement, + name text not null, + selected_task integer not null default 0 +); + + +create table if not exists setting +( + id integer primary key autoincrement, + name text not null, + value text not null +); diff --git a/src/app.rs b/src/app.rs index 86ef52b..2dff351 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,6 @@ // use indexmap::IndexMap; // use int_enum::IntEnum; +use crate::get_all_tasks; use serde::{Deserialize, Serialize}; use sqlx::SqlitePool; use std::cmp::min; @@ -17,7 +18,7 @@ pub struct Column { pub tasks: Vec, } -#[derive(Default, Deserialize, Serialize, Debug, sqlx::FromRow)] +#[derive(Clone, Default, Deserialize, Serialize, Debug, sqlx::FromRow)] pub struct Task { pub title: String, pub description: String, @@ -179,6 +180,25 @@ impl Project { } } + pub async fn load2(pool: &SqlitePool) -> Result { + let todos = get_all_tasks(&pool).await.unwrap(); + + Ok(Project { + name: String::from("Kanban Board"), + filepath: String::from("path"), + columns: todos + .iter() + .map(|(cname, tasks)| Column { + name: cname.clone(), + // TODO: Figure out how to avoid cloning here + tasks: tasks.to_vec(), + selected_task_idx: 0, + }) + .collect::>(), + selected_column_idx: 0, + }) + } + /// # Panics /// /// Will panic if there's an error serializing the Json or there's an issue diff --git a/src/db.rs b/src/db.rs index e397b94..773aac1 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,13 +1,30 @@ -use sqlx::SqlitePool; use crate::app::Task; +use sqlx::SqlitePool; -pub async fn get_all_tasks(pool: SqlitePool) -> Option> { - sqlx::query_as!(Task, +pub async fn get_tasks_by_column(pool: &SqlitePool, column_name: &String) -> Option> { + sqlx::query_as!( + Task, r#" select title, description from task - "# + join kb_column on column_id = kb_column.id + where kb_column.name = ?1 + "#, + column_name ) - .fetch_all(&pool) + .fetch_all(pool) .await .ok() } + +pub async fn get_all_tasks(pool: &SqlitePool) -> Option)>> { + let columns = sqlx::query!("select name from kb_column") + .fetch_all(pool) + .await + .unwrap(); + let mut tasks_by_column: Vec<(String, Vec)> = Vec::with_capacity(columns.len()); + for col in columns { + let tasks = get_tasks_by_column(pool, &col.name).await.unwrap(); + tasks_by_column.push((col.name, tasks)); + } + Some(tasks_by_column) +} diff --git a/src/lib.rs b/src/lib.rs index a3d2ded..0e6f329 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ #![deny(rust_2018_idioms)] mod app; +mod db; mod input; mod ui; -mod db; pub use app::*; pub use db::*; diff --git a/src/main.rs b/src/main.rs index 519ac3b..8cb19b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,7 +59,7 @@ fn prompt_project_init(default_name: &str) -> (String, io::Result) { #[async_std::main] async fn main() -> anyhow::Result<(), Box> { - let (filepath, file) = match CliArgs::parse() { + let (_filepath, _file) = match CliArgs::parse() { CliArgs { filepath: Some(filepath), } => { @@ -89,7 +89,8 @@ async fn main() -> anyhow::Result<(), Box> { let db_pool = SqlitePool::connect("sqlite:db.sqlite").await?; - let mut state = State::new(db_pool, Project::load(filepath, &file)?); + let project = Project::load2(&db_pool).await?; + let mut state = State::new(db_pool, project); enable_raw_mode()?; let mut stdout = io::stdout();