forked from alemi/upub
feat: add instance id in relations
this is needed to provide instance-scoped relations
This commit is contained in:
parent
846d0f21d5
commit
129724d30e
5 changed files with 142 additions and 7 deletions
|
@ -9,6 +9,8 @@ pub struct Model {
|
||||||
pub following: i64,
|
pub following: i64,
|
||||||
pub accept: Option<i64>,
|
pub accept: Option<i64>,
|
||||||
pub activity: i64,
|
pub activity: i64,
|
||||||
|
pub follower_instance: i64,
|
||||||
|
pub following_instance: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
@ -45,6 +47,22 @@ pub enum Relation {
|
||||||
on_delete = "Cascade"
|
on_delete = "Cascade"
|
||||||
)]
|
)]
|
||||||
ActorsFollowing,
|
ActorsFollowing,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::instance::Entity",
|
||||||
|
from = "Column::FollowerInstance",
|
||||||
|
to = "super::instance::Column::Internal",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
InstancesFollower,
|
||||||
|
#[sea_orm(
|
||||||
|
belongs_to = "super::instance::Entity",
|
||||||
|
from = "Column::FollowingInstance",
|
||||||
|
to = "super::instance::Column::Internal",
|
||||||
|
on_update = "Cascade",
|
||||||
|
on_delete = "NoAction"
|
||||||
|
)]
|
||||||
|
InstancesFollowing,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Related<super::actor::Entity> for Entity {
|
impl Related<super::actor::Entity> for Entity {
|
||||||
|
@ -59,6 +77,12 @@ impl Related<super::activity::Entity> for Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Related<super::instance::Entity> for Entity {
|
||||||
|
fn to() -> RelationDef {
|
||||||
|
Relation::InstancesFollowing.def()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
impl Entity {
|
impl Entity {
|
||||||
|
|
|
@ -116,15 +116,16 @@ pub async fn like(ctx: &crate::Context, activity: impl apb::Activity, tx: &Datab
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
|
pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &DatabaseTransaction) -> Result<(), ProcessorError> {
|
||||||
let source_actor_internal = crate::model::actor::Entity::ap_to_internal(activity.actor().id()?, tx)
|
let source_actor = crate::model::actor::Entity::find_by_ap_id(activity.actor().id()?)
|
||||||
|
.one(tx)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(ProcessorError::Incomplete)?;
|
.ok_or(ProcessorError::Incomplete)?;
|
||||||
let usr = ctx.fetch_user(activity.object().id()?, tx).await?;
|
let target_actor = ctx.fetch_user(activity.object().id()?, tx).await?;
|
||||||
let activity_model = ctx.insert_activity(activity, tx).await?;
|
let activity_model = ctx.insert_activity(activity, tx).await?;
|
||||||
|
|
||||||
if let Some(relation) = crate::model::relation::Entity::find()
|
if let Some(relation) = crate::model::relation::Entity::find()
|
||||||
.filter(crate::model::relation::Column::Follower.eq(source_actor_internal))
|
.filter(crate::model::relation::Column::Follower.eq(source_actor.internal))
|
||||||
.filter(crate::model::relation::Column::Following.eq(usr.internal))
|
.filter(crate::model::relation::Column::Following.eq(target_actor.internal))
|
||||||
.select_only()
|
.select_only()
|
||||||
.select_column(crate::model::relation::Column::Internal)
|
.select_column(crate::model::relation::Column::Internal)
|
||||||
.into_tuple::<i64>()
|
.into_tuple::<i64>()
|
||||||
|
@ -140,19 +141,29 @@ pub async fn follow(ctx: &crate::Context, activity: impl apb::Activity, tx: &Dat
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
let follower_instance = crate::model::instance::Entity::domain_to_internal(&source_actor.domain, tx)
|
||||||
|
.await?
|
||||||
|
.ok_or(ProcessorError::Incomplete)?;
|
||||||
|
|
||||||
|
let following_instance = crate::model::instance::Entity::domain_to_internal(&target_actor.domain, tx)
|
||||||
|
.await?
|
||||||
|
.ok_or(ProcessorError::Incomplete)?;
|
||||||
|
|
||||||
// new follow request, make new row
|
// new follow request, make new row
|
||||||
let relation_model = crate::model::relation::ActiveModel {
|
let relation_model = crate::model::relation::ActiveModel {
|
||||||
internal: NotSet,
|
internal: NotSet,
|
||||||
accept: Set(None),
|
accept: Set(None),
|
||||||
activity: Set(activity_model.internal),
|
activity: Set(activity_model.internal),
|
||||||
follower: Set(source_actor_internal),
|
follower: Set(source_actor.internal),
|
||||||
following: Set(usr.internal),
|
follower_instance: Set(follower_instance),
|
||||||
|
following: Set(target_actor.internal),
|
||||||
|
following_instance: Set(following_instance),
|
||||||
};
|
};
|
||||||
crate::model::relation::Entity::insert(relation_model)
|
crate::model::relation::Entity::insert(relation_model)
|
||||||
.exec(tx).await?;
|
.exec(tx).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::info!("{} wants to follow {}", activity_model.actor, usr.id);
|
tracing::info!("{} wants to follow {}", activity_model.actor, target_actor.id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod m20240529_000001_add_relation_unique_index;
|
||||||
mod m20240605_000001_add_jobs_table;
|
mod m20240605_000001_add_jobs_table;
|
||||||
mod m20240606_000001_add_audience_to_objects;
|
mod m20240606_000001_add_audience_to_objects;
|
||||||
mod m20240607_000001_activity_ref_is_optional;
|
mod m20240607_000001_activity_ref_is_optional;
|
||||||
|
mod m20240609_000001_add_instance_field_to_relations;
|
||||||
|
|
||||||
pub struct Migrator;
|
pub struct Migrator;
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ impl MigratorTrait for Migrator {
|
||||||
Box::new(m20240605_000001_add_jobs_table::Migration),
|
Box::new(m20240605_000001_add_jobs_table::Migration),
|
||||||
Box::new(m20240606_000001_add_audience_to_objects::Migration),
|
Box::new(m20240606_000001_add_audience_to_objects::Migration),
|
||||||
Box::new(m20240607_000001_activity_ref_is_optional::Migration),
|
Box::new(m20240607_000001_activity_ref_is_optional::Migration),
|
||||||
|
Box::new(m20240609_000001_add_instance_field_to_relations::Migration),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ pub enum Relations {
|
||||||
Following,
|
Following,
|
||||||
Activity,
|
Activity,
|
||||||
Accept,
|
Accept,
|
||||||
|
FollowerInstance, // ADDED AFTERWARDS
|
||||||
|
FollowingInstance, // ADDED AFTERWARDS
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
use sea_orm_migration::prelude::*;
|
||||||
|
|
||||||
|
use crate::{m20240524_000001_create_actor_activity_object_tables::Instances, m20240524_000002_create_relations_likes_shares::Relations};
|
||||||
|
|
||||||
|
#[derive(DeriveMigrationName)]
|
||||||
|
pub struct Migration;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl MigrationTrait for Migration {
|
||||||
|
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
|
||||||
|
manager
|
||||||
|
.alter_table(
|
||||||
|
Table::alter()
|
||||||
|
.table(Relations::Table)
|
||||||
|
.add_column(ColumnDef::new(Relations::FollowerInstance).big_integer().not_null())
|
||||||
|
.add_foreign_key(
|
||||||
|
TableForeignKey::new()
|
||||||
|
.name("fkey-relations-follower-instance")
|
||||||
|
.from_tbl(Relations::Table)
|
||||||
|
.from_col(Relations::FollowerInstance)
|
||||||
|
.to_tbl(Instances::Table)
|
||||||
|
.to_col(Instances::Internal)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
|
)
|
||||||
|
.add_column(ColumnDef::new(Relations::FollowingInstance).big_integer().not_null())
|
||||||
|
.add_foreign_key(
|
||||||
|
TableForeignKey::new()
|
||||||
|
.name("fkey-relations-following-instance")
|
||||||
|
.from_tbl(Relations::Table)
|
||||||
|
.from_col(Relations::FollowingInstance)
|
||||||
|
.to_tbl(Instances::Table)
|
||||||
|
.to_col(Instances::Internal)
|
||||||
|
.on_update(ForeignKeyAction::Cascade)
|
||||||
|
)
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
manager
|
||||||
|
.create_index(
|
||||||
|
Index::create()
|
||||||
|
.name("index-relations-follower-instance")
|
||||||
|
.table(Relations::Table)
|
||||||
|
.col(Relations::FollowerInstance)
|
||||||
|
.to_owned()
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
manager
|
||||||
|
.create_index(
|
||||||
|
Index::create()
|
||||||
|
.name("index-relations-following-instance")
|
||||||
|
.table(Relations::Table)
|
||||||
|
.col(Relations::FollowingInstance)
|
||||||
|
.to_owned()
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
|
|
||||||
|
manager
|
||||||
|
.drop_index(
|
||||||
|
Index::drop()
|
||||||
|
.name("index-relations-follower-instance")
|
||||||
|
.table(Relations::Table)
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
manager
|
||||||
|
.drop_index(
|
||||||
|
Index::drop()
|
||||||
|
.name("index-relations-following-instance")
|
||||||
|
.table(Relations::Table)
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
manager
|
||||||
|
.alter_table(
|
||||||
|
Table::alter()
|
||||||
|
.table(Relations::Table)
|
||||||
|
.drop_foreign_key(Alias::new("fkey-relations-follower-instance"))
|
||||||
|
.drop_column(Relations::FollowerInstance)
|
||||||
|
.drop_foreign_key(Alias::new("fkey-relations-following-instance"))
|
||||||
|
.drop_column(Relations::FollowingInstance)
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue