typed_sql/query/select/
join.rs1use super::SelectStatement;
2use crate::query::select::WildCard;
3use crate::query::Predicate;
4use crate::Table;
5use std::marker::PhantomData;
6
7pub struct Inner;
8
9pub trait JoinKind {
10 const KIND: &'static str;
11}
12
13impl JoinKind for Inner {
14 const KIND: &'static str = "INNER";
15}
16
17pub trait Join<P> {
48 type Table: Table;
49 type Fields: Default;
50 type Join: JoinSelect;
51
52 fn join<F>(f: F) -> Self::Join
53 where
54 F: FnOnce(Self::Fields) -> Self::Join,
55 {
56 f(Default::default())
57 }
58}
59
60pub trait JoinSelect {
61 type Table: Table;
62 type Fields: Default;
63
64 fn write_join_select(&self, sql: &mut String);
65
66 fn select(self) -> SelectStatement<Self, WildCard>
67 where
68 Self: Sized,
69 {
70 SelectStatement::new(self, WildCard)
71 }
72}
73
74pub struct Joined<P, K, T> {
75 predicate: P,
76 _kind: PhantomData<K>,
77 _table: PhantomData<T>,
78}
79
80impl<P, K, T> Joined<P, K, T>
81where
82 P: Predicate,
83 K: JoinKind,
84 T: Table,
85{
86 pub fn new(predicate: P) -> Self {
87 Self {
88 predicate,
89 _kind: PhantomData,
90 _table: PhantomData,
91 }
92 }
93
94 pub fn write_join(&self, sql: &mut String) {
95 sql.push(' ');
96 sql.push_str(K::KIND);
97 sql.push_str(" JOIN ");
98 sql.push_str(T::NAME);
99 sql.push_str(" ON ");
100 self.predicate.write_predicate(sql);
101 }
102}