sql_tools 0.11.10

A rust crate meant to make SQL queries simple and communication between various SQL versions easy.
Documentation
use crate::{Error, SQLImplementation, data_types::SQLDataTypes, statements::update::UpdateProps};

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

    let set_match_len = &update_set.set_match.len();
    let set = update_set.set_match.iter().enumerate().map(|(idx, set_match)| {
        let fmt_data_types = match &set_match.value {
            SQLDataTypes::Varchar(val) => format!("'{}'", val),
            SQLDataTypes::Number(val) => format!("{}", val),
            SQLDataTypes::Float(val) => format!("{}", val),
            SQLDataTypes::Date(val) => format!("to_date(to_char(to_timestamp('{}', 'YYYY-MM-DD HH24:MI:SS.FF3'), 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')", val),
            SQLDataTypes::NULL => format!("''"),
        };

        if set_match_len == &1 { format!("SET {} = {}", set_match.column, fmt_data_types) }
        else if idx == 0 { format!("SET {} = {},", set_match.column, fmt_data_types) }
        else if &idx == &(set_match_len - 1) { format!("{} = {}", set_match.column, fmt_data_types) }
        else { format!("{} = {},", set_match.column, fmt_data_types) }
    }).collect::<Vec<String>>().join(" ");

    let count_sql: String;
    let query = match update_set.clause {
        Some(filters) => {
            count_sql = format!(
                "SELECT COUNT(*) FROM {} WHERE {}",
                &update_set.table, &filters
            );
            format!("UPDATE {} {} WHERE {}", &update_set.table, set, filters)
        }
        None => {
            count_sql = format!("SELECT COUNT(*) FROM {}", &update_set.table);
            format!("UPDATE {} {}", &update_set.table, set)
        }
    };

    let conn = conn_info.initialize_connection()?;
    conn.execute(&query, [])?;
    let mut stmt = conn.prepare(&count_sql)?;
    let mut rows = stmt.query([])?;
    let mut res: Vec<usize> = Vec::new();
    while let Some(row) = rows.next()? {
        res.push(row.get(0).unwrap())
    }

    if res.len() == 0 {
        return Err(Error::CountError);
    }

    Ok(res[0])
}

pub fn batch_update_sqlite(updates: Vec<UpdateProps>) -> Result<(), Error> {
    let connect = &updates[0].connect;
    // let table = &updates[0].query_type.table;
    let conn_info = match connect {
        SQLImplementation::Oracle(_) => return Err(Error::SQLVariationError),
        SQLImplementation::SQLite(connect) => connect,
    };

    let sql = updates.iter().map(|update| {
        let set_match_len = &update.set_match.len();
        let set = update.set_match.iter().enumerate().map(|(idx, set_match)| {
            let fmt_data_types = match &set_match.value {
                SQLDataTypes::Varchar(val) => format!("'{}'", val),
                SQLDataTypes::Number(val) => format!("{}", val),
                SQLDataTypes::Float(val) => format!("{}", val),
                SQLDataTypes::Date(val) => format!("to_date(to_char(to_timestamp('{}', 'YYYY-MM-DD HH24:MI:SS.FF3'), 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')", val),
                SQLDataTypes::NULL => format!("''"),
            };

            if set_match_len == &1 { format!("SET {} = {}", set_match.column, fmt_data_types) }
            else if idx == 0 { format!("SET {} = {},", set_match.column, fmt_data_types) }
            else if &idx == &(set_match_len - 1) { format!("{} = {}", set_match.column, fmt_data_types) }
            else { format!("{} = {},", set_match.column, fmt_data_types) }
        }).collect::<Vec<String>>().join(" ");
        match &update.clause {
            Some(clause) => format!("UPDATE {} {} WHERE {}", &update.table, set, clause),
            None => format!("UPDATE {} {}", &update.table, set),
        }
    }).collect::<Vec<String>>().join("; ");

    let query = format!("BEGIN; {sql}; COMMIT;");

    let conn = conn_info.initialize_connection()?;
    conn.execute_batch(&query)?;

    Ok(())
}