Skip to content

Commit

Permalink
fixed and refactored all of backend and parts of frontend that were a…
Browse files Browse the repository at this point in the history
…ffected (basically all pieces calling tauri commands and some small ones using state variables here and there)
  • Loading branch information
Piyuuussshhh committed Sep 17, 2024
1 parent 9039211 commit 280b1a5
Show file tree
Hide file tree
Showing 4 changed files with 514 additions and 671 deletions.
172 changes: 126 additions & 46 deletions src-tauri/src/db/init.rs
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(())
}
4 changes: 2 additions & 2 deletions src-tauri/src/db/mod.rs
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;
Loading

0 comments on commit 280b1a5

Please sign in to comment.