Run migrations on first creation, fix a bunch of panics
This commit is contained in:
parent
6cbba10325
commit
7fe20e6ae8
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@
|
|||||||
/kanban.json
|
/kanban.json
|
||||||
/db.sqlite
|
/db.sqlite
|
||||||
/kanban.db
|
/kanban.db
|
||||||
|
/sql/queries.sql
|
||||||
|
@ -20,7 +20,8 @@ create table if not exists kb_column
|
|||||||
|
|
||||||
create table if not exists setting
|
create table if not exists setting
|
||||||
(
|
(
|
||||||
id integer primary key autoincrement,
|
key text not null primary key,
|
||||||
name text not null,
|
|
||||||
value text not null
|
value text not null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
insert into kb_column(name) values ("Todo"),("InProgress"),("Done"),("Ideas");
|
@ -145,7 +145,7 @@ impl<'a> Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_last_task(&mut self) {
|
pub fn select_last_task(&mut self) {
|
||||||
self.selected_task_idx = self.tasks.len() - 1;
|
self.selected_task_idx = self.tasks.len().saturating_sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_task_up(&mut self) -> bool {
|
pub fn move_task_up(&mut self) -> bool {
|
||||||
@ -160,7 +160,7 @@ impl<'a> Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_task_down(&mut self) -> bool {
|
pub fn move_task_down(&mut self) -> bool {
|
||||||
if self.selected_task_idx < self.tasks.len() - 1 {
|
if self.selected_task_idx < self.tasks.len().saturating_sub(1) {
|
||||||
self.tasks
|
self.tasks
|
||||||
.swap(self.selected_task_idx, self.selected_task_idx + 1);
|
.swap(self.selected_task_idx, self.selected_task_idx + 1);
|
||||||
self.selected_task_idx += 1;
|
self.selected_task_idx += 1;
|
||||||
|
@ -83,9 +83,10 @@ pub fn move_task_to_column(conn: &Connection, task: &Task, target_column: &Colum
|
|||||||
"update task
|
"update task
|
||||||
set
|
set
|
||||||
column_id = ?2,
|
column_id = ?2,
|
||||||
sort_order = 1 +
|
sort_order = coalesce(1 +
|
||||||
(select sort_order from task
|
(select sort_order from task
|
||||||
where column_id = ?2 order by sort_order desc limit 1)
|
where column_id = ?2 order by sort_order desc limit 1),
|
||||||
|
0)
|
||||||
where task.id = ?1",
|
where task.id = ?1",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -78,17 +78,21 @@ pub fn handle(state: &mut State<'_>) -> Result<(), std::io::Error> {
|
|||||||
KeyCode::Char('g') => column.select_first_task(),
|
KeyCode::Char('g') => column.select_first_task(),
|
||||||
KeyCode::Char('G') => column.select_last_task(),
|
KeyCode::Char('G') => column.select_last_task(),
|
||||||
KeyCode::Char('H') => {
|
KeyCode::Char('H') => {
|
||||||
|
if !column.tasks.is_empty() {
|
||||||
project.move_task_previous_column();
|
project.move_task_previous_column();
|
||||||
let col = project.get_selected_column();
|
let col = project.get_selected_column();
|
||||||
let t = col.get_selected_task().unwrap();
|
let t = col.get_selected_task().unwrap();
|
||||||
db::move_task_to_column(&state.db_conn, &t, &col);
|
db::move_task_to_column(&state.db_conn, &t, &col);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
KeyCode::Char('L') => {
|
KeyCode::Char('L') => {
|
||||||
|
if !column.tasks.is_empty() {
|
||||||
project.move_task_next_column();
|
project.move_task_next_column();
|
||||||
let col = project.get_selected_column();
|
let col = project.get_selected_column();
|
||||||
let t = col.get_selected_task().unwrap();
|
let t = col.get_selected_task().unwrap();
|
||||||
db::move_task_to_column(&state.db_conn, &t, &col);
|
db::move_task_to_column(&state.db_conn, &t, &col);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
KeyCode::Char('J') => {
|
KeyCode::Char('J') => {
|
||||||
if column.move_task_down() {
|
if column.move_task_down() {
|
||||||
let task1 = column.get_selected_task().unwrap();
|
let task1 = column.get_selected_task().unwrap();
|
||||||
@ -108,9 +112,11 @@ pub fn handle(state: &mut State<'_>) -> Result<(), std::io::Error> {
|
|||||||
state.task_edit_state = column.get_task_state_from_curr_selected_task()
|
state.task_edit_state = column.get_task_state_from_curr_selected_task()
|
||||||
}
|
}
|
||||||
KeyCode::Char('D') => {
|
KeyCode::Char('D') => {
|
||||||
|
if !column.tasks.is_empty() {
|
||||||
db::delete_task(&state.db_conn, column.get_selected_task().unwrap());
|
db::delete_task(&state.db_conn, column.get_selected_task().unwrap());
|
||||||
column.remove_task();
|
column.remove_task();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
22
src/main.rs
22
src/main.rs
@ -15,18 +15,32 @@ use tui::Terminal;
|
|||||||
/// kanban-tui is a simple, interactive TUI based task manager using kanban columns
|
/// kanban-tui is a simple, interactive TUI based task manager using kanban columns
|
||||||
pub struct CliArgs {
|
pub struct CliArgs {
|
||||||
#[arg(value_name="DATABASE", value_hint=FilePath, index=1)]
|
#[arg(value_name="DATABASE", value_hint=FilePath, index=1)]
|
||||||
/// Path to the
|
/// Path to the SQLite database
|
||||||
pub filepath: Option<PathBuf>,
|
pub filepath: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: We either make everything async or we remove the dependency
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() -> anyhow::Result<(), Box<dyn Error>> {
|
async fn main() -> anyhow::Result<(), Box<dyn Error>> {
|
||||||
let dbpath = CliArgs::parse()
|
let dbpath = CliArgs::parse()
|
||||||
.filepath
|
.filepath
|
||||||
.map(PathBuf::into_os_string)
|
.unwrap_or(PathBuf::from("./kanban.db"));
|
||||||
.unwrap_or("kanban.db".into());
|
|
||||||
|
|
||||||
let conn = Connection::open(dbpath)?;
|
let migrate = !dbpath.exists();
|
||||||
|
|
||||||
|
let mut conn = Connection::open(dbpath)?;
|
||||||
|
|
||||||
|
if migrate {
|
||||||
|
let migrations = include_str!("../sql/migrations.sql");
|
||||||
|
let migrations: Vec<&str> = migrations.split(";").collect();
|
||||||
|
let tx = conn.transaction()?;
|
||||||
|
for m in migrations {
|
||||||
|
if !m.trim().is_empty() {
|
||||||
|
tx.execute(m, ())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tx.commit()?;
|
||||||
|
}
|
||||||
|
|
||||||
let project = Project::load(&conn).await?;
|
let project = Project::load(&conn).await?;
|
||||||
let mut state = State::new(conn, project);
|
let mut state = State::new(conn, project);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user