diff --git a/crates/musicus_database/src/medium.rs b/crates/musicus_database/src/medium.rs index 3f42878..3d7cb3d 100644 --- a/crates/musicus_database/src/medium.rs +++ b/crates/musicus_database/src/medium.rs @@ -1,5 +1,5 @@ use super::generate_id; -use super::schema::{mediums, recordings, track_sets, tracks}; +use super::schema::{ensembles, mediums, performances, persons, recordings, track_sets, tracks}; use super::{Database, Error, Recording, Result}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -167,6 +167,50 @@ impl Database { Ok(medium) } + /// Get mediums on which this person is performing. + pub fn get_mediums_for_person(&self, person_id: &str) -> Result> { + let mut mediums: Vec = Vec::new(); + + let rows = mediums::table + .inner_join(track_sets::table.on(track_sets::medium.eq(mediums::id))) + .inner_join(recordings::table.on(recordings::id.eq(track_sets::recording))) + .inner_join(performances::table.on(performances::recording.eq(recordings::id))) + .inner_join(persons::table.on(persons::id.nullable().eq(performances::person))) + .filter(persons::id.eq(person_id)) + .select(mediums::table::all_columns()) + .distinct() + .load::(&self.connection)?; + + for row in rows { + let medium = self.get_medium_data(row)?; + mediums.push(medium); + } + + Ok(mediums) + } + + /// Get mediums on which this ensemble is performing. + pub fn get_mediums_for_ensemble(&self, ensemble_id: &str) -> Result> { + let mut mediums: Vec = Vec::new(); + + let rows = mediums::table + .inner_join(track_sets::table.on(track_sets::medium.eq(mediums::id))) + .inner_join(recordings::table.on(recordings::id.eq(track_sets::recording))) + .inner_join(performances::table.on(performances::recording.eq(recordings::id))) + .inner_join(ensembles::table.on(ensembles::id.nullable().eq(performances::ensemble))) + .filter(ensembles::id.eq(ensemble_id)) + .select(mediums::table::all_columns()) + .distinct() + .load::(&self.connection)?; + + for row in rows { + let medium = self.get_medium_data(row)?; + mediums.push(medium); + } + + Ok(mediums) + } + /// Delete a medium and all of its tracks. This will fail, if the music /// library contains audio files referencing any of those tracks. pub fn delete_medium(&self, id: &str) -> Result<()> { diff --git a/crates/musicus_database/src/thread.rs b/crates/musicus_database/src/thread.rs index 7a73a14..42eb9fe 100644 --- a/crates/musicus_database/src/thread.rs +++ b/crates/musicus_database/src/thread.rs @@ -29,6 +29,8 @@ pub enum Action { RecordingExists(String, Sender>), UpdateMedium(Medium, Sender>), GetMedium(String, Sender>>), + GetMediumsForPerson(String, Sender>>), + GetMediumsForEnsemble(String, Sender>>), DeleteMedium(String, Sender>), GetTrackSets(String, Sender>>), Stop(Sender<()>), @@ -130,6 +132,12 @@ impl DbThread { GetMedium(id, sender) => { sender.send(db.get_medium(&id)).unwrap(); } + GetMediumsForPerson(id, sender) => { + sender.send(db.get_mediums_for_person(&id)).unwrap(); + } + GetMediumsForEnsemble(id, sender) => { + sender.send(db.get_mediums_for_ensemble(&id)).unwrap(); + } DeleteMedium(id, sender) => { sender.send(db.delete_medium(&id)).unwrap(); } @@ -338,6 +346,20 @@ impl DbThread { receiver.await? } + /// Get all mediums on which a person performs. + pub async fn get_mediums_for_person(&self, id: &str) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetMediumsForPerson(id.to_owned(), sender))?; + receiver.await? + } + + /// Get all mediums on which an ensemble performs. + pub async fn get_mediums_for_ensemble(&self, id: &str) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetMediumsForEnsemble(id.to_owned(), sender))?; + receiver.await? + } + /// Get all track sets for a recording. pub async fn get_track_sets(&self, recording_id: &str) -> Result> { let (sender, receiver) = oneshot::channel();