Use nullable roles instead of default roles

This commit is contained in:
Elias Projahn 2025-03-29 17:29:29 +01:00
parent 130df0d60e
commit a371e356f7
16 changed files with 380 additions and 186 deletions

View file

@ -21,12 +21,10 @@ pub struct Work {
pub instruments: Vec<Instrument>,
}
#[derive(Queryable, Selectable, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct Composer {
#[diesel(embed)]
pub person: Person,
#[diesel(embed)]
pub role: Role,
pub role: Option<Role>,
}
#[derive(Boxed, Clone, Debug)]
@ -50,14 +48,14 @@ pub struct Recording {
#[derive(Clone, Debug)]
pub struct Performer {
pub person: Person,
pub role: Role,
pub role: Option<Role>,
pub instrument: Option<Instrument>,
}
#[derive(Clone, Debug)]
pub struct EnsemblePerformer {
pub ensemble: Ensemble,
pub role: Role,
pub role: Option<Role>,
}
#[derive(Clone, Debug)]
@ -133,12 +131,13 @@ impl Work {
.map(|w| Work::from_table(w, connection))
.collect::<Result<Vec<Work>>>()?;
let persons: Vec<Composer> = persons::table
.inner_join(work_persons::table.inner_join(roles::table))
let persons = work_persons::table
.order(work_persons::sequence_number)
.filter(work_persons::work_id.eq(&data.work_id))
.select(Composer::as_select())
.load(connection)?;
.load::<tables::WorkPerson>(connection)?
.into_iter()
.map(|r| Composer::from_table(r, connection))
.collect::<Result<Vec<Composer>>>()?;
let instruments: Vec<Instrument> = instruments::table
.inner_join(work_instruments::table)
@ -157,11 +156,10 @@ impl Work {
}
pub fn composers_string(&self) -> Option<String> {
// TODO: Include roles except default composer.
let composers_string = self
.persons
.iter()
.map(|p| p.person.name.get().to_string())
.map(ToString::to_string)
.collect::<Vec<String>>()
.join(", ");
@ -190,6 +188,34 @@ impl Display for Work {
}
}
impl Composer {
pub fn from_table(data: tables::WorkPerson, connection: &mut SqliteConnection) -> Result<Self> {
let person: Person = persons::table
.filter(persons::person_id.eq(&data.person_id))
.first(connection)?;
let role = match &data.role_id {
Some(role_id) => Some(
roles::table
.filter(roles::role_id.eq(role_id))
.first::<Role>(connection)?,
),
None => None,
};
Ok(Self { person, role })
}
}
impl Display for Composer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.role {
Some(role) => format!("{} ({})", self.person.name.get(), role.name.get()).fmt(f),
None => self.person.name.get().fmt(f),
}
}
}
impl Ensemble {
pub fn from_table(data: tables::Ensemble, connection: &mut SqliteConnection) -> Result<Self> {
let persons: Vec<(Person, Instrument)> = persons::table
@ -297,9 +323,14 @@ impl Performer {
.filter(persons::person_id.eq(&data.person_id))
.first(connection)?;
let role: Role = roles::table
.filter(roles::role_id.eq(&data.role_id))
.first(connection)?;
let role = match &data.role_id {
Some(role_id) => Some(
roles::table
.filter(roles::role_id.eq(role_id))
.first::<Role>(connection)?,
),
None => None,
};
let instrument = match &data.instrument_id {
Some(instrument_id) => Some(
@ -320,11 +351,12 @@ impl Performer {
impl Display for Performer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.instrument {
Some(instrument) => {
match (&self.role, &self.instrument) {
(_, Some(instrument)) => {
format!("{} ({})", self.person.name.get(), instrument.name.get()).fmt(f)
}
None => self.person.name.get().fmt(f),
(Some(role), _) => format!("{} ({})", self.person.name.get(), role.name.get()).fmt(f),
(None, None) => self.person.name.get().fmt(f),
}
}
}
@ -340,9 +372,14 @@ impl EnsemblePerformer {
let ensemble = Ensemble::from_table(ensemble_data, connection)?;
let role: Role = roles::table
.filter(roles::role_id.eq(&data.role_id))
.first(connection)?;
let role = match &data.role_id {
Some(role_id) => Some(
roles::table
.filter(roles::role_id.eq(role_id))
.first::<Role>(connection)?,
),
None => None,
};
Ok(Self { ensemble, role })
}

View file

@ -81,19 +81,19 @@ diesel::table! {
}
diesel::table! {
recording_ensembles (recording_id, ensemble_id, role_id) {
recording_ensembles (recording_id, ensemble_id, sequence_number) {
recording_id -> Text,
ensemble_id -> Text,
role_id -> Text,
role_id -> Nullable<Text>,
sequence_number -> Integer,
}
}
diesel::table! {
recording_persons (recording_id, person_id, role_id, instrument_id) {
recording_persons (recording_id, person_id, sequence_number) {
recording_id -> Text,
person_id -> Text,
role_id -> Text,
role_id -> Nullable<Text>,
instrument_id -> Nullable<Text>,
sequence_number -> Integer,
}
@ -153,10 +153,10 @@ diesel::table! {
}
diesel::table! {
work_persons (work_id, person_id, role_id) {
work_persons (work_id, person_id, sequence_number) {
work_id -> Text,
person_id -> Text,
role_id -> Text,
role_id -> Nullable<Text>,
sequence_number -> Integer,
}
}

View file

@ -60,7 +60,7 @@ pub struct Work {
pub struct WorkPerson {
pub work_id: String,
pub person_id: String,
pub role_id: String,
pub role_id: Option<String>,
pub sequence_number: i32,
}
@ -109,7 +109,7 @@ pub struct Recording {
pub struct RecordingPerson {
pub recording_id: String,
pub person_id: String,
pub role_id: String,
pub role_id: Option<String>,
pub instrument_id: Option<String>,
pub sequence_number: i32,
}
@ -119,7 +119,7 @@ pub struct RecordingPerson {
pub struct RecordingEnsemble {
pub recording_id: String,
pub ensemble_id: String,
pub role_id: String,
pub role_id: Option<String>,
pub sequence_number: i32,
}