aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author alemi <me@alemi.dev>2024-04-11 17:00:09 +0200
committer alemi <me@alemi.dev>2024-04-11 17:00:09 +0200
commit9e67eead69f5cbd426939d8003b3374476f6d725 (patch)
tree9f27aff740f087e0f85ff31d41ee151e8276fe8c
parentd5c5d341e8441b8969089db5f108ebedc8890687 (diff)
feat: multi-join maybe? fix inbox not embedding objtci
got this from https://github.com/SeaQL/sea-orm/discussions/1502, not sure it's what i need but i'm trying some stuff
-rw-r--r--src/main.rs1
-rw-r--r--src/routes/activitypub/user/inbox.rs23
-rw-r--r--src/tools.rs41
3 files changed, 59 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs
index 3c12cff..6178aa9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,7 @@ pub mod server;
pub mod model;
pub mod routes;
+pub mod tools;
pub mod errors;
#[cfg(feature = "migrations")]
diff --git a/src/routes/activitypub/user/inbox.rs b/src/routes/activitypub/user/inbox.rs
index d59a7cc..2d310ca 100644
--- a/src/routes/activitypub/user/inbox.rs
+++ b/src/routes/activitypub/user/inbox.rs
@@ -1,8 +1,8 @@
use axum::{extract::{Path, Query, State}, http::StatusCode, Json};
-use sea_orm::{ColumnTrait, Condition, EntityTrait, Order, QueryFilter, QueryOrder, QuerySelect};
+use sea_orm::{ColumnTrait, Condition, EntityTrait, JoinType, Order, QueryFilter, QueryOrder, QuerySelect, RelationTrait};
-use apb::{server::Inbox, ActivityType, Base, BaseType, ObjectType};
-use crate::{routes::activitypub::{activity::ap_activity, jsonld::LD, JsonLD, Pagination}, server::{Context, auth::{AuthIdentity, Identity}}, errors::UpubError, model, url};
+use apb::{server::Inbox, ActivityMut, ActivityType, Base, BaseType, ObjectType};
+use crate::{errors::UpubError, model, routes::activitypub::{activity::ap_activity, jsonld::LD, object::ap_object, JsonLD, Pagination}, server::{auth::{AuthIdentity, Identity}, Context}, tools::ActivityWithObject, url};
pub async fn get(
State(ctx): State<Context>,
@@ -33,12 +33,20 @@ pub async fn page(
Identity::Local(user) => if uid == user {
let limit = page.batch.unwrap_or(20).min(50);
let offset = page.offset.unwrap_or(0);
- match model::addressing::Entity::find()
+ let select = model::addressing::Entity::find()
.filter(Condition::all().add(model::addressing::Column::Actor.eq(uid)))
.order_by(model::addressing::Column::Published, Order::Asc)
- .find_also_related(model::activity::Entity)
+ .select_only();
+
+ match crate::tools::Prefixer::new(select)
+ .add_columns(model::activity::Entity)
+ .add_columns(model::object::Entity)
+ .selector
+ .join(JoinType::LeftJoin, model::activity::Relation::Addressing.def().rev())
+ .join(JoinType::LeftJoin, model::object::Relation::Activity.def().rev())
.limit(limit)
.offset(offset)
+ .into_model::<crate::tools::ActivityWithObject>()
.all(ctx.db())
.await
{
@@ -49,7 +57,10 @@ pub async fn page(
offset, limit,
activities
.into_iter()
- .filter_map(|(_, a)| Some(ap_activity(a?)))
+ .map(|ActivityWithObject { activity, object }| {
+ ap_activity(activity)
+ .set_object(apb::Node::maybe_object(object.map(ap_object)))
+ })
.collect::<Vec<serde_json::Value>>()
).ld_context()
))
diff --git a/src/tools.rs b/src/tools.rs
new file mode 100644
index 0000000..e6cee04
--- /dev/null
+++ b/src/tools.rs
@@ -0,0 +1,41 @@
+// yanked from https://github.com/SeaQL/sea-orm/discussions/1502
+use sea_orm::{prelude::*, FromQueryResult};
+use sea_orm::sea_query::{Alias, IntoIden, SelectExpr, SelectStatement};
+use sea_orm::{EntityTrait, QueryTrait};
+
+pub struct Prefixer<S: QueryTrait<QueryStatement = SelectStatement>> {
+ pub selector: S,
+}
+
+impl<S: QueryTrait<QueryStatement = SelectStatement>> Prefixer<S> {
+ pub fn new(selector: S) -> Self {
+ Self { selector }
+ }
+ pub fn add_columns<T: EntityTrait>(mut self, entity: T) -> Self {
+ for col in <T::Column as sea_orm::entity::Iterable>::iter() {
+ let alias = format!("{}{}", entity.table_name(), col.to_string()); // we use entity.table_name() as prefix
+ self.selector.query().expr(SelectExpr {
+ expr: col.select_as(col.into_expr()),
+ alias: Some(Alias::new(&alias).into_iden()),
+ window: None,
+ });
+ }
+ self
+ }
+}
+
+// adapted from https://github.com/SeaQL/sea-orm/discussions/1502
+#[derive(Debug)]
+pub struct ActivityWithObject {
+ pub activity: crate::model::activity::Model,
+ pub object: Option<crate::model::object::Model>,
+}
+
+impl FromQueryResult for ActivityWithObject {
+ fn from_query_result(res: &sea_orm::QueryResult, _pre: &str) -> Result<Self, sea_orm::DbErr> {
+ let activity = crate::model::activity::Model::from_query_result(res, crate::model::activity::Entity.table_name())?;
+ let object = crate::model::object::Model::from_query_result(res, crate::model::object::Entity.table_name()).ok();
+
+ Ok(Self { activity, object })
+ }
+}