First try of implementing database

This commit is contained in:
Julian Mutter 2024-02-02 09:18:45 +01:00
parent 7217ce8bc1
commit 4b6418c23a
6 changed files with 1284 additions and 20 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
DATABASE_URL=sqlite://testdb.db

1
.rustfmt.toml Normal file
View File

@ -0,0 +1 @@
edition = "2021"

1157
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,3 +16,11 @@ 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
sqlx = { version = "0.7", features = [ "runtime-tokio", "sqlite", "migrate", "macros" ] }
tokio = { version = "1", features = ["full"] }
blake3 = "1.5.0"
dotenvy = "0.15.7"
[profile.dev.package.sqlx-macros]
opt-level = 3

119
src/database.rs Normal file
View File

@ -0,0 +1,119 @@
use std::{fs, path::PathBuf};
use sqlx::{migrate::MigrateDatabase, Connection, Sqlite, SqliteConnection, SqlitePool};
#[derive(sqlx::FromRow, Debug)]
pub struct Sheet {
name: String,
// #[sqlx(from = "String")]
path: String,
// #[sqlx(from = "i64")]
file_size: i32,
file_hash: String,
}
#[derive(sqlx::FromRow)]
pub struct Composer {
name: String,
id: u32,
}
impl Sheet {
pub fn new_debug() -> Self {
Sheet {
name: "Hello world".to_string(),
path: "This/is/my/path".into(),
file_size: 42,
file_hash: "h4sh".to_string(),
}
}
pub fn verify_path(&self) -> std::io::Result<bool> {
// First compare file size since it is faster than hashing
// let file_size = fs::metadata(&self.path)?.len();
// if file_size == self.file_size {
// let file_content = fs::read(&self.path)?;
// let file_hash = blake3::hash(&file_content);
// if file_hash.to_string() == self.file_hash {
// return Ok(true);
// }
// }
Ok(false)
}
}
pub struct Database {
connection: Option<SqlitePool>,
}
impl Database {
pub fn new() -> Self {
Database { connection: None }
}
pub async fn init_connection(&mut self, 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),
}
} else {
println!("Database already exists");
}
let connection = SqlitePool::connect(database_path).await?;
self.connection = Some(connection);
Ok(())
}
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(&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<Vec<Sheet>> {
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())
}
}

View File

@ -1,12 +1,17 @@
mod database;
mod mcdu;
mod sheet_listing;
use std::{env, path::PathBuf, process};
use database::Database;
use gtk::prelude::*;
use mcdu::McduModel;
use relm4::prelude::*;
use sheet_listing::{SheetListingInput, SheetListingModel};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use crate::database::Sheet;
struct AppModel {
mcdu: Controller<McduModel>,
@ -89,7 +94,18 @@ impl SimpleComponent for AppModel {
}
}
fn main() {
#[tokio::main]
async fn main() {
dotenvy::dotenv().unwrap();
let mut database = Database::new();
database.init_connection("./testdb.db").await.unwrap();
database.setup_db().await.unwrap();
database.insert_sheet(Sheet::new_debug()).await.unwrap();
let sheets = database.fetch_all_sheets().await.unwrap();
println!("Sheets: {:?}", sheets);
let app = RelmApp::new("de.frajul.sheet-organizer");
let args: Vec<String> = env::args().collect();