grorm 0.1.1

Goroutine-native ORM for Rust with multi-database support
Documentation
use crate::types::Value;

pub struct InsertBuilder {
    table: String,
    columns: Vec<String>,
    values: Vec<Vec<Value>>,
    returning: Vec<String>,
}

impl InsertBuilder {
    pub fn new(table: &str) -> Self {
        InsertBuilder {
            table: table.to_string(),
            columns: Vec::new(),
            values: Vec::new(),
            returning: Vec::new(),
        }
    }

    pub fn columns(mut self, cols: &[&str]) -> Self {
        self.columns = cols.iter().map(|c| c.to_string()).collect();
        self
    }

    pub fn values(mut self, vals: Vec<Value>) -> Self {
        self.values.push(vals);
        self
    }

    pub fn returning(mut self, cols: &[&str]) -> Self {
        self.returning = cols.iter().map(|c| c.to_string()).collect();
        self
    }

    pub fn build(&self) -> (String, Vec<Value>) {
        let mut sql = format!("INSERT INTO {}", self.table);
        let mut params = Vec::new();

        if !self.columns.is_empty() {
            sql.push_str(&format!(" ({})", self.columns.join(", ")));
        }

        if !self.values.is_empty() {
            let value_groups: Vec<String> = self
                .values
                .iter()
                .map(|row| {
                    let placeholders: Vec<String> = row
                        .iter()
                        .map(|v| {
                            params.push(v.clone());
                            "?".to_string()
                        })
                        .collect();
                    format!("({})", placeholders.join(", "))
                })
                .collect();
            sql.push_str(&format!(" VALUES {}", value_groups.join(", ")));
        }

        if !self.returning.is_empty() {
            sql.push_str(&format!(" RETURNING {}", self.returning.join(", ")));
        }

        (sql, params)
    }
}