1use std::{marker::PhantomData, rc::Rc};
2
3use sea_query::IntoIden;
4
5use crate::{
6 Expr, Table,
7 alias::{JoinableTable, TmpTable},
8 ast::MySelect,
9 db::Join,
10 value::{IntoExpr, MyTableRef, MyTyp, Typed},
11};
12
13pub struct Rows<'inner, S> {
21 pub(crate) phantom: PhantomData<fn(&'inner ()) -> &'inner ()>,
23 pub(crate) _p: PhantomData<S>,
24 pub(crate) ast: Rc<MySelect>,
25}
26
27impl<'inner, S> Rows<'inner, S> {
28 pub fn join<T: Table<Schema = S>>(&mut self, _: T) -> Expr<'inner, S, T> {
35 self.join_inner(JoinableTable::Normal(T::NAME.into()))
36 }
37
38 pub(crate) fn join_custom<T: Table<Schema = S>>(&mut self, t: T) -> Expr<'inner, S, T> {
39 self.join_inner(t.name())
40 }
41
42 pub(crate) fn join_tmp<T: Table<Schema = S>>(&mut self, tmp: TmpTable) -> Expr<'inner, S, T> {
43 let tmp_string = tmp.into_iden();
44 self.join_inner(JoinableTable::Normal(tmp_string))
45 }
46
47 fn join_inner<T: Table<Schema = S>>(&mut self, name: JoinableTable) -> Expr<'inner, S, T> {
48 let table_idx = self.ast.tables.len();
49 Rc::make_mut(&mut self.ast).tables.push(name);
50 Expr::new(Join::new(MyTableRef {
51 scope_rc: self.ast.scope_rc.clone(),
52 idx: table_idx,
53 }))
54 }
55
56 pub fn filter(&mut self, prop: impl IntoExpr<'inner, S, Typ = bool>) {
63 let prop = prop.into_expr();
64 Rc::make_mut(&mut self.ast).filters.push(prop.inner);
65 }
66
67 pub fn filter_some<Typ: MyTyp>(
71 &mut self,
72 val: impl IntoExpr<'inner, S, Typ = Option<Typ>>,
73 ) -> Expr<'inner, S, Typ> {
74 let val = val.into_expr();
75 Rc::make_mut(&mut self.ast)
76 .filters
77 .push(val.is_some().inner);
78
79 Expr::adhoc(move |b| val.inner.build_expr(b))
80 }
81}