use super::*;
#[derive(Debug, Clone, PartialEq)]
pub struct InsertStatement {
pub token: Token,
pub table_name: Identifier,
pub columns: Vec<Identifier>,
pub values: Vec<Vec<Expression>>,
pub select: Option<Box<SelectStatement>>,
pub on_duplicate: bool,
pub update_columns: Vec<Identifier>,
pub update_expressions: Vec<Expression>,
pub do_nothing: bool,
pub conflict_target: Vec<Identifier>,
pub returning: Vec<Expression>,
}
impl fmt::Display for InsertStatement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut result = format!("INSERT INTO {}", self.table_name);
if !self.columns.is_empty() {
let cols: Vec<String> = self.columns.iter().map(|c| c.to_string()).collect();
result.push_str(&format!(" ({})", cols.join(", ")));
}
if let Some(ref select) = self.select {
result.push_str(&format!(" {}", select));
} else {
result.push_str(" VALUES ");
let rows: Vec<String> = self
.values
.iter()
.map(|row| {
let vals: Vec<String> = row.iter().map(|v| v.to_string()).collect();
format!("({})", vals.join(", "))
})
.collect();
result.push_str(&rows.join(", "));
}
if self.do_nothing {
result.push_str(" ON CONFLICT");
if !self.conflict_target.is_empty() {
let cols: Vec<String> =
self.conflict_target.iter().map(|c| c.to_string()).collect();
result.push_str(&format!(" ({})", cols.join(", ")));
}
result.push_str(" DO NOTHING");
} else if self.on_duplicate {
if !self.conflict_target.is_empty() {
let cols: Vec<String> =
self.conflict_target.iter().map(|c| c.to_string()).collect();
result.push_str(&format!(
" ON CONFLICT ({}) DO UPDATE SET ",
cols.join(", ")
));
} else {
result.push_str(" ON DUPLICATE KEY UPDATE ");
}
let updates: Vec<String> = self
.update_columns
.iter()
.zip(&self.update_expressions)
.map(|(col, expr)| format!("{} = {}", col, expr))
.collect();
result.push_str(&updates.join(", "));
}
if !self.returning.is_empty() {
let returning: Vec<String> = self.returning.iter().map(|e| e.to_string()).collect();
result.push_str(&format!(" RETURNING {}", returning.join(", ")));
}
write!(f, "{}", result)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct UpdateStatement {
pub token: Token,
pub table_name: Identifier,
pub updates: FxHashMap<SmartString, Expression>,
pub where_clause: Option<Box<Expression>>,
pub returning: Vec<Expression>,
}
impl fmt::Display for UpdateStatement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut result = format!("UPDATE {} SET ", self.table_name);
let updates: Vec<String> = self
.updates
.iter()
.map(|(col, val)| format!("{} = {}", col, val))
.collect();
result.push_str(&updates.join(", "));
if let Some(ref where_clause) = self.where_clause {
result.push_str(&format!(" WHERE {}", where_clause));
}
if !self.returning.is_empty() {
let returning: Vec<String> = self.returning.iter().map(|e| e.to_string()).collect();
result.push_str(&format!(" RETURNING {}", returning.join(", ")));
}
write!(f, "{}", result)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct DeleteStatement {
pub token: Token,
pub table_name: Identifier,
pub alias: Option<Identifier>,
pub where_clause: Option<Box<Expression>>,
pub returning: Vec<Expression>,
}
impl fmt::Display for DeleteStatement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut result = format!("DELETE FROM {}", self.table_name);
if let Some(ref alias) = self.alias {
result.push_str(&format!(" AS {}", alias));
}
if let Some(ref where_clause) = self.where_clause {
result.push_str(&format!(" WHERE {}", where_clause));
}
if !self.returning.is_empty() {
let returning: Vec<String> = self.returning.iter().map(|e| e.to_string()).collect();
result.push_str(&format!(" RETURNING {}", returning.join(", ")));
}
write!(f, "{}", result)
}
}