feat: add instance id in relations

this is needed to provide instance-scoped relations
This commit is contained in:
əlemi 2024-06-09 19:46:27 +02:00
parent 846d0f21d5
commit 129724d30e
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 142 additions and 7 deletions

View file

@ -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 {

View file

@ -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(())
} }

View file

@ -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),
] ]
} }
} }

View file

@ -10,6 +10,8 @@ pub enum Relations {
Following, Following,
Activity, Activity,
Accept, Accept,
FollowerInstance, // ADDED AFTERWARDS
FollowingInstance, // ADDED AFTERWARDS
} }
#[derive(DeriveIden)] #[derive(DeriveIden)]

View file

@ -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(())
}
}