use sea_orm::sea_query::Order;
use super::where_node::WhereNode;
#[derive(Debug, Clone, Default)]
pub struct Query {
pub select: Vec<String>,
pub where_clause: Option<WhereNode>,
pub orderings: Vec<(String, Order)>,
pub group_by: Vec<String>,
pub having: Option<WhereNode>,
pub limit: Option<u64>,
pub offset: Option<u64>,
pub distinct: bool,
pub annotations: Vec<Annotation>,
pub subquery: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Annotation {
pub alias: String,
pub expression: String,
}
impl Query {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.select.is_empty() && self.where_clause.is_none()
}
#[must_use]
pub fn has_limit_or_offset(&self) -> bool {
self.limit.is_some() || self.offset.is_some()
}
pub fn clear_ordering(&mut self) {
self.orderings.clear();
}
pub fn clear_limits(&mut self) {
self.limit = None;
self.offset = None;
}
pub fn add_annotation(&mut self, alias: impl Into<String>, expression: impl Into<String>) {
self.annotations.push(Annotation {
alias: alias.into(),
expression: expression.into(),
});
}
}
#[cfg(test)]
mod tests {
use sea_orm::sea_query::Order;
use super::{Annotation, Query};
use crate::db::models::sql::where_node::WhereNode;
#[test]
fn new_query_starts_empty() {
let query = Query::new();
assert!(query.select.is_empty());
assert!(query.where_clause.is_none());
assert!(query.is_empty());
}
#[test]
fn query_is_not_empty_when_select_columns_exist() {
let mut query = Query::new();
query.select.push("name".to_string());
assert!(!query.is_empty());
}
#[test]
fn query_is_not_empty_when_where_clause_exists() {
let mut query = Query::new();
query.where_clause = Some(WhereNode::leaf("name", "exact", "Ada"));
assert!(!query.is_empty());
}
#[test]
fn add_annotation_appends_annotation() {
let mut query = Query::new();
query.add_annotation("total", "COUNT(*)");
assert_eq!(
query.annotations,
vec![Annotation {
alias: "total".to_string(),
expression: "COUNT(*)".to_string(),
}]
);
}
#[test]
fn has_limit_or_offset_detects_limit() {
let mut query = Query::new();
query.limit = Some(10);
assert!(query.has_limit_or_offset());
}
#[test]
fn has_limit_or_offset_detects_offset() {
let mut query = Query::new();
query.offset = Some(5);
assert!(query.has_limit_or_offset());
}
#[test]
fn clear_ordering_removes_all_orderings() {
let mut query = Query::new();
query.orderings = vec![
("name".to_string(), Order::Asc),
("id".to_string(), Order::Desc),
];
query.clear_ordering();
assert!(query.orderings.is_empty());
}
#[test]
fn clear_limits_removes_limit_and_offset() {
let mut query = Query {
limit: Some(10),
offset: Some(20),
..Query::new()
};
query.clear_limits();
assert_eq!(query.limit, None);
assert_eq!(query.offset, None);
assert!(!query.has_limit_or_offset());
}
#[test]
fn distinct_flag_can_be_enabled() {
let query = Query {
distinct: true,
..Query::new()
};
assert!(query.distinct);
}
#[test]
fn new_query_defaults_to_non_distinct_and_not_subquery() {
let query = Query::new();
assert!(!query.distinct);
assert!(!query.subquery);
}
}