From dc33fa8416ce6b447494c6efdf46518da37ac1cc Mon Sep 17 00:00:00 2001 From: Tolmachev Igor Date: Tue, 26 Aug 2025 21:13:53 +0900 Subject: Add database migration and entities --- migration/Cargo.toml | 13 +++ migration/src/lib.rs | 17 ++++ migration/src/m0_init_tables.rs | 192 ++++++++++++++++++++++++++++++++++++++++ migration/src/main.rs | 6 ++ 4 files changed, 228 insertions(+) create mode 100644 migration/Cargo.toml create mode 100644 migration/src/lib.rs create mode 100644 migration/src/m0_init_tables.rs create mode 100644 migration/src/main.rs (limited to 'migration') diff --git a/migration/Cargo.toml b/migration/Cargo.toml new file mode 100644 index 0000000..bb33242 --- /dev/null +++ b/migration/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "migration" +version = "0.1.0" +edition = "2024" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +sea-orm-migration = { version = "1.1.14", features = ["sqlx-postgres", "runtime-tokio-rustls"] } +tokio = { version = "1.47.1", features = ["macros", "rt"] } diff --git a/migration/src/lib.rs b/migration/src/lib.rs new file mode 100644 index 0000000..ef740fc --- /dev/null +++ b/migration/src/lib.rs @@ -0,0 +1,17 @@ +#![deny(dead_code)] +mod m0_init_tables; + +use sea_orm_migration::prelude::*; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migration_table_name() -> DynIden { + Alias::new("migrations").into_iden() + } + + fn migrations() -> Vec> { + vec![Box::new(m0_init_tables::Migration)] + } +} diff --git a/migration/src/m0_init_tables.rs b/migration/src/m0_init_tables.rs new file mode 100644 index 0000000..576f45b --- /dev/null +++ b/migration/src/m0_init_tables.rs @@ -0,0 +1,192 @@ +use sea_orm_migration::prelude::extension::postgres::Type; +use sea_orm_migration::sea_orm::{EnumIter, Iterable}; +use sea_orm_migration::{prelude::*, schema::*}; + +#[derive(DeriveIden)] +enum Users { + Table, + Id, + Login, + Password, + PasswordIssueDate, + FirstName, + LastName, +} + +#[derive(DeriveIden)] +enum Queues { + Table, + Id, + OwnerId, + Name, +} + +#[derive(DeriveIden)] +enum AccessToQueue { + Table, + UserId, + QueueId, +} + +#[derive(DeriveIden)] +enum QueueElements { + Table, + Id, + QueueId, + UserId, + Position, + Status, +} + +mod queue_element_status { + use super::*; + + #[derive(DeriveIden)] + #[sea_orm(iden = "queue_element_status_enum")] + pub struct Iden; + + #[derive(Iden, EnumIter)] + pub enum Items { + Passed, + Waiting, + } +} + +#[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(Users::Table) + .if_not_exists() + .col(pk_auto(Users::Id).big_integer()) + .col(string(Users::Login).unique_key()) + .col(string(Users::Password)) + .col(timestamp(Users::PasswordIssueDate)) + .col(string(Users::FirstName)) + .col(string(Users::LastName)) + .to_owned(), + ) + .await?; + + manager + .create_table( + Table::create() + .table(Queues::Table) + .if_not_exists() + .col(pk_auto(Queues::Id).big_integer()) + .col(big_integer(Queues::OwnerId)) + .foreign_key( + ForeignKey::create() + .from(Queues::Table, Queues::OwnerId) + .to(Users::Table, Users::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .col(string(Queues::Name)) + .to_owned(), + ) + .await?; + + manager + .create_table( + Table::create() + .table(AccessToQueue::Table) + .if_not_exists() + .col(big_integer(AccessToQueue::UserId)) + .col(big_integer(AccessToQueue::QueueId)) + .foreign_key( + ForeignKey::create() + .from(AccessToQueue::Table, AccessToQueue::UserId) + .to(Users::Table, Users::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .foreign_key( + ForeignKey::create() + .from(AccessToQueue::Table, AccessToQueue::QueueId) + .to(Queues::Table, Queues::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .primary_key( + Index::create() + .col(AccessToQueue::UserId) + .col(AccessToQueue::QueueId), + ) + .to_owned(), + ) + .await?; + + manager + .create_type( + Type::create() + .as_enum(queue_element_status::Iden) + .values(queue_element_status::Items::iter()) + .to_owned(), + ) + .await?; + + manager + .create_table( + Table::create() + .table(QueueElements::Table) + .if_not_exists() + .col(pk_auto(QueueElements::Id).big_integer()) + .col(big_integer(QueueElements::QueueId)) + .col(big_integer(QueueElements::UserId)) + .col( + big_integer(QueueElements::Position) + .unique_key() + .auto_increment(), + ) + .col(enumeration( + QueueElements::Status, + queue_element_status::Iden, + queue_element_status::Items::iter(), + )) + .foreign_key( + ForeignKey::create() + .from(QueueElements::Table, QueueElements::UserId) + .to(Users::Table, Users::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .foreign_key( + ForeignKey::create() + .from(QueueElements::Table, QueueElements::QueueId) + .to(Queues::Table, Queues::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Users::Table).to_owned()) + .await?; + + manager + .drop_table(Table::drop().table(Queues::Table).to_owned()) + .await?; + + manager + .drop_table(Table::drop().table(AccessToQueue::Table).to_owned()) + .await?; + + manager + .drop_table(Table::drop().table(QueueElements::Table).to_owned()) + .await?; + + Ok(()) + } +} diff --git a/migration/src/main.rs b/migration/src/main.rs new file mode 100644 index 0000000..56190ac --- /dev/null +++ b/migration/src/main.rs @@ -0,0 +1,6 @@ +use sea_orm_migration::prelude::*; + +#[tokio::main(flavor = "current_thread")] +async fn main() { + cli::run_cli(migration::Migrator).await; +} -- cgit v1.2.3