Skip to content

Commit

Permalink
refactor(os/scan): move build artist indices to a separate function
Browse files Browse the repository at this point in the history
  • Loading branch information
vnghia committed Feb 1, 2024
1 parent 2ec11db commit 9d9a081
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
1 change: 0 additions & 1 deletion src/models/artists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ pub struct Artist {
#[diesel(table_name = artists)]
pub struct NewArtist<'a> {
pub name: Cow<'a, str>,
pub index: Cow<'a, str>,
}
65 changes: 60 additions & 5 deletions src/open_subsonic/scan/artist.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::models::*;
use crate::{DatabasePool, OSResult};

use diesel::ExpressionMethods;
use diesel::{ExpressionMethods, QueryDsl};
use diesel_async::RunQueryDsl;
use futures::stream::{self, StreamExt};
use futures::TryStreamExt;
use itertools::Itertools;
use uuid::Uuid;

pub async fn upsert_artists<TI: AsRef<str>, TN: AsRef<str>>(
pub async fn upsert_artists<TN: AsRef<str>>(
pool: &DatabasePool,
ignored_prefixes: &[TI],
names: &[TN],
) -> OSResult<Vec<Uuid>> {
Ok(diesel::insert_into(artists::table)
Expand All @@ -17,7 +18,6 @@ pub async fn upsert_artists<TI: AsRef<str>, TN: AsRef<str>>(
.iter()
.map(|name| artists::NewArtist {
name: std::borrow::Cow::Borrowed(name.as_ref()),
index: build_artist_index(ignored_prefixes, name.as_ref()).into(),
})
.collect_vec(),
)
Expand All @@ -30,7 +30,7 @@ pub async fn upsert_artists<TI: AsRef<str>, TN: AsRef<str>>(
}

// TODO: better index building mechanism
pub fn build_artist_index<T: AsRef<str>>(ignored_prefixes: &[T], name: &str) -> String {
fn build_artist_index<T: AsRef<str>>(ignored_prefixes: &[T], name: &str) -> String {
for ignored_prefix in ignored_prefixes {
if let Some(stripped) = name.strip_prefix(ignored_prefix.as_ref()) {
if let Some(index_char) = stripped.chars().next() {
Expand All @@ -46,6 +46,30 @@ pub fn build_artist_index<T: AsRef<str>>(ignored_prefixes: &[T], name: &str) ->
}
}

pub async fn build_artist_indices<T: AsRef<str>>(
pool: &DatabasePool,
ignored_prefixes: &[T],
) -> OSResult<()> {
stream::iter(
artists::table
.select((artists::id, artists::name))
.filter(artists::index.eq("?"))
.load::<(Uuid, String)>(&mut pool.get().await?)
.await?,
)
.then(|(id, name)| async move {
diesel::update(artists::table)
.filter(artists::id.eq(id))
.set(artists::index.eq(build_artist_index(ignored_prefixes, &name)))
.execute(&mut pool.get().await?)
.await?;
OSResult::Ok(())
})
.try_collect()
.await?;
Ok(())
}

fn index_char_to_string(index_char: char) -> String {
if index_char.is_ascii_alphabetic() {
index_char.to_ascii_uppercase().to_string()
Expand All @@ -59,6 +83,9 @@ fn index_char_to_string(index_char: char) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::test::db::TemporaryDatabase;

use fake;

#[test]
fn test_index_char_to_string_numeric() {
Expand Down Expand Up @@ -94,4 +121,32 @@ mod tests {
fn test_build_artist_index_no_article() {
assert_eq!(build_artist_index(&["The ", "A "], "test"), "T");
}

#[tokio::test]
async fn test_build_artist_indices() {
let db = TemporaryDatabase::new_from_env().await;
let artist_names = fake::vec![String; 10];
let ignored_prefixes = ["The ", "A "];

upsert_artists(db.get_pool(), &artist_names).await.unwrap();
build_artist_indices(db.get_pool(), &ignored_prefixes)
.await
.unwrap();

assert_eq!(
artist_names
.iter()
.map(|name| build_artist_index(&ignored_prefixes, name))
.sorted()
.collect_vec(),
artists::table
.select(artists::index)
.load::<String>(&mut db.get_pool().get().await.unwrap())
.await
.unwrap()
.into_iter()
.sorted()
.collect_vec()
);
}
}
6 changes: 4 additions & 2 deletions src/open_subsonic/scan/scan_full.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{
album::upsert_album, artist::upsert_artists, song::upsert_song, song::upsert_song_artists,
album::upsert_album, artist::build_artist_indices, artist::upsert_artists, song::upsert_song,
song::upsert_song_artists,
};
use crate::{
models::*,
Expand Down Expand Up @@ -54,7 +55,7 @@ pub async fn scan_full<T: AsRef<str>>(

let song_tag = SongTag::parse(&song_data, song_file_type)?;

let artist_ids = upsert_artists(pool, ignored_prefixes, &song_tag.artists).await?;
let artist_ids = upsert_artists(pool, &song_tag.artists).await?;
let album_id = upsert_album(pool, std::borrow::Cow::Borrowed(&song_tag.album)).await?;

let song_id = upsert_song(
Expand Down Expand Up @@ -83,6 +84,7 @@ pub async fn scan_full<T: AsRef<str>>(
.await?;
}
}
build_artist_indices(pool, ignored_prefixes).await?;

tracing::info!("done scanning songs");
Ok(())
Expand Down

0 comments on commit 9d9a081

Please sign in to comment.