From eec0d54e0a951561e0f0828185f3f1705705f09b Mon Sep 17 00:00:00 2001 From: noahlevi Date: Tue, 23 Dec 2025 19:11:09 +0200 Subject: [PATCH 1/2] fix: deduplicate contributions when joined with biographies --- thoth-api/src/model/contribution/crud.rs | 76 ++++++++++++++---------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/thoth-api/src/model/contribution/crud.rs b/thoth-api/src/model/contribution/crud.rs index bf980957..0cf896f9 100644 --- a/thoth-api/src/model/contribution/crud.rs +++ b/thoth-api/src/model/contribution/crud.rs @@ -40,63 +40,75 @@ impl Crud for Contribution { ) -> ThothResult> { use crate::schema::contribution::dsl::*; let mut connection = db.get()?; - let mut query = contribution - .inner_join(crate::schema::work::table.inner_join(crate::schema::imprint::table)) - .left_join( - crate::schema::biography::table - .on(crate::schema::biography::contribution_id.eq(contribution_id)), - ) - .select(crate::schema::contribution::all_columns) - .into_boxed(); + let mut query = diesel::query_dsl::methods::DistinctOnDsl::distinct_on( + contribution + .inner_join(crate::schema::work::table.inner_join( + crate::schema::imprint::table, + )) + .left_join( + crate::schema::biography::table.on( + crate::schema::biography::contribution_id.eq(contribution_id), + ), + ) + .select(crate::schema::contribution::all_columns), + contribution_id, + ) + .into_boxed(); query = match order.field { ContributionField::ContributionId => match order.direction { - Direction::Asc => query.order(contribution_id.asc()), - Direction::Desc => query.order(contribution_id.desc()), + Direction::Asc => query.order((contribution_id, contribution_id.asc())), + Direction::Desc => query.order((contribution_id, contribution_id.desc())), }, ContributionField::WorkId => match order.direction { - Direction::Asc => query.order(work_id.asc()), - Direction::Desc => query.order(work_id.desc()), + Direction::Asc => query.order((contribution_id, work_id.asc())), + Direction::Desc => query.order((contribution_id, work_id.desc())), }, ContributionField::ContributorId => match order.direction { - Direction::Asc => query.order(contributor_id.asc()), - Direction::Desc => query.order(contributor_id.desc()), + Direction::Asc => query.order((contribution_id, contributor_id.asc())), + Direction::Desc => query.order((contribution_id, contributor_id.desc())), }, ContributionField::ContributionType => match order.direction { - Direction::Asc => query.order(contribution_type.asc()), - Direction::Desc => query.order(contribution_type.desc()), + Direction::Asc => query.order((contribution_id, contribution_type.asc())), + Direction::Desc => query.order((contribution_id, contribution_type.desc())), }, ContributionField::MainContribution => match order.direction { - Direction::Asc => query.order(main_contribution.asc()), - Direction::Desc => query.order(main_contribution.desc()), + Direction::Asc => query.order((contribution_id, main_contribution.asc())), + Direction::Desc => query.order((contribution_id, main_contribution.desc())), }, ContributionField::Biography => match order.direction { - Direction::Asc => query.order(crate::schema::biography::content.asc()), - Direction::Desc => query.order(crate::schema::biography::content.desc()), + Direction::Asc => query.order(( + contribution_id, + crate::schema::biography::content.asc(), + )), + Direction::Desc => query.order(( + contribution_id, + crate::schema::biography::content.desc(), + )), }, ContributionField::CreatedAt => match order.direction { - Direction::Asc => query.order(created_at.asc()), - Direction::Desc => query.order(created_at.desc()), + Direction::Asc => query.order((contribution_id, created_at.asc())), + Direction::Desc => query.order((contribution_id, created_at.desc())), }, ContributionField::UpdatedAt => match order.direction { - Direction::Asc => query.order(updated_at.asc()), - Direction::Desc => query.order(updated_at.desc()), + Direction::Asc => query.order((contribution_id, updated_at.asc())), + Direction::Desc => query.order((contribution_id, updated_at.desc())), }, ContributionField::FirstName => match order.direction { - Direction::Asc => query.order(first_name.asc()), - Direction::Desc => query.order(first_name.desc()), + Direction::Asc => query.order((contribution_id, first_name.asc())), + Direction::Desc => query.order((contribution_id, first_name.desc())), }, ContributionField::LastName => match order.direction { - Direction::Asc => query.order(last_name.asc()), - Direction::Desc => query.order(last_name.desc()), + Direction::Asc => query.order((contribution_id, last_name.asc())), + Direction::Desc => query.order((contribution_id, last_name.desc())), }, ContributionField::FullName => match order.direction { - Direction::Asc => query.order(full_name.asc()), - Direction::Desc => query.order(full_name.desc()), + Direction::Asc => query.order((contribution_id, full_name.asc())), + Direction::Desc => query.order((contribution_id, full_name.desc())), }, ContributionField::ContributionOrdinal => match order.direction { - Direction::Asc => query.order(contribution_ordinal.asc()), - Direction::Desc => query.order(contribution_ordinal.desc()), + Direction::Asc => query.order((contribution_id, contribution_ordinal.asc())), + Direction::Desc => query.order((contribution_id, contribution_ordinal.desc())), }, }; if !publishers.is_empty() { From e6a772d877b223d961613af955f795b2024c9d31 Mon Sep 17 00:00:00 2001 From: noahlevi Date: Tue, 23 Dec 2025 19:13:23 +0200 Subject: [PATCH 2/2] chore: format --- thoth-api/src/model/contribution/crud.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/thoth-api/src/model/contribution/crud.rs b/thoth-api/src/model/contribution/crud.rs index 0cf896f9..f1045601 100644 --- a/thoth-api/src/model/contribution/crud.rs +++ b/thoth-api/src/model/contribution/crud.rs @@ -42,13 +42,10 @@ impl Crud for Contribution { let mut connection = db.get()?; let mut query = diesel::query_dsl::methods::DistinctOnDsl::distinct_on( contribution - .inner_join(crate::schema::work::table.inner_join( - crate::schema::imprint::table, - )) + .inner_join(crate::schema::work::table.inner_join(crate::schema::imprint::table)) .left_join( - crate::schema::biography::table.on( - crate::schema::biography::contribution_id.eq(contribution_id), - ), + crate::schema::biography::table + .on(crate::schema::biography::contribution_id.eq(contribution_id)), ) .select(crate::schema::contribution::all_columns), contribution_id, @@ -77,14 +74,12 @@ impl Crud for Contribution { Direction::Desc => query.order((contribution_id, main_contribution.desc())), }, ContributionField::Biography => match order.direction { - Direction::Asc => query.order(( - contribution_id, - crate::schema::biography::content.asc(), - )), - Direction::Desc => query.order(( - contribution_id, - crate::schema::biography::content.desc(), - )), + Direction::Asc => { + query.order((contribution_id, crate::schema::biography::content.asc())) + } + Direction::Desc => { + query.order((contribution_id, crate::schema::biography::content.desc())) + } }, ContributionField::CreatedAt => match order.direction { Direction::Asc => query.order((contribution_id, created_at.asc())),