forked from alemi/upub
feat: multi-join maybe? fix inbox not embedding obj
got this from https://github.com/SeaQL/sea-orm/discussions/1502, not sure it's what i need but i'm trying some stuff
This commit is contained in:
parent
d5c5d341e8
commit
9e67eead69
3 changed files with 59 additions and 6 deletions
|
@ -2,6 +2,7 @@ pub mod server;
|
|||
pub mod model;
|
||||
pub mod routes;
|
||||
|
||||
pub mod tools;
|
||||
pub mod errors;
|
||||
|
||||
#[cfg(feature = "migrations")]
|
||||
|
|
|
@ -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()
|
||||
))
|
||||
|
|
41
src/tools.rs
Normal file
41
src/tools.rs
Normal file
|
@ -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 })
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue