feat: query::objects

in the end i really needed it anyway to avoid dupes... but at least this
is cross-db! not like Query::feed which avoids dupes only on postgres
(sometimes)
This commit is contained in:
əlemi 2024-08-14 02:14:05 +02:00
parent 9b6b51889a
commit 660e5cf127
Signed by: alemi
GPG key ID: A4895B84D311642C
6 changed files with 37 additions and 21 deletions

View file

@ -4,15 +4,11 @@ use crate::model;
pub struct Query; pub struct Query;
impl Query { impl Query {
pub fn feed(my_id: Option<i64>, by_object: bool) -> Select<model::addressing::Entity> { pub fn feed(my_id: Option<i64>) -> Select<model::addressing::Entity> {
let mut select = model::addressing::Entity::find() let mut select = model::addressing::Entity::find()
.distinct_on([ .distinct_on([
(model::addressing::Entity, model::addressing::Column::Published).into_column_ref(), (model::addressing::Entity, model::addressing::Column::Published).into_column_ref(),
if by_object { (model::activity::Entity, model::activity::Column::Internal).into_column_ref(),
(model::object::Entity, model::object::Column::Internal).into_column_ref()
} else {
(model::activity::Entity, model::activity::Column::Internal).into_column_ref()
},
]) ])
.join(sea_orm::JoinType::LeftJoin, model::addressing::Relation::Activities.def()) .join(sea_orm::JoinType::LeftJoin, model::addressing::Relation::Activities.def())
.join(sea_orm::JoinType::LeftJoin, model::addressing::Relation::Objects.def()) .join(sea_orm::JoinType::LeftJoin, model::addressing::Relation::Objects.def())
@ -22,13 +18,9 @@ impl Query {
.add(model::activity::Column::Id.is_not_null()) .add(model::activity::Column::Id.is_not_null())
.add(model::object::Column::Id.is_not_null()) .add(model::object::Column::Id.is_not_null())
) )
.order_by(model::addressing::Column::Published, Order::Desc); .order_by(model::addressing::Column::Published, Order::Desc)
.order_by(model::activity::Column::Internal, Order::Desc)
select = if by_object { .select_only();
select.order_by(model::object::Column::Internal, Order::Desc).select_only()
} else {
select.order_by(model::activity::Column::Internal, Order::Desc).select_only()
};
for col in model::activity::Column::iter() { for col in model::activity::Column::iter() {
select = select.select_column_as(col, format!("{}{}", model::activity::Entity.table_name(), col.to_string())); select = select.select_column_as(col, format!("{}{}", model::activity::Entity.table_name(), col.to_string()));
@ -56,6 +48,30 @@ impl Query {
select select
} }
pub fn objects(my_id: Option<i64>) -> Select<model::addressing::Entity> {
let mut select = model::addressing::Entity::find()
.distinct()
.join(sea_orm::JoinType::InnerJoin, model::addressing::Relation::Objects.def())
.order_by(model::object::Column::Published, Order::Desc)
.select_only();
for col in model::object::Column::iter() {
select = select.select_column_as(col, format!("{}{}", model::object::Entity.table_name(), col.to_string()));
}
if let Some(uid) = my_id {
select = select
.join(
sea_orm::JoinType::LeftJoin,
model::object::Relation::Likes.def()
.on_condition(move |_l, _r| model::like::Column::Actor.eq(uid).into_condition()),
)
.select_column_as(model::like::Column::Actor, format!("{}{}", model::like::Entity.table_name(), model::like::Column::Actor.to_string()));
}
select
}
pub fn related(from: Option<i64>, to: Option<i64>, pending: bool) -> Select<model::relation::Entity> { pub fn related(from: Option<i64>, to: Option<i64>, pending: bool) -> Select<model::relation::Entity> {
let mut condition = Condition::all(); let mut condition = Condition::all();

View file

@ -23,7 +23,7 @@ pub async fn view(
} }
} }
let row = upub::Query::feed(auth.my_id(), false) let row = upub::Query::feed(auth.my_id())
.filter(model::activity::Column::Id.eq(&aid)) .filter(model::activity::Column::Id.eq(&aid))
.filter(auth.filter()) .filter(auth.filter())
.into_model::<RichActivity>() .into_model::<RichActivity>()

View file

@ -11,7 +11,7 @@ pub async fn get(
) -> crate::ApiResult<JsonLD<serde_json::Value>> { ) -> crate::ApiResult<JsonLD<serde_json::Value>> {
let context = ctx.oid(&id); let context = ctx.oid(&id);
let count = upub::Query::feed(auth.my_id(), true) let count = upub::Query::objects(auth.my_id())
.filter(auth.filter()) .filter(auth.filter())
.filter(model::object::Column::Context.eq(&context)) .filter(model::object::Column::Context.eq(&context))
.count(ctx.db()) .count(ctx.db())
@ -43,7 +43,7 @@ pub async fn page(
let offset = page.offset.unwrap_or(0); let offset = page.offset.unwrap_or(0);
let items = upub::Query::feed(auth.my_id(), true) let items = upub::Query::objects(auth.my_id())
.filter(filter) .filter(filter)
// TODO also limit to only local activities // TODO also limit to only local activities
.limit(limit) .limit(limit)

View file

@ -27,7 +27,7 @@ pub async fn view(
} }
} }
let item = upub::Query::feed(auth.my_id(), true) let item = upub::Query::objects(auth.my_id())
.filter(model::object::Column::Id.eq(&oid)) .filter(model::object::Column::Id.eq(&oid))
.filter(auth.filter()) .filter(auth.filter())
.into_model::<RichActivity>() .into_model::<RichActivity>()
@ -44,7 +44,7 @@ pub async fn view(
let mut replies = apb::Node::Empty; let mut replies = apb::Node::Empty;
if ctx.cfg().security.show_reply_ids { if ctx.cfg().security.show_reply_ids {
let replies_ids = upub::Query::feed(auth.my_id(), true) let replies_ids = upub::Query::objects(auth.my_id())
.filter(model::object::Column::InReplyTo.eq(oid)) .filter(model::object::Column::InReplyTo.eq(oid))
.filter(auth.filter()) .filter(auth.filter())
.select_only() .select_only()

View file

@ -15,7 +15,7 @@ pub async fn get(
// ctx.fetch_thread(&oid).await?; // ctx.fetch_thread(&oid).await?;
// } // }
let replies_ids = upub::Query::feed(auth.my_id(), true) let replies_ids = upub::Query::objects(auth.my_id())
.filter(model::object::Column::InReplyTo.eq(ctx.oid(&id))) .filter(model::object::Column::InReplyTo.eq(ctx.oid(&id)))
.filter(auth.filter()) .filter(auth.filter())
.select_only() .select_only()

View file

@ -5,7 +5,7 @@ use upub::selector::{BatchFillable, RichActivity};
use crate::activitypub::Pagination; use crate::activitypub::Pagination;
//#[deprecated = "just query directly maybe?"] //#[deprecated = "use upub::Query directly"]
pub async fn paginate_feed( pub async fn paginate_feed(
id: String, id: String,
filter: Condition, filter: Condition,
@ -17,7 +17,7 @@ pub async fn paginate_feed(
let limit = page.batch.unwrap_or(20).min(50); let limit = page.batch.unwrap_or(20).min(50);
let offset = page.offset.unwrap_or(0); let offset = page.offset.unwrap_or(0);
let mut select = upub::Query::feed(my_id, false); let mut select = upub::Query::feed(my_id);
if with_users { if with_users {
select = select select = select