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
This commit is contained in:
əlemi 2024-03-24 04:03:44 +01:00
parent 7251a3e92c
commit 0d1250fd6f
Signed by: alemi
GPG key ID: A4895B84D311642C
5 changed files with 176 additions and 2 deletions

View file

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

View file

@ -8,7 +8,6 @@ use super::Audience;
#[sea_orm(table_name = "activities")] #[sea_orm(table_name = "activities")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
/// must be https://instance.org/users/:user , even if local! TODO bad design...
pub id: String, pub id: String,
pub activity_type: ActivityType, pub activity_type: ActivityType,
@ -57,6 +56,9 @@ pub enum Relation {
to = "super::object::Column::Id" to = "super::object::Column::Id"
)] )]
Object, Object,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
} }
impl Related<super::user::Entity> for Entity { impl Related<super::user::Entity> for Entity {
@ -71,4 +73,10 @@ impl Related<super::object::Entity> for Entity {
} }
} }
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}

55
src/model/addressing.rs Normal file
View file

@ -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<String>,
}
#[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<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::activity::Entity> for Entity {
fn to() -> RelationDef {
Relation::Activity.def()
}
}
impl Related<super::object::Entity> for Entity {
fn to() -> RelationDef {
Relation::Object.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -8,7 +8,6 @@ use super::Audience;
#[sea_orm(table_name = "objects")] #[sea_orm(table_name = "objects")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
/// must be full uri!!! maybe not great?
pub id: String, pub id: String,
pub object_type: ObjectType, pub object_type: ObjectType,
pub attributed_to: Option<String>, pub attributed_to: Option<String>,
@ -59,6 +58,9 @@ pub enum Relation {
to = "super::user::Column::Id", to = "super::user::Column::Id",
)] )]
User, User,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
} }
impl Related<super::activity::Entity> for Entity { impl Related<super::activity::Entity> for Entity {
@ -73,4 +75,10 @@ impl Related<super::user::Entity> for Entity {
} }
} }
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}

View file

@ -79,6 +79,9 @@ pub enum Relation {
#[sea_orm(has_many = "super::session::Entity")] #[sea_orm(has_many = "super::session::Entity")]
Session, Session,
#[sea_orm(has_many = "super::addressing::Entity")]
Addressing,
} }
impl Related<super::activity::Entity> for Entity { impl Related<super::activity::Entity> for Entity {
@ -111,4 +114,10 @@ impl Related<super::session::Entity> for Entity {
} }
} }
impl Related<super::addressing::Entity> for Entity {
fn to() -> RelationDef {
Relation::Addressing.def()
}
}
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}