diff --git a/migration/Cargo.toml b/migration/Cargo.toml index 1246214..cf70197 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "migration" version = "0.1.0" -edition = "2024" +edition = "2021" [dependencies] +sea-orm-migration = "1" +async-trait = "0.1" diff --git a/migration/src/lib.rs b/migration/src/lib.rs index b93cf3f..b7125ee 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -1,14 +1,20 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +pub use sea_orm_migration::prelude::*; -#[cfg(test)] -mod tests { - use super::*; +mod m20260403_000001_create_domains; +mod m20260403_000002_create_resources; +mod m20260403_000003_create_service_tokens; +mod m20260403_000004_create_links; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![ + Box::new(m20260403_000001_create_domains::Migration), + Box::new(m20260403_000002_create_resources::Migration), + Box::new(m20260403_000003_create_service_tokens::Migration), + Box::new(m20260403_000004_create_links::Migration), + ] } } diff --git a/migration/src/m20260403_000001_create_domains.rs b/migration/src/m20260403_000001_create_domains.rs new file mode 100644 index 0000000..99c2ab0 --- /dev/null +++ b/migration/src/m20260403_000001_create_domains.rs @@ -0,0 +1,47 @@ +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(Domains::Table) + .if_not_exists() + .col(ColumnDef::new(Domains::Id).string().not_null().primary_key()) + .col(ColumnDef::new(Domains::Domain).string().not_null().unique_key()) + .col(ColumnDef::new(Domains::OwnerTokenHash).string().not_null()) + .col(ColumnDef::new(Domains::RegistrationSecret).string().not_null()) + .col(ColumnDef::new(Domains::ChallengeType).string().not_null()) + .col(ColumnDef::new(Domains::ChallengeToken).string().null()) + .col(ColumnDef::new(Domains::Verified).boolean().not_null().default(false)) + .col(ColumnDef::new(Domains::CreatedAt).date_time().not_null()) + .col(ColumnDef::new(Domains::VerifiedAt).date_time().null()) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Domains::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Domains { + Table, + Id, + Domain, + OwnerTokenHash, + RegistrationSecret, + ChallengeType, + ChallengeToken, + Verified, + CreatedAt, + VerifiedAt, +} diff --git a/migration/src/m20260403_000002_create_resources.rs b/migration/src/m20260403_000002_create_resources.rs new file mode 100644 index 0000000..cca87d9 --- /dev/null +++ b/migration/src/m20260403_000002_create_resources.rs @@ -0,0 +1,52 @@ +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(Resources::Table) + .if_not_exists() + .col(ColumnDef::new(Resources::Id).string().not_null().primary_key()) + .col(ColumnDef::new(Resources::DomainId).string().not_null()) + .col(ColumnDef::new(Resources::ResourceUri).string().not_null().unique_key()) + .col(ColumnDef::new(Resources::Aliases).string().null()) + .col(ColumnDef::new(Resources::Properties).string().null()) + .col(ColumnDef::new(Resources::CreatedAt).date_time().not_null()) + .col(ColumnDef::new(Resources::UpdatedAt).date_time().not_null()) + .foreign_key( + ForeignKey::create() + .from(Resources::Table, Resources::DomainId) + .to( + super::m20260403_000001_create_domains::Domains::Table, + super::m20260403_000001_create_domains::Domains::Id, + ) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Resources::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Resources { + Table, + Id, + DomainId, + ResourceUri, + Aliases, + Properties, + CreatedAt, + UpdatedAt, +} diff --git a/migration/src/m20260403_000003_create_service_tokens.rs b/migration/src/m20260403_000003_create_service_tokens.rs new file mode 100644 index 0000000..f799e1c --- /dev/null +++ b/migration/src/m20260403_000003_create_service_tokens.rs @@ -0,0 +1,54 @@ +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(ServiceTokens::Table) + .if_not_exists() + .col(ColumnDef::new(ServiceTokens::Id).string().not_null().primary_key()) + .col(ColumnDef::new(ServiceTokens::DomainId).string().not_null()) + .col(ColumnDef::new(ServiceTokens::Name).string().not_null()) + .col(ColumnDef::new(ServiceTokens::TokenHash).string().not_null()) + .col(ColumnDef::new(ServiceTokens::AllowedRels).string().not_null()) + .col(ColumnDef::new(ServiceTokens::ResourcePattern).string().not_null()) + .col(ColumnDef::new(ServiceTokens::CreatedAt).date_time().not_null()) + .col(ColumnDef::new(ServiceTokens::RevokedAt).date_time().null()) + .foreign_key( + ForeignKey::create() + .from(ServiceTokens::Table, ServiceTokens::DomainId) + .to( + super::m20260403_000001_create_domains::Domains::Table, + super::m20260403_000001_create_domains::Domains::Id, + ) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(ServiceTokens::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum ServiceTokens { + Table, + Id, + DomainId, + Name, + TokenHash, + AllowedRels, + ResourcePattern, + CreatedAt, + RevokedAt, +} diff --git a/migration/src/m20260403_000004_create_links.rs b/migration/src/m20260403_000004_create_links.rs new file mode 100644 index 0000000..ef57b67 --- /dev/null +++ b/migration/src/m20260403_000004_create_links.rs @@ -0,0 +1,96 @@ +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(Links::Table) + .if_not_exists() + .col(ColumnDef::new(Links::Id).string().not_null().primary_key()) + .col(ColumnDef::new(Links::ResourceId).string().not_null()) + .col(ColumnDef::new(Links::ServiceTokenId).string().not_null()) + .col(ColumnDef::new(Links::DomainId).string().not_null()) + .col(ColumnDef::new(Links::Rel).string().not_null()) + .col(ColumnDef::new(Links::Href).string().null()) + .col(ColumnDef::new(Links::Type).string().null()) + .col(ColumnDef::new(Links::Titles).string().null()) + .col(ColumnDef::new(Links::Properties).string().null()) + .col(ColumnDef::new(Links::Template).string().null()) + .col(ColumnDef::new(Links::TtlSeconds).integer().null()) + .col(ColumnDef::new(Links::CreatedAt).date_time().not_null()) + .col(ColumnDef::new(Links::ExpiresAt).date_time().null()) + .foreign_key( + ForeignKey::create() + .from(Links::Table, Links::ResourceId) + .to( + super::m20260403_000002_create_resources::Resources::Table, + super::m20260403_000002_create_resources::Resources::Id, + ) + .on_delete(ForeignKeyAction::Cascade), + ) + .foreign_key( + ForeignKey::create() + .from(Links::Table, Links::ServiceTokenId) + .to( + super::m20260403_000003_create_service_tokens::ServiceTokens::Table, + super::m20260403_000003_create_service_tokens::ServiceTokens::Id, + ) + .on_delete(ForeignKeyAction::Cascade), + ) + .foreign_key( + ForeignKey::create() + .from(Links::Table, Links::DomainId) + .to( + super::m20260403_000001_create_domains::Domains::Table, + super::m20260403_000001_create_domains::Domains::Id, + ) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + + // Unique constraint for upsert behavior + manager + .create_index( + Index::create() + .name("idx_links_resource_rel_href") + .table(Links::Table) + .col(Links::ResourceId) + .col(Links::Rel) + .col(Links::Href) + .unique() + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Links::Table).to_owned()) + .await + } +} + +#[derive(DeriveIden)] +pub enum Links { + Table, + Id, + ResourceId, + ServiceTokenId, + DomainId, + Rel, + Href, + Type, + Titles, + Properties, + Template, + TtlSeconds, + CreatedAt, + ExpiresAt, +}