use reifydb_core::{
interface::catalog::migration::{Migration, MigrationAction, MigrationEvent},
key::{migration::MigrationKey, migration_event::MigrationEventKey},
};
use reifydb_transaction::transaction::{Transaction, admin::AdminTransaction};
use reifydb_type::fragment::Fragment;
use crate::{
CatalogStore, Result,
error::{CatalogError, CatalogObjectKind},
store::{
migration::shape::{migration as migration_shape, migration_event as event_shape},
sequence::system::SystemSequence,
},
};
pub struct MigrationToCreate {
pub name: String,
pub body: String,
pub rollback_body: Option<String>,
}
impl CatalogStore {
pub(crate) fn create_migration(txn: &mut AdminTransaction, to_create: MigrationToCreate) -> Result<Migration> {
if let Some(_existing) =
CatalogStore::find_migration_by_name(&mut Transaction::Admin(&mut *txn), &to_create.name)?
{
return Err(CatalogError::AlreadyExists {
kind: CatalogObjectKind::Migration,
namespace: String::new(),
name: to_create.name,
fragment: Fragment::None,
}
.into());
}
let migration_id = SystemSequence::next_migration_id(txn)?;
let mut row = migration_shape::SHAPE.allocate();
migration_shape::SHAPE.set_u64(&mut row, migration_shape::ID, migration_id);
migration_shape::SHAPE.set_utf8(&mut row, migration_shape::NAME, &to_create.name);
migration_shape::SHAPE.set_utf8(&mut row, migration_shape::BODY, &to_create.body);
migration_shape::SHAPE.set_utf8(
&mut row,
migration_shape::ROLLBACK_BODY,
to_create.rollback_body.as_deref().unwrap_or(""),
);
txn.set(&MigrationKey::encoded(migration_id), row)?;
Ok(Migration {
id: migration_id,
name: to_create.name,
body: to_create.body,
rollback_body: to_create.rollback_body,
})
}
pub(crate) fn create_migration_event(
txn: &mut AdminTransaction,
migration: &Migration,
action: MigrationAction,
) -> Result<MigrationEvent> {
let event_id = SystemSequence::next_migration_event_id(txn)?;
let mut row = event_shape::SHAPE.allocate();
event_shape::SHAPE.set_u64(&mut row, event_shape::ID, event_id);
event_shape::SHAPE.set_u64(&mut row, event_shape::MIGRATION_ID, migration.id);
event_shape::SHAPE.set_u8(
&mut row,
event_shape::ACTION,
match action {
MigrationAction::Applied => 0,
MigrationAction::Rollback => 1,
},
);
txn.set(&MigrationEventKey::encoded(event_id), row)?;
Ok(MigrationEvent {
id: event_id,
migration_id: migration.id,
action,
})
}
}