diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 99abaa02ea1eefee9bd2fc69712498d8fa4f3a84..370b76eea330a3d9b2388f6a26d62b2ca34c4f1f 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -1745,6 +1745,7 @@ dependencies = [ "commons", "diesel", "diesel_migrations", + "hashbrown 0.13.2", "kurisu_api", "lektor_c_compat", "serde", diff --git a/src/rust/lektor_db/Cargo.toml b/src/rust/lektor_db/Cargo.toml index dceba9b336cc7a91fcad9343ceec3772ae3ccd14..d1d8f3594ea72d1bd54e8228ed19e82c0b5d741c 100644 --- a/src/rust/lektor_db/Cargo.toml +++ b/src/rust/lektor_db/Cargo.toml @@ -11,6 +11,7 @@ doctest = false [dependencies] serde.workspace = true thiserror.workspace = true +hashbrown.workspace = true diesel_migrations = "2" diesel = { version = "2", default-features = false, features = ["sqlite"] } diff --git a/src/rust/lektor_db/src/connexion.rs b/src/rust/lektor_db/src/connexion.rs index efedeaf94968542dd2e5090582d37376fa7a5548..120f90b0453f029f65fc19baa2db9642ee547db4 100644 --- a/src/rust/lektor_db/src/connexion.rs +++ b/src/rust/lektor_db/src/connexion.rs @@ -1,5 +1,5 @@ -use crate::{models::*, uri::LktUri, *}; -use diesel::connection::DefaultLoadingMode; +use crate::{models::*, types::*, uri::LktUri, *}; +use hashbrown::HashMap; use kurisu_api::v1 as api_v1; /// Create a connexion to a database and run automatically the migrations. @@ -275,39 +275,52 @@ impl LktDatabaseConnection { } } + /// Get basic information about a kara, like its source, title, origin, the + /// laguages, etc. Here we don't get the kara makers as it's not an + /// essential information. + pub fn get_kara_info(&mut self, local_id: i64) -> LktDatabaseResult<KaraInfo> { + todo!("get info for kara {local_id}") + } + /// Get all infos about a kara, its metadata, its tags, repo, repo id, - /// languages, karamakers... - pub fn get_kara_info( - &mut self, - local_id: i64, - ) -> LktDatabaseResult<Vec<(String, Option<String>)>> { - let repo: String = with_dsl!(repo_kara => repo_kara + /// karamakers... + pub fn get_kara_tags(&mut self, local_id: i64) -> LktDatabaseResult<KaraTags> { + let (repo, repo_id) = with_dsl!(repo_kara => repo_kara .filter(local_kara_id.is(local_id)) .inner_join(schema::repo::table) - .select(schema::repo::name) - .first::<String>(&mut self.sqlite)? + .select((schema::repo::name, repo_kara_id)) + .first::<(String, i64)>(&mut self.sqlite)? ); - let mut ret = vec![(String::from("repo"), Some(repo))]; - for kara_maker in with_dsl!(kara => kara + let kara_makers: Vec<String> = with_dsl!(kara => kara .filter(id.is(local_id)) .inner_join(schema::kara_maker::table) .select(schema::kara_maker::name) - .load_iter::<String, DefaultLoadingMode>(&mut self.sqlite)? - ) { - ret.push((String::from("karamaker"), Some(kara_maker?))); - } + .load::<String>(&mut self.sqlite)? + ); - for tag_entry in with_dsl!(kara_tag => kara_tag + let tags_raw: Vec<(String, Option<String>)> = with_dsl!(kara_tag => kara_tag .filter(kara_id.is(local_id)) .inner_join(schema::tag::table) .select((schema::tag::name, value)) - .load_iter::<(String, Option<String>), DefaultLoadingMode>(&mut self.sqlite)? - ) { - let (key, value) = tag_entry?; - ret.push((key, value)) + .load::<(String, Option<String>)>(&mut self.sqlite)? + ); + let mut tags: HashMap<String, Vec<String>> = Default::default(); + for (tag, value) in tags_raw.into_iter() { + match tags.get_mut(&tag) { + Some(values) => values.extend(value), + None => { + let values: Vec<_> = value.into_iter().collect(); + tags.insert(tag, values); + } + } } - Ok(ret) + Ok(KaraTags { + repo, + repo_id, + kara_makers, + tags, + }) } } diff --git a/src/rust/lektor_db/src/lib.rs b/src/rust/lektor_db/src/lib.rs index a46a3e53a7b7d8a178d9ccc6733d4de5dfdde6d7..add72f281086040fe052ad7b4ec92f3242be49d6 100644 --- a/src/rust/lektor_db/src/lib.rs +++ b/src/rust/lektor_db/src/lib.rs @@ -6,6 +6,7 @@ pub mod connexion; pub mod error; pub mod models; pub mod queue; +pub mod types; pub mod uri; pub(self) mod schema; diff --git a/src/rust/lektor_db/src/types.rs b/src/rust/lektor_db/src/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..76a9ed736b088298621b9e13e7985ed90510ac7b --- /dev/null +++ b/src/rust/lektor_db/src/types.rs @@ -0,0 +1,19 @@ +use hashbrown::HashMap; + +pub struct KaraInfo { + pub local_id: i64, + + pub source_name: String, + pub song_title: String, + pub song_origin: String, + pub song_type: String, + + pub languages: Vec<String>, +} + +pub struct KaraTags { + pub repo_id: i64, + pub repo: String, + pub kara_makers: Vec<String>, + pub tags: HashMap<String, Vec<String>>, +}