mirror of https://github.com/LemmyNet/lemmy.git
Add queries function
parent
47000ff9a8
commit
2aec4d68a8
|
@ -2762,6 +2762,7 @@ dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"diesel_ltree",
|
"diesel_ltree",
|
||||||
|
"futures",
|
||||||
"lemmy_db_schema",
|
"lemmy_db_schema",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
|
|
@ -30,6 +30,7 @@ serde = { workspace = true }
|
||||||
serde_with = { workspace = true }
|
serde_with = { workspace = true }
|
||||||
tracing = { workspace = true, optional = true }
|
tracing = { workspace = true, optional = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
|
futures = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -1,25 +1,17 @@
|
||||||
use crate::structs::CommentReportView;
|
use crate::structs::CommentReportView;
|
||||||
use diesel::{
|
use diesel::{
|
||||||
dsl,
|
|
||||||
dsl::now,
|
dsl::now,
|
||||||
helper_types::AliasedFields,
|
|
||||||
pg::Pg,
|
pg::Pg,
|
||||||
query_builder::{AsQuery, Query, QueryFragment, QueryId, SelectQuery},
|
|
||||||
query_dsl::methods,
|
|
||||||
result::Error,
|
result::Error,
|
||||||
sql_types,
|
sql_types,
|
||||||
sql_types::Nullable,
|
|
||||||
BoolExpressionMethods,
|
BoolExpressionMethods,
|
||||||
BoxableExpression,
|
|
||||||
Expression,
|
|
||||||
ExpressionMethods,
|
ExpressionMethods,
|
||||||
JoinOnDsl,
|
JoinOnDsl,
|
||||||
JoinTo,
|
|
||||||
NullableExpressionMethods,
|
NullableExpressionMethods,
|
||||||
QueryDsl,
|
QueryDsl,
|
||||||
Table,
|
|
||||||
};
|
};
|
||||||
use diesel_async::{methods::LoadQuery, RunQueryDsl};
|
use diesel_async::RunQueryDsl;
|
||||||
|
use futures::future::BoxFuture;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::CommentAggregates,
|
aggregates::structs::CommentAggregates,
|
||||||
newtypes::{CommentReportId, CommunityId, PersonId},
|
newtypes::{CommentReportId, CommunityId, PersonId},
|
||||||
|
@ -44,54 +36,25 @@ use lemmy_db_schema::{
|
||||||
traits::JoinView,
|
traits::JoinView,
|
||||||
utils::{get_conn, limit_and_offset, DbConn, DbPool},
|
utils::{get_conn, limit_and_offset, DbConn, DbPool},
|
||||||
};
|
};
|
||||||
|
use std::{future::Future, pin::Pin};
|
||||||
|
|
||||||
diesel::alias!(person as person_alias_1: PersonAlias1, person as person_alias_2:PersonAlias2);
|
diesel::alias!(person as person_alias_1: PersonAlias1, person as person_alias_2:PersonAlias2);
|
||||||
|
|
||||||
type Selection = (
|
fn queries<'a>() -> (
|
||||||
<comment_report::table as Table>::AllColumns,
|
impl Fn(
|
||||||
<comment::table as Table>::AllColumns,
|
DbConn<'a>,
|
||||||
<post::table as Table>::AllColumns,
|
CommentReportId,
|
||||||
<community::table as Table>::AllColumns,
|
PersonId,
|
||||||
<person::table as Table>::AllColumns,
|
) -> BoxFuture<'a, Result<<CommentReportView as JoinView>::JoinTuple, Error>>,
|
||||||
AliasedFields<PersonAlias1, <person::table as Table>::AllColumns>,
|
impl Fn(
|
||||||
<comment_aggregates::table as Table>::AllColumns,
|
DbConn<'a>,
|
||||||
dsl::Nullable<<community_person_ban::table as Table>::AllColumns>,
|
CommentReportQuery,
|
||||||
dsl::Nullable<comment_like::score>,
|
&'a Person,
|
||||||
dsl::Nullable<AliasedFields<PersonAlias2, <person::table as Table>::AllColumns>>,
|
) -> BoxFuture<'a, Result<Vec<<CommentReportView as JoinView>::JoinTuple>, Error>>,
|
||||||
);
|
) {
|
||||||
|
let full_query = move |query: comment_report::BoxedQuery<'static, Pg>,
|
||||||
/*trait BoxedFilter<T>:methods::FilterDsl<T,Output=Self> {}
|
|
||||||
|
|
||||||
impl<T:methods::FilterDsl
|
|
||||||
|
|
||||||
trait BoxedJoin: 'static + methods::LimitDsl<Output = Self> + LoadQuery + Send + AsQuery<SqlType = <Selection as Expression>::SqlType>+FilterDsl<dsl::Eq<post::community_id,CommunityId>,Output=Self> where <Self as AsQuery>::Query: QueryFragment<Pg>+QueryId+Send+'static {}
|
|
||||||
|
|
||||||
impl<T: 'static + methods::LimitDsl<Output = T> + LoadQuery + Send + AsQuery<SqlType = <Selection as Expression>::SqlType>> BoxedJoin for T where <T as AsQuery>::Query: QueryFragment<Pg>+QueryId+Send+'static {}*/
|
|
||||||
|
|
||||||
fn full_query<'a>(
|
|
||||||
mut query: comment_report::BoxedQuery<'a, Pg>,
|
|
||||||
//report_id: Option<CommentReportId>,
|
|
||||||
my_person_id: PersonId,
|
my_person_id: PersonId,
|
||||||
include_expired: bool,
|
include_expired: bool| {
|
||||||
) -> impl 'a + SelectQuery<SqlType = <Selection as Expression>::SqlType>
|
|
||||||
/*comment_report::BoxedQuery<
|
|
||||||
'_,
|
|
||||||
Pg,
|
|
||||||
<Selection as Expression>::SqlType,
|
|
||||||
/*(
|
|
||||||
comment_report::SqlType,
|
|
||||||
comment::SqlType,
|
|
||||||
post::SqlType,
|
|
||||||
community::SqlType,
|
|
||||||
person::SqlType,
|
|
||||||
AliasedFields<PersonAlias1, <person::table as Table>::AllColumns>,
|
|
||||||
comment_aggregates::SqlType,
|
|
||||||
Nullable<community_person_ban::SqlType>,
|
|
||||||
Nullable<<comment_like::score as Expression>::SqlType>,
|
|
||||||
Nullable<AliasedFields<PersonAlias2, <person::table as Table>::AllColumns>>,
|
|
||||||
)*/
|
|
||||||
>*/ {
|
|
||||||
//if let Some(report_id) = report_id {query = query.find(report_id);}
|
|
||||||
query
|
query
|
||||||
.inner_join(comment::table.on(comment_report::comment_id.eq(comment::id)))
|
.inner_join(comment::table.on(comment_report::comment_id.eq(comment::id)))
|
||||||
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
.inner_join(post::table.on(comment::post_id.eq(post::id)))
|
||||||
|
@ -110,8 +73,8 @@ fn full_query<'a>(
|
||||||
community_person_ban::expires
|
community_person_ban::expires
|
||||||
.is_null()
|
.is_null()
|
||||||
.or(community_person_ban::expires.gt(now))
|
.or(community_person_ban::expires.gt(now))
|
||||||
// TODO: avoid evaluation of this condition if include_expired is true
|
// TODO: avoid evaluation of expiration condition if include_expired is true
|
||||||
.or(!include_expired),
|
.or::<_, sql_types::Nullable<sql_types::Bool>>(include_expired),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -126,7 +89,7 @@ fn full_query<'a>(
|
||||||
person_alias_2
|
person_alias_2
|
||||||
.on(comment_report::resolver_id.eq(person_alias_2.field(person::id).nullable())),
|
.on(comment_report::resolver_id.eq(person_alias_2.field(person::id).nullable())),
|
||||||
)
|
)
|
||||||
.select::<Selection>((
|
.select((
|
||||||
comment_report::all_columns,
|
comment_report::all_columns,
|
||||||
comment::all_columns,
|
comment::all_columns,
|
||||||
post::all_columns,
|
post::all_columns,
|
||||||
|
@ -138,7 +101,73 @@ fn full_query<'a>(
|
||||||
comment_like::score.nullable(),
|
comment_like::score.nullable(),
|
||||||
person_alias_2.fields(person::all_columns).nullable(),
|
person_alias_2.fields(person::all_columns).nullable(),
|
||||||
))
|
))
|
||||||
//.into_boxed()
|
};
|
||||||
|
let read = move |mut conn: DbConn<'a>, report_id: CommentReportId, my_person_id: PersonId| {
|
||||||
|
let fut = async move {
|
||||||
|
let res = full_query(
|
||||||
|
comment_report::table.find(report_id).into_boxed(),
|
||||||
|
my_person_id,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.first::<<CommentReportView as JoinView>::JoinTuple>(&mut conn)
|
||||||
|
.await?;
|
||||||
|
Ok::<<CommentReportView as JoinView>::JoinTuple, Error>(res)
|
||||||
|
};
|
||||||
|
let b: Pin<
|
||||||
|
Box<
|
||||||
|
dyn Future<Output = Result<<CommentReportView as JoinView>::JoinTuple, Error>> + Send + '_,
|
||||||
|
>,
|
||||||
|
> = Box::pin(fut);
|
||||||
|
b
|
||||||
|
};
|
||||||
|
let list = move |mut conn: DbConn<'a>, options: CommentReportQuery, my_person: &'a Person| {
|
||||||
|
let fut = async move {
|
||||||
|
let mut query = full_query(comment_report::table.into_boxed(), my_person.id, false);
|
||||||
|
|
||||||
|
if let Some(community_id) = options.community_id {
|
||||||
|
query = query.filter(post::community_id.eq(community_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.unresolved_only.unwrap_or(false) {
|
||||||
|
query = query.filter(comment_report::resolved.eq(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (limit, offset) = limit_and_offset(options.page, options.limit)?;
|
||||||
|
|
||||||
|
query = query
|
||||||
|
.order_by(comment_report::published.desc())
|
||||||
|
.limit(limit)
|
||||||
|
.offset(offset);
|
||||||
|
|
||||||
|
// If its not an admin, get only the ones you mod
|
||||||
|
let res = if !my_person.admin {
|
||||||
|
query
|
||||||
|
.inner_join(
|
||||||
|
community_moderator::table.on(
|
||||||
|
community_moderator::community_id
|
||||||
|
.eq(post::community_id)
|
||||||
|
.and(community_moderator::person_id.eq(my_person.id)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.load::<<CommentReportView as JoinView>::JoinTuple>(&mut conn)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
query
|
||||||
|
.load::<<CommentReportView as JoinView>::JoinTuple>(&mut conn)
|
||||||
|
.await?
|
||||||
|
};
|
||||||
|
Ok::<Vec<<CommentReportView as JoinView>::JoinTuple>, Error>(res)
|
||||||
|
};
|
||||||
|
let b: Pin<
|
||||||
|
Box<
|
||||||
|
dyn Future<Output = Result<Vec<<CommentReportView as JoinView>::JoinTuple>, Error>>
|
||||||
|
+ Send
|
||||||
|
+ '_,
|
||||||
|
>,
|
||||||
|
> = Box::pin(fut);
|
||||||
|
b
|
||||||
|
};
|
||||||
|
(read, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommentReportView {
|
impl CommentReportView {
|
||||||
|
@ -150,15 +179,9 @@ impl CommentReportView {
|
||||||
report_id: CommentReportId,
|
report_id: CommentReportId,
|
||||||
my_person_id: PersonId,
|
my_person_id: PersonId,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = get_conn(pool).await?;
|
||||||
|
|
||||||
let res = full_query(
|
let res = (queries().0)(conn, report_id, my_person_id).await?;
|
||||||
comment_report::table.find(report_id).into_boxed(),
|
|
||||||
my_person_id,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
.first::<<CommentReportView as JoinView>::JoinTuple>(conn)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(Self::from_tuple(res))
|
Ok(Self::from_tuple(res))
|
||||||
}
|
}
|
||||||
|
@ -220,42 +243,9 @@ impl CommentReportQuery {
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
my_person: &Person,
|
my_person: &Person,
|
||||||
) -> Result<Vec<CommentReportView>, Error> {
|
) -> Result<Vec<CommentReportView>, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = get_conn(pool).await?;
|
||||||
|
|
||||||
let mut query = full_query(comment_report::table.into_boxed(), my_person.id, false);
|
let res = (queries().1)(conn, self, my_person).await?;
|
||||||
|
|
||||||
if let Some(community_id) = self.community_id {
|
|
||||||
query = query.filter(post::community_id.eq(community_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.unresolved_only.unwrap_or(false) {
|
|
||||||
query = query.filter(comment_report::resolved.eq(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (limit, offset) = limit_and_offset(self.page, self.limit)?;
|
|
||||||
|
|
||||||
query = query
|
|
||||||
.order_by(comment_report::published.desc())
|
|
||||||
.limit(limit)
|
|
||||||
.offset(offset);
|
|
||||||
|
|
||||||
// If its not an admin, get only the ones you mod
|
|
||||||
let res = if !my_person.admin {
|
|
||||||
query
|
|
||||||
.inner_join(
|
|
||||||
community_moderator::table.on(
|
|
||||||
community_moderator::community_id
|
|
||||||
.eq(post::community_id)
|
|
||||||
.and(community_moderator::person_id.eq(my_person.id)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.load::<<CommentReportView as JoinView>::JoinTuple>(conn)
|
|
||||||
.await?
|
|
||||||
} else {
|
|
||||||
query
|
|
||||||
.load::<<CommentReportView as JoinView>::JoinTuple>(conn)
|
|
||||||
.await?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(res.into_iter().map(CommentReportView::from_tuple).collect())
|
Ok(res.into_iter().map(CommentReportView::from_tuple).collect())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue