WIP: Switch to rusqlite
This commit is contained in:
		
							parent
							
								
									8393ed610f
								
							
						
					
					
						commit
						076c87c792
					
				
							
								
								
									
										740
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										740
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -14,6 +14,6 @@ serde_json = "1.0.89" | |||||||
| int-enum = "0.5.0" | int-enum = "0.5.0" | ||||||
| thiserror = "1" | thiserror = "1" | ||||||
| anyhow = "1" | anyhow = "1" | ||||||
| sqlx = { version = "0.6", features = [  "runtime-async-std-native-tls", "sqlite" ] } |  | ||||||
| async-std = { version = "1", features = [ "attributes" ] } |  | ||||||
| clap = { version = "4.3.2" , features = [ "derive" ] } | clap = { version = "4.3.2" , features = [ "derive" ] } | ||||||
|  | rusqlite = { version = "0.29", features = [ "bundled" ] } | ||||||
|  | async-std = { version = "1", features = [ "attributes" ] } | ||||||
| @ -5,6 +5,7 @@ create table if not exists task | |||||||
|     id integer primary key autoincrement, |     id integer primary key autoincrement, | ||||||
|     title text not null, |     title text not null, | ||||||
|     description text not null, |     description text not null, | ||||||
|  |     sort_order integer not null default 0, | ||||||
|     column_id integer, |     column_id integer, | ||||||
|     foreign key (column_id) references kb_column(id) |     foreign key (column_id) references kb_column(id) | ||||||
| ); | ); | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/app.rs
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/app.rs
									
									
									
									
									
								
							| @ -1,13 +1,15 @@ | |||||||
| // use indexmap::IndexMap;
 | // use indexmap::IndexMap;
 | ||||||
| // use int_enum::IntEnum;
 | // use int_enum::IntEnum;
 | ||||||
| use crate::get_all_tasks; | // use crate::get_all_tasks;
 | ||||||
|  | use rusqlite::Connection; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use sqlx::SqlitePool; |  | ||||||
| use std::cmp::min; | use std::cmp::min; | ||||||
| use std::fs::File; | use std::fs::File; | ||||||
| use std::io::Read; | use std::io::Read; | ||||||
| use tui_textarea::TextArea; | use tui_textarea::TextArea; | ||||||
| 
 | 
 | ||||||
|  | use crate::get_all_tasks; | ||||||
|  | 
 | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests; | mod tests; | ||||||
| 
 | 
 | ||||||
