use core::{marker::PhantomData, ops::Deref};
use crate::{SQL, SQLParam, ToSQL, Token};
pub trait CTEDefinition<'a, V: SQLParam> {
fn cte_definition(&self) -> SQL<'a, V>;
}
#[derive(Clone, Debug)]
pub struct CTEView<'a, V: SQLParam, Table, Query> {
pub table: Table,
name: &'static str,
query: Query,
value: PhantomData<(&'a (), V)>,
}
impl<'a, V, Table, Query> CTEView<'a, V, Table, Query>
where
V: SQLParam,
Query: ToSQL<'a, V>,
{
pub const fn new(table: Table, name: &'static str, query: Query) -> Self {
Self {
table,
name,
query,
value: PhantomData,
}
}
pub const fn cte_name(&self) -> &'static str {
self.name
}
pub const fn query(&self) -> &Query {
&self.query
}
}
impl<'a, V, Table, Query> CTEDefinition<'a, V> for CTEView<'a, V, Table, Query>
where
V: SQLParam,
Query: ToSQL<'a, V>,
{
fn cte_definition(&self) -> SQL<'a, V> {
SQL::ident(self.name)
.push(Token::AS)
.append(self.query.to_sql().parens())
}
}
impl<'a, V, Table, Query> CTEDefinition<'a, V> for &CTEView<'a, V, Table, Query>
where
V: SQLParam,
Query: ToSQL<'a, V>,
{
fn cte_definition(&self) -> SQL<'a, V> {
(*self).cte_definition()
}
}
impl<V: SQLParam, Table, Query> Deref for CTEView<'_, V, Table, Query> {
type Target = Table;
fn deref(&self) -> &Self::Target {
&self.table
}
}
impl<'a, V, Table, Query> ToSQL<'a, V> for CTEView<'a, V, Table, Query>
where
V: SQLParam,
Query: ToSQL<'a, V>,
{
fn to_sql(&self) -> SQL<'a, V> {
SQL::ident(self.name)
}
}