use serde::{Deserialize, Serialize};
use crate::ast::{
ddl::drop_database::SQLStatement,
types::{SQLExpression, SelectColumn, TableName},
DMLStatement,
};
use super::{
expressions::subquery::SubqueryExpression,
parts::{
_where::WhereClause,
from::{FromClause, FromTarget},
group_by::{GroupByClause, GroupByItem},
having::HavingClause,
join::JoinClause,
order_by::{OrderByClause, OrderByItem},
select_item::{SelectItem, SelectKind, SelectWildCard},
},
};
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
pub struct SelectQuery {
pub select_items: Vec<SelectKind>,
pub has_aggregate: bool,
pub from_table: Option<FromClause>,
pub join_clause: Vec<JoinClause>,
pub where_clause: Option<WhereClause>,
pub order_by_clause: Option<OrderByClause>,
pub group_by_clause: Option<GroupByClause>,
pub having_clause: Option<HavingClause>,
pub limit: Option<u32>,
pub offset: Option<u32>,
}
impl SelectQuery {
pub fn builder() -> Self {
SelectQuery {
select_items: vec![],
from_table: None,
join_clause: vec![],
where_clause: None,
group_by_clause: None,
having_clause: None,
order_by_clause: None,
limit: None,
offset: None,
has_aggregate: false,
}
}
pub fn add_select_item(mut self, item: SelectItem) -> Self {
self.select_items.push(SelectKind::SelectItem(item));
self
}
pub fn add_select_wildcard(mut self, item: SelectWildCard) -> Self {
self.select_items.push(SelectKind::WildCard(item));
self
}
pub fn set_from_table(mut self, from: TableName) -> Self {
self.from_table = Some(from.into());
self
}
pub fn has_from_table(&self) -> bool {
self.from_table.is_some()
}
pub fn set_from_subquery(mut self, from: SubqueryExpression) -> Self {
self.from_table = Some(FromClause {
from: FromTarget::Subquery(from),
alias: None,
});
self
}
pub fn set_from_alias(mut self, alias: String) -> Self {
if self.from_table.is_some() {
self.from_table = self.from_table.map(|mut e| {
e.alias = Some(alias);
e
});
}
self
}
pub fn add_join(mut self, join: JoinClause) -> Self {
self.join_clause.push(join);
self
}
pub fn set_where(mut self, where_clause: WhereClause) -> Self {
self.where_clause = Some(where_clause);
self
}
pub fn add_order_by(mut self, item: OrderByItem) -> Self {
match self.order_by_clause {
Some(ref mut order_by_clause) => {
order_by_clause.order_by_items.push(item);
}
None => {
self.order_by_clause = Some(OrderByClause {
order_by_items: vec![item],
})
}
}
self
}
pub fn add_group_by(mut self, item: GroupByItem) -> Self {
match self.group_by_clause {
Some(ref mut group_by_clause) => {
group_by_clause.group_by_items.push(item);
}
None => {
self.group_by_clause = Some(GroupByClause {
group_by_items: vec![item],
})
}
}
self
}
pub fn has_group_by(&self) -> bool {
match self.group_by_clause {
Some(ref group_by_clause) => !group_by_clause.group_by_items.is_empty(),
None => false,
}
}
pub fn set_having(mut self, having_clause: HavingClause) -> Self {
self.having_clause = Some(having_clause);
self
}
pub fn set_offset(mut self, offset: u32) -> Self {
self.offset = Some(offset);
self
}
pub fn set_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
pub fn set_has_aggregate(mut self, has_aggregate: bool) -> Self {
self.has_aggregate = has_aggregate;
self
}
pub fn has_aggregate(&self) -> bool {
for item in &self.select_items {
match item {
SelectKind::SelectItem(item) => {
let item = item.item.as_ref().unwrap();
if item.has_aggregate() {
return true;
}
}
SelectKind::WildCard(_) => return false,
}
}
false
}
pub fn get_non_aggregate_column(&self) -> Vec<SelectColumn> {
let mut list = vec![];
for item in &self.select_items {
match item {
SelectKind::SelectItem(item) => {
let item = item.item.as_ref().unwrap();
let mut none_aggregate_columns = item.find_non_aggregate_columns();
list.append(&mut none_aggregate_columns);
}
SelectKind::WildCard(_) => {}
}
}
list
}
pub fn get_aggregate_column(&self) -> Vec<SelectColumn> {
let mut list = vec![];
for item in &self.select_items {
match item {
SelectKind::SelectItem(item) => {
let item = item.item.as_ref().unwrap();
let mut aggregate_columns = item.find_aggregate_columns();
list.append(&mut aggregate_columns);
}
SelectKind::WildCard(_) => {}
}
}
list
}
pub fn build(self) -> SelectQuery {
self
}
}
impl From<SelectQuery> for SQLStatement {
fn from(value: SelectQuery) -> SQLStatement {
SQLStatement::DML(DMLStatement::SelectQuery(value))
}
}
impl From<SelectQuery> for SubqueryExpression {
fn from(value: SelectQuery) -> SubqueryExpression {
SubqueryExpression::Select(Box::new(value))
}
}
impl From<SelectQuery> for SQLExpression {
fn from(value: SelectQuery) -> SQLExpression {
SQLExpression::Subquery(SubqueryExpression::Select(Box::new(value)))
}
}