so6 0.2.0

Framework for manage background data migration with PostgreSQL
Documentation
use crate::database::{Database, DATABASE};
use serde::Deserialize;

#[derive(Deserialize, Debug, Clone)]
pub struct Index {
    condition: String,
    pub name: String,
    schema: Option<String>,
    table: String,
    unique: bool,
    definition: String,
}

impl Index {
    pub fn exists(&self) -> bool {
        let db = DATABASE.get_or_init(|| Database::new());

        let row = db
            .client()
            .query_one(
                "
    SELECT EXISTS (
        SELECT 1 FROM pg_indexes
          WHERE indexname = $1 AND schemaname = $2 AND tablename = $3
    )",
                &[&self.name, &self.schema, &self.table],
            )
            .unwrap();
        row.get(0)
    }
    fn create(&self, is_concurent: bool) -> String {
        let db = DATABASE.get_or_init(|| Database::new());
        let mut already_or_not = "already ";
        if !self.exists() {
            already_or_not = "";
            let concurrently = match is_concurent {
                true => "CONCURRENTLY ",
                false => "",
            };
            let unique = match self.unique {
                true => "UNIQUE ",
                false => "",
            };
            let table = match &self.schema {
                Some(schema) => {
                    let t = self.table.clone();
                    format!("{schema}.{t}")
                }
                None => self.table.clone(),
            };
            let name = self.name.clone();
            let definition = self.definition.clone();
            let _ = db.client().execute(
                format!(
                    "
            CREATE {unique}INDEX {concurrently}{name}
            ON {table} {definition}
            "
                )
                .as_str(),
                &[],
            );
        }
        format!("index {already_or_not}created")
    }
    pub fn background_run(&self) -> String {
        self.create(true)
    }
    pub fn final_run(&self) -> String {
        self.create(false)
    }
    pub fn required(&self) -> bool {
        let db = DATABASE.get_or_init(|| Database::new());
        db.client()
            .query_one(self.condition.as_str(), &[])
            .unwrap()
            .get(0)
    }
}

pub fn test_setup<T>(query: &T)
where
    T: ?Sized + postgres::ToStatement,
{
    let db = DATABASE.get_or_init(|| Database::new());
    let mut client = db.client();
    let _ = client.execute(query, &[]);
}