diff --git a/Cargo.lock b/Cargo.lock index 9e193ee..ea50239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,7 +24,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", "zerocopy", @@ -827,7 +826,7 @@ checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" dependencies = [ "darling", "either", - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.77", @@ -1181,22 +1180,13 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.5.0" @@ -1510,9 +1500,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -2553,6 +2543,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -2605,9 +2598,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2618,23 +2611,23 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" dependencies = [ - "ahash", "atoi", "byteorder", "bytes", "crc", "crossbeam-queue", "either", - "event-listener 2.5.3", + "event-listener 5.3.1", "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", + "hashbrown 0.14.5", "hashlink", "hex", "indexmap 2.5.0", @@ -2657,26 +2650,26 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] name = "sqlx-macros-core" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", "hex", "once_cell", "proc-macro2", @@ -2686,8 +2679,9 @@ dependencies = [ "sha2", "sqlx-core", "sqlx-mysql", + "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", + "syn 2.0.77", "tempfile", "tokio", "url", @@ -2695,12 +2689,12 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "byteorder", "bytes", @@ -2737,12 +2731,12 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bitflags 2.6.0", "byteorder", "crc", @@ -2775,9 +2769,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.4" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" dependencies = [ "atoi", "flume", @@ -2790,10 +2784,10 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", "tracing", "url", - "urlencoding", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1e6a79a..197c7cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ zstd = "0.12.4" serde_json = "1.0.104" fastrand = "2.0.0" rfd = { version = "0.12.1", features = ["xdg-portal"], default-features = false } -sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio"] } +sqlx = { version = "0.8.2", features = ["sqlite", "runtime-tokio", "macros"] } tokio = { version = "1.32.0", features = ["full"] } tracing-subscriber = { version = "0.3.17", features = ["fmt", "std", "chrono", "time", "local-time", "env-filter"] } tracing = "0.1.37" diff --git a/src/rust/songs/song_model.rs b/src/rust/songs/song_model.rs index 322bab5..945b897 100644 --- a/src/rust/songs/song_model.rs +++ b/src/rust/songs/song_model.rs @@ -243,12 +243,13 @@ pub mod song_model { use crate::models::*; use crate::schema::songs::dsl::*; use crate::songs::song_editor::song_editor::QList_QString; -use cxx_qt::CxxQtType; +use cxx_qt::{CxxQtType, Threading}; use cxx_qt_lib::{ QByteArray, QModelIndex, QString, QStringList, QVariant, }; -use diesel::sqlite::SqliteConnection; +// use diesel::sqlite::SqliteConnection; use diesel::{delete, insert_into, prelude::*, update}; +use sqlx::{query, query_as, Connection, SqliteConnection}; use std::collections::HashMap; use std::pin::Pin; use std::slice::Iter; @@ -294,6 +295,7 @@ pub struct SongModelRust { highest_id: i32, songs: Vec, inner_songs: Vec, + db: SqliteConnection, } impl song_model::SongModel { @@ -306,97 +308,7 @@ impl song_model::SongModel { } pub fn setup(mut self: Pin<&mut Self>) { - let db = &mut self.as_mut().get_db(); - run_migrations(db); - let results = songs - .load::(db) - .expect("NO TABLE?????????????"); - self.as_mut().rust_mut().highest_id = 0; - - println!("SHOWING SONGS"); - println!("--------------"); - for song in results { - println!("{}", song.title); - println!("{}", song.id); - println!( - "{}", - song.background.clone().unwrap_or_default() - ); - println!("--------------"); - if self.as_mut().highest_id < song.id { - self.as_mut().rust_mut().highest_id = song.id; - } - - let song = Song { - id: song.id, - title: song.title, - lyrics: song.lyrics.unwrap_or_default(), - author: song.author.unwrap_or_default(), - ccli: song.ccli.unwrap_or_default(), - audio: song.audio.unwrap_or_default(), - verse_order: song.verse_order.unwrap_or_default(), - background: song.background.unwrap_or_default(), - background_type: song - .background_type - .unwrap_or_default(), - horizontal_text_alignment: song - .horizontal_text_alignment - .unwrap_or_default(), - vertical_text_alignment: song - .vertical_text_alignment - .unwrap_or_default(), - font: song.font.unwrap_or_default(), - font_size: song.font_size.unwrap_or_default(), - }; - - self.as_mut().add_song(song); - } - println!("--------------------------------------"); - println!("{:?}", self.as_mut().songs); - println!("--------------------------------------"); - } - - pub fn remove_item(mut self: Pin<&mut Self>, index: i32) -> bool { - if index < 0 || (index as usize) >= self.songs.len() { - return false; - } - let db = &mut self.as_mut().get_db(); - - let song_id = self.songs.get(index as usize).unwrap().id; - - let result = delete(songs.filter(id.eq(song_id))).execute(db); - - match result { - Ok(_i) => { - unsafe { - self.as_mut().begin_remove_rows( - &QModelIndex::default(), - index, - index, - ); - self.as_mut() - .rust_mut() - .songs - .remove(index as usize); - self.as_mut() - .rust_mut() - .inner_songs - .remove(index as usize); - self.as_mut().end_remove_rows(); - } - println!("removed-item-at-index: {:?}", song_id); - println!("new-Vec: {:?}", self.as_mut().songs); - true - } - Err(_e) => { - println!("Cannot connect to database"); - false - } - } - } - - fn get_db(self: Pin<&mut Self>) -> SqliteConnection { let mut data = dirs::data_local_dir().unwrap(); data.push("lumina"); data.push("library-db.sqlite3"); @@ -404,9 +316,115 @@ impl song_model::SongModel { db_url.push_str(data.to_str().unwrap()); println!("DB: {:?}", db_url); - SqliteConnection::establish(&db_url).unwrap_or_else(|_| { - panic!("error connecting to {}", db_url) - }) + static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3"; + let thread = self.qt_thread(); + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + match SqliteConnection::connect(&db_url).await { + Ok(db) => { + thread.queue(|s| s.as_mut().rust_mut().db = db); + let result = query_as!(Song, r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.as_mut().rust_mut().db).await; + match result { + Ok(s) => s.into_iter().for_each(|s| self.as_mut().add_song(s)), + Err(e) => error!("There was an error in converting songs: {e}"), + } + }, + Err(e) => error!("There was an error in the db: {e}"), + } + }); + + // run_migrations(db); + // let results = songs + // .load::(db) + // .expect("NO TABLE?????????????"); + // self.as_mut().rust_mut().highest_id = 0; + + // println!("SHOWING SONGS"); + // println!("--------------"); + // for song in results { + // println!("{}", song.title); + // println!("{}", song.id); + // println!( + // "{}", + // song.background.clone().unwrap_or_default() + // ); + // println!("--------------"); + // if self.as_mut().highest_id < song.id { + // self.as_mut().rust_mut().highest_id = song.id; + // } + + // let song = Song { + // id: song.id, + // title: song.title, + // lyrics: song.lyrics.unwrap_or_default(), + // author: song.author.unwrap_or_default(), + // ccli: song.ccli.unwrap_or_default(), + // audio: song.audio.unwrap_or_default(), + // verse_order: song.verse_order.unwrap_or_default(), + // background: song.background.unwrap_or_default(), + // background_type: song + // .background_type + // .unwrap_or_default(), + // horizontal_text_alignment: song + // .horizontal_text_alignment + // .unwrap_or_default(), + // vertical_text_alignment: song + // .vertical_text_alignment + // .unwrap_or_default(), + // font: song.font.unwrap_or_default(), + // font_size: song.font_size.unwrap_or_default(), + // }; + + // self.as_mut().add_song(song); + // } + // println!("--------------------------------------"); + // println!("{:?}", self.as_mut().songs); + // println!("--------------------------------------"); + } + + pub fn remove_item(mut self: Pin<&mut Self>, index: i32) -> bool { + if index < 0 || (index as usize) >= self.songs.len() { + return false; + } + let db = &mut self.as_mut().rust_mut().db; + + let song_id = self.songs.get(index as usize).unwrap().id; + + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + let result = query!("delete from songs where id = ?", song_id).fetch_optional(db).await; + match result { + Ok(_) => { + unsafe { + self.as_mut().begin_remove_rows( + &QModelIndex::default(), + index, + index, + ); + self.as_mut() + .rust_mut() + .songs + .remove(index as usize); + self.as_mut() + .rust_mut() + .inner_songs + .remove(index as usize); + self.as_mut().end_remove_rows(); + } + debug!("removed-item-at-index: {:?}", song_id); + true + }, + Err(e) => { + error!("There was an error deleting the row {song_id}: {e}"); + false + } + } + }); + true + } + + fn get_db(self: Pin<&mut Self>) -> SqliteConnection { + todo!() } pub fn new_song(mut self: Pin<&mut Self>) -> bool {