@@ -7,141 +7,85 @@ use crate::ordering::{OrderByEntry, Ordering};
77use crate :: select_column:: { SelectColumn , SelectColumnImpl } ;
88use crate :: { DBImpl , Value } ;
99
10- /**
11- Trait representing a select builder.
12- */
13- pub trait Select < ' until_build , ' post_query > {
14- /**
15- Set a limit to the resulting rows.
16- */
17- fn limit_clause ( self , limit : LimitClause ) -> Self ;
18-
19- /**
20- Only retrieve distinct rows.
21- */
22- fn distinct ( self ) -> Self ;
23-
24- /**
25- Set a where clause to the query.
26- */
27- fn where_clause ( self , where_clause : & ' until_build Condition < ' post_query > ) -> Self ;
28-
29- /**
30- Build the select query
31- */
32- fn build ( self ) -> ( String , Vec < Value < ' post_query > > ) ;
33- }
34-
35- /**
36- Representation of the data of a SELECT operation in SQL.
37- */
10+ /// Select builder
11+ ///
12+ /// Can be constructed via [`DBImpl::select`]
3813#[ derive( Debug ) ]
39- pub struct SelectData < ' until_build , ' post_query > {
14+ pub struct Select < ' until_build , ' post_query > {
15+ // Set on construction
16+ pub ( crate ) db_impl : DBImpl ,
4017 pub ( crate ) resulting_columns : & ' until_build [ SelectColumnImpl < ' until_build > ] ,
41- pub ( crate ) limit : Option < u64 > ,
42- pub ( crate ) offset : Option < u64 > ,
4318 pub ( crate ) from_clause : & ' until_build str ,
44- pub ( crate ) where_clause : Option < & ' until_build Condition < ' post_query > > ,
45- pub ( crate ) distinct : bool ,
46- pub ( crate ) lookup : Vec < Value < ' post_query > > ,
4719 pub ( crate ) join_tables : & ' until_build [ JoinTableImpl < ' until_build , ' post_query > ] ,
48- pub ( crate ) order_by_clause : & ' until_build [ OrderByEntry < ' until_build > ] ,
49- }
50-
51- /**
52- Implementation of the [Select] trait for the different implementations.
20+ pub ( crate ) where_clause : Option < & ' until_build Condition < ' post_query > > ,
5321
54- Should only be constructed via [DBImpl::select]
55- */
56- #[ derive( Debug ) ]
57- pub enum SelectImpl < ' until_build , ' post_query > {
58- /**
59- SQLite representation of the SELECT operation.
60- */
61- #[ cfg( feature = "sqlite" ) ]
62- SQLite ( SelectData < ' until_build , ' post_query > ) ,
63- /**
64- Postgres representation of the SELECT operation.
65- */
66- #[ cfg( feature = "postgres" ) ]
67- Postgres ( SelectData < ' until_build , ' post_query > ) ,
22+ // Set by builder
23+ pub ( crate ) order_by_clause : & ' until_build [ OrderByEntry < ' until_build > ] ,
24+ pub ( crate ) distinct : bool ,
25+ pub ( crate ) limit : Option < u64 > ,
26+ pub ( crate ) offset : Option < u64 > ,
6827}
6928
70- impl < ' until_build , ' post_build > Select < ' until_build , ' post_build >
71- for SelectImpl < ' until_build , ' post_build >
72- {
73- fn limit_clause ( mut self , limit : LimitClause ) -> Self {
74- match self {
75- #[ cfg( feature = "sqlite" ) ]
76- SelectImpl :: SQLite ( ref mut d) => {
77- d. limit = Some ( limit. limit ) ;
78- d. offset = limit. offset ;
79- }
80- #[ cfg( feature = "postgres" ) ]
81- SelectImpl :: Postgres ( ref mut d) => {
82- d. limit = Some ( limit. limit ) ;
83- d. offset = limit. offset ;
84- }
85- } ;
29+ impl < ' until_build , ' post_build > Select < ' until_build , ' post_build > {
30+ /// Set a limit to the resulting rows.
31+ pub fn limit_clause ( mut self , limit : LimitClause ) -> Self {
32+ self . limit = Some ( limit. limit ) ;
33+ self . offset = limit. offset ;
8634 self
8735 }
8836
89- fn distinct ( mut self ) -> Self {
90- match self {
91- #[ cfg( feature = "sqlite" ) ]
92- SelectImpl :: SQLite ( ref mut d) => d. distinct = true ,
93- #[ cfg( feature = "postgres" ) ]
94- SelectImpl :: Postgres ( ref mut d) => d. distinct = true ,
95- } ;
37+ /// Only retrieve distinct rows.
38+ pub fn distinct ( mut self ) -> Self {
39+ self . distinct = true ;
9640 self
9741 }
9842
99- fn where_clause ( mut self , where_clause : & ' until_build Condition < ' post_build > ) -> Self {
100- match self {
101- #[ cfg( feature = "sqlite" ) ]
102- SelectImpl :: SQLite ( ref mut d) => d. where_clause = Some ( where_clause) ,
103- #[ cfg( feature = "postgres" ) ]
104- SelectImpl :: Postgres ( ref mut d) => d. where_clause = Some ( where_clause) ,
105- } ;
43+ /// Set a where clause to the query.
44+ pub fn where_clause ( mut self , where_clause : & ' until_build Condition < ' post_build > ) -> Self {
45+ self . where_clause = Some ( where_clause) ;
10646 self
10747 }
10848
109- fn build ( self ) -> ( String , Vec < Value < ' post_build > > ) {
110- match self {
49+ /// Build the select query
50+ pub fn build ( self ) -> ( String , Vec < Value < ' post_build > > ) {
51+ let mut sql;
52+ let mut values = Vec :: new ( ) ;
53+
54+ match self . db_impl {
11155 #[ cfg( feature = "sqlite" ) ]
112- SelectImpl :: SQLite ( mut d ) => {
113- let mut s = format ! ( "SELECT{} " , if d . distinct { " DISTINCT" } else { "" } ) ;
56+ DBImpl :: SQLite => {
57+ sql = format ! ( "SELECT{} " , if self . distinct { " DISTINCT" } else { "" } ) ;
11458
115- let column_len = d . resulting_columns . len ( ) ;
116- for ( idx, column) in d . resulting_columns . iter ( ) . enumerate ( ) {
117- column. build ( & mut s ) ;
59+ let column_len = self . resulting_columns . len ( ) ;
60+ for ( idx, column) in self . resulting_columns . iter ( ) . enumerate ( ) {
61+ column. build ( & mut sql ) ;
11862
11963 if idx != column_len - 1 {
120- write ! ( s , ", " ) . unwrap ( ) ;
64+ write ! ( sql , ", " ) . unwrap ( ) ;
12165 }
12266 }
12367
124- write ! ( s , " FROM \" {}\" " , d . from_clause) . unwrap ( ) ;
68+ write ! ( sql , " FROM \" {}\" " , self . from_clause) . unwrap ( ) ;
12569
126- for x in d . join_tables {
127- write ! ( s , " " ) . unwrap ( ) ;
128- x. build ( & mut s , & mut d . lookup ) ;
70+ for x in self . join_tables {
71+ write ! ( sql , " " ) . unwrap ( ) ;
72+ x. build ( & mut sql , & mut values ) ;
12973 }
13074
131- if let Some ( c) = d . where_clause {
132- write ! ( s , " WHERE {}" , c. build( DBImpl :: SQLite , & mut d . lookup ) ) . unwrap ( )
75+ if let Some ( c) = self . where_clause {
76+ write ! ( sql , " WHERE {}" , c. build( DBImpl :: SQLite , & mut values ) ) . unwrap ( )
13377 } ;
13478
135- if !d . order_by_clause . is_empty ( ) {
136- write ! ( s , " ORDER BY " ) . unwrap ( ) ;
79+ if !self . order_by_clause . is_empty ( ) {
80+ write ! ( sql , " ORDER BY " ) . unwrap ( ) ;
13781
138- let order_by_len = d . order_by_clause . len ( ) ;
139- for ( idx, entry) in d . order_by_clause . iter ( ) . enumerate ( ) {
82+ let order_by_len = self . order_by_clause . len ( ) ;
83+ for ( idx, entry) in self . order_by_clause . iter ( ) . enumerate ( ) {
14084 if let Some ( table_name) = entry. table_name {
141- write ! ( s , "{table_name}." ) . unwrap ( ) ;
85+ write ! ( sql , "{table_name}." ) . unwrap ( ) ;
14286 } ;
14387 write ! (
144- s ,
88+ sql ,
14589 "{}{}" ,
14690 entry. column_name,
14791 match entry. ordering {
@@ -152,56 +96,54 @@ impl<'until_build, 'post_build> Select<'until_build, 'post_build>
15296 . unwrap ( ) ;
15397
15498 if idx != order_by_len - 1 {
155- write ! ( s , ", " ) . unwrap ( ) ;
99+ write ! ( sql , ", " ) . unwrap ( ) ;
156100 }
157101 }
158102 } ;
159103
160- if let Some ( limit) = d . limit {
161- write ! ( s , " LIMIT {limit}" ) . unwrap ( ) ;
162- if let Some ( offset) = d . offset {
163- write ! ( s , " OFFSET {offset}" ) . unwrap ( ) ;
104+ if let Some ( limit) = self . limit {
105+ write ! ( sql , " LIMIT {limit}" ) . unwrap ( ) ;
106+ if let Some ( offset) = self . offset {
107+ write ! ( sql , " OFFSET {offset}" ) . unwrap ( ) ;
164108 }
165109 } ;
166110
167- write ! ( s, ";" ) . unwrap ( ) ;
168-
169- ( s, d. lookup )
111+ write ! ( sql, ";" ) . unwrap ( ) ;
170112 }
171113 #[ cfg( feature = "postgres" ) ]
172- SelectImpl :: Postgres ( mut d ) => {
173- let mut s = format ! ( "SELECT{} " , if d . distinct { " DISTINCT" } else { "" } ) ;
114+ DBImpl :: Postgres => {
115+ sql = format ! ( "SELECT{} " , if self . distinct { " DISTINCT" } else { "" } ) ;
174116
175- let column_len = d . resulting_columns . len ( ) ;
176- for ( idx, column) in d . resulting_columns . iter ( ) . enumerate ( ) {
177- column. build ( & mut s ) ;
117+ let column_len = self . resulting_columns . len ( ) ;
118+ for ( idx, column) in self . resulting_columns . iter ( ) . enumerate ( ) {
119+ column. build ( & mut sql ) ;
178120
179121 if idx != column_len - 1 {
180- write ! ( s , ", " ) . unwrap ( ) ;
122+ write ! ( sql , ", " ) . unwrap ( ) ;
181123 }
182124 }
183125
184- write ! ( s , " FROM \" {}\" " , d . from_clause) . unwrap ( ) ;
126+ write ! ( sql , " FROM \" {}\" " , self . from_clause) . unwrap ( ) ;
185127
186- for x in d . join_tables {
187- write ! ( s , " " ) . unwrap ( ) ;
188- x. build ( & mut s , & mut d . lookup ) ;
128+ for x in self . join_tables {
129+ write ! ( sql , " " ) . unwrap ( ) ;
130+ x. build ( & mut sql , & mut values ) ;
189131 }
190132
191- if let Some ( c) = d . where_clause {
192- write ! ( s , " WHERE {}" , c. build( DBImpl :: Postgres , & mut d . lookup ) ) . unwrap ( )
133+ if let Some ( c) = self . where_clause {
134+ write ! ( sql , " WHERE {}" , c. build( DBImpl :: Postgres , & mut values ) ) . unwrap ( )
193135 } ;
194136
195- if !d . order_by_clause . is_empty ( ) {
196- write ! ( s , " ORDER BY " ) . unwrap ( ) ;
137+ if !self . order_by_clause . is_empty ( ) {
138+ write ! ( sql , " ORDER BY " ) . unwrap ( ) ;
197139
198- let order_by_len = d . order_by_clause . len ( ) ;
199- for ( idx, entry) in d . order_by_clause . iter ( ) . enumerate ( ) {
140+ let order_by_len = self . order_by_clause . len ( ) ;
141+ for ( idx, entry) in self . order_by_clause . iter ( ) . enumerate ( ) {
200142 if let Some ( table_name) = entry. table_name {
201- write ! ( s , "\" {table_name}\" ." ) . unwrap ( ) ;
143+ write ! ( sql , "\" {table_name}\" ." ) . unwrap ( ) ;
202144 } ;
203145 write ! (
204- s ,
146+ sql ,
205147 "\" {}\" {}" ,
206148 entry. column_name,
207149 match entry. ordering {
@@ -212,22 +154,22 @@ impl<'until_build, 'post_build> Select<'until_build, 'post_build>
212154 . unwrap ( ) ;
213155
214156 if idx != order_by_len - 1 {
215- write ! ( s , ", " ) . unwrap ( ) ;
157+ write ! ( sql , ", " ) . unwrap ( ) ;
216158 }
217159 }
218160 } ;
219161
220- if let Some ( limit) = d . limit {
221- write ! ( s , " LIMIT {limit}" ) . unwrap ( ) ;
222- if let Some ( offset) = d . offset {
223- write ! ( s , " OFFSET {offset}" ) . unwrap ( ) ;
162+ if let Some ( limit) = self . limit {
163+ write ! ( sql , " LIMIT {limit}" ) . unwrap ( ) ;
164+ if let Some ( offset) = self . offset {
165+ write ! ( sql , " OFFSET {offset}" ) . unwrap ( ) ;
224166 }
225167 } ;
226168
227- write ! ( s, ";" ) . unwrap ( ) ;
228-
229- ( s, d. lookup )
169+ write ! ( sql, ";" ) . unwrap ( ) ;
230170 }
231171 }
172+
173+ ( sql, values)
232174 }
233175}
0 commit comments