use crate::expr::{Dialect, Expr};
use sqlmodel_core::Value;
#[derive(Debug, Clone)]
pub struct Where {
expr: Expr,
}
impl Where {
pub fn new(expr: Expr) -> Self {
Self { expr }
}
pub fn and(self, expr: Expr) -> Self {
Self {
expr: self.expr.and(expr),
}
}
pub fn or(self, expr: Expr) -> Self {
Self {
expr: self.expr.or(expr),
}
}
pub fn build(&self) -> (String, Vec<Value>) {
self.build_with_dialect(Dialect::default(), 0)
}
pub fn build_with_offset(&self, offset: usize) -> (String, Vec<Value>) {
self.build_with_dialect(Dialect::default(), offset)
}
pub fn build_with_dialect(&self, dialect: Dialect, offset: usize) -> (String, Vec<Value>) {
let mut params = Vec::new();
let sql = self.expr.build_with_dialect(dialect, &mut params, offset);
(sql, params)
}
}
#[derive(Debug, Clone)]
pub struct OrderBy {
pub expr: Expr,
pub direction: OrderDirection,
pub nulls: Option<NullsOrder>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum OrderDirection {
#[default]
Asc,
Desc,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NullsOrder {
First,
Last,
}
impl OrderBy {
pub fn asc(expr: impl Into<Expr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Asc,
nulls: None,
}
}
pub fn desc(expr: impl Into<Expr>) -> Self {
Self {
expr: expr.into(),
direction: OrderDirection::Desc,
nulls: None,
}
}
pub fn nulls_first(mut self) -> Self {
self.nulls = Some(NullsOrder::First);
self
}
pub fn nulls_last(mut self) -> Self {
self.nulls = Some(NullsOrder::Last);
self
}
pub fn build(&self, dialect: Dialect, params: &mut Vec<Value>, offset: usize) -> String {
let mut sql = self.expr.build_with_dialect(dialect, params, offset);
sql.push_str(match self.direction {
OrderDirection::Asc => " ASC",
OrderDirection::Desc => " DESC",
});
if let Some(nulls) = self.nulls {
sql.push_str(match nulls {
NullsOrder::First => " NULLS FIRST",
NullsOrder::Last => " NULLS LAST",
});
}
sql
}
}
#[derive(Debug, Clone, Copy)]
pub struct Limit(pub u64);
#[derive(Debug, Clone, Copy)]
pub struct Offset(pub u64);
#[derive(Debug, Clone)]
pub struct GroupBy {
columns: Vec<String>,
}
impl GroupBy {
pub fn new(columns: &[&str]) -> Self {
Self {
columns: columns.iter().map(|&s| s.to_string()).collect(),
}
}
pub fn to_sql(&self) -> String {
self.columns.join(", ")
}
}