90 lines
2.6 KiB
Rust
90 lines
2.6 KiB
Rust
use crate::data::Value;
|
|
|
|
pub struct InsertBuilder {
|
|
table: String,
|
|
columns: Vec<String>,
|
|
returning: Vec<String>,
|
|
values: Vec<Value>,
|
|
}
|
|
|
|
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<sqlx::postgres::PgQueryResult, sqlx::Error> {
|
|
// 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<Value>) {
|
|
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::<Vec<_>>()
|
|
.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)
|
|
}
|
|
}
|