use crate::ast::{Action, CTEDef, CteCycle, CteMaterialization, CteSearch, Expr, Qail};
impl Qail {
pub fn to_cte(self, name: impl Into<String>) -> CTEDef {
let cte_name = name.into();
let columns: Vec<String> = if matches!(self.action, Action::Add | Action::Set | Action::Del)
{
Vec::new()
} else {
self.columns
.iter()
.filter_map(|c| match c {
Expr::Named(n) => Some(n.clone()),
Expr::Aliased { alias, .. } => Some(alias.clone()),
_ => None,
})
.collect()
};
CTEDef {
name: cte_name,
recursive: false,
columns,
base_query: Box::new(self),
recursive_query: None,
source_table: None,
materialization: None,
search: None,
cycle: None,
}
}
pub fn with(self, name: impl Into<String>, query: Qail) -> Self {
self.with_cte(query.to_cte(name))
}
pub fn recursive(mut self, recursive_part: Qail) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.recursive = true;
cte.recursive_query = Some(Box::new(recursive_part));
}
self
}
pub fn from_cte(mut self, cte_name: impl Into<String>) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.source_table = Some(cte_name.into());
}
self
}
pub fn select_from_cte(mut self, columns: &[&str]) -> Self {
self.columns = columns.iter().map(|c| Expr::Named(c.to_string())).collect();
self
}
pub fn with_cte(mut self, cte: CTEDef) -> Self {
self.ctes.push(cte);
self
}
pub fn cte_materialized(mut self) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.materialization = Some(CteMaterialization::Materialized);
}
self
}
pub fn cte_not_materialized(mut self) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.materialization = Some(CteMaterialization::NotMaterialized);
}
self
}
pub fn cte_search(mut self, search: CteSearch) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.search = Some(search);
}
self
}
pub fn cte_cycle(mut self, cycle: CteCycle) -> Self {
if let Some(cte) = self.ctes.last_mut() {
cte.cycle = Some(cycle);
}
self
}
}