1use std::marker::PhantomData;
2
3use sea_query::{Expr, SimpleExpr};
4
5use crate::{
6    ast::MySelect,
7    db::Join,
8    value::{operations::Assume, IntoColumn},
9    Column, Table,
10};
11
12pub struct Rows<'inner, S> {
20    pub(crate) phantom: PhantomData<fn(&'inner S) -> &'inner S>,
22    pub(crate) ast: MySelect,
23}
24
25impl<'inner, S> Rows<'inner, S> {
26    pub fn join<T: Table<Schema = S>>(&mut self) -> Column<'inner, S, T> {
33        let alias = self.ast.scope.new_alias();
34        self.ast.tables.push((T::NAME.to_owned(), alias));
35        IntoColumn::into_column(Join::new(alias))
36    }
37
38    pub(crate) fn join_custom<T: Table>(&mut self, t: T) -> Join<'inner, T> {
39        let alias = self.ast.scope.new_alias();
40        self.ast.tables.push((t.name(), alias));
41        Join::new(alias)
42    }
43
44    pub fn filter(&mut self, prop: impl IntoColumn<'inner, S, Typ = bool>) {
51        self.filter_private(prop.build_expr(self.ast.builder()));
52    }
53
54    fn filter_private(&mut self, prop: SimpleExpr) {
55        self.ast.filters.push(Box::new(prop));
56    }
57
58    pub fn filter_some<Typ>(
62        &mut self,
63        val: impl IntoColumn<'inner, S, Typ = Option<Typ>>,
64    ) -> Column<'inner, S, Typ> {
65        self.filter_private(Expr::expr(val.build_expr(self.ast.builder())).is_not_null());
66        Assume(val).into_column()
67    }
68}