From 8e2cbc9a0f99cc4008e67bab6f35507912cc6a5c Mon Sep 17 00:00:00 2001 From: dullbananas Date: Mon, 13 Nov 2023 06:14:07 -0700 Subject: [PATCH] Remove id column and use different primary key on some tables (#4093) * post_saved * fmt * remove unique and not null * put person_id first in primary key and remove index * use post_saved.find * change captcha_answer * remove removal of not null * comment_aggregates * comment_like * comment_saved * aggregates * remove "\" * deduplicate site_aggregates * person_post_aggregates * community_moderator * community_block * community_person_ban * custom_emoji_keyword * federation allow/block list * federation_queue_state * instance_block * local_site_rate_limit, local_user_language, login_token * person_ban, person_block, person_follower, post_like, post_read, received_activity * community_follower, community_language, site_language * fmt * image_upload * remove unused newtypes * remove more indexes * use .find * merge * fix site_aggregates_site function * fmt * Primary keys dess (#17) * Also order reports by oldest first (ref #4123) (#4129) * Support signed fetch for federation (fixes #868) (#4125) * Support signed fetch for federation (fixes #868) * taplo * add federation queue state to get_federated_instances api (#4104) * add federation queue state to get_federated_instances api * feature gate * move retry sleep function * move stuff around * Add UI setting for collapsing bot comments. Fixes #3838 (#4098) * Add UI setting for collapsing bot comments. Fixes #3838 * Fixing clippy check. * Only keep sent and received activities for 7 days (fixes #4113, fixes #4110) (#4131) * Only check auth secure on release mode. (#4127) * Only check auth secure on release mode. * Fixing wrong js-client. * Adding is_debug_mode var. * Fixing the desktop image on the README. (#4135) * Delete dupes and add possibly missing unique constraint on person_aggregates. * Fixing clippy lints. --------- Co-authored-by: Nutomic Co-authored-by: phiresky * fmt * Update community_block.rs * Update instance_block.rs * Update person_block.rs * Update person_block.rs --------- Co-authored-by: Dessalines Co-authored-by: Nutomic Co-authored-by: phiresky --- .../src/aggregates/comment_aggregates.rs | 5 +- .../src/aggregates/community_aggregates.rs | 9 +- .../src/aggregates/person_aggregates.rs | 4 +- .../src/aggregates/person_post_aggregates.rs | 5 +- .../src/aggregates/post_aggregates.rs | 5 +- crates/db_schema/src/aggregates/structs.rs | 12 +- crates/db_schema/src/impls/activity.rs | 9 +- crates/db_schema/src/impls/actor_language.rs | 8 +- crates/db_schema/src/impls/captcha_answer.rs | 17 +- crates/db_schema/src/impls/comment.rs | 24 +- crates/db_schema/src/impls/community.rs | 60 ++--- crates/db_schema/src/impls/community_block.rs | 14 +- crates/db_schema/src/impls/image_upload.rs | 18 +- crates/db_schema/src/impls/instance.rs | 8 +- crates/db_schema/src/impls/instance_block.rs | 14 +- crates/db_schema/src/impls/language.rs | 4 +- crates/db_schema/src/impls/login_token.rs | 10 +- crates/db_schema/src/impls/person.rs | 12 +- crates/db_schema/src/impls/person_block.rs | 21 +- crates/db_schema/src/impls/post.rs | 24 +- crates/db_schema/src/newtypes.rs | 24 -- crates/db_schema/src/schema.rs | 93 +++---- crates/db_schema/src/source/actor_language.rs | 19 +- crates/db_schema/src/source/captcha_answer.rs | 1 - crates/db_schema/src/source/comment.rs | 4 +- crates/db_schema/src/source/community.rs | 6 +- .../db_schema/src/source/community_block.rs | 4 +- .../src/source/custom_emoji_keyword.rs | 2 +- .../src/source/federation_allowlist.rs | 2 +- .../src/source/federation_blocklist.rs | 2 +- crates/db_schema/src/source/image_upload.rs | 4 +- crates/db_schema/src/source/instance_block.rs | 2 +- .../src/source/local_site_rate_limit.rs | 2 +- crates/db_schema/src/source/login_token.rs | 2 +- crates/db_schema/src/source/person.rs | 2 +- crates/db_schema/src/source/person_block.rs | 4 +- crates/db_schema/src/source/post.rs | 4 +- crates/db_views/src/comment_report_view.rs | 3 +- crates/db_views/src/comment_view.rs | 10 +- crates/db_views/src/post_report_view.rs | 2 +- crates/db_views/src/post_view.rs | 2 - crates/db_views/src/private_message_view.rs | 1 - .../db_views_actor/src/comment_reply_view.rs | 8 +- crates/db_views_actor/src/community_view.rs | 2 +- .../db_views_actor/src/person_mention_view.rs | 8 +- .../down.sql | 191 +++++++++++++++ .../up.sql | 228 ++++++++++++++++++ src/scheduled_tasks.rs | 15 +- 48 files changed, 597 insertions(+), 333 deletions(-) create mode 100644 migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/down.sql create mode 100644 migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/up.sql diff --git a/crates/db_schema/src/aggregates/comment_aggregates.rs b/crates/db_schema/src/aggregates/comment_aggregates.rs index e081d1a1e..110532c5a 100644 --- a/crates/db_schema/src/aggregates/comment_aggregates.rs +++ b/crates/db_schema/src/aggregates/comment_aggregates.rs @@ -11,7 +11,7 @@ impl CommentAggregates { pub async fn read(pool: &mut DbPool<'_>, comment_id: CommentId) -> Result { let conn = &mut get_conn(pool).await?; comment_aggregates::table - .filter(comment_aggregates::comment_id.eq(comment_id)) + .find(comment_id) .first::(conn) .await } @@ -22,8 +22,7 @@ impl CommentAggregates { ) -> Result { let conn = &mut get_conn(pool).await?; - diesel::update(comment_aggregates::table) - .filter(comment_aggregates::comment_id.eq(comment_id)) + diesel::update(comment_aggregates::table.find(comment_id)) .set(comment_aggregates::hot_rank.eq(hot_rank( comment_aggregates::score, comment_aggregates::published, diff --git a/crates/db_schema/src/aggregates/community_aggregates.rs b/crates/db_schema/src/aggregates/community_aggregates.rs index e968fdb08..f61a95c7d 100644 --- a/crates/db_schema/src/aggregates/community_aggregates.rs +++ b/crates/db_schema/src/aggregates/community_aggregates.rs @@ -1,10 +1,7 @@ use crate::{ aggregates::structs::CommunityAggregates, newtypes::CommunityId, - schema::{ - community_aggregates, - community_aggregates::{community_id, subscribers}, - }, + schema::{community_aggregates, community_aggregates::subscribers}, utils::{get_conn, DbPool}, }; use diesel::{result::Error, ExpressionMethods, QueryDsl}; @@ -14,7 +11,7 @@ impl CommunityAggregates { pub async fn read(pool: &mut DbPool<'_>, for_community_id: CommunityId) -> Result { let conn = &mut get_conn(pool).await?; community_aggregates::table - .filter(community_id.eq(for_community_id)) + .find(for_community_id) .first::(conn) .await } @@ -26,7 +23,7 @@ impl CommunityAggregates { ) -> Result { let conn = &mut get_conn(pool).await?; let new_subscribers: i64 = new_subscribers.into(); - diesel::update(community_aggregates::table.filter(community_id.eq(for_community_id))) + diesel::update(community_aggregates::table.find(for_community_id)) .set(subscribers.eq(new_subscribers)) .get_result::(conn) .await diff --git a/crates/db_schema/src/aggregates/person_aggregates.rs b/crates/db_schema/src/aggregates/person_aggregates.rs index e6195de28..d3065daf3 100644 --- a/crates/db_schema/src/aggregates/person_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_aggregates.rs @@ -4,14 +4,14 @@ use crate::{ schema::person_aggregates, utils::{get_conn, DbPool}, }; -use diesel::{result::Error, ExpressionMethods, QueryDsl}; +use diesel::{result::Error, QueryDsl}; use diesel_async::RunQueryDsl; impl PersonAggregates { pub async fn read(pool: &mut DbPool<'_>, person_id: PersonId) -> Result { let conn = &mut get_conn(pool).await?; person_aggregates::table - .filter(person_aggregates::person_id.eq(person_id)) + .find(person_id) .first::(conn) .await } diff --git a/crates/db_schema/src/aggregates/person_post_aggregates.rs b/crates/db_schema/src/aggregates/person_post_aggregates.rs index 1cbaa2422..7657dae9e 100644 --- a/crates/db_schema/src/aggregates/person_post_aggregates.rs +++ b/crates/db_schema/src/aggregates/person_post_aggregates.rs @@ -1,11 +1,10 @@ use crate::{ aggregates::structs::{PersonPostAggregates, PersonPostAggregatesForm}, - diesel::BoolExpressionMethods, newtypes::{PersonId, PostId}, schema::person_post_aggregates::dsl::{person_id, person_post_aggregates, post_id}, utils::{get_conn, DbPool}, }; -use diesel::{insert_into, result::Error, ExpressionMethods, QueryDsl}; +use diesel::{insert_into, result::Error, QueryDsl}; use diesel_async::RunQueryDsl; impl PersonPostAggregates { @@ -29,7 +28,7 @@ impl PersonPostAggregates { ) -> Result { let conn = &mut get_conn(pool).await?; person_post_aggregates - .filter(post_id.eq(post_id_).and(person_id.eq(person_id_))) + .find((person_id_, post_id_)) .first::(conn) .await } diff --git a/crates/db_schema/src/aggregates/post_aggregates.rs b/crates/db_schema/src/aggregates/post_aggregates.rs index 1816ee5f3..a8efe9581 100644 --- a/crates/db_schema/src/aggregates/post_aggregates.rs +++ b/crates/db_schema/src/aggregates/post_aggregates.rs @@ -15,7 +15,7 @@ impl PostAggregates { pub async fn read(pool: &mut DbPool<'_>, post_id: PostId) -> Result { let conn = &mut get_conn(pool).await?; post_aggregates::table - .filter(post_aggregates::post_id.eq(post_id)) + .find(post_id) .first::(conn) .await } @@ -33,8 +33,7 @@ impl PostAggregates { .first::(conn) .await?; - diesel::update(post_aggregates::table) - .filter(post_aggregates::post_id.eq(post_id)) + diesel::update(post_aggregates::table.find(post_id)) .set(( post_aggregates::hot_rank.eq(hot_rank(post_aggregates::score, post_aggregates::published)), post_aggregates::hot_rank_active.eq(hot_rank( diff --git a/crates/db_schema/src/aggregates/structs.rs b/crates/db_schema/src/aggregates/structs.rs index e01e6d984..24b2d82c5 100644 --- a/crates/db_schema/src/aggregates/structs.rs +++ b/crates/db_schema/src/aggregates/structs.rs @@ -16,10 +16,10 @@ use ts_rs::TS; #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = comment_aggregates))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::comment::Comment)))] +#[cfg_attr(feature = "full", diesel(primary_key(comment_id)))] #[cfg_attr(feature = "full", ts(export))] /// Aggregate data for a comment. pub struct CommentAggregates { - pub id: i32, pub comment_id: CommentId, pub score: i64, pub upvotes: i64, @@ -40,10 +40,10 @@ pub struct CommentAggregates { feature = "full", diesel(belongs_to(crate::source::community::Community)) )] +#[cfg_attr(feature = "full", diesel(primary_key(community_id)))] #[cfg_attr(feature = "full", ts(export))] /// Aggregate data for a community. pub struct CommunityAggregates { - pub id: i32, pub community_id: CommunityId, pub subscribers: i64, pub posts: i64, @@ -65,10 +65,10 @@ pub struct CommunityAggregates { #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = person_aggregates))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::person::Person)))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id)))] #[cfg_attr(feature = "full", ts(export))] /// Aggregate data for a person. pub struct PersonAggregates { - pub id: i32, pub person_id: PersonId, pub post_count: i64, #[serde(skip)] @@ -82,10 +82,10 @@ pub struct PersonAggregates { #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = post_aggregates))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::post::Post)))] +#[cfg_attr(feature = "full", diesel(primary_key(post_id)))] #[cfg_attr(feature = "full", ts(export))] /// Aggregate data for a post. pub struct PostAggregates { - pub id: i32, pub post_id: PostId, pub comments: i64, pub score: i64, @@ -124,10 +124,10 @@ pub struct PostAggregates { #[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))] #[cfg_attr(feature = "full", diesel(table_name = person_post_aggregates))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, post_id)))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::person::Person)))] /// Aggregate data for a person's post. pub struct PersonPostAggregates { - pub id: i32, pub person_id: PersonId, pub post_id: PostId, /// The number of comments they've read on that post. @@ -151,10 +151,10 @@ pub struct PersonPostAggregatesForm { #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = site_aggregates))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::site::Site)))] +#[cfg_attr(feature = "full", diesel(primary_key(site_id)))] #[cfg_attr(feature = "full", ts(export))] /// Aggregate data for a site. pub struct SiteAggregates { - pub id: i32, pub site_id: SiteId, pub users: i64, pub posts: i64, diff --git a/crates/db_schema/src/impls/activity.rs b/crates/db_schema/src/impls/activity.rs index 9b781d597..fe1a521a9 100644 --- a/crates/db_schema/src/impls/activity.rs +++ b/crates/db_schema/src/impls/activity.rs @@ -39,16 +39,15 @@ impl SentActivity { impl ReceivedActivity { pub async fn create(pool: &mut DbPool<'_>, ap_id_: &DbUrl) -> Result<(), Error> { - use crate::schema::received_activity::dsl::{ap_id, id, received_activity}; + use crate::schema::received_activity::dsl::{ap_id, received_activity}; let conn = &mut get_conn(pool).await?; - let res = insert_into(received_activity) + let rows_affected = insert_into(received_activity) .values(ap_id.eq(ap_id_)) .on_conflict_do_nothing() - .returning(id) - .get_result::(conn) + .execute(conn) .await .optional()?; - if res.is_some() { + if rows_affected == Some(1) { // new activity inserted successfully Ok(()) } else { diff --git a/crates/db_schema/src/impls/actor_language.rs b/crates/db_schema/src/impls/actor_language.rs index 313762a72..5c4e252d4 100644 --- a/crates/db_schema/src/impls/actor_language.rs +++ b/crates/db_schema/src/impls/actor_language.rs @@ -119,7 +119,7 @@ impl SiteLanguage { site::table .inner_join(local_site::table) .inner_join(site_language::table) - .order(site_language::id) + .order(site_language::language_id) .select(site_language::language_id) .load(conn) .await @@ -191,14 +191,12 @@ impl CommunityLanguage { for_language_id: Option, for_community_id: CommunityId, ) -> Result<(), LemmyError> { - use crate::schema::community_language::dsl::{community_id, community_language, language_id}; + use crate::schema::community_language::dsl::community_language; let conn = &mut get_conn(pool).await?; if let Some(for_language_id) = for_language_id { let is_allowed = select(exists( - community_language - .filter(language_id.eq(for_language_id)) - .filter(community_id.eq(for_community_id)), + community_language.find((for_community_id, for_language_id)), )) .get_result(conn) .await?; diff --git a/crates/db_schema/src/impls/captcha_answer.rs b/crates/db_schema/src/impls/captcha_answer.rs index 0404ce005..72e2d1285 100644 --- a/crates/db_schema/src/impls/captcha_answer.rs +++ b/crates/db_schema/src/impls/captcha_answer.rs @@ -1,5 +1,5 @@ use crate::{ - schema::captcha_answer::dsl::{answer, captcha_answer, uuid}, + schema::captcha_answer::dsl::{answer, captcha_answer}, source::captcha_answer::{CaptchaAnswer, CaptchaAnswerForm, CheckCaptchaAnswer}, utils::{functions::lower, get_conn, DbPool}, }; @@ -31,16 +31,15 @@ impl CaptchaAnswer { let conn = &mut get_conn(pool).await?; // fetch requested captcha - let captcha_exists = select(exists( - captcha_answer - .filter((uuid).eq(to_check.uuid)) - .filter(lower(answer).eq(to_check.answer.to_lowercase().clone())), - )) - .get_result::(conn) - .await?; + let captcha_exists = + select(exists(captcha_answer.find(to_check.uuid).filter( + lower(answer).eq(to_check.answer.to_lowercase().clone()), + ))) + .get_result::(conn) + .await?; // delete checked captcha - delete(captcha_answer.filter(uuid.eq(to_check.uuid))) + delete(captcha_answer.find(to_check.uuid)) .execute(conn) .await?; diff --git a/crates/db_schema/src/impls/comment.rs b/crates/db_schema/src/impls/comment.rs index cab033df3..35bc8314a 100644 --- a/crates/db_schema/src/impls/comment.rs +++ b/crates/db_schema/src/impls/comment.rs @@ -192,18 +192,14 @@ impl Likeable for CommentLike { } async fn remove( pool: &mut DbPool<'_>, - person_id_: PersonId, - comment_id_: CommentId, + person_id: PersonId, + comment_id: CommentId, ) -> Result { - use crate::schema::comment_like::dsl::{comment_id, comment_like, person_id}; + use crate::schema::comment_like::dsl::comment_like; let conn = &mut get_conn(pool).await?; - diesel::delete( - comment_like - .filter(comment_id.eq(comment_id_)) - .filter(person_id.eq(person_id_)), - ) - .execute(conn) - .await + diesel::delete(comment_like.find((person_id, comment_id))) + .execute(conn) + .await } } @@ -228,12 +224,10 @@ impl Saveable for CommentSaved { pool: &mut DbPool<'_>, comment_saved_form: &CommentSavedForm, ) -> Result { - use crate::schema::comment_saved::dsl::{comment_id, comment_saved, person_id}; + use crate::schema::comment_saved::dsl::comment_saved; let conn = &mut get_conn(pool).await?; diesel::delete( - comment_saved - .filter(comment_id.eq(comment_saved_form.comment_id)) - .filter(person_id.eq(comment_saved_form.person_id)), + comment_saved.find((comment_saved_form.person_id, comment_saved_form.comment_id)), ) .execute(conn) .await @@ -349,7 +343,6 @@ mod tests { let inserted_comment_like = CommentLike::like(pool, &comment_like_form).await.unwrap(); let expected_comment_like = CommentLike { - id: inserted_comment_like.id, comment_id: inserted_comment.id, post_id: inserted_post.id, person_id: inserted_person.id, @@ -366,7 +359,6 @@ mod tests { let inserted_comment_saved = CommentSaved::save(pool, &comment_saved_form).await.unwrap(); let expected_comment_saved = CommentSaved { - id: inserted_comment_saved.id, comment_id: inserted_comment.id, person_id: inserted_person.id, published: inserted_comment_saved.published, diff --git a/crates/db_schema/src/impls/community.rs b/crates/db_schema/src/impls/community.rs index 442239289..0d2cc88ba 100644 --- a/crates/db_schema/src/impls/community.rs +++ b/crates/db_schema/src/impls/community.rs @@ -95,13 +95,12 @@ impl Joinable for CommunityModerator { pool: &mut DbPool<'_>, community_moderator_form: &CommunityModeratorForm, ) -> Result { - use crate::schema::community_moderator::dsl::{community_id, community_moderator, person_id}; + use crate::schema::community_moderator::dsl::community_moderator; let conn = &mut get_conn(pool).await?; - diesel::delete( - community_moderator - .filter(community_id.eq(community_moderator_form.community_id)) - .filter(person_id.eq(community_moderator_form.person_id)), - ) + diesel::delete(community_moderator.find(( + community_moderator_form.person_id, + community_moderator_form.community_id, + ))) .execute(conn) .await } @@ -199,13 +198,12 @@ impl Bannable for CommunityPersonBan { pool: &mut DbPool<'_>, community_person_ban_form: &CommunityPersonBanForm, ) -> Result { - use crate::schema::community_person_ban::dsl::{community_id, community_person_ban, person_id}; + use crate::schema::community_person_ban::dsl::community_person_ban; let conn = &mut get_conn(pool).await?; - diesel::delete( - community_person_ban - .filter(community_id.eq(community_person_ban_form.community_id)) - .filter(person_id.eq(community_person_ban_form.person_id)), - ) + diesel::delete(community_person_ban.find(( + community_person_ban_form.person_id, + community_person_ban_form.community_id, + ))) .execute(conn) .await } @@ -274,35 +272,22 @@ impl Followable for CommunityFollower { } async fn follow_accepted( pool: &mut DbPool<'_>, - community_id_: CommunityId, - person_id_: PersonId, + community_id: CommunityId, + person_id: PersonId, ) -> Result { - use crate::schema::community_follower::dsl::{ - community_follower, - community_id, - pending, - person_id, - }; + use crate::schema::community_follower::dsl::{community_follower, pending}; let conn = &mut get_conn(pool).await?; - diesel::update( - community_follower - .filter(community_id.eq(community_id_)) - .filter(person_id.eq(person_id_)), - ) - .set(pending.eq(false)) - .get_result::(conn) - .await + diesel::update(community_follower.find((person_id, community_id))) + .set(pending.eq(false)) + .get_result::(conn) + .await } async fn unfollow(pool: &mut DbPool<'_>, form: &CommunityFollowerForm) -> Result { - use crate::schema::community_follower::dsl::{community_follower, community_id, person_id}; + use crate::schema::community_follower::dsl::community_follower; let conn = &mut get_conn(pool).await?; - diesel::delete( - community_follower - .filter(community_id.eq(&form.community_id)) - .filter(person_id.eq(&form.person_id)), - ) - .execute(conn) - .await + diesel::delete(community_follower.find((form.person_id, form.community_id))) + .execute(conn) + .await } } @@ -448,7 +433,6 @@ mod tests { .unwrap(); let expected_community_follower = CommunityFollower { - id: inserted_community_follower.id, community_id: inserted_community.id, person_id: inserted_person.id, pending: false, @@ -465,7 +449,6 @@ mod tests { .unwrap(); let expected_community_moderator = CommunityModerator { - id: inserted_community_moderator.id, community_id: inserted_community.id, person_id: inserted_person.id, published: inserted_community_moderator.published, @@ -482,7 +465,6 @@ mod tests { .unwrap(); let expected_community_person_ban = CommunityPersonBan { - id: inserted_community_person_ban.id, community_id: inserted_community.id, person_id: inserted_person.id, published: inserted_community_person_ban.published, diff --git a/crates/db_schema/src/impls/community_block.rs b/crates/db_schema/src/impls/community_block.rs index 997985a5b..1393f49d3 100644 --- a/crates/db_schema/src/impls/community_block.rs +++ b/crates/db_schema/src/impls/community_block.rs @@ -9,7 +9,6 @@ use diesel::{ dsl::{exists, insert_into}, result::Error, select, - ExpressionMethods, QueryDsl, }; use diesel_async::RunQueryDsl; @@ -22,9 +21,7 @@ impl CommunityBlock { ) -> Result { let conn = &mut get_conn(pool).await?; select(exists( - community_block - .filter(community_id.eq(for_community_id)) - .filter(person_id.eq(for_person_id)), + community_block.find((for_person_id, for_community_id)), )) .get_result(conn) .await @@ -49,11 +46,10 @@ impl Blockable for CommunityBlock { community_block_form: &Self::Form, ) -> Result { let conn = &mut get_conn(pool).await?; - diesel::delete( - community_block - .filter(person_id.eq(community_block_form.person_id)) - .filter(community_id.eq(community_block_form.community_id)), - ) + diesel::delete(community_block.find(( + community_block_form.person_id, + community_block_form.community_id, + ))) .execute(conn) .await } diff --git a/crates/db_schema/src/impls/image_upload.rs b/crates/db_schema/src/impls/image_upload.rs index 58edbf2e3..b62e5ceba 100644 --- a/crates/db_schema/src/impls/image_upload.rs +++ b/crates/db_schema/src/impls/image_upload.rs @@ -1,6 +1,6 @@ use crate::{ - newtypes::{ImageUploadId, LocalUserId}, - schema::image_upload::dsl::{image_upload, local_user_id, pictrs_alias}, + newtypes::LocalUserId, + schema::image_upload::dsl::{image_upload, local_user_id}, source::image_upload::{ImageUpload, ImageUploadForm}, utils::{get_conn, DbPool}, }; @@ -28,20 +28,8 @@ impl ImageUpload { .await } - pub async fn delete( - pool: &mut DbPool<'_>, - image_upload_id: ImageUploadId, - ) -> Result { - let conn = &mut get_conn(pool).await?; - diesel::delete(image_upload.find(image_upload_id)) - .execute(conn) - .await - } - pub async fn delete_by_alias(pool: &mut DbPool<'_>, alias: &str) -> Result { let conn = &mut get_conn(pool).await?; - diesel::delete(image_upload.filter(pictrs_alias.eq(alias))) - .execute(conn) - .await + diesel::delete(image_upload.find(alias)).execute(conn).await } } diff --git a/crates/db_schema/src/impls/instance.rs b/crates/db_schema/src/impls/instance.rs index b94e628d6..7da4ce354 100644 --- a/crates/db_schema/src/impls/instance.rs +++ b/crates/db_schema/src/impls/instance.rs @@ -115,7 +115,7 @@ impl Instance { .left_join(federation_allowlist::table) .select(( Self::as_select(), - federation_allowlist::id.nullable().is_not_null(), + federation_allowlist::instance_id.nullable().is_not_null(), is_dead_expr, )) .order_by(instance::id) @@ -126,7 +126,7 @@ impl Instance { .left_join(federation_blocklist::table) .select(( Self::as_select(), - federation_blocklist::id.nullable().is_null(), + federation_blocklist::instance_id.nullable().is_null(), is_dead_expr, )) .order_by(instance::id) @@ -150,8 +150,8 @@ impl Instance { .select(( Self::as_select(), Option::::as_select(), - federation_blocklist::id.nullable().is_not_null(), - federation_allowlist::id.nullable().is_not_null(), + federation_blocklist::instance_id.nullable().is_not_null(), + federation_allowlist::instance_id.nullable().is_not_null(), )) .get_results(conn) .await diff --git a/crates/db_schema/src/impls/instance_block.rs b/crates/db_schema/src/impls/instance_block.rs index f024f2636..e32688411 100644 --- a/crates/db_schema/src/impls/instance_block.rs +++ b/crates/db_schema/src/impls/instance_block.rs @@ -9,7 +9,6 @@ use diesel::{ dsl::{exists, insert_into}, result::Error, select, - ExpressionMethods, QueryDsl, }; use diesel_async::RunQueryDsl; @@ -22,9 +21,7 @@ impl InstanceBlock { ) -> Result { let conn = &mut get_conn(pool).await?; select(exists( - instance_block - .filter(instance_id.eq(for_instance_id)) - .filter(person_id.eq(for_person_id)), + instance_block.find((for_person_id, for_instance_id)), )) .get_result(conn) .await @@ -49,11 +46,10 @@ impl Blockable for InstanceBlock { instance_block_form: &Self::Form, ) -> Result { let conn = &mut get_conn(pool).await?; - diesel::delete( - instance_block - .filter(person_id.eq(instance_block_form.person_id)) - .filter(instance_id.eq(instance_block_form.instance_id)), - ) + diesel::delete(instance_block.find(( + instance_block_form.person_id, + instance_block_form.instance_id, + ))) .execute(conn) .await } diff --git a/crates/db_schema/src/impls/language.rs b/crates/db_schema/src/impls/language.rs index 53aadbac8..db72b837f 100644 --- a/crates/db_schema/src/impls/language.rs +++ b/crates/db_schema/src/impls/language.rs @@ -1,7 +1,7 @@ use crate::{ diesel::ExpressionMethods, newtypes::LanguageId, - schema::language::dsl::{code, id, language}, + schema::language::dsl::{code, language}, source::language::Language, utils::{get_conn, DbPool}, }; @@ -16,7 +16,7 @@ impl Language { pub async fn read_from_id(pool: &mut DbPool<'_>, id_: LanguageId) -> Result { let conn = &mut get_conn(pool).await?; - language.filter(id.eq(id_)).first::(conn).await + language.find(id_).first::(conn).await } /// Attempts to find the given language code and return its ID. If not found, returns none. diff --git a/crates/db_schema/src/impls/login_token.rs b/crates/db_schema/src/impls/login_token.rs index b1d1124d6..71cac6a19 100644 --- a/crates/db_schema/src/impls/login_token.rs +++ b/crates/db_schema/src/impls/login_token.rs @@ -1,7 +1,7 @@ use crate::{ diesel::{ExpressionMethods, QueryDsl}, newtypes::LocalUserId, - schema::login_token::{dsl::login_token, token, user_id}, + schema::login_token::{dsl::login_token, user_id}, source::login_token::{LoginToken, LoginTokenCreateForm}, utils::{get_conn, DbPool}, }; @@ -25,9 +25,7 @@ impl LoginToken { ) -> Result { let conn = &mut get_conn(pool).await?; select(exists( - login_token - .filter(user_id.eq(user_id_)) - .filter(token.eq(token_)), + login_token.find(token_).filter(user_id.eq(user_id_)), )) .get_result(conn) .await @@ -48,9 +46,7 @@ impl LoginToken { /// Invalidate specific token on user logout. pub async fn invalidate(pool: &mut DbPool<'_>, token_: &str) -> Result { let conn = &mut get_conn(pool).await?; - delete(login_token.filter(token.eq(token_))) - .execute(conn) - .await + delete(login_token.find(token_)).execute(conn).await } /// Invalidate all logins of given user on password reset/change, account deletion or site ban. diff --git a/crates/db_schema/src/impls/person.rs b/crates/db_schema/src/impls/person.rs index 12ec0392f..e36e7b35e 100644 --- a/crates/db_schema/src/impls/person.rs +++ b/crates/db_schema/src/impls/person.rs @@ -155,15 +155,11 @@ impl Followable for PersonFollower { unimplemented!() } async fn unfollow(pool: &mut DbPool<'_>, form: &PersonFollowerForm) -> Result { - use crate::schema::person_follower::dsl::{follower_id, person_follower, person_id}; + use crate::schema::person_follower::dsl::person_follower; let conn = &mut get_conn(pool).await?; - diesel::delete( - person_follower - .filter(follower_id.eq(&form.follower_id)) - .filter(person_id.eq(&form.person_id)), - ) - .execute(conn) - .await + diesel::delete(person_follower.find((form.follower_id, form.person_id))) + .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/person_block.rs b/crates/db_schema/src/impls/person_block.rs index a616375e1..0dbf003d8 100644 --- a/crates/db_schema/src/impls/person_block.rs +++ b/crates/db_schema/src/impls/person_block.rs @@ -9,7 +9,6 @@ use diesel::{ dsl::{exists, insert_into}, result::Error, select, - ExpressionMethods, QueryDsl, }; use diesel_async::RunQueryDsl; @@ -21,13 +20,9 @@ impl PersonBlock { for_recipient_id: PersonId, ) -> Result { let conn = &mut get_conn(pool).await?; - select(exists( - person_block - .filter(person_id.eq(for_person_id)) - .filter(target_id.eq(for_recipient_id)), - )) - .get_result(conn) - .await + select(exists(person_block.find((for_person_id, for_recipient_id)))) + .get_result(conn) + .await } } @@ -49,12 +44,8 @@ impl Blockable for PersonBlock { } async fn unblock(pool: &mut DbPool<'_>, person_block_form: &Self::Form) -> Result { let conn = &mut get_conn(pool).await?; - diesel::delete( - person_block - .filter(person_id.eq(person_block_form.person_id)) - .filter(target_id.eq(person_block_form.target_id)), - ) - .execute(conn) - .await + diesel::delete(person_block.find((person_block_form.person_id, person_block_form.target_id))) + .execute(conn) + .await } } diff --git a/crates/db_schema/src/impls/post.rs b/crates/db_schema/src/impls/post.rs index 4a719415a..f7ff633ec 100644 --- a/crates/db_schema/src/impls/post.rs +++ b/crates/db_schema/src/impls/post.rs @@ -266,13 +266,9 @@ impl Likeable for PostLike { ) -> Result { use crate::schema::post_like::dsl; let conn = &mut get_conn(pool).await?; - diesel::delete( - dsl::post_like - .filter(dsl::post_id.eq(post_id)) - .filter(dsl::person_id.eq(person_id)), - ) - .execute(conn) - .await + diesel::delete(dsl::post_like.find((person_id, post_id))) + .execute(conn) + .await } } @@ -291,15 +287,11 @@ impl Saveable for PostSaved { .await } async fn unsave(pool: &mut DbPool<'_>, post_saved_form: &PostSavedForm) -> Result { - use crate::schema::post_saved::dsl::{person_id, post_id, post_saved}; + use crate::schema::post_saved::dsl::post_saved; let conn = &mut get_conn(pool).await?; - diesel::delete( - post_saved - .filter(post_id.eq(post_saved_form.post_id)) - .filter(person_id.eq(post_saved_form.person_id)), - ) - .execute(conn) - .await + diesel::delete(post_saved.find((post_saved_form.person_id, post_saved_form.post_id))) + .execute(conn) + .await } } @@ -444,7 +436,6 @@ mod tests { let inserted_post_like = PostLike::like(pool, &post_like_form).await.unwrap(); let expected_post_like = PostLike { - id: inserted_post_like.id, post_id: inserted_post.id, person_id: inserted_person.id, published: inserted_post_like.published, @@ -460,7 +451,6 @@ mod tests { let inserted_post_saved = PostSaved::save(pool, &post_saved_form).await.unwrap(); let expected_post_saved = PostSaved { - id: inserted_post_saved.id, post_id: inserted_post.id, person_id: inserted_person.id, published: inserted_post_saved.published, diff --git a/crates/db_schema/src/newtypes.rs b/crates/db_schema/src/newtypes.rs index c59577670..5e5970e91 100644 --- a/crates/db_schema/src/newtypes.rs +++ b/crates/db_schema/src/newtypes.rs @@ -83,12 +83,6 @@ pub struct PersonMentionId(i32); /// The person block id. pub struct PersonBlockId(i32); -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "full", derive(DieselNewType, TS))] -#[cfg_attr(feature = "full", ts(export))] -/// The community block id. -pub struct CommunityBlockId(i32); - #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "full", derive(DieselNewType, TS))] #[cfg_attr(feature = "full", ts(export))] @@ -119,30 +113,12 @@ pub struct SiteId(i32); /// The language id. pub struct LanguageId(pub i32); -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "full", derive(DieselNewType))] -pub struct LocalUserLanguageId(pub i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "full", derive(DieselNewType))] -pub struct SiteLanguageId(pub i32); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "full", derive(DieselNewType))] -pub struct CommunityLanguageId(pub i32); - #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "full", derive(DieselNewType, TS))] #[cfg_attr(feature = "full", ts(export))] /// The comment reply id. pub struct CommentReplyId(i32); -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] -#[cfg_attr(feature = "full", derive(DieselNewType, TS))] -#[cfg_attr(feature = "full", ts(export))] -/// The Image Upload id. -pub struct ImageUploadId(i32); - #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "full", derive(DieselNewType, TS))] #[cfg_attr(feature = "full", ts(export))] diff --git a/crates/db_schema/src/schema.rs b/crates/db_schema/src/schema.rs index fe23a6a30..88d468a6f 100644 --- a/crates/db_schema/src/schema.rs +++ b/crates/db_schema/src/schema.rs @@ -65,8 +65,7 @@ diesel::table! { } diesel::table! { - captcha_answer (id) { - id -> Int4, + captcha_answer (uuid) { uuid -> Uuid, answer -> Text, published -> Timestamptz, @@ -96,8 +95,7 @@ diesel::table! { } diesel::table! { - comment_aggregates (id) { - id -> Int4, + comment_aggregates (comment_id) { comment_id -> Int4, score -> Int8, upvotes -> Int8, @@ -110,8 +108,7 @@ diesel::table! { } diesel::table! { - comment_like (id) { - id -> Int4, + comment_like (person_id, comment_id) { person_id -> Int4, comment_id -> Int4, post_id -> Int4, @@ -145,8 +142,7 @@ diesel::table! { } diesel::table! { - comment_saved (id) { - id -> Int4, + comment_saved (person_id, comment_id) { comment_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -191,8 +187,7 @@ diesel::table! { } diesel::table! { - community_aggregates (id) { - id -> Int4, + community_aggregates (community_id) { community_id -> Int4, subscribers -> Int8, posts -> Int8, @@ -207,8 +202,7 @@ diesel::table! { } diesel::table! { - community_block (id) { - id -> Int4, + community_block (person_id, community_id) { person_id -> Int4, community_id -> Int4, published -> Timestamptz, @@ -216,8 +210,7 @@ diesel::table! { } diesel::table! { - community_follower (id) { - id -> Int4, + community_follower (person_id, community_id) { community_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -226,16 +219,14 @@ diesel::table! { } diesel::table! { - community_language (id) { - id -> Int4, + community_language (community_id, language_id) { community_id -> Int4, language_id -> Int4, } } diesel::table! { - community_moderator (id) { - id -> Int4, + community_moderator (person_id, community_id) { community_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -243,8 +234,7 @@ diesel::table! { } diesel::table! { - community_person_ban (id) { - id -> Int4, + community_person_ban (person_id, community_id) { community_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -267,8 +257,7 @@ diesel::table! { } diesel::table! { - custom_emoji_keyword (id) { - id -> Int4, + custom_emoji_keyword (custom_emoji_id, keyword) { custom_emoji_id -> Int4, #[max_length = 128] keyword -> Varchar, @@ -286,8 +275,7 @@ diesel::table! { } diesel::table! { - federation_allowlist (id) { - id -> Int4, + federation_allowlist (instance_id) { instance_id -> Int4, published -> Timestamptz, updated -> Nullable, @@ -295,8 +283,7 @@ diesel::table! { } diesel::table! { - federation_blocklist (id) { - id -> Int4, + federation_blocklist (instance_id) { instance_id -> Int4, published -> Timestamptz, updated -> Nullable, @@ -304,8 +291,7 @@ diesel::table! { } diesel::table! { - federation_queue_state (id) { - id -> Int4, + federation_queue_state (instance_id) { instance_id -> Int4, last_successful_id -> Nullable, fail_count -> Int4, @@ -315,8 +301,7 @@ diesel::table! { } diesel::table! { - image_upload (id) { - id -> Int4, + image_upload (pictrs_alias) { local_user_id -> Int4, pictrs_alias -> Text, pictrs_delete_token -> Text, @@ -339,8 +324,7 @@ diesel::table! { } diesel::table! { - instance_block (id) { - id -> Int4, + instance_block (person_id, instance_id) { person_id -> Int4, instance_id -> Int4, published -> Timestamptz, @@ -391,8 +375,7 @@ diesel::table! { } diesel::table! { - local_site_rate_limit (id) { - id -> Int4, + local_site_rate_limit (local_site_id) { local_site_id -> Int4, message -> Int4, message_per_second -> Int4, @@ -452,16 +435,14 @@ diesel::table! { } diesel::table! { - local_user_language (id) { - id -> Int4, + local_user_language (local_user_id, language_id) { local_user_id -> Int4, language_id -> Int4, } } diesel::table! { - login_token (id) { - id -> Int4, + login_token (token) { token -> Text, user_id -> Int4, published -> Timestamptz, @@ -632,8 +613,7 @@ diesel::table! { } diesel::table! { - person_aggregates (id) { - id -> Int4, + person_aggregates (person_id) { person_id -> Int4, post_count -> Int8, post_score -> Int8, @@ -643,16 +623,14 @@ diesel::table! { } diesel::table! { - person_ban (id) { - id -> Int4, + person_ban (person_id) { person_id -> Int4, published -> Timestamptz, } } diesel::table! { - person_block (id) { - id -> Int4, + person_block (person_id, target_id) { person_id -> Int4, target_id -> Int4, published -> Timestamptz, @@ -660,8 +638,7 @@ diesel::table! { } diesel::table! { - person_follower (id) { - id -> Int4, + person_follower (follower_id, person_id) { person_id -> Int4, follower_id -> Int4, published -> Timestamptz, @@ -680,8 +657,7 @@ diesel::table! { } diesel::table! { - person_post_aggregates (id) { - id -> Int4, + person_post_aggregates (person_id, post_id) { person_id -> Int4, post_id -> Int4, read_comments -> Int8, @@ -719,8 +695,7 @@ diesel::table! { } diesel::table! { - post_aggregates (id) { - id -> Int4, + post_aggregates (post_id) { post_id -> Int4, comments -> Int8, score -> Int8, @@ -742,8 +717,7 @@ diesel::table! { } diesel::table! { - post_like (id) { - id -> Int4, + post_like (person_id, post_id) { post_id -> Int4, person_id -> Int4, score -> Int2, @@ -752,8 +726,7 @@ diesel::table! { } diesel::table! { - post_read (id) { - id -> Int4, + post_read (person_id, post_id) { post_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -778,8 +751,7 @@ diesel::table! { } diesel::table! { - post_saved (id) { - id -> Int4, + post_saved (person_id, post_id) { post_id -> Int4, person_id -> Int4, published -> Timestamptz, @@ -817,8 +789,7 @@ diesel::table! { } diesel::table! { - received_activity (id) { - id -> Int8, + received_activity (ap_id) { ap_id -> Text, published -> Timestamptz, } @@ -884,8 +855,7 @@ diesel::table! { } diesel::table! { - site_aggregates (id) { - id -> Int4, + site_aggregates (site_id) { site_id -> Int4, users -> Int8, posts -> Int8, @@ -899,8 +869,7 @@ diesel::table! { } diesel::table! { - site_language (id) { - id -> Int4, + site_language (site_id, language_id) { site_id -> Int4, language_id -> Int4, } diff --git a/crates/db_schema/src/source/actor_language.rs b/crates/db_schema/src/source/actor_language.rs index 6780be51b..b3da61abc 100644 --- a/crates/db_schema/src/source/actor_language.rs +++ b/crates/db_schema/src/source/actor_language.rs @@ -1,12 +1,4 @@ -use crate::newtypes::{ - CommunityId, - CommunityLanguageId, - LanguageId, - LocalUserId, - LocalUserLanguageId, - SiteId, - SiteLanguageId, -}; +use crate::newtypes::{CommunityId, LanguageId, LocalUserId, SiteId}; #[cfg(feature = "full")] use crate::schema::local_user_language; use serde::{Deserialize, Serialize}; @@ -14,9 +6,8 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Identifiable))] #[cfg_attr(feature = "full", diesel(table_name = local_user_language))] +#[cfg_attr(feature = "full", diesel(primary_key(local_user_id, language_id)))] pub struct LocalUserLanguage { - #[serde(skip)] - pub id: LocalUserLanguageId, pub local_user_id: LocalUserId, pub language_id: LanguageId, } @@ -35,9 +26,8 @@ use crate::schema::community_language; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Identifiable))] #[cfg_attr(feature = "full", diesel(table_name = community_language))] +#[cfg_attr(feature = "full", diesel(primary_key(community_id, language_id)))] pub struct CommunityLanguage { - #[serde(skip)] - pub id: CommunityLanguageId, pub community_id: CommunityId, pub language_id: LanguageId, } @@ -56,9 +46,8 @@ use crate::schema::site_language; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Identifiable))] #[cfg_attr(feature = "full", diesel(table_name = site_language))] +#[cfg_attr(feature = "full", diesel(primary_key(site_id, language_id)))] pub struct SiteLanguage { - #[serde(skip)] - pub id: SiteLanguageId, pub site_id: SiteId, pub language_id: LanguageId, } diff --git a/crates/db_schema/src/source/captcha_answer.rs b/crates/db_schema/src/source/captcha_answer.rs index b7e9636c4..2660968ec 100644 --- a/crates/db_schema/src/source/captcha_answer.rs +++ b/crates/db_schema/src/source/captcha_answer.rs @@ -10,7 +10,6 @@ use uuid::Uuid; #[cfg_attr(feature = "full", derive(Queryable))] #[cfg_attr(feature = "full", diesel(table_name = captcha_answer))] pub struct CaptchaAnswer { - pub id: i32, pub uuid: Uuid, pub answer: String, pub published: DateTime, diff --git a/crates/db_schema/src/source/comment.rs b/crates/db_schema/src/source/comment.rs index efe3b7cdf..4969968be 100644 --- a/crates/db_schema/src/source/comment.rs +++ b/crates/db_schema/src/source/comment.rs @@ -86,8 +86,8 @@ pub struct CommentUpdateForm { #[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::comment::Comment)))] #[cfg_attr(feature = "full", diesel(table_name = comment_like))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, comment_id)))] pub struct CommentLike { - pub id: i32, pub person_id: PersonId, pub comment_id: CommentId, pub post_id: PostId, // TODO this is redundant @@ -109,8 +109,8 @@ pub struct CommentLikeForm { #[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::comment::Comment)))] #[cfg_attr(feature = "full", diesel(table_name = comment_saved))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, comment_id)))] pub struct CommentSaved { - pub id: i32, pub comment_id: CommentId, pub person_id: PersonId, pub published: DateTime, diff --git a/crates/db_schema/src/source/community.rs b/crates/db_schema/src/source/community.rs index 5da772be3..29663c81d 100644 --- a/crates/db_schema/src/source/community.rs +++ b/crates/db_schema/src/source/community.rs @@ -134,8 +134,8 @@ pub struct CommunityUpdateForm { diesel(belongs_to(crate::source::community::Community)) )] #[cfg_attr(feature = "full", diesel(table_name = community_moderator))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, community_id)))] pub struct CommunityModerator { - pub id: i32, pub community_id: CommunityId, pub person_id: PersonId, pub published: DateTime, @@ -156,8 +156,8 @@ pub struct CommunityModeratorForm { diesel(belongs_to(crate::source::community::Community)) )] #[cfg_attr(feature = "full", diesel(table_name = community_person_ban))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, community_id)))] pub struct CommunityPersonBan { - pub id: i32, pub community_id: CommunityId, pub person_id: PersonId, pub published: DateTime, @@ -180,8 +180,8 @@ pub struct CommunityPersonBanForm { diesel(belongs_to(crate::source::community::Community)) )] #[cfg_attr(feature = "full", diesel(table_name = community_follower))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, community_id)))] pub struct CommunityFollower { - pub id: i32, pub community_id: CommunityId, pub person_id: PersonId, pub published: DateTime, diff --git a/crates/db_schema/src/source/community_block.rs b/crates/db_schema/src/source/community_block.rs index 628e77ade..3154f1d77 100644 --- a/crates/db_schema/src/source/community_block.rs +++ b/crates/db_schema/src/source/community_block.rs @@ -1,4 +1,4 @@ -use crate::newtypes::{CommunityBlockId, CommunityId, PersonId}; +use crate::newtypes::{CommunityId, PersonId}; #[cfg(feature = "full")] use crate::schema::community_block; use chrono::{DateTime, Utc}; @@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize}; diesel(belongs_to(crate::source::community::Community)) )] #[cfg_attr(feature = "full", diesel(table_name = community_block))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, community_id)))] pub struct CommunityBlock { - pub id: CommunityBlockId, pub person_id: PersonId, pub community_id: CommunityId, pub published: DateTime, diff --git a/crates/db_schema/src/source/custom_emoji_keyword.rs b/crates/db_schema/src/source/custom_emoji_keyword.rs index b1811cf44..679bbccea 100644 --- a/crates/db_schema/src/source/custom_emoji_keyword.rs +++ b/crates/db_schema/src/source/custom_emoji_keyword.rs @@ -13,10 +13,10 @@ use typed_builder::TypedBuilder; feature = "full", diesel(belongs_to(crate::source::custom_emoji::CustomEmoji)) )] +#[cfg_attr(feature = "full", diesel(primary_key(custom_emoji_id, keyword)))] #[cfg_attr(feature = "full", ts(export))] /// A custom keyword for an emoji. pub struct CustomEmojiKeyword { - pub id: i32, pub custom_emoji_id: CustomEmojiId, pub keyword: String, } diff --git a/crates/db_schema/src/source/federation_allowlist.rs b/crates/db_schema/src/source/federation_allowlist.rs index 534e1b02e..62ceb7d6f 100644 --- a/crates/db_schema/src/source/federation_allowlist.rs +++ b/crates/db_schema/src/source/federation_allowlist.rs @@ -12,8 +12,8 @@ use std::fmt::Debug; diesel(belongs_to(crate::source::instance::Instance)) )] #[cfg_attr(feature = "full", diesel(table_name = federation_allowlist))] +#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] pub struct FederationAllowList { - pub id: i32, pub instance_id: InstanceId, pub published: DateTime, pub updated: Option>, diff --git a/crates/db_schema/src/source/federation_blocklist.rs b/crates/db_schema/src/source/federation_blocklist.rs index 0cf615d7b..5f5bd835b 100644 --- a/crates/db_schema/src/source/federation_blocklist.rs +++ b/crates/db_schema/src/source/federation_blocklist.rs @@ -12,8 +12,8 @@ use std::fmt::Debug; diesel(belongs_to(crate::source::instance::Instance)) )] #[cfg_attr(feature = "full", diesel(table_name = federation_blocklist))] +#[cfg_attr(feature = "full", diesel(primary_key(instance_id)))] pub struct FederationBlockList { - pub id: i32, pub instance_id: InstanceId, pub published: DateTime, pub updated: Option>, diff --git a/crates/db_schema/src/source/image_upload.rs b/crates/db_schema/src/source/image_upload.rs index 0a3c4d6c4..db1b7800b 100644 --- a/crates/db_schema/src/source/image_upload.rs +++ b/crates/db_schema/src/source/image_upload.rs @@ -1,4 +1,4 @@ -use crate::newtypes::{ImageUploadId, LocalUserId}; +use crate::newtypes::LocalUserId; #[cfg(feature = "full")] use crate::schema::image_upload; use chrono::{DateTime, Utc}; @@ -13,13 +13,13 @@ use typed_builder::TypedBuilder; #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = image_upload))] +#[cfg_attr(feature = "full", diesel(primary_key(pictrs_alias)))] #[cfg_attr(feature = "full", ts(export))] #[cfg_attr( feature = "full", diesel(belongs_to(crate::source::local_user::LocalUser)) )] pub struct ImageUpload { - pub id: ImageUploadId, pub local_user_id: LocalUserId, pub pictrs_alias: String, pub pictrs_delete_token: String, diff --git a/crates/db_schema/src/source/instance_block.rs b/crates/db_schema/src/source/instance_block.rs index 1aa215e45..fe737ec6f 100644 --- a/crates/db_schema/src/source/instance_block.rs +++ b/crates/db_schema/src/source/instance_block.rs @@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize}; diesel(belongs_to(crate::source::instance::Instance)) )] #[cfg_attr(feature = "full", diesel(table_name = instance_block))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, instance_id)))] pub struct InstanceBlock { - pub id: i32, pub person_id: PersonId, pub instance_id: InstanceId, pub published: DateTime, diff --git a/crates/db_schema/src/source/local_site_rate_limit.rs b/crates/db_schema/src/source/local_site_rate_limit.rs index af7023f0f..59da06270 100644 --- a/crates/db_schema/src/source/local_site_rate_limit.rs +++ b/crates/db_schema/src/source/local_site_rate_limit.rs @@ -12,6 +12,7 @@ use typed_builder::TypedBuilder; #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = local_site_rate_limit))] +#[cfg_attr(feature = "full", diesel(primary_key(local_site_id)))] #[cfg_attr( feature = "full", diesel(belongs_to(crate::source::local_site::LocalSite)) @@ -19,7 +20,6 @@ use typed_builder::TypedBuilder; #[cfg_attr(feature = "full", ts(export))] /// Rate limits for your site. Given in count / length of time. pub struct LocalSiteRateLimit { - pub id: i32, pub local_site_id: LocalSiteId, pub message: i32, pub message_per_second: i32, diff --git a/crates/db_schema/src/source/login_token.rs b/crates/db_schema/src/source/login_token.rs index 45f74c41f..97a3bba53 100644 --- a/crates/db_schema/src/source/login_token.rs +++ b/crates/db_schema/src/source/login_token.rs @@ -12,9 +12,9 @@ use ts_rs::TS; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] #[cfg_attr(feature = "full", derive(Queryable, Identifiable, TS))] #[cfg_attr(feature = "full", diesel(table_name = login_token))] +#[cfg_attr(feature = "full", diesel(primary_key(token)))] #[cfg_attr(feature = "full", ts(export))] pub struct LoginToken { - pub id: i32, /// Jwt token for this login #[serde(skip)] pub token: String, diff --git a/crates/db_schema/src/source/person.rs b/crates/db_schema/src/source/person.rs index 82772fefa..657006f20 100644 --- a/crates/db_schema/src/source/person.rs +++ b/crates/db_schema/src/source/person.rs @@ -115,8 +115,8 @@ pub struct PersonUpdateForm { #[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::person::Person)))] #[cfg_attr(feature = "full", diesel(table_name = person_follower))] +#[cfg_attr(feature = "full", diesel(primary_key(follower_id, person_id)))] pub struct PersonFollower { - pub id: i32, pub person_id: PersonId, pub follower_id: PersonId, pub published: DateTime, diff --git a/crates/db_schema/src/source/person_block.rs b/crates/db_schema/src/source/person_block.rs index 3380fbfc3..3b22aec2c 100644 --- a/crates/db_schema/src/source/person_block.rs +++ b/crates/db_schema/src/source/person_block.rs @@ -1,4 +1,4 @@ -use crate::newtypes::{PersonBlockId, PersonId}; +use crate::newtypes::PersonId; #[cfg(feature = "full")] use crate::schema::person_block; use chrono::{DateTime, Utc}; @@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::person::Person)))] #[cfg_attr(feature = "full", diesel(table_name = person_block))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, target_id)))] pub struct PersonBlock { - pub id: PersonBlockId, pub person_id: PersonId, pub target_id: PersonId, pub published: DateTime, diff --git a/crates/db_schema/src/source/post.rs b/crates/db_schema/src/source/post.rs index 72c32d4af..760697b0b 100644 --- a/crates/db_schema/src/source/post.rs +++ b/crates/db_schema/src/source/post.rs @@ -114,8 +114,8 @@ pub struct PostUpdateForm { #[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::post::Post)))] #[cfg_attr(feature = "full", diesel(table_name = post_like))] +#[cfg_attr(feature = "full", diesel(primary_key(person_id, post_id)))] pub struct PostLike { - pub id: i32, pub post_id: PostId, pub person_id: PersonId, pub score: i16, @@ -135,8 +135,8 @@ pub struct PostLikeForm { #[cfg_attr(feature = "full", derive(Identifiable, Queryable, Associations))] #[cfg_attr(feature = "full", diesel(belongs_to(crate::source::post::Post)))] #[cfg_attr(feature = "full", diesel(table_name = post_saved))] +#[cfg_attr(feature = "full", diesel(primary_key(post_id, person_id)))] pub struct PostSaved { - pub id: i32, pub post_id: PostId, pub person_id: PersonId, pub published: DateTime, diff --git a/crates/db_views/src/comment_report_view.rs b/crates/db_views/src/comment_report_view.rs index e1b182caf..b883fb8fe 100644 --- a/crates/db_views/src/comment_report_view.rs +++ b/crates/db_views/src/comment_report_view.rs @@ -62,7 +62,7 @@ fn queries<'a>() -> Queries< person::all_columns, aliases::person1.fields(person::all_columns), comment_aggregates::all_columns, - community_person_ban::id.nullable().is_not_null(), + community_person_ban::community_id.nullable().is_not_null(), comment_like::score.nullable(), aliases::person2.fields(person::all_columns).nullable(), ); @@ -425,7 +425,6 @@ mod tests { }, creator_banned_from_community: false, counts: CommentAggregates { - id: agg.id, comment_id: inserted_comment.id, score: 0, upvotes: 0, diff --git a/crates/db_views/src/comment_view.rs b/crates/db_views/src/comment_view.rs index 99f046cdf..ad01ff309 100644 --- a/crates/db_views/src/comment_view.rs +++ b/crates/db_views/src/comment_view.rs @@ -110,14 +110,14 @@ fn queries<'a>() -> Queries< post::all_columns, community::all_columns, comment_aggregates::all_columns, - community_person_ban::id.nullable().is_not_null(), + community_person_ban::community_id.nullable().is_not_null(), aliases::community_moderator1 - .field(community_moderator::id) + .field(community_moderator::community_id) .nullable() .is_not_null(), CommunityFollower::select_subscribed_type(), - comment_saved::id.nullable().is_not_null(), - person_block::id.nullable().is_not_null(), + comment_saved::comment_id.nullable().is_not_null(), + person_block::person_id.nullable().is_not_null(), comment_like::score.nullable(), ); @@ -509,7 +509,6 @@ mod tests { .unwrap(); let expected_block = PersonBlock { - id: inserted_block.id, person_id: inserted_person.id, target_id: inserted_person_2.id, published: inserted_block.published, @@ -947,7 +946,6 @@ mod tests { featured_url: data.inserted_community.featured_url.clone(), }, counts: CommentAggregates { - id: agg.id, comment_id: data.inserted_comment_0.id, score: 1, upvotes: 1, diff --git a/crates/db_views/src/post_report_view.rs b/crates/db_views/src/post_report_view.rs index 4e0d896ca..32d8f8392 100644 --- a/crates/db_views/src/post_report_view.rs +++ b/crates/db_views/src/post_report_view.rs @@ -60,7 +60,7 @@ fn queries<'a>() -> Queries< community::all_columns, person::all_columns, aliases::person1.fields(person::all_columns), - community_person_ban::id.nullable().is_not_null(), + community_person_ban::community_id.nullable().is_not_null(), post_like::score.nullable(), post_aggregates::all_columns, aliases::person2.fields(person::all_columns.nullable()), diff --git a/crates/db_views/src/post_view.rs b/crates/db_views/src/post_view.rs index 51213abb2..909b8079f 100644 --- a/crates/db_views/src/post_view.rs +++ b/crates/db_views/src/post_view.rs @@ -995,7 +995,6 @@ mod tests { let inserted_post_like = PostLike::like(pool, &post_like_form).await.unwrap(); let expected_post_like = PostLike { - id: inserted_post_like.id, post_id: data.inserted_post.id, person_id: data.local_user_view.person.id, published: inserted_post_like.published, @@ -1462,7 +1461,6 @@ mod tests { featured_url: inserted_community.featured_url.clone(), }, counts: PostAggregates { - id: agg.id, post_id: inserted_post.id, comments: 0, score: 0, diff --git a/crates/db_views/src/private_message_view.rs b/crates/db_views/src/private_message_view.rs index de0ae2282..54bae9482 100644 --- a/crates/db_views/src/private_message_view.rs +++ b/crates/db_views/src/private_message_view.rs @@ -312,7 +312,6 @@ mod tests { .unwrap(); let expected_block = PersonBlock { - id: inserted_block.id, person_id: timmy.id, target_id: sara.id, published: inserted_block.published, diff --git a/crates/db_views_actor/src/comment_reply_view.rs b/crates/db_views_actor/src/comment_reply_view.rs index e5a03eaf6..eed8f73ad 100644 --- a/crates/db_views_actor/src/comment_reply_view.rs +++ b/crates/db_views_actor/src/comment_reply_view.rs @@ -96,11 +96,11 @@ fn queries<'a>() -> Queries< community::all_columns, aliases::person1.fields(person::all_columns), comment_aggregates::all_columns, - community_person_ban::id.nullable().is_not_null(), - community_moderator::id.nullable().is_not_null(), + community_person_ban::community_id.nullable().is_not_null(), + community_moderator::community_id.nullable().is_not_null(), CommunityFollower::select_subscribed_type(), - comment_saved::id.nullable().is_not_null(), - person_block::id.nullable().is_not_null(), + comment_saved::comment_id.nullable().is_not_null(), + person_block::person_id.nullable().is_not_null(), comment_like::score.nullable(), )) }; diff --git a/crates/db_views_actor/src/community_view.rs b/crates/db_views_actor/src/community_view.rs index f646e21f8..7db6cfcf8 100644 --- a/crates/db_views_actor/src/community_view.rs +++ b/crates/db_views_actor/src/community_view.rs @@ -62,7 +62,7 @@ fn queries<'a>() -> Queries< let selection = ( community::all_columns, CommunityFollower::select_subscribed_type(), - community_block::id.nullable().is_not_null(), + community_block::community_id.nullable().is_not_null(), community_aggregates::all_columns, ); diff --git a/crates/db_views_actor/src/person_mention_view.rs b/crates/db_views_actor/src/person_mention_view.rs index c44ee791c..4b1178fe6 100644 --- a/crates/db_views_actor/src/person_mention_view.rs +++ b/crates/db_views_actor/src/person_mention_view.rs @@ -85,11 +85,11 @@ fn queries<'a>() -> Queries< community::all_columns, aliases::person1.fields(person::all_columns), comment_aggregates::all_columns, - community_person_ban::id.nullable().is_not_null(), - community_moderator::id.nullable().is_not_null(), + community_person_ban::community_id.nullable().is_not_null(), + community_moderator::community_id.nullable().is_not_null(), CommunityFollower::select_subscribed_type(), - comment_saved::id.nullable().is_not_null(), - person_block::id.nullable().is_not_null(), + comment_saved::comment_id.nullable().is_not_null(), + person_block::person_id.nullable().is_not_null(), comment_like::score.nullable(), ); diff --git a/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/down.sql b/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/down.sql new file mode 100644 index 000000000..b5078355e --- /dev/null +++ b/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/down.sql @@ -0,0 +1,191 @@ +ALTER TABLE captcha_answer + ADD UNIQUE (uuid), + DROP CONSTRAINT captcha_answer_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE comment_aggregates + ADD UNIQUE (comment_id), + DROP CONSTRAINT comment_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_comment_like_person ON comment_like (person_id); + +ALTER TABLE comment_like + ADD UNIQUE (comment_id, person_id), + DROP CONSTRAINT comment_like_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_comment_saved_person_id ON comment_saved (person_id); + +ALTER TABLE comment_saved + ADD UNIQUE (comment_id, person_id), + DROP CONSTRAINT comment_saved_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE community_aggregates + ADD UNIQUE (community_id), + DROP CONSTRAINT community_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_community_block_person ON community_block (person_id); + +ALTER TABLE community_block + ADD UNIQUE (person_id, community_id), + DROP CONSTRAINT community_block_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_community_follower_person ON community_follower (person_id); + +ALTER TABLE community_follower + ADD UNIQUE (community_id, person_id), + DROP CONSTRAINT community_follower_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE community_language + ADD UNIQUE (community_id, language_id), + DROP CONSTRAINT community_language_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_community_moderator_person ON community_moderator (person_id); + +ALTER TABLE community_moderator + ADD UNIQUE (community_id, person_id), + DROP CONSTRAINT community_moderator_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE community_person_ban + ADD UNIQUE (community_id, person_id), + DROP CONSTRAINT community_person_ban_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE custom_emoji_keyword + ADD UNIQUE (custom_emoji_id, keyword), + DROP CONSTRAINT custom_emoji_keyword_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE federation_allowlist + ADD UNIQUE (instance_id), + DROP CONSTRAINT federation_allowlist_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE federation_blocklist + ADD UNIQUE (instance_id), + DROP CONSTRAINT federation_blocklist_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE federation_queue_state + ADD UNIQUE (instance_id), + DROP CONSTRAINT federation_queue_state_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE image_upload + ADD UNIQUE (pictrs_alias), + DROP CONSTRAINT image_upload_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE instance_block + ADD UNIQUE (person_id, instance_id), + DROP CONSTRAINT instance_block_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE local_site_rate_limit + ADD UNIQUE (local_site_id), + DROP CONSTRAINT local_site_rate_limit_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE local_user_language + ADD UNIQUE (local_user_id, language_id), + DROP CONSTRAINT local_user_language_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE login_token + ADD UNIQUE (token), + DROP CONSTRAINT login_token_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE person_aggregates + ADD UNIQUE (person_id), + DROP CONSTRAINT person_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE person_ban + ADD UNIQUE (person_id), + DROP CONSTRAINT person_ban_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE person_block + ADD UNIQUE (person_id, target_id), + DROP CONSTRAINT person_block_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE person_follower + ADD UNIQUE (follower_id, person_id), + DROP CONSTRAINT person_follower_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE person_post_aggregates + ADD UNIQUE (person_id, post_id), + DROP CONSTRAINT person_post_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE post_aggregates + ADD UNIQUE (post_id), + DROP CONSTRAINT post_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_post_like_person ON post_like (person_id); + +ALTER TABLE post_like + ADD UNIQUE (post_id, person_id), + DROP CONSTRAINT post_like_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE post_read + ADD UNIQUE (post_id, person_id), + DROP CONSTRAINT post_read_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE received_activity + ADD UNIQUE (ap_id), + DROP CONSTRAINT received_activity_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE INDEX idx_post_saved_person_id ON post_saved (person_id); + +ALTER TABLE post_saved + ADD UNIQUE (post_id, person_id), + DROP CONSTRAINT post_saved_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE site_aggregates + DROP CONSTRAINT site_aggregates_pkey, + ADD COLUMN id serial PRIMARY KEY; + +ALTER TABLE site_language + ADD UNIQUE (site_id, language_id), + DROP CONSTRAINT site_language_pkey, + ADD COLUMN id serial PRIMARY KEY; + +CREATE OR REPLACE FUNCTION site_aggregates_site () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- we only ever want to have a single value in site_aggregate because the site_aggregate triggers update all rows in that table. + -- a cleaner check would be to insert it for the local_site but that would break assumptions at least in the tests + IF (TG_OP = 'INSERT') AND NOT EXISTS ( + SELECT + id + FROM + site_aggregates + LIMIT 1) THEN + INSERT INTO site_aggregates (site_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM site_aggregates + WHERE site_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + diff --git a/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/up.sql b/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/up.sql new file mode 100644 index 000000000..9d27e0279 --- /dev/null +++ b/migrations/2023-10-24-030352_change_primary_keys_and_remove_some_id_columns/up.sql @@ -0,0 +1,228 @@ +ALTER TABLE captcha_answer + DROP COLUMN id, + ADD PRIMARY KEY (uuid), + DROP CONSTRAINT captcha_answer_uuid_key; + +ALTER TABLE comment_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (comment_id), + DROP CONSTRAINT comment_aggregates_comment_id_key; + +ALTER TABLE comment_like + DROP COLUMN id, + ADD PRIMARY KEY (person_id, comment_id), + DROP CONSTRAINT comment_like_comment_id_person_id_key; + +DROP INDEX idx_comment_like_person; + +ALTER TABLE comment_saved + DROP COLUMN id, + ADD PRIMARY KEY (person_id, comment_id), + DROP CONSTRAINT comment_saved_comment_id_person_id_key; + +DROP INDEX idx_comment_saved_person_id; + +ALTER TABLE community_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (community_id), + DROP CONSTRAINT community_aggregates_community_id_key; + +ALTER TABLE community_block + DROP COLUMN id, + ADD PRIMARY KEY (person_id, community_id), + DROP CONSTRAINT community_block_person_id_community_id_key; + +DROP INDEX idx_community_block_person; + +ALTER TABLE community_follower + DROP COLUMN id, + ADD PRIMARY KEY (person_id, community_id), + DROP CONSTRAINT community_follower_community_id_person_id_key; + +DROP INDEX idx_community_follower_person; + +ALTER TABLE community_language + DROP COLUMN id, + ADD PRIMARY KEY (community_id, language_id), + DROP CONSTRAINT community_language_community_id_language_id_key; + +ALTER TABLE community_moderator + DROP COLUMN id, + ADD PRIMARY KEY (person_id, community_id), + DROP CONSTRAINT community_moderator_community_id_person_id_key; + +DROP INDEX idx_community_moderator_person; + +ALTER TABLE community_person_ban + DROP COLUMN id, + ADD PRIMARY KEY (person_id, community_id), + DROP CONSTRAINT community_person_ban_community_id_person_id_key; + +ALTER TABLE custom_emoji_keyword + DROP COLUMN id, + ADD PRIMARY KEY (custom_emoji_id, keyword), + DROP CONSTRAINT custom_emoji_keyword_custom_emoji_id_keyword_key; + +ALTER TABLE federation_allowlist + DROP COLUMN id, + ADD PRIMARY KEY (instance_id), + DROP CONSTRAINT federation_allowlist_instance_id_key; + +ALTER TABLE federation_blocklist + DROP COLUMN id, + ADD PRIMARY KEY (instance_id), + DROP CONSTRAINT federation_blocklist_instance_id_key; + +ALTER TABLE federation_queue_state + DROP COLUMN id, + ADD PRIMARY KEY (instance_id), + DROP CONSTRAINT federation_queue_state_instance_id_key; + +ALTER TABLE image_upload + DROP COLUMN id, + ADD PRIMARY KEY (pictrs_alias), + DROP CONSTRAINT image_upload_pictrs_alias_key; + +ALTER TABLE instance_block + DROP COLUMN id, + ADD PRIMARY KEY (person_id, instance_id), + DROP CONSTRAINT instance_block_person_id_instance_id_key; + +ALTER TABLE local_site_rate_limit + DROP COLUMN id, + ADD PRIMARY KEY (local_site_id), + DROP CONSTRAINT local_site_rate_limit_local_site_id_key; + +ALTER TABLE local_user_language + DROP COLUMN id, + ADD PRIMARY KEY (local_user_id, language_id), + DROP CONSTRAINT local_user_language_local_user_id_language_id_key; + +ALTER TABLE login_token + DROP COLUMN id, + ADD PRIMARY KEY (token), + DROP CONSTRAINT login_token_token_key; + +-- Delete duplicates which can exist because of missing `UNIQUE` constraint +DELETE FROM person_aggregates AS a USING ( + SELECT + min(id) AS id, + person_id + FROM + person_aggregates + GROUP BY + person_id + HAVING + count(*) > 1) AS b +WHERE + a.person_id = b.person_id + AND a.id != b.id; + +ALTER TABLE person_aggregates + DROP CONSTRAINT IF EXISTS person_aggregates_person_id_key; + +ALTER TABLE person_aggregates + ADD UNIQUE (person_id); + +ALTER TABLE person_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (person_id), + DROP CONSTRAINT person_aggregates_person_id_key; + +ALTER TABLE person_ban + DROP COLUMN id, + ADD PRIMARY KEY (person_id), + DROP CONSTRAINT person_ban_person_id_key; + +ALTER TABLE person_block + DROP COLUMN id, + ADD PRIMARY KEY (person_id, target_id), + DROP CONSTRAINT person_block_person_id_target_id_key; + +ALTER TABLE person_follower + DROP COLUMN id, + ADD PRIMARY KEY (follower_id, person_id), + DROP CONSTRAINT person_follower_follower_id_person_id_key; + +ALTER TABLE person_post_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (person_id, post_id), + DROP CONSTRAINT person_post_aggregates_person_id_post_id_key; + +ALTER TABLE post_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (post_id), + DROP CONSTRAINT post_aggregates_post_id_key; + +ALTER TABLE post_like + DROP COLUMN id, + ADD PRIMARY KEY (person_id, post_id), + DROP CONSTRAINT post_like_post_id_person_id_key; + +DROP INDEX idx_post_like_person; + +ALTER TABLE post_read + DROP COLUMN id, + ADD PRIMARY KEY (person_id, post_id), + DROP CONSTRAINT post_read_post_id_person_id_key; + +ALTER TABLE post_saved + DROP COLUMN id, + ADD PRIMARY KEY (person_id, post_id), + DROP CONSTRAINT post_saved_post_id_person_id_key; + +DROP INDEX idx_post_saved_person_id; + +ALTER TABLE received_activity + DROP COLUMN id, + ADD PRIMARY KEY (ap_id), + DROP CONSTRAINT received_activity_ap_id_key; + +-- Delete duplicates which can exist because of missing `UNIQUE` constraint +DELETE FROM site_aggregates AS a USING ( + SELECT + min(id) AS id, + site_id + FROM + site_aggregates + GROUP BY + site_id + HAVING + count(*) > 1) AS b +WHERE + a.site_id = b.site_id + AND a.id != b.id; + +ALTER TABLE site_aggregates + DROP COLUMN id, + ADD PRIMARY KEY (site_id); + +ALTER TABLE site_language + DROP COLUMN id, + ADD PRIMARY KEY (site_id, language_id), + DROP CONSTRAINT site_language_site_id_language_id_key; + +-- Change functions to not use the removed columns +CREATE OR REPLACE FUNCTION site_aggregates_site () + RETURNS TRIGGER + LANGUAGE plpgsql + AS $$ +BEGIN + -- we only ever want to have a single value in site_aggregate because the site_aggregate triggers update all rows in that table. + -- a cleaner check would be to insert it for the local_site but that would break assumptions at least in the tests + IF (TG_OP = 'INSERT') AND NOT EXISTS ( + SELECT + * + FROM + site_aggregates + LIMIT 1) THEN + INSERT INTO site_aggregates (site_id) + VALUES (NEW.id); + ELSIF (TG_OP = 'DELETE') THEN + DELETE FROM site_aggregates + WHERE site_id = OLD.id; + END IF; + RETURN NULL; +END +$$; + diff --git a/src/scheduled_tasks.rs b/src/scheduled_tasks.rs index 5c1cab3fa..b669836e5 100644 --- a/src/scheduled_tasks.rs +++ b/src/scheduled_tasks.rs @@ -130,7 +130,7 @@ async fn update_hot_ranks(pool: &mut DbPool<'_>) { process_ranks_in_batches( &mut conn, - "comment_aggregates", + "comment", "a.hot_rank != 0", "SET hot_rank = hot_rank(a.score, a.published)", ) @@ -138,7 +138,7 @@ async fn update_hot_ranks(pool: &mut DbPool<'_>) { process_ranks_in_batches( &mut conn, - "community_aggregates", + "community", "a.hot_rank != 0", "SET hot_rank = hot_rank(a.subscribers, a.published)", ) @@ -180,16 +180,17 @@ async fn process_ranks_in_batches( // Raw `sql_query` is used as a performance optimization - Diesel does not support doing this // in a single query (neither as a CTE, nor using a subquery) let result = sql_query(format!( - r#"WITH batch AS (SELECT a.id + r#"WITH batch AS (SELECT a.{id_column} FROM {aggregates_table} a WHERE a.published > $1 AND ({where_clause}) ORDER BY a.published LIMIT $2 FOR UPDATE SKIP LOCKED) UPDATE {aggregates_table} a {set_clause} - FROM batch WHERE a.id = batch.id RETURNING a.published; + FROM batch WHERE a.{id_column} = batch.{id_column} RETURNING a.published; "#, - aggregates_table = table_name, + id_column = format!("{table_name}_id"), + aggregates_table = format!("{table_name}_aggregates"), set_clause = set_clause, where_clause = where_clause )) @@ -228,7 +229,7 @@ async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection) let mut previous_batch_result = Some(process_start_time); while let Some(previous_batch_last_published) = previous_batch_result { let result = sql_query( - r#"WITH batch AS (SELECT pa.id + r#"WITH batch AS (SELECT pa.post_id FROM post_aggregates pa WHERE pa.published > $1 AND (pa.hot_rank != 0 OR pa.hot_rank_active != 0) @@ -240,7 +241,7 @@ async fn process_post_aggregates_ranks_in_batches(conn: &mut AsyncPgConnection) hot_rank_active = hot_rank(pa.score, pa.newest_comment_time_necro), scaled_rank = scaled_rank(pa.score, pa.published, ca.users_active_month) FROM batch, community_aggregates ca - WHERE pa.id = batch.id and pa.community_id = ca.community_id RETURNING pa.published; + WHERE pa.post_id = batch.post_id and pa.community_id = ca.community_id RETURNING pa.published; "#, ) .bind::(previous_batch_last_published)