use crate::data::Value; pub struct InsertBuilder { table: String, columns: Vec, returning: Vec, values: Vec, } impl InsertBuilder { pub fn new(table: &str) -> Self { Self { table: table.to_string(), columns: Vec::new(), returning: Vec::new(), values: Vec::new(), } } pub fn column(mut self, column: &str, value: Value) -> Self { self.columns.push(column.to_string()); self.values.push(value); self } pub fn returning(mut self, columns: &[&str]) -> Self { self.returning = columns.iter().map(|s| s.to_string()).collect(); self } pub async fn execute(self) -> Result { // Build the SQL query and its values let (query_string, values) = self.build(); // Start constructing the query let mut query = sqlx::query(&query_string); // Bind each value to its respective placeholder for value in values { match value { Value::Int(n) => query = query.bind(n), Value::OptionalInt(n) => query = query.bind(n), Value::BigInt(n) => query = query.bind(n), Value::OptionalBigInt(n) => query = query.bind(n), Value::Float(n) => query = query.bind(n), Value::OptionalFloat(n) => query = query.bind(n), Value::Double(n) => query = query.bind(n), Value::OptionalDouble(n) => query = query.bind(n), Value::Bool(n) => query = query.bind(n), Value::OptionalBool(n) => query = query.bind(n), Value::Text(n) => query = query.bind(n), Value::OptionalText(n) => query = query.bind(n), Value::DateTime(n) => query = query.bind(n), Value::OptionalDateTime(n) => query = query.bind(n), } } let pool = crate::data::pool(); query.execute(pool).await } fn build(self) -> (String, Vec) { if self.columns.is_empty() || self.values.is_empty() { panic!("Cannot build insert query without columns and values"); } // Create the list of column names let columns = self.columns.join(", "); // Generate placeholders for values ($1, $2, etc.) let placeholders = (1..=self.values.len()) .map(|i| format!("${}", i)) .collect::>() .join(", "); // Create the basic INSERT statement let mut query = format!( "INSERT INTO {} ({}) VALUES ({})", self.table, columns, placeholders ); // Add RETURNING clause if specified if !self.returning.is_empty() { query.push_str(&format!(" RETURNING {}", self.returning.join(", "))); } (query, self.values) } }