From 0d1250fd6f31dc0017a940f7d218ded72a9c6ba9 Mon Sep 17 00:00:00 2001 From: alemi Date: Sun, 24 Mar 2024 04:03:44 +0100 Subject: [PATCH] feat: add addressing table this should allow to build timelines and check access permissions quickly. my only concern is keeping thousands, if not even millions, of rows always with full strings. future optimizations may look into an intermediary table to map ids to integers and optimize this table's storage --- .../m20240324_000001_add_addressing.rs | 94 +++++++++++++++++++ src/model/activity.rs | 10 +- src/model/addressing.rs | 55 +++++++++++ src/model/object.rs | 10 +- src/model/user.rs | 9 ++ 5 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 src/migrations/m20240324_000001_add_addressing.rs create mode 100644 src/model/addressing.rs diff --git a/src/migrations/m20240324_000001_add_addressing.rs b/src/migrations/m20240324_000001_add_addressing.rs new file mode 100644 index 00000000..ea8773f9 --- /dev/null +++ b/src/migrations/m20240324_000001_add_addressing.rs @@ -0,0 +1,94 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Addressing::Table) + .col( + ColumnDef::new(Addressing::Id) + .integer() + .not_null() + .auto_increment() + .primary_key() + ) + .col(ColumnDef::new(Addressing::Actor).string().not_null()) + .col(ColumnDef::new(Addressing::Activity).string().not_null()) + .col(ColumnDef::new(Addressing::Object).string().null()) + .col(ColumnDef::new(Addressing::Published).date_time().not_null()) + .to_owned() + ) + .await?; + + // TODO these indexes may not be ordered, killing out timeline query performance + // it may be necessary to include datetime in the index itself? or maybe specify + // some ordering to use another type of indes? + + manager + .create_index( + Index::create() + .name("addressing-actor-index") + .table(Addressing::Table) + .col(Addressing::Actor) + .to_owned() + ) + .await?; + + manager + .create_index( + Index::create() + .name("addressing-activity-index") + .table(Addressing::Table) + .col(Addressing::Activity) + .to_owned() + ) + .await?; + + manager + .create_index( + Index::create() + .name("addressing-object-index") + .table(Addressing::Table) + .col(Addressing::Object) + .to_owned() + ) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Addressing::Table).to_owned()) + .await?; + + manager + .drop_index(Index::drop().name("addressing-actor-index").to_owned()) + .await?; + + manager + .drop_index(Index::drop().name("addressing-activity-index").to_owned()) + .await?; + + manager + .drop_index(Index::drop().name("addressing-object-index").to_owned()) + .await?; + + Ok(()) + } +} + +#[derive(DeriveIden)] +enum Addressing { + Table, + Id, + Actor, + Activity, + Object, + Published, +} diff --git a/src/model/activity.rs b/src/model/activity.rs index 3a5477cb..7a4a2caa 100644 --- a/src/model/activity.rs +++ b/src/model/activity.rs @@ -8,7 +8,6 @@ use super::Audience; #[sea_orm(table_name = "activities")] pub struct Model { #[sea_orm(primary_key)] - /// must be https://instance.org/users/:user , even if local! TODO bad design... pub id: String, pub activity_type: ActivityType, @@ -57,6 +56,9 @@ pub enum Relation { to = "super::object::Column::Id" )] Object, + + #[sea_orm(has_many = "super::addressing::Entity")] + Addressing, } impl Related for Entity { @@ -71,4 +73,10 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Addressing.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/src/model/addressing.rs b/src/model/addressing.rs new file mode 100644 index 00000000..4eae990c --- /dev/null +++ b/src/model/addressing.rs @@ -0,0 +1,55 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "addressing")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: String, + pub actor: String, + pub activity: String, + pub object: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::Actor", + to = "super::user::Column::Id" + )] + User, + + #[sea_orm( + belongs_to = "super::activity::Entity", + from = "Column::Activity", + to = "super::activity::Column::Id" + )] + Activity, + + #[sea_orm( + belongs_to = "super::object::Entity", + from = "Column::Object", + to = "super::object::Column::Id" + )] + Object, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Activity.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Object.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/src/model/object.rs b/src/model/object.rs index 6c84e128..4b143005 100644 --- a/src/model/object.rs +++ b/src/model/object.rs @@ -8,7 +8,6 @@ use super::Audience; #[sea_orm(table_name = "objects")] pub struct Model { #[sea_orm(primary_key)] - /// must be full uri!!! maybe not great? pub id: String, pub object_type: ObjectType, pub attributed_to: Option, @@ -59,6 +58,9 @@ pub enum Relation { to = "super::user::Column::Id", )] User, + + #[sea_orm(has_many = "super::addressing::Entity")] + Addressing, } impl Related for Entity { @@ -73,4 +75,10 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Addressing.def() + } +} + impl ActiveModelBehavior for ActiveModel {} diff --git a/src/model/user.rs b/src/model/user.rs index e61eab50..869762f2 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -79,6 +79,9 @@ pub enum Relation { #[sea_orm(has_many = "super::session::Entity")] Session, + + #[sea_orm(has_many = "super::addressing::Entity")] + Addressing, } impl Related for Entity { @@ -111,4 +114,10 @@ impl Related for Entity { } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Addressing.def() + } +} + impl ActiveModelBehavior for ActiveModel {}