-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fixed and refactored all of backend and parts of frontend that were a…
…ffected (basically all pieces calling tauri commands and some small ones using state variables here and there)
- Loading branch information
1 parent
9039211
commit 280b1a5
Showing
4 changed files
with
514 additions
and
671 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,143 @@ | ||
use std::fs; | ||
use std::path::Path; | ||
use std::{fs, path::Path, sync::{Arc, Mutex}}; | ||
use chrono::Local; | ||
use rusqlite::{Connection, params, Result as SQLiteResult}; | ||
|
||
use tauri::AppHandle; | ||
use crate::db::todos::commands::ROOT_GROUP as TODO_ROOT_GROUP; | ||
|
||
const DB_NAME: &str = "database.sqlite"; | ||
pub type DbConn = Arc<Mutex<Connection>>; | ||
|
||
// Initializer struct so that we don't pass AppHandle separately to all helper functions. | ||
pub struct DbInitializer { | ||
pub app_handle: AppHandle, | ||
} | ||
pub fn init(path: &str) -> Connection { | ||
if !db_exists(path) { | ||
create_db(path); | ||
} | ||
|
||
// TODO conditional path for diff OS | ||
let db_name = format!("{path}/database.sqlite"); | ||
|
||
impl DbInitializer { | ||
pub fn new(app_handle: AppHandle) -> Self { | ||
Self { app_handle } | ||
match Connection::open(db_name) { | ||
Ok(conn) => conn, | ||
Err(e) => panic!("[ERROR] {e}"), | ||
} | ||
} | ||
|
||
pub fn init(self) -> Self { | ||
if !self.db_file_exists() { | ||
self.create_db_file(); | ||
} | ||
// Creation functions. | ||
fn db_exists(path: &str) -> bool { | ||
Path::new(path).exists() | ||
} | ||
|
||
self | ||
fn create_db(path: &str) { | ||
let db_dir = Path::new(&path).parent().unwrap(); | ||
|
||
// If the parent directory does not exist, create it. | ||
if !db_dir.exists() { | ||
fs::create_dir_all(db_dir).unwrap(); | ||
} | ||
|
||
// Create the database file. | ||
fn create_db_file(&self) { | ||
let db_path = self.get_db_path(); | ||
let db_dir = Path::new(&db_path).parent().unwrap(); | ||
fs::File::create(path).unwrap(); | ||
} | ||
|
||
// If the parent directory does not exist, create it. | ||
if !db_dir.exists() { | ||
fs::create_dir_all(db_dir).unwrap(); | ||
} | ||
// Setup functions (to be called in main.rs). | ||
pub fn create_tables(conn: &Connection) -> SQLiteResult<()> { | ||
// TODAY | ||
conn.execute( | ||
"CREATE TABLE IF NOT EXISTS today ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
name TEXT NOT NULL, | ||
type TEXT NOT NULL, | ||
is_active INTEGER, | ||
parent_group_id INTEGER, | ||
created_at DATE DEFAULT (datetime('now','localtime')) NOT NULL | ||
)", | ||
[], | ||
)?; | ||
// Only add the root group when the table is created for the first time. | ||
conn.execute( | ||
&format!("INSERT INTO today (id, name, type) VALUES (0, '{TODO_ROOT_GROUP}', 'TaskGroup') ON CONFLICT DO NOTHING"), | ||
[], | ||
)?; | ||
|
||
// Create the database file. | ||
fs::File::create(db_path).unwrap(); | ||
} | ||
// TOMORROW. | ||
conn.execute( | ||
"CREATE TABLE IF NOT EXISTS tomorrow ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
name TEXT NOT NULL, | ||
type TEXT NOT NULL, | ||
is_active INTEGER, | ||
parent_group_id INTEGER | ||
)", | ||
[], | ||
)?; | ||
// Only add the root group when the table is created for the first time. | ||
conn.execute( | ||
&format!("INSERT INTO tomorrow (id, name, type) VALUES (0, '{TODO_ROOT_GROUP}', 'TaskGroup') ON CONFLICT DO NOTHING"), | ||
[], | ||
)?; | ||
|
||
// Check whether the database file exists. | ||
fn db_file_exists(&self) -> bool { | ||
let db_path = self.get_db_path(); | ||
let res = Path::new(&db_path).exists(); | ||
conn.execute( | ||
"CREATE TABLE IF NOT EXISTS migration_log ( | ||
date TEXT PRIMARY KEY | ||
)", | ||
[], | ||
)?; | ||
|
||
return res; | ||
} | ||
Ok(()) | ||
} | ||
|
||
pub fn migrate_todos(conn: &Connection) -> SQLiteResult<()> { | ||
let today = Local::now().naive_local().date(); | ||
|
||
let last_migration_date: Option<String> = | ||
match conn | ||
.query_row("SELECT MAX(date) FROM migration_log", [], |row| row.get(0)) | ||
{ | ||
Ok(latest_date) => latest_date, | ||
Err(err) => panic!("{err}"), | ||
}; | ||
|
||
if last_migration_date != Some(today.to_string()) { | ||
// Delete completed tasks from today. | ||
conn | ||
.execute("DELETE FROM today WHERE is_active=0", [])?; | ||
|
||
let max_id: Option<i64> = | ||
match conn | ||
.query_row("SELECT MAX(id) from today", [], |row| row.get(0)) | ||
{ | ||
Ok(val) => val, | ||
Err(err) => panic!("{err}"), | ||
}; | ||
|
||
/// Get the path where the database file should be located. | ||
/// For Linux and macOS only. | ||
pub fn get_db_path(&self) -> String { | ||
let mut res = String::from(""); | ||
let app = &self.app_handle; | ||
if let Some(path) = app.path_resolver().app_data_dir() { | ||
if std::env::consts::OS == "windows" { | ||
res = format!("{}\\{DB_NAME}", path.to_string_lossy().into_owned()); | ||
} else { | ||
res = format!("{}/{DB_NAME}", path.to_string_lossy().into_owned()); | ||
} | ||
} | ||
|
||
res | ||
// Update ids of all tasks in tomorrow so that uniqueness is maintained. | ||
conn.execute( | ||
"UPDATE tomorrow SET id=id+(?1) WHERE id!=0", | ||
params![max_id], | ||
)?; | ||
|
||
// Update parent_group_ids of all migrated rows. | ||
conn.execute( | ||
"UPDATE tomorrow SET parent_group_id=parent_group_id+(?1) WHERE parent_group_id!=0", | ||
params![max_id], | ||
)?; | ||
|
||
// Migrate tasks | ||
conn.execute( | ||
&format!("INSERT INTO today (id, name, type, is_active, parent_group_id) | ||
SELECT id, name, type, is_active, parent_group_id FROM tomorrow WHERE name!='{TODO_ROOT_GROUP}'"), | ||
[], | ||
)?; | ||
|
||
// Clear tomorrow's tasks | ||
conn.execute( | ||
&format!("DELETE FROM tomorrow WHERE name!='{TODO_ROOT_GROUP}'"), | ||
[], | ||
)?; | ||
} | ||
// Log the migration | ||
conn.execute( | ||
"INSERT INTO migration_log (date) VALUES (?1) ON CONFLICT DO NOTHING", | ||
params![today.to_string()], | ||
)?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
pub mod ops; | ||
pub mod init; | ||
pub mod init; | ||
pub mod todos; |
Oops, something went wrong.