schema-sync 1.0.0

Production-grade schema synchronization for multi-tenant databases
Documentation
//! Developer: s4gor
//! Github: https://github.com/s4gor
//!
//! Migration execution
//!
//! The executor orchestrates the execution of migration plans.
//! It handles:
//! - Lock acquisition
//! - Transaction management
//! - Step-by-step execution
//! - Rollback on failure
//! - Progress tracking
//!
//! ## Design Rationale
//!
//! Separating execution from planning allows:
//! - Different execution strategies (transactional, non-transactional)
//! - Progress reporting
//! - Retry logic
//! - Testing with mock executors

use async_trait::async_trait;

use crate::adapters::MigrationRunner;
use crate::errors::Result;
use crate::planner::MigrationPlan;

/// Result of executing a migration plan
#[derive(Debug, Clone)]
pub struct ExecutionResult {
    /// Number of steps executed successfully
    pub steps_executed: usize,

    /// Total number of steps in the plan
    pub total_steps: usize,

    /// Whether execution completed successfully
    pub success: bool,

    /// Error message if execution failed
    pub error: Option<String>,

    /// Duration of execution
    pub duration_secs: f64,
}

/// Trait for executing migration plans
///
/// The executor coordinates between the planner, migration runner,
/// and other components to safely execute migrations.
#[async_trait]
pub trait Executor: Send + Sync {
    /// Execute a migration plan for a tenant
    ///
    /// # Arguments
    ///
    /// * `tenant` - The tenant context
    /// * `plan` - The migration plan to execute
    /// * `runner` - The migration runner to use
    ///
    /// # Returns
    ///
    /// Execution result with success status and details.
    async fn execute(
        &self,
        tenant: &crate::cli::TenantContext,
        plan: &MigrationPlan,
        runner: &dyn MigrationRunner,
    ) -> Result<ExecutionResult>;

    /// Execute a migration plan in dry-run mode
    ///
    /// This validates the plan and returns what would happen,
    /// but doesn't actually execute any changes.
    async fn dry_run(
        &self,
        tenant: &crate::cli::TenantContext,
        plan: &MigrationPlan,
        runner: &dyn MigrationRunner,
    ) -> Result<ExecutionResult>;
}