use sea_orm_migration::prelude::*;
pub struct Migration;
impl sea_orm_migration::MigrationName for Migration {
fn name(&self) -> &str {
"m20260514_000001_create_projection_snapshots_table"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(ProjectionSnapshots::Table)
.if_not_exists()
.col(
ColumnDef::new(ProjectionSnapshots::ProjectionName)
.string()
.not_null(),
)
.col(ColumnDef::new(ProjectionSnapshots::Key).string().not_null())
.col(ColumnDef::new(ProjectionSnapshots::State).json().not_null())
.col(
ColumnDef::new(ProjectionSnapshots::Version)
.big_integer()
.not_null(),
)
.col(
ColumnDef::new(ProjectionSnapshots::UpdatedAt)
.timestamp()
.not_null()
.default(Expr::current_timestamp()),
)
.primary_key(
Index::create()
.col(ProjectionSnapshots::ProjectionName)
.col(ProjectionSnapshots::Key),
)
.to_owned(),
)
.await
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(ProjectionSnapshots::Table).to_owned())
.await
}
}
#[derive(DeriveIden)]
enum ProjectionSnapshots {
Table,
ProjectionName,
Key,
State,
Version,
UpdatedAt,
}
#[cfg(test)]
mod tests {
use sea_orm::{ConnectionTrait, Database, Statement};
use sea_orm_migration::MigratorTrait;
struct TestMigrator;
#[async_trait::async_trait]
impl MigratorTrait for TestMigrator {
fn migrations() -> Vec<Box<dyn sea_orm_migration::MigrationTrait>> {
vec![Box::new(super::Migration)]
}
}
#[tokio::test]
async fn migration_creates_projection_snapshots_table() {
let conn = Database::connect("sqlite::memory:").await.expect("connect");
TestMigrator::up(&conn, None).await.expect("migrate up");
let row = conn
.query_one(Statement::from_string(
sea_orm::DatabaseBackend::Sqlite,
"SELECT name FROM sqlite_master WHERE type='table' AND name='projection_snapshots'"
.to_string(),
))
.await
.expect("query sqlite_master");
assert!(row.is_some(), "projection_snapshots table not created");
}
}