Use typed-builder crate for queries (#2379)

* Use typed-builder crate for PrivateMessageQuery

* derive builder for all queries

* remove unnecessary clones

* fix tests
fix_upgrade_script
Nutomic 2 years ago committed by GitHub
parent 7094a0c0a4
commit 8a4d9cc1ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -41,7 +41,7 @@ steps:
commands:
- apt-get update
- apt-get -y install --no-install-recommends postgresql-client
- cargo test --workspace --no-fail-fast
- cargo test --workspace --no-fail-fast --all-features
- name: check defaults.hjson updated
image: clux/muslrust:1.57.0

13
Cargo.lock generated

@ -2020,6 +2020,7 @@ dependencies = [
"serde",
"serial_test",
"tracing",
"typed-builder",
]
[[package]]
@ -2029,6 +2030,7 @@ dependencies = [
"diesel",
"lemmy_db_schema",
"serde",
"typed-builder",
]
[[package]]
@ -4201,6 +4203,17 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
[[package]]
name = "typed-builder"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c"
dependencies = [
"proc-macro2 1.0.39",
"quote 1.0.18",
"syn 1.0.96",
]
[[package]]
name = "typenum"
version = "1.15.0"

@ -4,7 +4,7 @@ use lemmy_api_common::{
comment::{ListCommentReports, ListCommentReportsResponse},
utils::{blocking, get_local_user_view_from_jwt},
};
use lemmy_db_views::comment_report_view::CommentReportQueryBuilder;
use lemmy_db_views::comment_report_view::CommentReportQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -32,11 +32,15 @@ impl Perform for ListCommentReports {
let page = data.page;
let limit = data.limit;
let comment_reports = blocking(context.pool(), move |conn| {
CommentReportQueryBuilder::create(conn, person_id, admin)
CommentReportQuery::builder()
.conn(conn)
.my_person_id(person_id)
.admin(admin)
.community_id(community_id)
.unresolved_only(unresolved_only)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -4,7 +4,7 @@ use lemmy_api_common::{
person::{GetPersonMentions, GetPersonMentionsResponse},
utils::{blocking, get_local_user_view_from_jwt},
};
use lemmy_db_views_actor::person_mention_view::PersonMentionQueryBuilder;
use lemmy_db_views_actor::person_mention_view::PersonMentionQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -26,11 +26,12 @@ impl Perform for GetPersonMentions {
let page = data.page;
let limit = data.limit;
let unread_only = data.unread_only;
let person_id = local_user_view.person.id;
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
let person_id = Some(local_user_view.person.id);
let show_bot_accounts = Some(local_user_view.local_user.show_bot_accounts);
let mentions = blocking(context.pool(), move |conn| {
PersonMentionQueryBuilder::create(conn)
PersonMentionQuery::builder()
.conn(conn)
.recipient_id(person_id)
.my_person_id(person_id)
.sort(sort)
@ -38,6 +39,7 @@ impl Perform for GetPersonMentions {
.show_bot_accounts(show_bot_accounts)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -4,7 +4,7 @@ use lemmy_api_common::{
person::{GetReplies, GetRepliesResponse},
utils::{blocking, get_local_user_view_from_jwt},
};
use lemmy_db_views_actor::comment_reply_view::CommentReplyQueryBuilder;
use lemmy_db_views_actor::comment_reply_view::CommentReplyQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -26,11 +26,12 @@ impl Perform for GetReplies {
let page = data.page;
let limit = data.limit;
let unread_only = data.unread_only;
let person_id = local_user_view.person.id;
let show_bot_accounts = local_user_view.local_user.show_bot_accounts;
let person_id = Some(local_user_view.person.id);
let show_bot_accounts = Some(local_user_view.local_user.show_bot_accounts);
let replies = blocking(context.pool(), move |conn| {
CommentReplyQueryBuilder::create(conn)
CommentReplyQuery::builder()
.conn(conn)
.recipient_id(person_id)
.my_person_id(person_id)
.sort(sort)
@ -38,6 +39,7 @@ impl Perform for GetReplies {
.show_bot_accounts(show_bot_accounts)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -4,7 +4,7 @@ use lemmy_api_common::{
post::{ListPostReports, ListPostReportsResponse},
utils::{blocking, get_local_user_view_from_jwt},
};
use lemmy_db_views::post_report_view::PostReportQueryBuilder;
use lemmy_db_views::post_report_view::PostReportQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -32,11 +32,15 @@ impl Perform for ListPostReports {
let page = data.page;
let limit = data.limit;
let post_reports = blocking(context.pool(), move |conn| {
PostReportQueryBuilder::create(conn, person_id, admin)
PostReportQuery::builder()
.conn(conn)
.my_person_id(person_id)
.admin(admin)
.community_id(community_id)
.unresolved_only(unresolved_only)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -5,7 +5,7 @@ use lemmy_api_common::{
utils::{blocking, get_local_user_view_from_jwt, is_admin},
};
use lemmy_db_schema::source::site::Site;
use lemmy_db_views::registration_application_view::RegistrationApplicationQueryBuilder;
use lemmy_db_views::registration_application_view::RegistrationApplicationQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -34,11 +34,13 @@ impl Perform for ListRegistrationApplications {
let page = data.page;
let limit = data.limit;
let registration_applications = blocking(context.pool(), move |conn| {
RegistrationApplicationQueryBuilder::create(conn)
RegistrationApplicationQuery::builder()
.conn(conn)
.unread_only(unread_only)
.verified_email_only(verified_email_only)
.verified_email_only(Some(verified_email_only))
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -11,11 +11,8 @@ use lemmy_db_schema::{
utils::post_to_comment_sort_type,
SearchType,
};
use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
use lemmy_db_views_actor::{
community_view::CommunityQueryBuilder,
person_view::PersonQueryBuilder,
};
use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery};
use lemmy_db_views_actor::{community_view::CommunityQuery, person_view::PersonQuery};
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -73,7 +70,8 @@ impl Perform for Search {
match search_type {
SearchType::Posts => {
posts = blocking(context.pool(), move |conn| {
PostQueryBuilder::create(conn)
PostQuery::builder()
.conn(conn)
.sort(sort)
.show_nsfw(show_nsfw)
.show_bot_accounts(show_bot_accounts)
@ -83,19 +81,21 @@ impl Perform for Search {
.community_actor_id(community_actor_id)
.creator_id(creator_id)
.my_person_id(person_id)
.search_term(q)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
}
SearchType::Comments => {
comments = blocking(context.pool(), move |conn| {
CommentQueryBuilder::create(conn)
CommentQuery::builder()
.conn(conn)
.sort(sort.map(post_to_comment_sort_type))
.listing_type(listing_type)
.search_term(q)
.search_term(Some(q))
.show_bot_accounts(show_bot_accounts)
.community_id(community_id)
.community_actor_id(community_actor_id)
@ -103,30 +103,35 @@ impl Perform for Search {
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
}
SearchType::Communities => {
communities = blocking(context.pool(), move |conn| {
CommunityQueryBuilder::create(conn)
CommunityQuery::builder()
.conn(conn)
.sort(sort)
.listing_type(listing_type)
.search_term(q)
.search_term(Some(q))
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
}
SearchType::Users => {
users = blocking(context.pool(), move |conn| {
PersonQueryBuilder::create(conn)
PersonQuery::builder()
.conn(conn)
.sort(sort)
.search_term(q)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
@ -138,7 +143,8 @@ impl Perform for Search {
let community_actor_id_2 = community_actor_id.to_owned();
posts = blocking(context.pool(), move |conn| {
PostQueryBuilder::create(conn)
PostQuery::builder()
.conn(conn)
.sort(sort)
.show_nsfw(show_nsfw)
.show_bot_accounts(show_bot_accounts)
@ -148,9 +154,10 @@ impl Perform for Search {
.community_actor_id(community_actor_id_2)
.creator_id(creator_id)
.my_person_id(person_id)
.search_term(q)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
@ -159,10 +166,11 @@ impl Perform for Search {
let community_actor_id = community_actor_id.to_owned();
comments = blocking(context.pool(), move |conn| {
CommentQueryBuilder::create(conn)
CommentQuery::builder()
.conn(conn)
.sort(sort.map(post_to_comment_sort_type))
.listing_type(listing_type)
.search_term(q)
.search_term(Some(q))
.show_bot_accounts(show_bot_accounts)
.community_id(community_id)
.community_actor_id(community_actor_id)
@ -170,6 +178,7 @@ impl Perform for Search {
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;
@ -180,13 +189,15 @@ impl Perform for Search {
vec![]
} else {
blocking(context.pool(), move |conn| {
CommunityQueryBuilder::create(conn)
CommunityQuery::builder()
.conn(conn)
.sort(sort)
.listing_type(listing_type)
.search_term(q)
.search_term(Some(q))
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await??
@ -198,11 +209,13 @@ impl Perform for Search {
vec![]
} else {
blocking(context.pool(), move |conn| {
PersonQueryBuilder::create(conn)
PersonQuery::builder()
.conn(conn)
.sort(sort)
.search_term(q)
.search_term(Some(q))
.page(page)
.limit(limit)
.build()
.list()
})
.await??
@ -210,7 +223,8 @@ impl Perform for Search {
}
SearchType::Url => {
posts = blocking(context.pool(), move |conn| {
PostQueryBuilder::create(conn)
PostQuery::builder()
.conn(conn)
.sort(sort)
.show_nsfw(show_nsfw)
.show_bot_accounts(show_bot_accounts)
@ -220,9 +234,10 @@ impl Perform for Search {
.community_id(community_id)
.community_actor_id(community_actor_id)
.creator_id(creator_id)
.url_search(q)
.url_search(Some(q))
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -20,7 +20,7 @@ use lemmy_db_schema::{
ListingType,
};
use lemmy_db_views::{
comment_view::CommentQueryBuilder,
comment_view::CommentQuery,
structs::{LocalUserSettingsView, LocalUserView},
};
use lemmy_db_views_actor::structs::{
@ -667,10 +667,12 @@ pub async fn remove_user_data_in_community(
// Comments
// TODO Diesel doesn't allow updates with joins, so this has to be a loop
let comments = blocking(pool, move |conn| {
CommentQueryBuilder::create(conn)
.creator_id(banned_person_id)
.community_id(community_id)
.limit(std::i64::MAX)
CommentQuery::builder()
.conn(conn)
.creator_id(Some(banned_person_id))
.community_id(Some(community_id))
.limit(Some(i64::MAX))
.build()
.list()
})
.await??;

@ -14,7 +14,7 @@ use lemmy_db_schema::{
source::{comment::Comment, community::Community},
traits::{Crud, DeleteableOrRemoveable},
};
use lemmy_db_views::comment_view::CommentQueryBuilder;
use lemmy_db_views::comment_view::CommentQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -71,8 +71,9 @@ impl PerformCrud for GetComments {
let post_id = data.post_id;
let mut comments = blocking(context.pool(), move |conn| {
CommentQueryBuilder::create(conn)
.listing_type(listing_type)
CommentQuery::builder()
.conn(conn)
.listing_type(Some(listing_type))
.sort(sort)
.max_depth(max_depth)
.saved_only(saved_only)
@ -84,6 +85,7 @@ impl PerformCrud for GetComments {
.show_bot_accounts(show_bot_accounts)
.page(page)
.limit(limit)
.build()
.list()
})
.await?

@ -5,7 +5,7 @@ use lemmy_api_common::{
utils::{blocking, check_private_instance, get_local_user_view_from_jwt_opt},
};
use lemmy_db_schema::traits::DeleteableOrRemoveable;
use lemmy_db_views_actor::community_view::CommunityQueryBuilder;
use lemmy_db_views_actor::community_view::CommunityQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -39,13 +39,15 @@ impl PerformCrud for ListCommunities {
let page = data.page;
let limit = data.limit;
let mut communities = blocking(context.pool(), move |conn| {
CommunityQueryBuilder::create(conn)
CommunityQuery::builder()
.conn(conn)
.listing_type(listing_type)
.sort(sort)
.show_nsfw(show_nsfw)
.show_nsfw(Some(show_nsfw))
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await??;

@ -11,7 +11,7 @@ use lemmy_api_common::{
};
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::community::ApubCommunity};
use lemmy_db_schema::{source::community::Community, traits::DeleteableOrRemoveable};
use lemmy_db_views::post_view::PostQueryBuilder;
use lemmy_db_views::post_view::PostQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -59,8 +59,9 @@ impl PerformCrud for GetPosts {
let saved_only = data.saved_only;
let mut posts = blocking(context.pool(), move |conn| {
PostQueryBuilder::create(conn)
.listing_type(listing_type)
PostQuery::builder()
.conn(conn)
.listing_type(Some(listing_type))
.sort(sort)
.show_nsfw(show_nsfw)
.show_bot_accounts(show_bot_accounts)
@ -71,6 +72,7 @@ impl PerformCrud for GetPosts {
.my_person_id(person_id)
.page(page)
.limit(limit)
.build()
.list()
})
.await?

@ -5,7 +5,7 @@ use lemmy_api_common::{
utils::{blocking, get_local_user_view_from_jwt},
};
use lemmy_db_schema::traits::DeleteableOrRemoveable;
use lemmy_db_views::private_message_view::PrivateMessageQueryBuilder;
use lemmy_db_views::private_message_view::PrivateMessageQuery;
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -28,10 +28,13 @@ impl PerformCrud for GetPrivateMessages {
let limit = data.limit;
let unread_only = data.unread_only;
let mut messages = blocking(context.pool(), move |conn| {
PrivateMessageQueryBuilder::create(conn, person_id)
PrivateMessageQuery::builder()
.conn(conn)
.recipient_id(person_id)
.page(page)
.limit(limit)
.unread_only(unread_only)
.build()
.list()
})
.await??;

@ -6,7 +6,7 @@ use lemmy_api_common::{
};
use lemmy_apub::{fetcher::resolve_actor_identifier, objects::person::ApubPerson};
use lemmy_db_schema::{source::person::Person, utils::post_to_comment_sort_type};
use lemmy_db_views::{comment_view::CommentQueryBuilder, post_view::PostQueryBuilder};
use lemmy_db_views::{comment_view::CommentQuery, post_view::PostQuery};
use lemmy_db_views_actor::structs::{CommunityModeratorView, PersonViewSafe};
use lemmy_utils::{error::LemmyError, ConnectionId};
use lemmy_websocket::LemmyContext;
@ -74,7 +74,8 @@ impl PerformCrud for GetPersonDetails {
let community_id = data.community_id;
let (posts, comments) = blocking(context.pool(), move |conn| {
let mut posts_query = PostQueryBuilder::create(conn)
let posts_query = PostQuery::builder()
.conn(conn)
.sort(sort)
.show_nsfw(show_nsfw)
.show_bot_accounts(show_bot_accounts)
@ -85,7 +86,8 @@ impl PerformCrud for GetPersonDetails {
.page(page)
.limit(limit);
let mut comments_query = CommentQueryBuilder::create(conn)
let comments_query = CommentQuery::builder()
.conn(conn)
.my_person_id(person_id)
.show_bot_accounts(show_bot_accounts)
.sort(sort.map(post_to_comment_sort_type))
@ -96,13 +98,20 @@ impl PerformCrud for GetPersonDetails {
// If its saved only, you don't care what creator it was
// Or, if its not saved, then you only want it for that specific creator
if !saved_only.unwrap_or(false) {
posts_query = posts_query.creator_id(person_details_id);
comments_query = comments_query.creator_id(person_details_id);
}
let posts = posts_query.list()?;
let comments = comments_query.list()?;
let (posts, comments) = if !saved_only.unwrap_or(false) {
(
posts_query
.creator_id(Some(person_details_id))
.build()
.list()?,
comments_query
.creator_id(Some(person_details_id))
.build()
.list()?,
)
} else {
(posts_query.build().list()?, comments_query.build().list()?)
};
Ok((posts, comments)) as Result<_, LemmyError>
})

@ -130,22 +130,6 @@ pub trait DeleteableOrRemoveable {
fn blank_out_deleted_or_removed_info(self) -> Self;
}
pub trait MaybeOptional<T> {
fn get_optional(self) -> Option<T>;
}
impl<T> MaybeOptional<T> for T {
fn get_optional(self) -> Option<T> {
Some(self)
}
}
impl<T> MaybeOptional<T> for Option<T> {
fn get_optional(self) -> Option<T> {
self
}
}
pub trait ToSafe {
type SafeColumns;
fn safe_columns_tuple() -> Self::SafeColumns;

@ -20,6 +20,7 @@ diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json
serde = { version = "1.0.136", features = ["derive"] }
tracing = { version = "0.1.32", optional = true }
diesel_ltree = "0.2.7"
typed-builder = "0.10.0"
[dev-dependencies]
serial_test = "0.6.0"

@ -23,9 +23,10 @@ use lemmy_db_schema::{
person::{Person, PersonAlias1, PersonAlias2, PersonSafe, PersonSafeAlias1, PersonSafeAlias2},
post::Post,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::limit_and_offset,
};
use typed_builder::TypedBuilder;
type CommentReportViewTuple = (
CommentReport,
@ -159,9 +160,14 @@ impl CommentReportView {
}
}
pub struct CommentReportQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct CommentReportQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
#[builder(!default)]
my_person_id: PersonId,
#[builder(!default)]
admin: bool,
community_id: Option<CommunityId>,
page: Option<i64>,
@ -169,39 +175,7 @@ pub struct CommentReportQueryBuilder<'a> {
unresolved_only: Option<bool>,
}
impl<'a> CommentReportQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection, my_person_id: PersonId, admin: bool) -> Self {
CommentReportQueryBuilder {
conn,
my_person_id,
admin,
community_id: None,
page: None,
limit: None,
unresolved_only: Some(true),
}
}
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
self.community_id = community_id.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
pub fn unresolved_only<T: MaybeOptional<bool>>(mut self, unresolved_only: T) -> Self {
self.unresolved_only = unresolved_only.get_optional();
self
}
impl<'a> CommentReportQuery<'a> {
pub fn list(self) -> Result<Vec<CommentReportView>, Error> {
let mut query = comment_report::table
.inner_join(comment::table)
@ -252,7 +226,7 @@ impl<'a> CommentReportQueryBuilder<'a> {
query = query.filter(post::community_id.eq(community_id));
}
if self.unresolved_only.unwrap_or(false) {
if self.unresolved_only.unwrap_or(true) {
query = query.filter(comment_report::resolved.eq(false));
}
@ -286,18 +260,18 @@ impl ViewToVec for CommentReportView {
type DbTuple = CommentReportViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
comment_report: a.0.to_owned(),
comment: a.1.to_owned(),
post: a.2.to_owned(),
community: a.3.to_owned(),
creator: a.4.to_owned(),
comment_creator: a.5.to_owned(),
counts: a.6.to_owned(),
comment_report: a.0,
comment: a.1,
post: a.2,
community: a.3,
creator: a.4,
comment_creator: a.5,
counts: a.6,
creator_banned_from_community: a.7.is_some(),
my_vote: a.8,
resolver: a.9.to_owned(),
resolver: a.9,
})
.collect::<Vec<Self>>()
}
@ -305,7 +279,7 @@ impl ViewToVec for CommentReportView {
#[cfg(test)]
mod tests {
use crate::comment_report_view::{CommentReportQueryBuilder, CommentReportView};
use crate::comment_report_view::{CommentReportQuery, CommentReportView};
use lemmy_db_schema::{
aggregates::structs::CommentAggregates,
source::{comment::*, comment_report::*, community::*, person::*, post::*},
@ -504,7 +478,11 @@ mod tests {
};
// Do a batch read of timmys reports
let reports = CommentReportQueryBuilder::create(&conn, inserted_timmy.id, false)
let reports = CommentReportQuery::builder()
.conn(&conn)
.my_person_id(inserted_timmy.id)
.admin(false)
.build()
.list()
.unwrap();
@ -566,10 +544,15 @@ mod tests {
// Do a batch read of timmys reports
// It should only show saras, which is unresolved
let reports_after_resolve = CommentReportQueryBuilder::create(&conn, inserted_timmy.id, false)
let reports_after_resolve = CommentReportQuery::builder()
.conn(&conn)
.my_person_id(inserted_timmy.id)
.admin(false)
.build()
.list()
.unwrap();
assert_eq!(reports_after_resolve[0], expected_sara_report_view);
assert_eq!(reports_after_resolve.len(), 1);
// Make sure the counts are correct
let report_count_after_resolved =

@ -24,11 +24,12 @@ use lemmy_db_schema::{
person_block::PersonBlock,
post::Post,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, fuzzy_search, limit_and_offset_unlimited},
CommentSortType,
ListingType,
};
use typed_builder::TypedBuilder;
type CommentViewTuple = (
Comment,
@ -146,7 +147,10 @@ impl CommentView {
}
}
pub struct CommentQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct CommentQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
listing_type: Option<ListingType>,
sort: Option<CommentSortType>,
@ -164,97 +168,7 @@ pub struct CommentQueryBuilder<'a> {
max_depth: Option<i32>,
}
impl<'a> CommentQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
CommentQueryBuilder {
conn,
listing_type: Some(ListingType::All),
sort: None,
community_id: None,
community_actor_id: None,
post_id: None,
parent_path: None,
creator_id: None,
my_person_id: None,
search_term: None,
saved_only: None,
show_bot_accounts: None,
page: None,
limit: None,
max_depth: None,
}
}
pub fn listing_type<T: MaybeOptional<ListingType>>(mut self, listing_type: T) -> Self {
self.listing_type = listing_type.get_optional();
self
}
pub fn sort<T: MaybeOptional<CommentSortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn post_id<T: MaybeOptional<PostId>>(mut self, post_id: T) -> Self {
self.post_id = post_id.get_optional();
self
}
pub fn creator_id<T: MaybeOptional<PersonId>>(mut self, creator_id: T) -> Self {
self.creator_id = creator_id.get_optional();
self
}
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
self.community_id = community_id.get_optional();
self
}
pub fn my_person_id<T: MaybeOptional<PersonId>>(mut self, my_person_id: T) -> Self {
self.my_person_id = my_person_id.get_optional();
self
}
pub fn community_actor_id<T: MaybeOptional<DbUrl>>(mut self, community_actor_id: T) -> Self {
self.community_actor_id = community_actor_id.get_optional();
self
}
pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
self.search_term = search_term.get_optional();
self
}
pub fn saved_only<T: MaybeOptional<bool>>(mut self, saved_only: T) -> Self {
self.saved_only = saved_only.get_optional();
self
}
pub fn show_bot_accounts<T: MaybeOptional<bool>>(mut self, show_bot_accounts: T) -> Self {
self.show_bot_accounts = show_bot_accounts.get_optional();
self
}
pub fn parent_path<T: MaybeOptional<Ltree>>(mut self, parent_path: T) -> Self {
self.parent_path = parent_path.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
pub fn max_depth<T: MaybeOptional<i32>>(mut self, max_depth: T) -> Self {
self.max_depth = max_depth.get_optional();
self
}
impl<'a> CommentQuery<'a> {
pub fn list(self) -> Result<Vec<CommentView>, Error> {
use diesel::dsl::*;
@ -437,13 +351,13 @@ impl ViewToVec for CommentView {
type DbTuple = CommentViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
comment: a.0.to_owned(),
creator: a.1.to_owned(),
post: a.2.to_owned(),
community: a.3.to_owned(),
counts: a.4.to_owned(),
comment: a.0,
creator: a.1,
post: a.2,
community: a.3,
counts: a.4,
creator_banned_from_community: a.5.is_some(),
subscribed: CommunityFollower::to_subscribed_type(&a.6),
saved: a.7.is_some(),
@ -691,8 +605,10 @@ mod tests {
let mut expected_comment_view_with_person = expected_comment_view_no_person.to_owned();
expected_comment_view_with_person.my_vote = Some(1);
let read_comment_views_no_person = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
let read_comment_views_no_person = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.build()
.list()
.unwrap();
@ -701,9 +617,11 @@ mod tests {
read_comment_views_no_person[0]
);
let read_comment_views_with_person = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
.my_person_id(inserted_person.id)
let read_comment_views_with_person = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.my_person_id(Some(inserted_person.id))
.build()
.list()
.unwrap();
@ -722,16 +640,20 @@ mod tests {
assert!(read_comment_from_blocked_person.creator_blocked);
let top_path = inserted_comment_0.path;
let read_comment_views_top_path = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
.parent_path(top_path)
let read_comment_views_top_path = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.parent_path(Some(top_path))
.build()
.list()
.unwrap();
let child_path = inserted_comment_1.to_owned().path;
let read_comment_views_child_path = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
.parent_path(child_path)
let read_comment_views_child_path = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.parent_path(Some(child_path))
.build()
.list()
.unwrap();
@ -747,9 +669,11 @@ mod tests {
assert!(child_comments.contains(&inserted_comment_1));
assert!(!child_comments.contains(&inserted_comment_2));
let read_comment_views_top_max_depth = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
.max_depth(1)
let read_comment_views_top_max_depth = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.max_depth(Some(1))
.build()
.list()
.unwrap();
@ -761,11 +685,13 @@ mod tests {
assert_eq!(1, read_comment_views_top_max_depth.len());
let child_path = inserted_comment_1.path;
let read_comment_views_parent_max_depth = CommentQueryBuilder::create(&conn)
.post_id(inserted_post.id)
.parent_path(child_path)
.max_depth(1)
.sort(CommentSortType::New)
let read_comment_views_parent_max_depth = CommentQuery::builder()
.conn(&conn)
.post_id(Some(inserted_post.id))
.parent_path(Some(child_path))
.max_depth(Some(1))
.sort(Some(CommentSortType::New))
.build()
.list()
.unwrap();

@ -21,9 +21,10 @@ use lemmy_db_schema::{
post::Post,
post_report::PostReport,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::limit_and_offset,
};
use typed_builder::TypedBuilder;
type PostReportViewTuple = (
PostReport,
@ -148,9 +149,14 @@ impl PostReportView {
}
}
pub struct PostReportQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PostReportQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
#[builder(!default)]
my_person_id: PersonId,
#[builder(!default)]
admin: bool,
community_id: Option<CommunityId>,
page: Option<i64>,
@ -158,39 +164,7 @@ pub struct PostReportQueryBuilder<'a> {
unresolved_only: Option<bool>,
}
impl<'a> PostReportQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection, my_person_id: PersonId, admin: bool) -> Self {
PostReportQueryBuilder {
conn,
my_person_id,
admin,
community_id: None,
page: None,
limit: None,
unresolved_only: Some(true),
}
}
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
self.community_id = community_id.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
pub fn unresolved_only<T: MaybeOptional<bool>>(mut self, unresolved_only: T) -> Self {
self.unresolved_only = unresolved_only.get_optional();
self
}
impl<'a> PostReportQuery<'a> {
pub fn list(self) -> Result<Vec<PostReportView>, Error> {
let mut query = post_report::table
.inner_join(post::table)
@ -237,7 +211,7 @@ impl<'a> PostReportQueryBuilder<'a> {
query = query.filter(post::community_id.eq(community_id));
}
if self.unresolved_only.unwrap_or(false) {
if self.unresolved_only.unwrap_or(true) {
query = query.filter(post_report::resolved.eq(false));
}
@ -271,17 +245,17 @@ impl ViewToVec for PostReportView {
type DbTuple = PostReportViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
post_report: a.0.to_owned(),
post: a.1.to_owned(),
community: a.2.to_owned(),
creator: a.3.to_owned(),
post_creator: a.4.to_owned(),
post_report: a.0,
post: a.1,
community: a.2,
creator: a.3,
post_creator: a.4,
creator_banned_from_community: a.5.is_some(),
my_vote: a.6,
counts: a.7.to_owned(),
resolver: a.8.to_owned(),
counts: a.7,
resolver: a.8,
})
.collect::<Vec<Self>>()
}
@ -289,7 +263,7 @@ impl ViewToVec for PostReportView {
#[cfg(test)]
mod tests {
use crate::post_report_view::{PostReportQueryBuilder, PostReportView};
use crate::post_report_view::{PostReportQuery, PostReportView};
use lemmy_db_schema::{
aggregates::structs::PostAggregates,
source::{
@ -491,7 +465,11 @@ mod tests {
};
// Do a batch read of timmys reports
let reports = PostReportQueryBuilder::create(&conn, inserted_timmy.id, false)
let reports = PostReportQuery::builder()
.conn(&conn)
.my_person_id(inserted_timmy.id)
.admin(false)
.build()
.list()
.unwrap();
@ -551,7 +529,11 @@ mod tests {
// Do a batch read of timmys reports
// It should only show saras, which is unresolved
let reports_after_resolve = PostReportQueryBuilder::create(&conn, inserted_timmy.id, false)
let reports_after_resolve = PostReportQuery::builder()
.conn(&conn)
.my_person_id(inserted_timmy.id)
.admin(false)
.build()
.list()
.unwrap();
assert_eq!(reports_after_resolve[0], expected_sara_report_view);

@ -22,12 +22,13 @@ use lemmy_db_schema::{
person_block::PersonBlock,
post::{Post, PostRead, PostSaved},
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, fuzzy_search, limit_and_offset},
ListingType,
SortType,
};
use tracing::debug;
use typed_builder::TypedBuilder;
type PostViewTuple = (
Post,
@ -151,7 +152,10 @@ impl PostView {
}
}
pub struct PostQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PostQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
listing_type: Option<ListingType>,
sort: Option<SortType>,
@ -169,97 +173,7 @@ pub struct PostQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> PostQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
PostQueryBuilder {
conn,
listing_type: Some(ListingType::All),
sort: None,
creator_id: None,
community_id: None,
community_actor_id: None,
my_person_id: None,
search_term: None,
url_search: None,
show_nsfw: None,
show_bot_accounts: None,
show_read_posts: None,
saved_only: None,
page: None,
limit: None,
}
}
pub fn listing_type<T: MaybeOptional<ListingType>>(mut self, listing_type: T) -> Self {
self.listing_type = listing_type.get_optional();
self
}
pub fn sort<T: MaybeOptional<SortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn community_id<T: MaybeOptional<CommunityId>>(mut self, community_id: T) -> Self {
self.community_id = community_id.get_optional();
self
}
pub fn my_person_id<T: MaybeOptional<PersonId>>(mut self, my_person_id: T) -> Self {
self.my_person_id = my_person_id.get_optional();
self
}
pub fn community_actor_id<T: MaybeOptional<DbUrl>>(mut self, community_actor_id: T) -> Self {
self.community_actor_id = community_actor_id.get_optional();
self
}
pub fn creator_id<T: MaybeOptional<PersonId>>(mut self, creator_id: T) -> Self {
self.creator_id = creator_id.get_optional();
self
}
pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
self.search_term = search_term.get_optional();
self
}
pub fn url_search<T: MaybeOptional<String>>(mut self, url_search: T) -> Self {
self.url_search = url_search.get_optional();
self
}
pub fn show_nsfw<T: MaybeOptional<bool>>(mut self, show_nsfw: T) -> Self {
self.show_nsfw = show_nsfw.get_optional();
self
}
pub fn show_bot_accounts<T: MaybeOptional<bool>>(mut self, show_bot_accounts: T) -> Self {
self.show_bot_accounts = show_bot_accounts.get_optional();
self
}
pub fn show_read_posts<T: MaybeOptional<bool>>(mut self, show_read_posts: T) -> Self {
self.show_read_posts = show_read_posts.get_optional();
self
}
pub fn saved_only<T: MaybeOptional<bool>>(mut self, saved_only: T) -> Self {
self.saved_only = saved_only.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> PostQuery<'a> {
pub fn list(self) -> Result<Vec<PostView>, Error> {
use diesel::dsl::*;
@ -477,13 +391,13 @@ impl ViewToVec for PostView {
type DbTuple = PostViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
post: a.0.to_owned(),
creator: a.1.to_owned(),
community: a.2.to_owned(),
post: a.0,
creator: a.1,
community: a.2,
creator_banned_from_community: a.3.is_some(),
counts: a.4.to_owned(),
counts: a.4,
subscribed: CommunityFollower::to_subscribed_type(&a.5),
saved: a.6.is_some(),
read: a.7.is_some(),
@ -496,7 +410,7 @@ impl ViewToVec for PostView {
#[cfg(test)]
mod tests {
use crate::post_view::{PostQueryBuilder, PostView};
use crate::post_view::{PostQuery, PostView};
use lemmy_db_schema::{
aggregates::structs::PostAggregates,
source::{
@ -610,17 +524,21 @@ mod tests {
score: 1,
};
let read_post_listings_with_person = PostQueryBuilder::create(&conn)
.sort(SortType::New)
.show_bot_accounts(false)
.community_id(inserted_community.id)
.my_person_id(inserted_person.id)
let read_post_listings_with_person = PostQuery::builder()
.conn(&conn)
.sort(Some(SortType::New))
.show_bot_accounts(Some(false))
.community_id(Some(inserted_community.id))
.my_person_id(Some(inserted_person.id))
.build()
.list()
.unwrap();
let read_post_listings_no_person = PostQueryBuilder::create(&conn)
.sort(SortType::New)
.community_id(inserted_community.id)
let read_post_listings_no_person = PostQuery::builder()
.conn(&conn)
.sort(Some(SortType::New))
.community_id(Some(inserted_community.id))
.build()
.list()
.unwrap();
@ -717,11 +635,13 @@ mod tests {
};
CommunityBlock::block(&conn, &community_block).unwrap();
let read_post_listings_with_person_after_block = PostQueryBuilder::create(&conn)
.sort(SortType::New)
.show_bot_accounts(false)
.community_id(inserted_community.id)
.my_person_id(inserted_person.id)
let read_post_listings_with_person_after_block = PostQuery::builder()
.conn(&conn)
.sort(Some(SortType::New))
.show_bot_accounts(Some(false))
.community_id(Some(inserted_community.id))
.my_person_id(Some(inserted_person.id))
.build()
.list()
.unwrap();

@ -7,10 +7,11 @@ use lemmy_db_schema::{
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
private_message::PrivateMessage,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::limit_and_offset,
};
use tracing::debug;
use typed_builder::TypedBuilder;
type PrivateMessageViewTuple = (PrivateMessage, PersonSafe, PersonSafeAlias1);
@ -47,40 +48,19 @@ impl PrivateMessageView {
}
}
pub struct PrivateMessageQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PrivateMessageQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
#[builder(!default)]
recipient_id: PersonId,
unread_only: Option<bool>,
page: Option<i64>,
limit: Option<i64>,
}
impl<'a> PrivateMessageQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection, recipient_id: PersonId) -> Self {
PrivateMessageQueryBuilder {
conn,
recipient_id,
unread_only: None,
page: None,
limit: None,
}
}
pub fn unread_only<T: MaybeOptional<bool>>(mut self, unread_only: T) -> Self {
self.unread_only = unread_only.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> PrivateMessageQuery<'a> {
pub fn list(self) -> Result<Vec<PrivateMessageView>, Error> {
let mut query = private_message::table
.inner_join(person::table.on(private_message::creator_id.eq(person::id)))
@ -130,11 +110,11 @@ impl ViewToVec for PrivateMessageView {
type DbTuple = PrivateMessageViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
private_message: a.0.to_owned(),
creator: a.1.to_owned(),
recipient: a.2.to_owned(),
private_message: a.0,
creator: a.1,
recipient: a.2,
})
.collect::<Vec<Self>>()
}

@ -7,9 +7,10 @@ use lemmy_db_schema::{
person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
registration_application::RegistrationApplication,
},
traits::{MaybeOptional, ToSafe, ToSafeSettings, ViewToVec},
traits::{ToSafe, ToSafeSettings, ViewToVec},
utils::limit_and_offset,
};
use typed_builder::TypedBuilder;
type RegistrationApplicationViewTuple = (
RegistrationApplication,
@ -70,7 +71,10 @@ impl RegistrationApplicationView {
}
}
pub struct RegistrationApplicationQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct RegistrationApplicationQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
unread_only: Option<bool>,
verified_email_only: Option<bool>,
@ -78,37 +82,7 @@ pub struct RegistrationApplicationQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> RegistrationApplicationQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
RegistrationApplicationQueryBuilder {
conn,
unread_only: None,
verified_email_only: None,
page: None,
limit: None,
}
}
pub fn unread_only<T: MaybeOptional<bool>>(mut self, unread_only: T) -> Self {
self.unread_only = unread_only.get_optional();
self
}
pub fn verified_email_only<T: MaybeOptional<bool>>(mut self, verified_email_only: T) -> Self {
self.verified_email_only = verified_email_only.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> RegistrationApplicationQuery<'a> {
pub fn list(self) -> Result<Vec<RegistrationApplicationView>, Error> {
let mut query = registration_application::table
.inner_join(local_user::table.on(registration_application::local_user_id.eq(local_user::id)))
@ -151,12 +125,12 @@ impl ViewToVec for RegistrationApplicationView {
type DbTuple = RegistrationApplicationViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
registration_application: a.0.to_owned(),
creator_local_user: a.1.to_owned(),
creator: a.2.to_owned(),
admin: a.3.to_owned(),
registration_application: a.0,
creator_local_user: a.1,
creator: a.2,
admin: a.3,
})
.collect::<Vec<Self>>()
}
@ -165,7 +139,7 @@ impl ViewToVec for RegistrationApplicationView {
#[cfg(test)]
mod tests {
use crate::registration_application_view::{
RegistrationApplicationQueryBuilder,
RegistrationApplicationQuery,
RegistrationApplicationView,
};
use lemmy_db_schema::{
@ -302,8 +276,10 @@ mod tests {
assert_eq!(read_sara_app_view, expected_sara_app_view);
// Do a batch read of the applications
let apps = RegistrationApplicationQueryBuilder::create(&conn)
.unread_only(true)
let apps = RegistrationApplicationQuery::builder()
.conn(&conn)
.unread_only(Some(true))
.build()
.list()
.unwrap();
@ -369,8 +345,10 @@ mod tests {
// Do a batch read of apps again
// It should show only jessicas which is unresolved
let apps_after_resolve = RegistrationApplicationQueryBuilder::create(&conn)
.unread_only(true)
let apps_after_resolve = RegistrationApplicationQuery::builder()
.conn(&conn)
.unread_only(Some(true))
.build()
.list()
.unwrap();
assert_eq!(apps_after_resolve, vec![read_jess_app_view]);
@ -381,7 +359,9 @@ mod tests {
assert_eq!(unread_count_after_approve, 1);
// Make sure the not undenied_only has all the apps
let all_apps = RegistrationApplicationQueryBuilder::create(&conn)
let all_apps = RegistrationApplicationQuery::builder()
.conn(&conn)
.build()
.list()
.unwrap();
assert_eq!(all_apps.len(), 2);

@ -18,3 +18,4 @@ full = ["lemmy_db_schema/full", "diesel"]
lemmy_db_schema = { version = "=0.16.5", path = "../db_schema" }
diesel = { version = "1.4.8", features = ["postgres","chrono","r2d2","serde_json"], optional = true }
serde = { version = "1.0.136", features = ["derive"] }
typed-builder = "0.10.0"

@ -25,10 +25,11 @@ use lemmy_db_schema::{
person_block::PersonBlock,
post::Post,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, limit_and_offset},
CommentSortType,
};
use typed_builder::TypedBuilder;
type CommentReplyViewTuple = (
CommentReply,
@ -159,7 +160,10 @@ impl CommentReplyView {
}
}
pub struct CommentReplyQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct CommentReplyQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
my_person_id: Option<PersonId>,
recipient_id: Option<PersonId>,
@ -170,55 +174,7 @@ pub struct CommentReplyQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> CommentReplyQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
CommentReplyQueryBuilder {
conn,
my_person_id: None,
recipient_id: None,
sort: None,
unread_only: None,
show_bot_accounts: None,
page: None,
limit: None,
}
}
pub fn sort<T: MaybeOptional<CommentSortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn unread_only<T: MaybeOptional<bool>>(mut self, unread_only: T) -> Self {
self.unread_only = unread_only.get_optional();
self
}
pub fn show_bot_accounts<T: MaybeOptional<bool>>(mut self, show_bot_accounts: T) -> Self {
self.show_bot_accounts = show_bot_accounts.get_optional();
self
}
pub fn recipient_id<T: MaybeOptional<PersonId>>(mut self, recipient_id: T) -> Self {
self.recipient_id = recipient_id.get_optional();
self
}
pub fn my_person_id<T: MaybeOptional<PersonId>>(mut self, my_person_id: T) -> Self {
self.my_person_id = my_person_id.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> CommentReplyQuery<'a> {
pub fn list(self) -> Result<Vec<CommentReplyView>, Error> {
use diesel::dsl::*;

@ -33,10 +33,10 @@ impl ViewToVec for CommunityBlockView {
type DbTuple = CommunityBlockViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
person: a.0.to_owned(),
community: a.1.to_owned(),
person: a.0,
community: a.1,
})
.collect::<Vec<Self>>()
}

@ -48,10 +48,10 @@ impl ViewToVec for CommunityFollowerView {
type DbTuple = CommunityFollowerViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
community: a.0.to_owned(),
follower: a.1.to_owned(),
community: a.0,
follower: a.1,
})
.collect::<Vec<Self>>()
}

@ -70,10 +70,10 @@ impl ViewToVec for CommunityModeratorView {
type DbTuple = CommunityModeratorViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
community: a.0.to_owned(),
moderator: a.1.to_owned(),
community: a.0,
moderator: a.1,
})
.collect::<Vec<Self>>()
}

@ -8,11 +8,12 @@ use lemmy_db_schema::{
community::{Community, CommunityFollower, CommunitySafe},
community_block::CommunityBlock,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, fuzzy_search, limit_and_offset},
ListingType,
SortType,
};
use typed_builder::TypedBuilder;
type CommunityViewTuple = (
CommunitySafe,
@ -91,7 +92,10 @@ impl CommunityView {
}
}
pub struct CommunityQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct CommunityQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
listing_type: Option<ListingType>,
sort: Option<SortType>,
@ -102,55 +106,7 @@ pub struct CommunityQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> CommunityQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
CommunityQueryBuilder {
conn,
my_person_id: None,
listing_type: Some(ListingType::All),
sort: None,
show_nsfw: None,
search_term: None,
page: None,
limit: None,
}
}
pub fn listing_type<T: MaybeOptional<ListingType>>(mut self, listing_type: T) -> Self {
self.listing_type = listing_type.get_optional();
self
}
pub fn sort<T: MaybeOptional<SortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn show_nsfw<T: MaybeOptional<bool>>(mut self, show_nsfw: T) -> Self {
self.show_nsfw = show_nsfw.get_optional();
self
}
pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
self.search_term = search_term.get_optional();
self
}
pub fn my_person_id<T: MaybeOptional<PersonId>>(mut self, my_person_id: T) -> Self {
self.my_person_id = my_person_id.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> CommunityQuery<'a> {
pub fn list(self) -> Result<Vec<CommunityView>, Error> {
// The left join below will return None in this case
let person_id_join = self.my_person_id.unwrap_or(PersonId(-1));
@ -258,10 +214,10 @@ impl ViewToVec for CommunityView {
type DbTuple = CommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
community: a.0.to_owned(),
counts: a.1.to_owned(),
community: a.0,
counts: a.1,
subscribed: CommunityFollower::to_subscribed_type(&a.2),
blocked: a.3.is_some(),
})

@ -30,10 +30,10 @@ impl ViewToVec for PersonBlockView {
type DbTuple = PersonBlockViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
person: a.0.to_owned(),
target: a.1.to_owned(),
person: a.0,
target: a.1,
})
.collect::<Vec<Self>>()
}

@ -25,10 +25,11 @@ use lemmy_db_schema::{
person_mention::PersonMention,
post::Post,
},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{functions::hot_rank, limit_and_offset},
CommentSortType,
};
use typed_builder::TypedBuilder;
type PersonMentionViewTuple = (
PersonMention,
@ -159,7 +160,10 @@ impl PersonMentionView {
}
}
pub struct PersonMentionQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PersonMentionQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
my_person_id: Option<PersonId>,
recipient_id: Option<PersonId>,
@ -170,55 +174,7 @@ pub struct PersonMentionQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> PersonMentionQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
PersonMentionQueryBuilder {
conn,
my_person_id: None,
recipient_id: None,
sort: None,
unread_only: None,
show_bot_accounts: None,
page: None,
limit: None,
}
}
pub fn sort<T: MaybeOptional<CommentSortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn unread_only<T: MaybeOptional<bool>>(mut self, unread_only: T) -> Self {
self.unread_only = unread_only.get_optional();
self
}
pub fn show_bot_accounts<T: MaybeOptional<bool>>(mut self, show_bot_accounts: T) -> Self {
self.show_bot_accounts = show_bot_accounts.get_optional();
self
}
pub fn recipient_id<T: MaybeOptional<PersonId>>(mut self, recipient_id: T) -> Self {
self.recipient_id = recipient_id.get_optional();
self
}
pub fn my_person_id<T: MaybeOptional<PersonId>>(mut self, my_person_id: T) -> Self {
self.my_person_id = my_person_id.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> PersonMentionQuery<'a> {
pub fn list(self) -> Result<Vec<PersonMentionView>, Error> {
use diesel::dsl::*;
@ -324,15 +280,15 @@ impl ViewToVec for PersonMentionView {
type DbTuple = PersonMentionViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
person_mention: a.0.to_owned(),
comment: a.1.to_owned(),
creator: a.2.to_owned(),
post: a.3.to_owned(),
community: a.4.to_owned(),
recipient: a.5.to_owned(),
counts: a.6.to_owned(),
person_mention: a.0,
comment: a.1,
creator: a.2,
post: a.3,
community: a.4,
recipient: a.5,
counts: a.6,
creator_banned_from_community: a.7.is_some(),
subscribed: CommunityFollower::to_subscribed_type(&a.8),
saved: a.9.is_some(),

@ -5,10 +5,11 @@ use lemmy_db_schema::{
newtypes::PersonId,
schema::{person, person_aggregates},
source::person::{Person, PersonSafe},
traits::{MaybeOptional, ToSafe, ViewToVec},
traits::{ToSafe, ViewToVec},
utils::{fuzzy_search, limit_and_offset},
SortType,
};
use typed_builder::TypedBuilder;
type PersonViewSafeTuple = (PersonSafe, PersonAggregates);
@ -50,7 +51,10 @@ impl PersonViewSafe {
}
}
pub struct PersonQueryBuilder<'a> {
#[derive(TypedBuilder)]
#[builder(field_defaults(default))]
pub struct PersonQuery<'a> {
#[builder(!default)]
conn: &'a PgConnection,
sort: Option<SortType>,
search_term: Option<String>,
@ -58,37 +62,7 @@ pub struct PersonQueryBuilder<'a> {
limit: Option<i64>,
}
impl<'a> PersonQueryBuilder<'a> {
pub fn create(conn: &'a PgConnection) -> Self {
PersonQueryBuilder {
conn,
search_term: None,
sort: None,
page: None,
limit: None,
}
}
pub fn sort<T: MaybeOptional<SortType>>(mut self, sort: T) -> Self {
self.sort = sort.get_optional();
self
}
pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
self.search_term = search_term.get_optional();
self
}
pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
self.page = page.get_optional();
self
}
pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
self.limit = limit.get_optional();
self
}
impl<'a> PersonQuery<'a> {
pub fn list(self) -> Result<Vec<PersonViewSafe>, Error> {
let mut query = person::table
.inner_join(person_aggregates::table)
@ -138,10 +112,10 @@ impl ViewToVec for PersonViewSafe {
type DbTuple = PersonViewSafeTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
person: a.0.to_owned(),
counts: a.1.to_owned(),
person: a.0,
counts: a.1,
})
.collect::<Vec<Self>>()
}

@ -51,11 +51,11 @@ impl ViewToVec for AdminPurgeCommentView {
type DbTuple = AdminPurgeCommentViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
admin_purge_comment: a.0.to_owned(),
admin: a.1.to_owned(),
post: a.2.to_owned(),
admin_purge_comment: a.0,
admin: a.1,
post: a.2,
})
.collect::<Vec<Self>>()
}

@ -48,10 +48,10 @@ impl ViewToVec for AdminPurgeCommunityView {
type DbTuple = AdminPurgeCommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
admin_purge_community: a.0.to_owned(),
admin: a.1.to_owned(),
admin_purge_community: a.0,
admin: a.1,
})
.collect::<Vec<Self>>()
}

@ -48,10 +48,10 @@ impl ViewToVec for AdminPurgePersonView {
type DbTuple = AdminPurgePersonViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
admin_purge_person: a.0.to_owned(),
admin: a.1.to_owned(),
admin_purge_person: a.0,
admin: a.1,
})
.collect::<Vec<Self>>()
}

@ -51,11 +51,11 @@ impl ViewToVec for AdminPurgePostView {
type DbTuple = AdminPurgePostViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
admin_purge_post: a.0.to_owned(),
admin: a.1.to_owned(),
community: a.2.to_owned(),
admin_purge_post: a.0,
admin: a.1,
community: a.2,
})
.collect::<Vec<Self>>()
}

@ -60,12 +60,12 @@ impl ViewToVec for ModAddCommunityView {
type DbTuple = ModAddCommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_add_community: a.0.to_owned(),
moderator: a.1.to_owned(),
community: a.2.to_owned(),
modded_person: a.3.to_owned(),
mod_add_community: a.0,
moderator: a.1,
community: a.2,
modded_person: a.3,
})
.collect::<Vec<Self>>()
}

@ -50,11 +50,11 @@ impl ViewToVec for ModAddView {
type DbTuple = ModAddViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_add: a.0.to_owned(),
moderator: a.1.to_owned(),
modded_person: a.2.to_owned(),
mod_add: a.0,
moderator: a.1,
modded_person: a.2,
})
.collect::<Vec<Self>>()
}

@ -65,12 +65,12 @@ impl ViewToVec for ModBanFromCommunityView {
type DbTuple = ModBanFromCommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_ban_from_community: a.0.to_owned(),
moderator: a.1.to_owned(),
community: a.2.to_owned(),
banned_person: a.3.to_owned(),
mod_ban_from_community: a.0,
moderator: a.1,
community: a.2,
banned_person: a.3,
})
.collect::<Vec<Self>>()
}

@ -50,11 +50,11 @@ impl ViewToVec for ModBanView {
type DbTuple = ModBanViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_ban: a.0.to_owned(),
moderator: a.1.to_owned(),
banned_person: a.2.to_owned(),
mod_ban: a.0,
moderator: a.1,
banned_person: a.2,
})
.collect::<Vec<Self>>()
}

@ -57,11 +57,11 @@ impl ViewToVec for ModHideCommunityView {
type DbTuple = ModHideCommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_hide_community: a.0.to_owned(),
admin: a.1.to_owned(),
community: a.2.to_owned(),
mod_hide_community: a.0,
admin: a.1,
community: a.2,
})
.collect::<Vec<Self>>()
}

@ -59,12 +59,12 @@ impl ViewToVec for ModLockPostView {
type DbTuple = ModLockPostViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_lock_post: a.0.to_owned(),
moderator: a.1.to_owned(),
post: a.2.to_owned(),
community: a.3.to_owned(),
mod_lock_post: a.0,
moderator: a.1,
post: a.2,
community: a.3,
})
.collect::<Vec<Self>>()
}

@ -71,14 +71,14 @@ impl ViewToVec for ModRemoveCommentView {
type DbTuple = ModRemoveCommentViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_remove_comment: a.0.to_owned(),
moderator: a.1.to_owned(),
comment: a.2.to_owned(),
commenter: a.3.to_owned(),
post: a.4.to_owned(),
community: a.5.to_owned(),
mod_remove_comment: a.0,
moderator: a.1,
comment: a.2,
commenter: a.3,
post: a.4,
community: a.5,
})
.collect::<Vec<Self>>()
}

@ -51,11 +51,11 @@ impl ViewToVec for ModRemoveCommunityView {
type DbTuple = ModRemoveCommunityTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_remove_community: a.0.to_owned(),
moderator: a.1.to_owned(),
community: a.2.to_owned(),
mod_remove_community: a.0,
moderator: a.1,
community: a.2,
})
.collect::<Vec<Self>>()
}

@ -59,12 +59,12 @@ impl ViewToVec for ModRemovePostView {
type DbTuple = ModRemovePostViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_remove_post: a.0.to_owned(),
moderator: a.1.to_owned(),
post: a.2.to_owned(),
community: a.3.to_owned(),
mod_remove_post: a.0,
moderator: a.1,
post: a.2,
community: a.3,
})
.collect::<Vec<Self>>()
}

@ -59,12 +59,12 @@ impl ViewToVec for ModStickyPostView {
type DbTuple = ModStickyPostViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_sticky_post: a.0.to_owned(),
moderator: a.1.to_owned(),
post: a.2.to_owned(),
community: a.3.to_owned(),
mod_sticky_post: a.0,
moderator: a.1,
post: a.2,
community: a.3,
})
.collect::<Vec<Self>>()
}

@ -65,12 +65,12 @@ impl ViewToVec for ModTransferCommunityView {
type DbTuple = ModTransferCommunityViewTuple;
fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
items
.iter()
.into_iter()
.map(|a| Self {
mod_transfer_community: a.0.to_owned(),
moderator: a.1.to_owned(),
community: a.2.to_owned(),
modded_person: a.3.to_owned(),
mod_transfer_community: a.0,
moderator: a.1,
community: a.2,
modded_person: a.3,
})
.collect::<Vec<Self>>()
}

@ -12,12 +12,12 @@ use lemmy_db_schema::{
SortType,
};
use lemmy_db_views::{
post_view::PostQueryBuilder,
post_view::PostQuery,
structs::{PostView, SiteView},
};
use lemmy_db_views_actor::{
comment_reply_view::CommentReplyQueryBuilder,
person_mention_view::PersonMentionQueryBuilder,
comment_reply_view::CommentReplyQuery,
person_mention_view::PersonMentionQuery,
structs::{CommentReplyView, PersonMentionView},
};
use lemmy_utils::{claims::Claims, error::LemmyError, utils::markdown_to_html};
@ -91,10 +91,12 @@ async fn get_feed_data(
let site_view = blocking(context.pool(), SiteView::read_local).await??;
let posts = blocking(context.pool(), move |conn| {
PostQueryBuilder::create(conn)
.listing_type(listing_type)
.sort(sort_type)
.limit(RSS_FETCH_LIMIT)
PostQuery::builder()
.conn(conn)
.listing_type(Some(listing_type))
.sort(Some(sort_type))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()
})
.await??;
@ -184,11 +186,13 @@ fn get_feed_user(
let site_view = SiteView::read_local(conn)?;
let person = Person::read_from_name(conn, user_name, false)?;
let posts = PostQueryBuilder::create(conn)
.listing_type(ListingType::All)
.sort(*sort_type)
.creator_id(person.id)
.limit(RSS_FETCH_LIMIT)
let posts = PostQuery::builder()
.conn(conn)
.listing_type(Some(ListingType::All))
.sort(Some(*sort_type))
.creator_id(Some(person.id))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()?;
let items = create_post_items(posts, protocol_and_hostname)?;
@ -213,10 +217,12 @@ fn get_feed_community(
let site_view = SiteView::read_local(conn)?;
let community = Community::read_from_name(conn, community_name, false)?;
let posts = PostQueryBuilder::create(conn)
.sort(*sort_type)
.community_id(community.id)
.limit(RSS_FETCH_LIMIT)
let posts = PostQuery::builder()
.conn(conn)
.sort(Some(*sort_type))
.community_id(Some(community.id))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()?;
let items = create_post_items(posts, protocol_and_hostname)?;
@ -247,13 +253,15 @@ fn get_feed_front(
let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub);
let local_user = LocalUser::read(conn, local_user_id)?;
let posts = PostQueryBuilder::create(conn)
.listing_type(ListingType::Subscribed)
.my_person_id(local_user.person_id)
.show_bot_accounts(local_user.show_bot_accounts)
.show_read_posts(local_user.show_read_posts)
.sort(*sort_type)
.limit(RSS_FETCH_LIMIT)
let posts = PostQuery::builder()
.conn(conn)
.listing_type(Some(ListingType::Subscribed))
.my_person_id(Some(local_user.person_id))
.show_bot_accounts(Some(local_user.show_bot_accounts))
.show_read_posts(Some(local_user.show_read_posts))
.sort(Some(*sort_type))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()?;
let items = create_post_items(posts, protocol_and_hostname)?;
@ -287,20 +295,24 @@ fn get_feed_inbox(
let sort = CommentSortType::New;
let replies = CommentReplyQueryBuilder::create(conn)
.recipient_id(person_id)
.my_person_id(person_id)
.show_bot_accounts(show_bot_accounts)
.sort(sort)
.limit(RSS_FETCH_LIMIT)
let replies = CommentReplyQuery::builder()
.conn(conn)
.recipient_id(Some(person_id))
.my_person_id(Some(person_id))
.show_bot_accounts(Some(show_bot_accounts))
.sort(Some(sort))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()?;
let mentions = PersonMentionQueryBuilder::create(conn)
.recipient_id(person_id)
.my_person_id(person_id)
.show_bot_accounts(show_bot_accounts)
.sort(sort)
.limit(RSS_FETCH_LIMIT)
let mentions = PersonMentionQuery::builder()
.conn(conn)
.recipient_id(Some(person_id))
.my_person_id(Some(person_id))
.show_bot_accounts(Some(show_bot_accounts))
.sort(Some(sort))
.limit(Some(RSS_FETCH_LIMIT))
.build()
.list()?;
let items = create_reply_and_mention_items(replies, mentions, protocol_and_hostname)?;

Loading…
Cancel
Save