diff --git a/src/rust/lektor_db/src/connexion.rs b/src/rust/lektor_db/src/connexion.rs index 03f8ca4e60f73e0390e01f0beaf65da46b2fae5c..a540a037320aef72e50dc947d31db2989fc3ef06 100644 --- a/src/rust/lektor_db/src/connexion.rs +++ b/src/rust/lektor_db/src/connexion.rs @@ -246,109 +246,92 @@ impl LktDatabaseConnection { /// Search the database with the built search. We return the local ids. pub fn search(&mut self, search: LktDatabaseSearch) -> LktDatabaseResult<Vec<i64>> { - // We begin by filtering the database, for KaraMaker, Language, Search - // and Playlist we get all non virtual karas, because we are joining - // other tables we can't use [into_boxed]... - - let karas = match search.uri { - LktUri::Id(uri_id) => with_dsl! { kara => kara - .filter(id.is(uri_id)) - .filter(is_virtual.is(false)) - .into_boxed() - }, - - LktUri::Origin(ref uri_origin) => with_dsl! { kara => kara - .filter(song_origin.is(uri_origin.as_str())) - .filter(is_virtual.is(false)) - .into_boxed() - }, - - LktUri::Type(ref uri_type) => with_dsl!(kara => kara - .filter(song_type.is(uri_type.as_str())) - .filter(is_virtual.is(false)) - .into_boxed() - ), - - LktUri::FuzzySearch(_) => with_dsl! { kara => kara.into_boxed() }, - - LktUri::KaraMaker(_) - | LktUri::Language(_) - | LktUri::Search(_) - | LktUri::Playlist(_) - | LktUri::Any => with_dsl! { kara => kara - .filter(is_virtual.is(false)) - .into_boxed() - }, - }; - - todo!() - } - - /// Search karas by URIs. We return the local ids. - pub fn search_database(&mut self, uri: LktUri) -> LktDatabaseResult<Vec<i64>> { - match uri { - LktUri::Id(uri_id) => Ok(vec![with_dsl! { kara => kara + let karas: Vec<_> = match search.uri { + LktUri::Id(uri_id) => vec![with_dsl! { kara => kara .filter(id.is(uri_id)) .filter(is_virtual.is(false)) .select(id) .first::<i64>(&mut self.sqlite)? - }]), + }], - LktUri::KaraMaker(uri_kara_maker) => Ok(with_dsl! { kara_maker => kara_maker + LktUri::KaraMaker(uri_kara_maker) => with_dsl! { kara_maker => kara_maker .filter(name.like(uri_kara_maker.as_str())) .inner_join(schema::kara::table) .filter(schema::kara::is_virtual.is(false)) .select(id) .load::<i64>(&mut self.sqlite)? - }), + }, - LktUri::Origin(uri_origin) => Ok(with_dsl! { kara => kara + LktUri::Origin(uri_origin) => with_dsl! { kara => kara .filter(song_origin.is(uri_origin.as_str())) .filter(is_virtual.is(false)) .select(id) .load::<i64>(&mut self.sqlite)? - }), + }, - LktUri::Type(uri_type) => Ok(with_dsl!(kara => kara + LktUri::Type(uri_type) => with_dsl!(kara => kara .filter(song_type.is(uri_type.as_str())) .filter(is_virtual.is(false)) .select(id) .load::<i64>(&mut self.sqlite)? - )), + ), - LktUri::Language(uri_lang) => Ok(with_dsl!(kara_lang => kara_lang + LktUri::Language(uri_lang) => with_dsl!(kara_lang => kara_lang .filter(code.is(uri_lang.as_str())) .inner_join(schema::kara::table) .filter(schema::kara::is_virtual.is(false)) .select(id) .load::<i64>(&mut self.sqlite)? - )), + ), LktUri::FuzzySearch(uri_search) | LktUri::Search(uri_search) => { let uri_search = uri_search.join("%"); let uri_search = uri_search.as_str(); - Ok(with_dsl! { kara => { + with_dsl! { kara => { use schema::kara_lang::code as code; let fuzzy = fuzzy!( song_title source_name song_origin song_type code ); kara.inner_join(schema::kara_lang::table) .filter(fuzzy.like(uri_search)) .select(id) .load::<i64>(&mut self.sqlite)? - }}) + }} } - LktUri::Playlist(uri_playlist) => Ok(with_dsl!(playlist_kara => playlist_kara + LktUri::Playlist(uri_playlist) => with_dsl!(playlist_kara => playlist_kara .inner_join(schema::playlist::table) .filter(schema::playlist::name.like(uri_playlist.as_str())) .select(kara_id) .load::<i64>(&mut self.sqlite)? - )), + ), - LktUri::Any => Ok(with_dsl! { kara => kara + LktUri::Any => with_dsl! { kara => kara .select(id) .load::<i64>(&mut self.sqlite)? + }, + }; + + let karas = match search.search_type { + LktDatabaseSearchType::Playlist(plt_name) => { + let mut plt_ids: Vec<_> = schema::playlist::table + .filter(schema::playlist::name.is(plt_name.as_str())) + .inner_join(schema::playlist_kara::table) + .select(schema::playlist_kara::kara_id) + .load::<i64>(&mut self.sqlite)?; + plt_ids.retain(|plt_id| karas.contains(plt_id)); + plt_ids + } + LktDatabaseSearchType::History => with_dsl!(history => { + let mut history_ids: Vec<_> = history.order(epoch.desc()).select(id).load::<i64>(&mut self.sqlite)?; + history_ids.retain(|history_id| karas.contains(history_id)); + history_ids }), - } + LktDatabaseSearchType::Database => karas, + }; + + Ok(search + .range + .map(|Range { start, end }| karas[start..end].to_vec()) + .unwrap_or(karas)) } /// Get basic information about a kara, like its source, title, origin, the