feat: Implement database migration framework with initial migrations for organizations, workspaces, agents, virtual hosts, upstreams, certificates, and users
This commit is contained in:
19
migration/Cargo.toml
Normal file
19
migration/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||
|
||||
[dependencies.sea-orm-migration]
|
||||
version = "2.0.0-rc"
|
||||
features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlx-postgres",
|
||||
]
|
||||
41
migration/README.md
Normal file
41
migration/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Running Migrator CLI
|
||||
|
||||
- Generate a new migration file
|
||||
```sh
|
||||
cargo run -- generate MIGRATION_NAME
|
||||
```
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
||||
26
migration/src/lib.rs
Normal file
26
migration/src/lib.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20240301_000001_create_organizations;
|
||||
mod m20240301_000002_create_workspaces;
|
||||
mod m20240301_000003_create_agents;
|
||||
mod m20240301_000004_create_virtual_hosts;
|
||||
mod m20240301_000005_create_upstreams;
|
||||
mod m20240301_000006_create_certificates;
|
||||
mod m20240301_000007_create_users;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![
|
||||
Box::new(m20240301_000001_create_organizations::Migration),
|
||||
Box::new(m20240301_000002_create_workspaces::Migration),
|
||||
Box::new(m20240301_000003_create_agents::Migration),
|
||||
Box::new(m20240301_000004_create_virtual_hosts::Migration),
|
||||
Box::new(m20240301_000005_create_upstreams::Migration),
|
||||
Box::new(m20240301_000006_create_certificates::Migration),
|
||||
Box::new(m20240301_000007_create_users::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
59
migration/src/m20240301_000001_create_organizations.rs
Normal file
59
migration/src/m20240301_000001_create_organizations.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
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(Organizations::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Organizations::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Organizations::Name).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(Organizations::Slug)
|
||||
.string()
|
||||
.not_null()
|
||||
.unique_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Organizations::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Organizations::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Organizations::Settings).json())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Organizations::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Organizations {
|
||||
Table,
|
||||
Id,
|
||||
Name,
|
||||
Slug,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Settings,
|
||||
}
|
||||
88
migration/src/m20240301_000002_create_workspaces.rs
Normal file
88
migration/src/m20240301_000002_create_workspaces.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
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(Workspaces::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Workspaces::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Workspaces::OrganizationId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Workspaces::Name).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(Workspaces::Slug)
|
||||
.string()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Workspaces::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Workspaces::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_workspace_organization")
|
||||
.from(Workspaces::Table, Workspaces::OrganizationId)
|
||||
.to(Organizations::Table, Organizations::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Create unique index on organization_id + slug
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.unique()
|
||||
.name("idx_workspaces_org_slug")
|
||||
.table(Workspaces::Table)
|
||||
.col(Workspaces::OrganizationId)
|
||||
.col(Workspaces::Slug)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Workspaces::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Workspaces {
|
||||
Table,
|
||||
Id,
|
||||
OrganizationId,
|
||||
Name,
|
||||
Slug,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Organizations {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
90
migration/src/m20240301_000003_create_agents.rs
Normal file
90
migration/src/m20240301_000003_create_agents.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
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(Agents::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Agents::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Agents::WorkspaceId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Agents::Name).string().not_null())
|
||||
.col(ColumnDef::new(Agents::Hostname).string().not_null())
|
||||
.col(ColumnDef::new(Agents::IpAddress).string())
|
||||
.col(ColumnDef::new(Agents::Version).string())
|
||||
.col(ColumnDef::new(Agents::State).string().not_null())
|
||||
.col(ColumnDef::new(Agents::DeploymentMode).string())
|
||||
.col(
|
||||
ColumnDef::new(Agents::LastSeenAt)
|
||||
.timestamp_with_time_zone(),
|
||||
)
|
||||
.col(ColumnDef::new(Agents::Capabilities).json())
|
||||
.col(ColumnDef::new(Agents::Labels).json())
|
||||
.col(ColumnDef::new(Agents::TokenHash).string())
|
||||
.col(
|
||||
ColumnDef::new(Agents::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Agents::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_agent_workspace")
|
||||
.from(Agents::Table, Agents::WorkspaceId)
|
||||
.to(Workspaces::Table, Workspaces::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Agents::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Agents {
|
||||
Table,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
Name,
|
||||
Hostname,
|
||||
IpAddress,
|
||||
Version,
|
||||
State,
|
||||
DeploymentMode,
|
||||
LastSeenAt,
|
||||
Capabilities,
|
||||
Labels,
|
||||
TokenHash,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Workspaces {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
115
migration/src/m20240301_000004_create_virtual_hosts.rs
Normal file
115
migration/src/m20240301_000004_create_virtual_hosts.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
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(VirtualHosts::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::WorkspaceId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(VirtualHosts::Name).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::ServerName)
|
||||
.string()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::ListenPort)
|
||||
.integer()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::SslEnabled)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
.col(ColumnDef::new(VirtualHosts::SslCertificateId).uuid())
|
||||
.col(ColumnDef::new(VirtualHosts::Locations).json())
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::Http2Enabled)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::Http3Enabled)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::GzipEnabled)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(true),
|
||||
)
|
||||
.col(ColumnDef::new(VirtualHosts::TargetAgents).json())
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(VirtualHosts::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_vh_workspace")
|
||||
.from(VirtualHosts::Table, VirtualHosts::WorkspaceId)
|
||||
.to(Workspaces::Table, Workspaces::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(VirtualHosts::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum VirtualHosts {
|
||||
Table,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
Name,
|
||||
ServerName,
|
||||
ListenPort,
|
||||
SslEnabled,
|
||||
SslCertificateId,
|
||||
Locations,
|
||||
Http2Enabled,
|
||||
Http3Enabled,
|
||||
GzipEnabled,
|
||||
TargetAgents,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Workspaces {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
83
migration/src/m20240301_000005_create_upstreams.rs
Normal file
83
migration/src/m20240301_000005_create_upstreams.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
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(Upstreams::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Upstreams::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Upstreams::WorkspaceId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Upstreams::Name).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(Upstreams::Algorithm)
|
||||
.string()
|
||||
.not_null(),
|
||||
)
|
||||
.col(ColumnDef::new(Upstreams::Servers).json())
|
||||
.col(ColumnDef::new(Upstreams::HealthCheck).json())
|
||||
.col(ColumnDef::new(Upstreams::KeepaliveConnections).integer())
|
||||
.col(ColumnDef::new(Upstreams::KeepaliveTimeout).integer())
|
||||
.col(
|
||||
ColumnDef::new(Upstreams::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Upstreams::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_upstream_workspace")
|
||||
.from(Upstreams::Table, Upstreams::WorkspaceId)
|
||||
.to(Workspaces::Table, Workspaces::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Upstreams::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Upstreams {
|
||||
Table,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
Name,
|
||||
Algorithm,
|
||||
Servers,
|
||||
HealthCheck,
|
||||
KeepaliveConnections,
|
||||
KeepaliveTimeout,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Workspaces {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
99
migration/src/m20240301_000006_create_certificates.rs
Normal file
99
migration/src/m20240301_000006_create_certificates.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
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(Certificates::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Certificates::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Certificates::WorkspaceId)
|
||||
.uuid()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Certificates::Domain)
|
||||
.string()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Certificates::IsWildcard)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
.col(ColumnDef::new(Certificates::Provider).string())
|
||||
.col(ColumnDef::new(Certificates::Status).string())
|
||||
.col(ColumnDef::new(Certificates::IssuedAt).timestamp_with_time_zone())
|
||||
.col(ColumnDef::new(Certificates::ExpiresAt).timestamp_with_time_zone())
|
||||
.col(
|
||||
ColumnDef::new(Certificates::AutoRenew)
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(true),
|
||||
)
|
||||
.col(ColumnDef::new(Certificates::CertificatePem).text())
|
||||
.col(ColumnDef::new(Certificates::PrivateKeyPem).text())
|
||||
.col(
|
||||
ColumnDef::new(Certificates::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Certificates::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_certificate_workspace")
|
||||
.from(Certificates::Table, Certificates::WorkspaceId)
|
||||
.to(Workspaces::Table, Workspaces::Id)
|
||||
.on_delete(ForeignKeyAction::Cascade),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Certificates::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Certificates {
|
||||
Table,
|
||||
Id,
|
||||
WorkspaceId,
|
||||
Domain,
|
||||
IsWildcard,
|
||||
Provider,
|
||||
Status,
|
||||
IssuedAt,
|
||||
ExpiresAt,
|
||||
AutoRenew,
|
||||
CertificatePem,
|
||||
PrivateKeyPem,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Workspaces {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
74
migration/src/m20240301_000007_create_users.rs
Normal file
74
migration/src/m20240301_000007_create_users.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
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(Users::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Users::Id)
|
||||
.uuid()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Users::Email).string().not_null().unique_key())
|
||||
.col(ColumnDef::new(Users::PasswordHash).string().not_null())
|
||||
.col(ColumnDef::new(Users::Name).string())
|
||||
.col(ColumnDef::new(Users::Role).string().not_null())
|
||||
.col(
|
||||
ColumnDef::new(Users::OrganizationId)
|
||||
.uuid(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Users::CreatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Users::UpdatedAt)
|
||||
.timestamp_with_time_zone()
|
||||
.not_null(),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_user_organization")
|
||||
.from(Users::Table, Users::OrganizationId)
|
||||
.to(Organizations::Table, Organizations::Id)
|
||||
.on_delete(ForeignKeyAction::SetNull),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Users::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Users {
|
||||
Table,
|
||||
Id,
|
||||
Email,
|
||||
PasswordHash,
|
||||
Name,
|
||||
Role,
|
||||
OrganizationId,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Organizations {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
6
migration/src/main.rs
Normal file
6
migration/src/main.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
cli::run_cli(migration::Migrator).await;
|
||||
}
|
||||
Reference in New Issue
Block a user