use redb::TableDefinition;
use crate::control::security::catalog::SystemCatalog;
use crate::types::TenantId;
pub(crate) const MOVE_TENANT_JOURNAL: TableDefinition<u64, &[u8]> =
TableDefinition::new("_system.move_tenant_journal");
#[derive(Debug, Clone, Copy, PartialEq, Eq, zerompk::ToMessagePack, zerompk::FromMessagePack)]
#[repr(u8)]
pub enum MovePhase {
Preflight = 1,
Drain = 2,
Snapshot = 3,
Cutover = 4,
Resumed = 5,
}
#[derive(zerompk::ToMessagePack, zerompk::FromMessagePack, Debug, Clone)]
#[msgpack(map)]
pub struct MoveTenantJournalEntry {
pub tenant_id: u64,
pub tenant_name: String,
pub source_db_id: u64,
pub source_db_name: String,
pub target_db_id: u64,
pub target_db_name: String,
pub phase: MovePhase,
pub last_durable_lsn: u64,
#[msgpack(default)]
pub temp_snapshot_key: Option<String>,
}
impl MoveTenantJournalEntry {
pub fn with_phase(self, phase: MovePhase) -> Self {
Self { phase, ..self }
}
pub fn with_temp_snapshot_key(self, key: String) -> Self {
Self {
temp_snapshot_key: Some(key),
..self
}
}
}
pub fn load_journal_entry(
catalog: &SystemCatalog,
tenant_id: TenantId,
) -> crate::Result<Option<MoveTenantJournalEntry>> {
catalog.move_tenant_journal_load(tenant_id.as_u64())
}
pub fn save_journal_entry(
catalog: &SystemCatalog,
entry: &MoveTenantJournalEntry,
) -> crate::Result<()> {
catalog.move_tenant_journal_save(entry)
}
pub fn delete_journal_entry(catalog: &SystemCatalog, tenant_id: TenantId) -> crate::Result<()> {
catalog.move_tenant_journal_delete(tenant_id.as_u64())
}
pub fn delete_journal_entry_logged(catalog: &SystemCatalog, tenant_id: TenantId) {
if let Err(e) = delete_journal_entry(catalog, tenant_id) {
tracing::warn!(
tenant = tenant_id.as_u64(),
error = %e,
"move_tenant: failed to delete journal entry; will be retried on next startup"
);
}
}
pub fn scan_all_journal_entries(
catalog: &SystemCatalog,
) -> crate::Result<Vec<MoveTenantJournalEntry>> {
catalog.move_tenant_journal_scan_all()
}