hinge 0.1.0

SQL-native ELT engine — dependency graph resolved automatically from FROM/JOIN clauses, parallel execution, single binary
Documentation
use crate::application::Engine;
use crate::application::{Executor, ExecutorError};
use crate::domain::{Asset, Graph};
use futures::future::try_join_all;

/// Executes **all** assets in the graph in topological order.
///
/// Assets with no dependency between them run **concurrently** within the same
/// wave; sequential ordering is enforced only where the dependency graph requires it.
///
/// # Example
///
/// ```rust,ignore
/// use hinge::{BuildGraph, RunAll, PostgresExecutor};
///
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let graph    = BuildGraph::from_dir("models")?;
///     let executor = PostgresExecutor::new("postgresql://localhost/mydb").await?;
///     RunAll::new(graph, executor).execute().await?;
///     Ok(())
/// }
/// ```
pub struct RunAll<E> {
    engine: Engine,
    executor: E,
}

impl<E: Executor> RunAll<E> {
    pub fn new(graph: Graph, executor: E) -> Self {
        Self { engine: Engine::new(graph), executor }
    }

    /// Run all assets. Independent assets within the same wave run in parallel.
    pub async fn execute(&self) -> Result<(), ExecutorError> {
        for wave in self.engine.topo_levels() {
            let futs: Vec<_> = wave.iter().map(|asset| self.executor.run(asset)).collect();
            try_join_all(futs).await?;
        }
        Ok(())
    }

    /// Returns the planned execution order (flat topo, for display / dry-run).
    pub fn plan(&self) -> Vec<Asset> {
        self.engine.all_nodes()
    }
}