From 9ffdfa1a7762737925f477a5539aefbf73bf9fb6 Mon Sep 17 00:00:00 2001 From: Julian Mutter Date: Fri, 2 Feb 2024 16:27:45 +0100 Subject: [PATCH] Improve database, add log and cli --- Cargo.lock | 180 +++++++++++++++++++++++++++++++++++ Cargo.toml | 4 + db-migrations/0_creation.sql | 2 + src/database.rs | 85 +++++++---------- src/main.rs | 17 +++- 5 files changed, 230 insertions(+), 58 deletions(-) create mode 100644 db-migrations/0_creation.sql diff --git a/Cargo.lock b/Cargo.lock index 571f7ea..d311a15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,12 +30,69 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.79" @@ -233,6 +290,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "const-oid" version = "0.9.6" @@ -341,6 +444,19 @@ dependencies = [ "serde", ] +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -922,6 +1038,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.5.0" @@ -942,6 +1064,17 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "itertools" version = "0.12.1" @@ -1439,11 +1572,34 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + [[package]] name = "regex-automata" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "relm4" @@ -1642,7 +1798,10 @@ name = "sheet-organizer" version = "0.1.0" dependencies = [ "blake3", + "clap", "dotenvy", + "env_logger", + "log", "opener", "relm4", "relm4-components", @@ -1945,6 +2104,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.5.0" @@ -2005,6 +2170,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.56" @@ -2234,6 +2408,12 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 09ce102..604042e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,10 @@ relm4-icons = { version = "0.6.0", features = ["plus"] } walkdir = "2" # For traversing directories recursively opener = "0.6.1" # For opening files with the systems default application +log = "0.4.20" +env_logger = "0.10.1" +clap = { version = "4.4.6", features = ["derive"] } + sqlx = { version = "0.7", features = [ "runtime-tokio", "sqlite", "migrate", "macros" ] } tokio = { version = "1", features = ["full"] } blake3 = "1.5.0" diff --git a/db-migrations/0_creation.sql b/db-migrations/0_creation.sql new file mode 100644 index 0000000..90cc619 --- /dev/null +++ b/db-migrations/0_creation.sql @@ -0,0 +1,2 @@ +CREATE TABLE IF NOT EXISTS sheets (name TEXT, path TEXT, file_size INTEGER, file_hash TEXT); +CREATE TABLE IF NOT EXISTS composers (name TEXT, id INTEGER); diff --git a/src/database.rs b/src/database.rs index af546ca..d830f04 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,5 +1,6 @@ use std::{fs, path::PathBuf}; +use log::debug; use sqlx::{migrate::MigrateDatabase, Connection, Sqlite, SqliteConnection, SqlitePool}; #[derive(sqlx::FromRow, Debug)] @@ -44,76 +45,54 @@ impl Sheet { } pub struct Database { - connection: Option, + connection: SqlitePool, } impl Database { - pub fn new() -> Self { - Database { connection: None } + pub async fn setup(database_path: &str) -> sqlx::Result { + let connection = Database::create_connection(database_path).await?; + sqlx::migrate!("./db-migrations").run(&connection).await?; + Ok(Database { connection }) } - pub async fn init_connection(&mut self, database_path: &str) -> sqlx::Result<()> { + async fn create_connection(database_path: &str) -> sqlx::Result { if !Sqlite::database_exists(database_path) .await .unwrap_or(false) { match Sqlite::create_database(database_path).await { - Ok(_) => println!("Database created"), - Err(e) => println!("Error creating database: {}", e), + Ok(_) => debug!("Database created"), + Err(e) => { + debug!("Error creating database: {}", e); + return Err(e); + } } - } else { - println!("Database already exists"); } let connection = SqlitePool::connect(database_path).await?; - self.connection = Some(connection); - Ok(()) + debug!("Connected to database"); + Ok(connection) } - pub async fn setup_db(&mut self) -> sqlx::Result<()> { - // TODO: put this in migrations - if let Some(connection) = &self.connection { - sqlx::query!(" - CREATE TABLE IF NOT EXISTS sheets (name TEXT, path TEXT, file_size INTEGER, file_hash TEXT); - CREATE TABLE IF NOT EXISTS composers (name TEXT, id INTEGER); - ").execute(connection).await?; - } - Ok(()) + pub async fn insert_sheet(&self, sheet: Sheet) -> sqlx::Result<()> { + sqlx::query!( + " + INSERT INTO sheets (name, path, file_size, file_hash) + VALUES ($1, $2, $3, $4) + ", + sheet.name, + sheet.path, + sheet.file_size, + sheet.file_hash, + ) + .execute(&self.connection) + .await + .map(|_| ()) } - pub async fn insert_sheet(&mut self, sheet: Sheet) -> sqlx::Result<()> { - if let Some(connection) = &self.connection { - // let path = sheet.path.to_str().unwrap().to_string(); - // let size = sheet.file_size as i64; - - let result = sqlx::query!( - " - INSERT INTO sheets (name, path, file_size, file_hash) - VALUES ($1, $2, $3, $4) - ", - sheet.name, - sheet.path, - sheet.file_size, - sheet.file_hash, - ) - .execute(connection) - .await; - result.unwrap(); - println!("Inserted!!!"); - } - Ok(()) - } - - pub async fn fetch_all_sheets(&mut self) -> sqlx::Result> { - if let Some(connection) = &self.connection { - // return sqlx::query_as!(Sheet, "SELECT * FROM sheets") - // .fetch_all(connection) - // .await; - return sqlx::query_as::<_, Sheet>("SELECT * FROM sheets") - .fetch_all(connection) - .await; - // return sqlx::query_as("SELECT * FROM sheets").fetch_all(connection).await; - } - Ok(Vec::new()) + pub async fn fetch_all_sheets(&self) -> sqlx::Result> { + sqlx::query_as::<_, Sheet>("SELECT * FROM sheets") + .fetch_all(&self.connection) + .await } } diff --git a/src/main.rs b/src/main.rs index d22d3b8..0a2bfbb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,13 @@ mod sheet_listing; use std::{env, path::PathBuf, process}; +use clap::Parser; use database::Database; +use env_logger::Env; use gtk::prelude::*; use mcdu::McduModel; use relm4::prelude::*; use sheet_listing::{SheetListingInput, SheetListingModel}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::database::Sheet; @@ -94,13 +95,19 @@ impl SimpleComponent for AppModel { } } +#[derive(Parser)] +#[command(author, version, about)] +struct Cli { + directory: Option, +} + #[tokio::main] async fn main() { - dotenvy::dotenv().unwrap(); + // dotenvy::dotenv().unwrap(); + env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init(); + let cli = Cli::parse(); - let mut database = Database::new(); - database.init_connection("./testdb.db").await.unwrap(); - database.setup_db().await.unwrap(); + let database = Database::setup("./testdb.db").await.unwrap(); database.insert_sheet(Sheet::new_debug()).await.unwrap(); let sheets = database.fetch_all_sheets().await.unwrap();