1use std::{fmt::Debug, marker::PhantomData};
2
3use sea_query::Alias;
4
5use crate::{
6 Expr, IntoExpr, Table,
7 alias::MyAlias,
8 value::{MyTableRef, Typed, ValueBuilder},
9};
10
11pub(crate) struct Join<T> {
15 pub(crate) table_idx: MyTableRef,
16 pub(crate) _p: PhantomData<T>,
17}
18
19impl<T> Join<T> {
20 pub(crate) fn new(table_idx: MyTableRef) -> Self {
21 Self {
22 table_idx,
23 _p: PhantomData,
24 }
25 }
26}
27
28impl<T: Table> Typed for Join<T> {
29 type Typ = T;
30 fn build_expr(&self, b: &mut ValueBuilder) -> sea_query::Expr {
31 sea_query::Expr::col((self.build_table(b), Alias::new(T::ID))).into()
32 }
33 fn maybe_optional(&self) -> bool {
34 false }
36
37 fn build_table(&self, b: &mut ValueBuilder) -> MyAlias {
38 b.get_table::<T>(self.table_idx.clone())
39 }
40}
41
42pub struct TableRow<T: Table> {
46 pub(crate) _local: PhantomData<*const ()>,
47 pub(crate) inner: TableRowInner<T>,
48}
49
50impl<T: Table> Eq for TableRow<T> {}
51
52impl<T: Table> PartialOrd for TableRow<T> {
53 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
54 Some(self.cmp(other))
55 }
56}
57
58impl<T: Table> Ord for TableRow<T> {
59 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
60 self.inner.idx.cmp(&other.inner.idx)
61 }
62}
63
64pub(crate) struct TableRowInner<T> {
65 pub(crate) _p: PhantomData<T>,
66 pub(crate) idx: i64,
67}
68
69impl<T: Table> PartialEq for TableRow<T> {
70 fn eq(&self, other: &Self) -> bool {
71 self.inner.idx == other.inner.idx
72 }
73}
74
75impl<T: Table> Debug for TableRow<T> {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 write!(f, "db_{}", self.inner.idx)
78 }
79}
80
81impl<T: Table> Clone for TableRow<T> {
82 fn clone(&self) -> Self {
83 *self
84 }
85}
86
87impl<T: Table> Copy for TableRow<T> {}
88
89impl<T> Clone for TableRowInner<T> {
90 fn clone(&self) -> Self {
91 *self
92 }
93}
94impl<T> Copy for TableRowInner<T> {}
95
96impl<T: Table> From<TableRow<T>> for sea_query::Value {
97 fn from(value: TableRow<T>) -> Self {
98 value.inner.idx.into()
99 }
100}
101
102impl<T: Table> Typed for TableRowInner<T> {
103 type Typ = T;
104 fn build_expr(&self, _: &mut ValueBuilder) -> sea_query::Expr {
105 sea_query::Expr::val(self.idx).into()
106 }
107 fn maybe_optional(&self) -> bool {
108 false
109 }
110}
111
112impl<'column, S, T: Table> IntoExpr<'column, S> for TableRow<T> {
114 type Typ = T;
115 fn into_expr(self) -> Expr<'static, S, Self::Typ> {
116 Expr::new(self.inner)
117 }
118}
119
120impl<T: Table> rusqlite::ToSql for TableRow<T> {
123 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
124 self.inner.idx.to_sql()
125 }
126}