Properly sync associated items of recordings and works

This commit is contained in:
Elias Projahn 2020-11-29 01:29:03 +01:00
parent bec0dfbf56
commit 37f21c582d
7 changed files with 103 additions and 89 deletions

View file

@ -1,5 +1,6 @@
use super::schema::{ensembles, performances, persons, recordings};
use super::{get_ensemble, get_instrument, get_person, get_work};
use super::{update_ensemble, update_instrument, update_person, update_work};
use super::{DbConn, Ensemble, Instrument, Person, User, Work};
use crate::error::ServerError;
use anyhow::{anyhow, Error, Result};
@ -48,7 +49,6 @@ struct PerformanceRow {
/// Update an existing recording or insert a new one. This will only work, if the provided user is
/// allowed to do that.
// TODO: Also add newly created associated items.
pub fn update_recording(conn: &DbConn, recording: &Recording, user: &User) -> Result<()> {
conn.transaction::<(), Error, _>(|| {
let old_row = get_recording_row(conn, &recording.id)?;
@ -66,6 +66,34 @@ pub fn update_recording(conn: &DbConn, recording: &Recording, user: &User) -> Re
.filter(recordings::id.eq(id))
.execute(conn)?;
// Add associated items, if they don't already exist.
if get_work(conn, &recording.work.id)?.is_none() {
update_work(conn, &recording.work, &user)?;
}
for performance in &recording.performances {
if let Some(person) = &performance.person {
if get_person(conn, &person.id)?.is_none() {
update_person(conn, person, &user)?;
}
}
if let Some(ensemble) = &performance.ensemble {
if get_ensemble(conn, &ensemble.id)?.is_none() {
update_ensemble(conn, ensemble, &user)?;
}
}
if let Some(role) = &performance.role {
if get_instrument(conn, &role.id)?.is_none() {
update_instrument(conn, role, &user)?;
}
}
}
// Add the actual recording.
let row = RecordingRow {
id: id.clone(),
work: recording.work.id.clone(),

View file

@ -1,5 +1,6 @@
use super::schema::{instrumentations, work_parts, work_sections, works};
use super::{get_instrument, get_person, DbConn, Instrument, Person, User};
use super::{get_instrument, get_person, update_instrument, update_person};
use super::{DbConn, Instrument, Person, User};
use crate::error::ServerError;
use anyhow::{anyhow, Error, Result};
use diesel::prelude::*;
@ -76,7 +77,6 @@ struct WorkSectionRow {
/// Update an existing work or insert a new one. This will only succeed, if the user is allowed to
/// do that.
// TODO: Also add newly created associated items.
pub fn update_work(conn: &DbConn, work: &Work, user: &User) -> Result<()> {
conn.transaction::<(), Error, _>(|| {
let old_row = get_work_row(conn, &work.id)?;
@ -94,6 +94,28 @@ pub fn update_work(conn: &DbConn, work: &Work, user: &User) -> Result<()> {
.filter(works::id.eq(id))
.execute(conn)?;
// Add associated items, if they don't already exist.
if get_person(conn, &work.composer.id)?.is_none() {
update_person(conn, &work.composer, &user)?;
}
for instrument in &work.instruments {
if get_instrument(conn, &instrument.id)?.is_none() {
update_instrument(conn, instrument, &user)?;
}
}
for part in &work.parts {
if let Some(person) = &part.composer {
if get_person(conn, &person.id)?.is_none() {
update_person(conn, person, &user)?;
}
}
}
// Add the actual work.
let row = WorkRow {
id: id.clone(),
composer: work.composer.id.clone(),