diff --git a/morutine-infra/Cargo.toml b/morutine-infra/Cargo.toml index 878eb86..75ccc38 100644 --- a/morutine-infra/Cargo.toml +++ b/morutine-infra/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] sea-orm = { version = "1.1.19", features = ["runtime-tokio-rustls", "macros", "sqlx-postgres", "chrono"] } +sea-orm-migration = { version = "1.1.19", features = ["runtime-tokio-rustls", "sqlx-postgres"] } async-trait = "0.1" serde = { version = "1.0", features = ["derive"] } tracing = "0.1" diff --git a/morutine-infra/src/database/postgres/migration/init_tables.rs b/morutine-infra/src/database/postgres/migration/init_tables.rs new file mode 100644 index 0000000..912889c --- /dev/null +++ b/morutine-infra/src/database/postgres/migration/init_tables.rs @@ -0,0 +1,228 @@ +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> { + // 1. users 테이블 + manager + .create_table( + Table::create() + .table(Users::Table) + .if_not_exists() + .col( + ColumnDef::new(Users::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Users::Nickname).string().not_null()) + .col(ColumnDef::new(Users::ProfileImageUrl).string().null()) + .col( + ColumnDef::new(Users::CreatedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .col( + ColumnDef::new(Users::ModifiedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .to_owned(), + ) + .await?; + + // 2. social_accounts 테이블 + manager + .create_table( + Table::create() + .table(SocialAccounts::Table) + .if_not_exists() + .col( + ColumnDef::new(SocialAccounts::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(SocialAccounts::UserId) + .big_integer() + .not_null(), + ) + .col(ColumnDef::new(SocialAccounts::Provider).string().not_null()) + .col( + ColumnDef::new(SocialAccounts::ProviderUserId) + .string() + .not_null(), + ) + .col( + ColumnDef::new(SocialAccounts::CreatedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .col( + ColumnDef::new(SocialAccounts::ModifiedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .foreign_key( + ForeignKey::create() + .name("fk-social_accounts-user_id") + .from(SocialAccounts::Table, SocialAccounts::UserId) + .to(Users::Table, Users::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + + // 3. todos 테이블 + manager + .create_table( + Table::create() + .table(Todos::Table) + .if_not_exists() + .col( + ColumnDef::new(Todos::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Todos::UserId).big_integer().not_null()) + .col(ColumnDef::new(Todos::Date).date().not_null()) + .col( + ColumnDef::new(Todos::CreatedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .col( + ColumnDef::new(Todos::ModifiedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .foreign_key( + ForeignKey::create() + .name("fk-todos-user_id") + .from(Todos::Table, Todos::UserId) + .to(Users::Table, Users::Id), + ) + .to_owned(), + ) + .await?; + + // 4. todo_items 테이블 + manager + .create_table( + Table::create() + .table(TodoItems::Table) + .if_not_exists() + .col( + ColumnDef::new(TodoItems::Id) + .big_integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(TodoItems::TodoId).big_integer().not_null()) + .col(ColumnDef::new(TodoItems::Content).string().not_null()) + .col(ColumnDef::new(TodoItems::Status).string().not_null()) + .col(ColumnDef::new(TodoItems::AlteredContent).string().null()) + .col(ColumnDef::new(TodoItems::ImageUrl).string().null()) + .col( + ColumnDef::new(TodoItems::CreatedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .col( + ColumnDef::new(TodoItems::ModifiedAt) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .foreign_key( + ForeignKey::create() + .name("fk-todo_items-todo_id") + .from(TodoItems::Table, TodoItems::TodoId) + .to(Todos::Table, Todos::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(TodoItems::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(Todos::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(SocialAccounts::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(Users::Table).to_owned()) + .await?; + + Ok(()) + } +} + +#[derive(Iden)] +enum Users { + Table, + Id, + Nickname, + ProfileImageUrl, + CreatedAt, + ModifiedAt, +} + +#[derive(Iden)] +enum SocialAccounts { + Table, + Id, + UserId, + Provider, + ProviderUserId, + CreatedAt, + ModifiedAt, +} + +#[derive(Iden)] +enum Todos { + Table, + Id, + UserId, + Date, + CreatedAt, + ModifiedAt, +} + +#[derive(Iden)] +enum TodoItems { + Table, + Id, + TodoId, + Content, + Status, + AlteredContent, + ImageUrl, + CreatedAt, + ModifiedAt, +} diff --git a/morutine-infra/src/database/postgres/migration/mod.rs b/morutine-infra/src/database/postgres/migration/mod.rs new file mode 100644 index 0000000..14b885a --- /dev/null +++ b/morutine-infra/src/database/postgres/migration/mod.rs @@ -0,0 +1,12 @@ +pub use sea_orm_migration::prelude::*; + +mod init_tables; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![Box::new(init_tables::Migration)] + } +} diff --git a/morutine-infra/src/database/postgres/mod.rs b/morutine-infra/src/database/postgres/mod.rs index 7b697c5..44604e2 100644 --- a/morutine-infra/src/database/postgres/mod.rs +++ b/morutine-infra/src/database/postgres/mod.rs @@ -1,2 +1,3 @@ +pub mod migration; pub mod todo; -mod user; +pub mod user;