sql_tools 0.11.10

A rust crate meant to make SQL queries simple and communication between various SQL versions easy.
Documentation
use indicatif::ProgressBar;

use crate::{
    Error, SQLImplementation,
    data_types::SQLDataTypes,
    statements::insert::{
        InsertProps,
        sql_implementations::sqlite::utils::{create_sqlite_table, does_sqlite_table_exist},
    },
};

pub(crate) mod utils;

pub(crate) fn sqlite_build_insert(insert_props: InsertProps) -> Result<(), Error> {
    let conn_info = match &insert_props.connect {
        SQLImplementation::Oracle(_) => return Err(Error::SQLVariationError),
        SQLImplementation::SQLite(connect) => connect,
    };

    let table_exist = does_sqlite_table_exist(&insert_props, &conn_info)?;
    if !table_exist && insert_props.create {
        create_sqlite_table(&insert_props, conn_info)?;
    } else if !table_exist && !insert_props.create {
        return Err(Error::TableDoesNotExist);
    }

    let mut values = Vec::new();
    for idx in 0..insert_props.grid.len() {
        values.push(["?", &(idx + 1).to_string()].concat())
    }

    let conn = conn_info.initialize_connection()?;

    let mut batch: Vec<String> = Vec::new();
    insert_props.grid.iter().for_each(|row| {
        let values = row
            .iter()
            .map(|cell| match cell {
                SQLDataTypes::Varchar(val) => format!("'{val}'"),
                SQLDataTypes::Number(val) => format!("{val}"),
                SQLDataTypes::Float(val) => format!("{val}"),
                SQLDataTypes::Date(val) => format!("'{}'", val.to_string()),
                SQLDataTypes::NULL => format!("NULL"),
            })
            .collect::<Vec<String>>();
        let sql = format!(
            "INSERT INTO {} ({}) VALUES ({})",
            insert_props.table,
            insert_props.header.join(", "),
            values.join(", ")
        );
        batch.push(sql);
    });

    let sql = format!(
        "
        BEGIN;
        {};
        COMMIT;
    ",
        batch.join("; ")
    );
    conn.execute_batch(&sql)?;

    Ok(())
}

pub(crate) fn sqlite_build_insert_pb(insert_props: InsertProps) -> Result<(), Error> {
    let conn_info = match &insert_props.connect {
        SQLImplementation::Oracle(_) => return Err(Error::SQLVariationError),
        SQLImplementation::SQLite(connect) => connect,
    };

    does_sqlite_table_exist(&insert_props, conn_info)?;

    let mut values = Vec::new();
    for idx in 0..insert_props.grid.len() {
        values.push(["?", &(idx + 1).to_string()].concat())
    }

    let conn = conn_info.initialize_connection()?;
    let progress_bar = ProgressBar::new(*&insert_props.grid.len() as u64);

    let mut batch: Vec<String> = Vec::new();
    insert_props.grid.iter().for_each(|row| {
        let values = row
            .iter()
            .map(|cell| match cell {
                SQLDataTypes::Varchar(val) => format!("'{val}'"),
                SQLDataTypes::Number(val) => format!("{val}"),
                SQLDataTypes::Float(val) => format!("{val}"),
                SQLDataTypes::Date(val) => format!("'{}'", val.to_string()),
                SQLDataTypes::NULL => format!(""),
            })
            .collect::<Vec<String>>();
        let sql = format!(
            "INSERT INTO {} ({}) VALUES ({})",
            insert_props.table,
            insert_props.header.join(", "),
            values.join(", ")
        );
        batch.push(sql);
        progress_bar.inc(1u64);
    });

    let sql = format!(
        "
        BEGIN;
        {};
        COMMIT;
    ",
        batch.join("; ")
    );
    conn.execute_batch(&sql)?;

    Ok(())
}