From 4e3572ac0e909b69ba679a77bafa1ec1edd39624 Mon Sep 17 00:00:00 2001 From: fluo10 Date: Sat, 10 May 2025 09:11:46 +0900 Subject: [PATCH] Implement migration --- progress-pile-migration-client/Cargo.toml | 9 +- progress-pile-migration-client/src/lib.rs | 13 + .../src/m20220101_000001_create_table.rs | 8 +- .../src/m20220101_000001_create_table.rs | 412 +++++++++++++++--- progress-pile-migration-server/src/lib.rs | 13 + .../src/m20220101_000001_create_table.rs | 16 +- 6 files changed, 379 insertions(+), 92 deletions(-) diff --git a/progress-pile-migration-client/Cargo.toml b/progress-pile-migration-client/Cargo.toml index 558495a..657cbd7 100644 --- a/progress-pile-migration-client/Cargo.toml +++ b/progress-pile-migration-client/Cargo.toml @@ -11,9 +11,6 @@ progress-pile-migration-core = {workspace = true, features = ["client"]} [dependencies.sea-orm-migration] version = "1.1.0" features = [ - # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. - # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. - # e.g. - # "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature - # "sqlx-postgres", # `DATABASE_DRIVER` feature -] + "runtime-tokio-rustls", + "sqlx-sqlite", +] \ No newline at end of file diff --git a/progress-pile-migration-client/src/lib.rs b/progress-pile-migration-client/src/lib.rs index 2c605af..661d874 100644 --- a/progress-pile-migration-client/src/lib.rs +++ b/progress-pile-migration-client/src/lib.rs @@ -10,3 +10,16 @@ impl MigratorTrait for Migrator { vec![Box::new(m20220101_000001_create_table::Migration)] } } + +#[cfg(test)] +mod tests { + use sea_orm_migration::sea_orm::{ConnectOptions, Database}; + + use super::*; + #[async_std::test] + async fn test_migration_server() { + let db = Database::connect(ConnectOptions::new("sqlite::memory:")).await.unwrap(); + Migrator::up(&db, None).await.unwrap(); + Migrator::down(&db, None).await.unwrap(); + } +} diff --git a/progress-pile-migration-client/src/m20220101_000001_create_table.rs b/progress-pile-migration-client/src/m20220101_000001_create_table.rs index a6d96bb..8fffce7 100644 --- a/progress-pile-migration-client/src/m20220101_000001_create_table.rs +++ b/progress-pile-migration-client/src/m20220101_000001_create_table.rs @@ -8,15 +8,15 @@ use progress_pile_migration_core::m20220101_000001_create_table::*; impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager.create_table(ProgressCategory::client_table_create_statement()).await?; - manager.create_table(ProgressEntry::client_table_create_statement()).await?; + ProgressCategory::up_client(manager).await?; + ProgressEntry::up_client(manager).await?; Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager.drop_table(ProgressCategory::table_drop_statement()).await?; - manager.drop_table(ProgressEntry::table_drop_statement()).await?; + ProgressEntry::down_client(manager).await?; + ProgressCategory::down_client(manager).await?; Ok(()) } } diff --git a/progress-pile-migration-core/src/m20220101_000001_create_table.rs b/progress-pile-migration-core/src/m20220101_000001_create_table.rs index 369e458..a1233e0 100644 --- a/progress-pile-migration-core/src/m20220101_000001_create_table.rs +++ b/progress-pile-migration-core/src/m20220101_000001_create_table.rs @@ -1,5 +1,71 @@ use sea_orm_migration::{prelude::*, schema::*}; +pub trait TableMigrator { + + #[cfg(feature="server")] + async fn up_server<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> { + manager.create_table(Self::table_create_statement_server()).await?; + for statement in Self::index_create_statements_server().into_iter() { + manager.create_index(statement).await? + } + Ok(()) + } + + #[cfg(feature="server")] + async fn down_server<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> { + manager.drop_table(Self::table_drop_statement_server()).await?; + Ok(()) + } + #[cfg(feature="client")] + async fn up_client<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> { + manager.create_table(Self::table_create_statement_client()).await?; + for statement in Self::index_create_statements_client().into_iter() { + manager.create_index(statement).await? + } + Ok(()) + } + #[cfg(feature="client")] + async fn down_client<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> { + manager.drop_table(Self::table_drop_statement_client()).await?; + Ok(()) + } + + fn table_create_statement_default() -> TableCreateStatement; + + #[cfg(feature="client")] + fn table_create_statement_client() -> TableCreateStatement { + Self::table_create_statement_default() + } + + #[cfg(feature="server")] + fn table_create_statement_server() -> TableCreateStatement { + Self::table_create_statement_default() + } + + fn index_create_statements_default() -> Vec; + + #[cfg(feature="client")] + fn index_create_statements_client() -> Vec { + Self::index_create_statements_default() + } + + #[cfg(feature="server")] + fn index_create_statements_server() -> Vec{ + Self::index_create_statements_default() + } + + fn table_drop_statement_default() -> TableDropStatement; + + #[cfg(feature="client")] + fn table_drop_statement_client() -> TableDropStatement { + Self::table_drop_statement_default() + } + + #[cfg(feature="server")] + fn table_drop_statement_server() -> TableDropStatement { + Self::table_drop_statement_default() + } +} #[cfg(feature="server")] #[derive(DeriveIden)] @@ -12,9 +78,15 @@ pub enum User { LoginName, PasswordHash, } +static IDX_USER_LOGIN_NAME: &str = "idx_user_login_name"; +static IDX_USER_CREATED_AT: &str = "idx_user_created_at"; +static IDX_USER_UPDATED_AT: &str = "idx_user_updated_at"; +static IDX_USER_DELETED_AT: &str = "idx_user_deleted_at"; + #[cfg(feature="server")] -impl User { - pub fn server_table_create_statement() -> TableCreateStatement{ +impl TableMigrator for User { + + fn table_create_statement_default() -> TableCreateStatement{ Table::create() .table(Self::Table) .if_not_exists() @@ -24,10 +96,32 @@ impl User { .col(timestamp_with_time_zone_null(Self::DeletedAt)) .col(string_uniq(Self::LoginName)) .col(string(Self::PasswordHash)) + .to_owned() } - pub fn table_drop_statement() -> TableDropStatement { + fn index_create_statements_default() -> Vec { + vec![ + Index::create().name(IDX_USER_LOGIN_NAME) + .table(Self::Table) + .col(Self::LoginName) + .to_owned(), + Index::create().name(IDX_USER_CREATED_AT) + .table(Self::Table) + .col((Self::CreatedAt, IndexOrder::Desc)) + .to_owned(), + Index::create().name(IDX_USER_UPDATED_AT) + .table(Self::Table) + .col((Self::UpdatedAt, IndexOrder::Desc)) + .to_owned(), + Index::create().name(IDX_USER_DELETED_AT) + .table(Self::Table) + .col((Self::DeletedAt, IndexOrder::Desc)) + .to_owned(), + ] + } + + fn table_drop_statement_default() -> TableDropStatement { Table::drop().table(Self::Table).to_owned() } } @@ -41,26 +135,77 @@ pub enum AccessToken{ CreatedAt, UpdatedAt, ExpiredAt, - AccessToken, + TokenValue, Note, } -#[cfg(feature="server")] -impl AccessToken { - pub fn server_table_create_statement() -> TableCreateStatement { - Table::create() - .table(Self::Table) - .if_not_exists() - .col(pk_auto(Self::Id)) - .col(timestamp_with_time_zone(Self::CreatedAt)) - .col(timestamp_with_time_zone(Self::UpdatedAt)) - .col(timestamp_with_time_zone_null(Self::ExpiredAt)) - .col(string(Self::AccessToken)) - .col(string(Self::Note)) - .to_owned() - } +static IDX_ACCESS_TOKEN_TOKEN_VALUE: &str = "idx_access_token_token_value"; +static IDX_ACCESS_TOKEN_CREATED_AT: &str = "idx_access_token_created_at"; +static IDX_ACCESS_TOKEN_UPDATED_AT: &str = "idx_access_token_updated_at"; +static IDX_ACCESS_TOKEN_EXPIRED_AT: &str = "idx_access_token_expired_at"; +static IDX_ACCESS_TOKEN_USER_ID_CREATED_AT: &str = "idx_access_token_user_id_created_at"; +static IDX_ACCESS_TOKEN_USER_ID_UPDATED_AT: &str = "idx_access_token_user_id_updated_at"; +static IDX_ACCESS_TOKEN_USER_ID_EXPIRED_AT: &str = "idx_access_token_user_id_expired_at"; +static FK_ACCESS_TOKEN_USER: &str = "fk_access_token_user"; - pub fn table_drop_statement() -> TableDropStatement { +#[cfg(feature="server")] +impl TableMigrator for AccessToken { + + fn table_create_statement_default() -> TableCreateStatement { + Table::create() + .table(Self::Table) + .if_not_exists() + .col(pk_auto(Self::Id)) + .col(timestamp_with_time_zone(Self::CreatedAt)) + .col(timestamp_with_time_zone(Self::UpdatedAt)) + .col(timestamp_with_time_zone_null(Self::ExpiredAt)) + .col(string(Self::TokenValue)) + .col(string(Self::Note)) + .foreign_key(ForeignKey::create() + .name(FK_ACCESS_TOKEN_USER) + .from(Self::Table, Self::UserId) + .to(User::Table, User::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + ) + .to_owned() + } + fn index_create_statements_default() -> Vec { + vec![ + Index::create().name(IDX_ACCESS_TOKEN_CREATED_AT) + .table(Self::Table) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_EXPIRED_AT) + .table(Self::Table) + .col(Self::ExpiredAt) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_TOKEN_VALUE) + .table(Self::Table) + .col(Self::TokenValue) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_UPDATED_AT) + .table(Self::Table) + .col(Self::UpdatedAt) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_USER_ID_CREATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_USER_ID_EXPIRED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::ExpiredAt) + .to_owned(), + Index::create().name(IDX_ACCESS_TOKEN_USER_ID_UPDATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::UpdatedAt) + .to_owned(), + ] + } + fn table_drop_statement_default() -> TableDropStatement { Table::drop().table(Self::Table).to_owned() } } @@ -69,40 +214,103 @@ impl AccessToken { pub enum ProgressCategory { Table, #[cfg(feature="server")] - Id, - #[cfg(feature="server")] UserId, - Uuid, + Id, CreatedAt, UpdatedAt, DeletedAt, Name, } -impl ProgressCategory { - fn default_table_create_statement() -> TableCreateStatement { +static IDX_PROGRESS_CATEGORY_NAME: &str = "idx_progress_category_name"; +static IDX_PROGRESS_CATEGORY_CREATED_AT: &str = "idx_progress_category_created_at"; +static IDX_PROGRESS_CATEGORY_UPDATED_AT: &str = "idx_progress_category_updated_at"; +static IDX_PROGRESS_CATEGORY_DELETED_AT: &str = "idx_progress_category_deleted_at"; +static IDX_PROGRESS_CATEGORY_USER_ID_NAME: &str = "idx_progress_category_user_id_name"; +static IDX_PROGRESS_CATEGORY_USER_ID_CREATED_AT: &str = "idx_progress_category_user_id_created_at"; +static IDX_PROGRESS_CATEGORY_USER_ID_UPDATED_AT: &str = "idx_progress_category_user_id_updated_at"; +static IDX_PROGRESS_CATEGORY_USER_ID_DELETED_AT: &str = "idx_progress_category_user_id_deleted_at"; +static FK_PROGRESS_CATEGORY_USER: &str = "fk_progress_category_user"; +static PK_PROGRESS_CATEGORY: &str = "pk_progress_category"; + +impl TableMigrator for ProgressCategory { + + fn table_create_statement_default() -> TableCreateStatement { Table::create() - .table(Self::Table) - .if_not_exists() - .col(timestamp_with_time_zone(Self::CreatedAt)) - .col(timestamp_with_time_zone(Self::UpdatedAt)) - .col(timestamp_with_time_zone_null(Self::DeletedAt)) - .to_owned() + .table(Self::Table) + .if_not_exists() + .col(uuid(Self::Id)) + .col(string(Self::Name)) + .col(timestamp_with_time_zone(Self::CreatedAt)) + .col(timestamp_with_time_zone(Self::UpdatedAt)) + .col(timestamp_with_time_zone_null(Self::DeletedAt)) + .to_owned() } + #[cfg(feature="client")] - pub fn client_table_create_statement() -> TableCreateStatement{ - let mut tcs = Self::default_table_create_statement(); - tcs.col(pk_uuid(Self::Uuid)) - .col(string_uniq(Self::Name)); + fn table_create_statement_client() -> TableCreateStatement{ + let mut tcs = Self::table_create_statement_default(); + tcs.primary_key(Index::create().name(PK_PROGRESS_CATEGORY).col(Self::Id)); tcs } #[cfg(feature="server")] - pub fn server_table_create_statement() -> TableCreateStatement{ - todo!() + fn table_create_statement_server() -> TableCreateStatement{ + let mut tcs = Self::table_create_statement_default(); + tcs.col(integer(Self::UserId)); + tcs.foreign_key(ForeignKey::create().name(FK_PROGRESS_CATEGORY_USER).from(Self::Table, Self::UserId) + .to(User::Table, User::Id)); + tcs.primary_key(Index::create().name(PK_PROGRESS_CATEGORY).col(Self::UserId).col(Self::Id)); + tcs + } + + fn index_create_statements_default() -> Vec { + vec![ + Index::create().name(IDX_PROGRESS_CATEGORY_CREATED_AT) + .table(Self::Table) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_DELETED_AT) + .table(Self::Table) + .col(Self::DeletedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_NAME) + .table(Self::Table) + .col(Self::Name) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_UPDATED_AT) + .table(Self::Table) + .col(Self::UpdatedAt) + .to_owned(), + ] + } + #[cfg(feature="server")] + fn index_create_statements_server() -> Vec { + [Self::index_create_statements_default(), vec![ + Index::create().name(IDX_PROGRESS_CATEGORY_USER_ID_CREATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_USER_ID_DELETED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::DeletedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_USER_ID_NAME) + .table(Self::Table) + .col(Self::UserId) + .col(Self::Name) + .to_owned(), + Index::create().name(IDX_PROGRESS_CATEGORY_USER_ID_UPDATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::UpdatedAt) + .to_owned(), + ]].concat() } - pub fn table_drop_statement() -> TableDropStatement { + fn table_drop_statement_default() -> TableDropStatement { Table::drop().table(Self::Table).to_owned() } } @@ -111,56 +319,124 @@ impl ProgressCategory { pub enum ProgressEntry { Table, #[cfg(feature="server")] - Id, - #[cfg(feature="server")] UserId, - Uuid, - ProgressCategoryUuid, + Id, + ProgressCategoryId, CreatedAt, UpdatedAt, DeletedAt, - EnteredAt, + ProgressedAt, Quantity, Note, } -static PROGRESS_ENTRY_PROGRESS_CATEGORY_FOREIGN_KEY_NAME: &str = "fk__progress_entry__progress__category"; +static IDX_PROGRESS_ENTITY_CREATED_AT: &str = "idx_progress_entity_created_at"; +static IDX_PROGRESS_ENTITY_UPDATED_AT: &str = "idx_progress_entity_updated_at"; +static IDX_PROGRESS_ENTITY_DELETED_AT: &str = "idx_progress_entity_deleted_at"; +static IDX_PROGRESS_ENTITY_PROGRESSED_AT: &str = "idx_progress_entity_progressed_at"; +static IDX_PROGRESS_ENTITY_USER_ID_CREATED_AT: &str = "idx_progress_entity_user_id_created_at"; +static IDX_PROGRESS_ENTITY_USER_ID_UPDATED_AT: &str = "idx_progress_entity_user_id_updated_at"; +static IDX_PROGRESS_ENTITY_USER_ID_DELETED_AT: &str = "idx_progress_entity_user_id_deleted_at"; +static IDX_PROGRESS_ENTITY_USER_ID_PROGRESSED_AT: &str = "idx_progress_entity_user_id_progressed_at"; +static FK_PROGRESS_ENTITY_PROGRESS_CATEGORY: &str = "fk_progress_entity_progress_category"; +static FK_PROGRESS_ENTITY_USER: &str = "fk_progress_entity_user"; +static PK_PROGRESS_ENTITY: &str = "pk_progress_entity"; + +static PROGRESS_ENTRY_PROGRESS_ENTITY_FOREIGN_KEY_NAME: &str = "fk__progress_entry__progress__category"; -impl ProgressEntry { - fn default_table_create_statement() -> TableCreateStatement { +impl TableMigrator for ProgressEntry { + + fn table_create_statement_default() -> TableCreateStatement { Table::create() - .table(Self::Table) - .if_not_exists() - .col(uuid(Self::ProgressCategoryUuid)) - .col(timestamp_with_time_zone(Self::CreatedAt)) - .col(timestamp_with_time_zone(Self::UpdatedAt)) - .col(timestamp_with_time_zone_null(Self::DeletedAt)) - .col(timestamp_with_time_zone(Self::EnteredAt)) - .col(integer(Self::Quantity)) - .col(string(Self::Note)) - - .to_owned() - } - #[cfg(feature="client")] - pub fn client_table_create_statement() -> TableCreateStatement{ - let mut tcs = Self::default_table_create_statement(); - tcs.col(pk_uuid(Self::Uuid)) + .table(Self::Table) + .if_not_exists() + .col(uuid(Self::Id)) + .col(uuid(Self::ProgressCategoryId)) + .col(timestamp_with_time_zone(Self::CreatedAt)) + .col(timestamp_with_time_zone(Self::UpdatedAt)) + .col(timestamp_with_time_zone_null(Self::DeletedAt)) + .col(timestamp_with_time_zone(Self::ProgressedAt)) + .col(integer(Self::Quantity)) + .col(string(Self::Note)) .foreign_key(ForeignKey::create() - .name(PROGRESS_ENTRY_PROGRESS_CATEGORY_FOREIGN_KEY_NAME) - .from(Self::Table, Self::ProgressCategoryUuid) - .to(ProgressCategory::Table, ProgressCategory::Uuid) + .name(FK_PROGRESS_ENTITY_PROGRESS_CATEGORY) + .from(Self::Table, Self::ProgressCategoryId) + .to(ProgressCategory::Table, ProgressCategory::Id) .on_delete(ForeignKeyAction::Cascade) .on_update(ForeignKeyAction::Cascade) - ); + ) + .to_owned() + } + #[cfg(feature="client")] + fn table_create_statement_client() -> TableCreateStatement{ + let mut tcs: TableCreateStatement = Self::table_create_statement_default(); + tcs.primary_key(Index::create().name(PK_PROGRESS_ENTITY).col(Self::Id)); tcs } #[cfg(feature="server")] - pub fn server_table_create_statement() -> TableCreateStatement{ - todo!() + fn table_create_statement_server() -> TableCreateStatement{ + let mut tcs: TableCreateStatement = Self::table_create_statement_default(); + tcs.primary_key(Index::create().name(PK_PROGRESS_ENTITY).col(Self::UserId).col(Self::Id)); + tcs.foreign_key(ForeignKey::create() + .name(FK_PROGRESS_ENTITY_USER) + .from(Self::Table, Self::UserId) + .to(User::Table, User::Id) + ); + tcs + } - pub fn table_drop_statement() -> TableDropStatement { + + fn index_create_statements_default() -> Vec { + vec![ + Index::create().name(IDX_PROGRESS_ENTITY_CREATED_AT) + .table(Self::Table) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_DELETED_AT) + .table(Self::Table) + .col(Self::DeletedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_PROGRESSED_AT) + .table(Self::Table) + .col(Self::ProgressedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_UPDATED_AT) + .table(Self::Table) + .col(Self::UpdatedAt) + .to_owned(), + ] + } + + #[cfg(feature="server")] + fn index_create_statements_server() -> Vec { + let mut default = Self::index_create_statements_default(); + default.append(&mut vec![ + Index::create().name(IDX_PROGRESS_ENTITY_USER_ID_CREATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::CreatedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_USER_ID_DELETED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::DeletedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_USER_ID_PROGRESSED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::ProgressedAt) + .to_owned(), + Index::create().name(IDX_PROGRESS_ENTITY_USER_ID_UPDATED_AT) + .table(Self::Table) + .col(Self::UserId) + .col(Self::UpdatedAt) + .to_owned(), + ]); + default + } + fn table_drop_statement_default() -> TableDropStatement { Table::drop().table(Self::Table).to_owned() } } diff --git a/progress-pile-migration-server/src/lib.rs b/progress-pile-migration-server/src/lib.rs index 23af25d..8545e1b 100644 --- a/progress-pile-migration-server/src/lib.rs +++ b/progress-pile-migration-server/src/lib.rs @@ -13,3 +13,16 @@ impl MigratorTrait for Migrator { } } + +#[cfg(test)] +mod tests { + use sea_orm_migration::sea_orm::{ConnectOptions, Database}; + + use super::*; + #[async_std::test] + async fn test_migration_server() { + let db = Database::connect(ConnectOptions::new("sqlite::memory:")).await.unwrap(); + Migrator::up(&db, None).await.unwrap(); + Migrator::down(&db, None).await.unwrap(); + } +} \ No newline at end of file diff --git a/progress-pile-migration-server/src/m20220101_000001_create_table.rs b/progress-pile-migration-server/src/m20220101_000001_create_table.rs index 9bb8e56..76a9070 100644 --- a/progress-pile-migration-server/src/m20220101_000001_create_table.rs +++ b/progress-pile-migration-server/src/m20220101_000001_create_table.rs @@ -7,22 +7,10 @@ use progress_pile_migration_core::m20220101_000001_create_table::*; #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - - manager.create_table(User::server_table_create_statement()).await?; - - manager.create_table(AccessToken::server_table_create_statement()).await?; - - Ok(()) - + User::up_server(manager).await } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - - manager.drop_table(User::table_drop_statement()).await?; - manager.drop_table(AccessToken::table_drop_statement()).await?; - manager.drop_table(ProgressCategory::table_drop_statement()).await?; - manager.drop_table(ProgressEntry::table_drop_statement()).await?; - - Ok(()) + User::down_server(manager).await } }