use keelson_core::clause::{HasLimit, HasOrderBy, HasValues, Limit, OrderBy, Values};
use keelson_core::expr::{Expr, IntoExpr, IntoExprList};
use keelson_core::{Dialect, Error, Expression, Mod, Query, QueryExtensions, QueryType, SqlWriter};
use crate::Mysql;
#[derive(Debug, Clone, Default)]
pub struct ValuesQuery {
pub values: Values,
pub order_by: OrderBy,
pub limit: Limit,
}
impl ValuesQuery {
pub fn new() -> ValuesQuery {
ValuesQuery::default()
}
pub fn apply(&mut self, mods: impl Mod<ValuesQuery>) {
mods.apply(self);
}
}
impl Expression for ValuesQuery {
fn write_sql(&self, w: &mut SqlWriter<'_>) {
if self.values.query.is_some() {
w.record_error(Error::other(
"a standalone VALUES statement takes rows; a source query belongs to INSERT",
));
return;
}
if self.values.rows.is_empty() {
w.record_error(Error::Incomplete("the rows of a VALUES statement"));
return;
}
w.push_str("VALUES ");
for (i, row) in self.values.rows.iter().enumerate() {
if i > 0 {
w.push_str(", ");
}
w.push_str("ROW");
w.write_expr(row);
}
w.write_if(!self.order_by.is_empty(), " ", &self.order_by, "");
w.write_if(!self.limit.is_empty(), " ", &self.limit, "");
}
}
impl Query for ValuesQuery {
fn query_type(&self) -> QueryType {
QueryType::Select
}
fn dialect(&self) -> &dyn Dialect {
&Mysql
}
}
impl<H, L, M> QueryExtensions<H, L, M> for ValuesQuery {}
impl IntoExpr for ValuesQuery {
fn into_expr(self) -> Expr {
crate::query(self)
}
}
impl IntoExprList for ValuesQuery {
fn into_expr_list(self) -> Vec<Expr> {
vec![self.into_expr()]
}
}
impl HasValues for ValuesQuery {
fn values_mut(&mut self) -> &mut Values {
&mut self.values
}
}
impl HasOrderBy for ValuesQuery {
fn order_by_mut(&mut self) -> &mut OrderBy {
&mut self.order_by
}
}
impl HasLimit for ValuesQuery {
fn limit_mut(&mut self) -> &mut Limit {
&mut self.limit
}
}