| @ -18,7 +20,7 @@ pub struct Column { | |||||||
|     pub tasks: Vec<Task>, |     pub tasks: Vec<Task>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Clone, Default, Deserialize, Serialize, Debug, sqlx::FromRow)] | #[derive(Clone, Default, Deserialize, Serialize, Debug)] | ||||||
| pub struct Task { | pub struct Task { | ||||||
|     pub title: String, |     pub title: String, | ||||||
|     pub description: String, |     pub description: String, | ||||||
| @ -69,7 +71,7 @@ impl Default for TaskState<'_> { | |||||||
| 
 | 
 | ||||||
| pub struct State<'a> { | pub struct State<'a> { | ||||||
|     pub project: Project, |     pub project: Project, | ||||||
|     pub db_pool: SqlitePool, |     pub db_pool: Connection, | ||||||
|     pub quit: bool, |     pub quit: bool, | ||||||
|     pub columns: Vec<Column>, |     pub columns: Vec<Column>, | ||||||
|     pub task_edit_state: Option<TaskState<'a>>, |     pub task_edit_state: Option<TaskState<'a>>, | ||||||
| @ -77,7 +79,7 @@ pub struct State<'a> { | |||||||
| 
 | 
 | ||||||
| impl State<'_> { | impl State<'_> { | ||||||
|     #[must_use] |     #[must_use] | ||||||
|     pub fn new(db_pool: SqlitePool, project: Project) -> Self { |     pub fn new(db_pool: Connection, project: Project) -> Self { | ||||||
|         State { |         State { | ||||||
|             quit: false, |             quit: false, | ||||||
|             task_edit_state: None, |             task_edit_state: None, | ||||||
| @ -180,8 +182,8 @@ impl Project { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn load2(pool: &SqlitePool) -> Result<Self, KanbanError> { |     pub async fn load2(pool: &Connection) -> Result<Self, KanbanError> { | ||||||
|         let todos = get_all_tasks(&pool).await.unwrap(); |         let todos = get_all_tasks(&pool).unwrap(); | ||||||
| 
 | 
 | ||||||
|         Ok(Project { |         Ok(Project { | ||||||
|             name: String::from("Kanban Board"), |             name: String::from("Kanban Board"), | ||||||
|  | |||||||
							
								
								
									
										84
									
								
								src/db.rs
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								src/db.rs
									
									
									
									
									
								
							| @ -1,30 +1,76 @@ | |||||||
| use crate::app::Task; | use crate::{Task}; | ||||||
| use sqlx::SqlitePool; | use rusqlite::{Connection, Result}; | ||||||
| 
 | 
 | ||||||
| pub async fn get_tasks_by_column(pool: &SqlitePool, column_name: &String) -> Option<Vec<Task>> { | pub fn get_tasks_by_column(conn: &Connection, column_name: &String) -> Result<Vec<Task>> { | ||||||
|     sqlx::query_as!( |     let mut stmt = conn.prepare( | ||||||
|         Task, |  | ||||||
|         r#" |         r#" | ||||||
|             select title, description from task |             select title, description from task | ||||||
|             join kb_column on column_id = kb_column.id |             join kb_column on column_id = kb_column.id | ||||||
|             where kb_column.name = ?1 |             where kb_column.name = ?1 | ||||||
|         "#,
 |         "#,
 | ||||||
|         column_name |     )?; | ||||||
|     ) |     let mut tasks = Vec::new(); | ||||||
|     .fetch_all(pool) |     let rows = stmt.query_map(&[column_name], |row| { | ||||||
|     .await |         Ok(Task { | ||||||
|     .ok() |             title: row.get(0)?, | ||||||
|  |             description: row.get(1)?, | ||||||
|  |         }) | ||||||
|  |     })?; | ||||||
|  |     for row in rows { | ||||||
|  |         tasks.push(row?); | ||||||
|  |     } | ||||||
|  |     Ok(tasks) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub async fn get_all_tasks(pool: &SqlitePool) -> Option<Vec<(String, Vec<Task>)>> { | pub fn get_all_tasks(conn: &Connection) -> Result<Vec<(String, Vec<Task>)>> { | ||||||
|     let columns = sqlx::query!("select name from kb_column") |     let mut stmt = conn.prepare("select name from kb_column")?; | ||||||
|         .fetch_all(pool) |     let columns = stmt.query_map((), |row| { | ||||||
|         .await |         Ok(row.get::<usize, String>(0)?) | ||||||
|         .unwrap(); |     })?; | ||||||
|     let mut tasks_by_column: Vec<(String, Vec<Task>)> = Vec::with_capacity(columns.len()); |     let mut tasks_by_column: Vec<(String, Vec<Task>)> = Vec::new(); | ||||||
|     for col in columns { |     for col in columns { | ||||||
|         let tasks = get_tasks_by_column(pool, &col.name).await.unwrap(); |         let name = &col?; | ||||||
|         tasks_by_column.push((col.name, tasks)); |         let tasks = get_tasks_by_column(conn, name).unwrap(); | ||||||
|  |         tasks_by_column.push((name.to_string(), tasks)); | ||||||
|     } |     } | ||||||
|     Some(tasks_by_column) |     Ok(tasks_by_column) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // pub async fn insert_new_task(pool: &SqlitePool, task: &Task, column: &Column) {
 | ||||||
|  | //     // TODO: You have to add the id to the column
 | ||||||
|  | //     sqlx::query!("insert into task(title, description, column_id) values (?1, ?2, ?3)", task.title, task.description, 1)
 | ||||||
|  | //         .execute(pool)
 | ||||||
|  | //         .await
 | ||||||
|  | //         .unwrap();
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // pub async fn update_task(pool: &SqlitePool, task: &Task) {
 | ||||||
|  | //     sqlx::query!("update task set title = ?1, description = ?2", task.title, task.description)
 | ||||||
|  | //         .execute(pool)
 | ||||||
|  | //         .await
 | ||||||
|  | //         .unwrap();
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // pub async fn move_task_to_column(pool: &SqlitePool, task: &Task, target_column: &Column) {
 | ||||||
|  | //     // TODO: You have to add the id to the column
 | ||||||
|  | //     sqlx::query!("update task set column_id = ?1", 1)
 | ||||||
|  | //         .execute(pool)
 | ||||||
|  | //         .await
 | ||||||
|  | //         .unwrap();
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // pub async fn move_task_order(pool: &SqlitePool, task: &Task) {
 | ||||||
|  | //     // TODO: We have to add some kind of ordering mechanism to tasks
 | ||||||
|  | //     sqlx::query!("update task set column_id = ?1", 1)
 | ||||||
|  | //         .execute(pool)
 | ||||||
|  | //         .await
 | ||||||
|  | //         .unwrap();
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | // pub async fn delete_task(pool: &SqlitePool, task: &Task) {
 | ||||||
|  | //     // TODO: We have to add ids to tasks
 | ||||||
|  | //     sqlx::query!("delete from task where id = ?1", 1)
 | ||||||
|  | //         .execute(pool)
 | ||||||
|  | //         .await
 | ||||||
|  | //         .unwrap();
 | ||||||
|  | // }
 | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ use crossterm::{ | |||||||
|     terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, |     terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, | ||||||
| }; | }; | ||||||
| use kanban_tui::{Project, State}; | use kanban_tui::{Project, State}; | ||||||
| use sqlx::sqlite::SqlitePool; | use rusqlite::Connection; | ||||||
| use std::{ | use std::{ | ||||||
|     error::Error, |     error::Error, | ||||||
|     fs::{File, OpenOptions}, |     fs::{File, OpenOptions}, | ||||||
| @ -87,8 +87,9 @@ async fn main() -> anyhow::Result<(), Box<dyn Error>> { | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let db_pool = SqlitePool::connect("sqlite:db.sqlite").await?; |     let db_pool = Connection::open("db.sqlite")?; | ||||||
| 
 | 
 | ||||||
|  |     // let project = Project::load(_filepath, &_file)?;
 | ||||||
|     let project = Project::load2(&db_pool).await?; |     let project = Project::load2(&db_pool).await?; | ||||||
|     let mut state = State::new(db_pool, project); |     let mut state = State::new(db_pool, project); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user