use std::{marker::PhantomData, rc::Rc};
use crate::{Expr, Table, TableRow, lower, value::DbTyp};
pub trait IntoJoinable<'inner, S> {
type Typ: DbTyp;
fn into_joinable(self) -> Joinable<'inner, S, Self::Typ>;
}
pub struct Joinable<'inner, S, T: DbTyp> {
_p: PhantomData<Expr<'inner, S, T>>,
pub(crate) table: lower::JoinableTableWithId,
pub(crate) conds: Vec<(&'static str, Rc<lower::Expr>)>,
}
impl<'inner, S, T: DbTyp> Joinable<'inner, S, T> {
pub fn new(j: lower::JoinableTableWithId) -> Self {
Self {
_p: PhantomData,
table: j,
conds: Vec::new(),
}
}
}
impl<'inner, S, T: Table> Joinable<'inner, S, TableRow<T>> {
pub fn table() -> Self {
Self::new(lower::JoinableTableWithId {
name: lower::JoinableTable::Table(T::NAME, None),
main_column: T::ID,
})
}
}
impl<'inner, S, T: DbTyp> Joinable<'inner, S, T> {
pub fn add_cond<C: DbTyp>(mut self, col: &'static str, val: Expr<'inner, S, C>) -> Self {
self.conds.push((col, val.inner));
self
}
}
impl<'inner, S, T: DbTyp> IntoJoinable<'inner, S> for Joinable<'inner, S, T> {
type Typ = T;
fn into_joinable(self) -> Joinable<'inner, S, Self::Typ> {
self
}
}