#[cfg(feature = "cli")]
pub mod commands;
mod config;
mod macros;
mod parser;
mod repo;
mod schema;
mod types;
mod utils;
use anyhow::Result;
use async_trait::async_trait;
use config::RenovateOutputConfig;
use pg_query::NodeEnum;
use std::{collections::BTreeSet, path::PathBuf};
pub use config::RenovateConfig;
pub use parser::DatabaseSchema;
pub use repo::git::{BumpVersion, GitRepo};
#[async_trait]
pub trait SchemaLoader {
async fn load(&self) -> Result<DatabaseSchema>;
async fn load_sql(&self) -> Result<String>;
}
#[async_trait]
pub trait SqlSaver {
async fn save(&self, config: &RenovateOutputConfig) -> Result<()>;
}
pub trait NodeItem: ToString {
type Inner;
fn id(&self) -> String;
fn type_name(&self) -> &'static str;
fn node(&self) -> &NodeEnum;
fn inner(&self) -> Result<&Self::Inner>;
fn map<F, T>(&self, f: F, data: Option<T>) -> Result<NodeEnum>
where
F: Fn(&Self::Inner, Option<T>) -> Result<NodeEnum>,
{
f(self.inner()?, data)
}
fn revert(&self) -> Result<NodeEnum>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NodeDiff<T> {
pub old: Option<T>,
pub new: Option<T>,
pub diff: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NodeDelta<T> {
pub added: BTreeSet<T>,
pub removed: BTreeSet<T>,
pub changed: BTreeSet<(T, T)>,
}
pub trait Differ {
type Diff: MigrationPlanner;
fn diff(&self, remote: &Self) -> Result<Option<Self::Diff>>;
}
pub type MigrationResult<T> = Result<Vec<T>>;
pub trait MigrationPlanner {
type Migration: ToString;
fn drop(&self) -> MigrationResult<Self::Migration>;
fn create(&self) -> MigrationResult<Self::Migration>;
fn alter(&self) -> MigrationResult<Self::Migration>;
fn plan(&self) -> Result<Vec<Self::Migration>> {
let items = self.alter()?;
if !items.is_empty() {
return Ok(items);
}
let drop = self.drop()?;
let create = self.create()?;
Ok([drop, create].into_iter().flatten().collect())
}
}
pub trait DeltaItem: ToString {
type SqlNode: NodeItem;
fn drop(self, node: &Self::SqlNode) -> Result<Vec<String>>;
fn create(self, node: &Self::SqlNode) -> Result<Vec<String>>;
fn rename(self, node: &Self::SqlNode, new: Self) -> Result<Vec<String>>;
fn alter(self, node: &Self::SqlNode, new: Self) -> Result<Vec<String>>;
}
pub trait SqlFormatter {
fn format(&self) -> Result<String>;
}
#[async_trait]
pub trait MigrationExecutor {
async fn execute(&self) -> Result<()>;
}
#[derive(Debug, Clone)]
pub struct LocalRepo {
pub path: PathBuf,
}
#[derive(Debug, Clone)]
pub struct DatabaseRepo {
url: String,
remote_url: String,
}
#[derive(Debug, Clone)]
pub struct SqlLoader(String);