Skip to content

Commit aa0aef1

Browse files
committed
Added method with as a postgreql syntax
1 parent 10604fe commit aa0aef1

File tree

8 files changed

+873
-361
lines changed

8 files changed

+873
-361
lines changed

src/behavior.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ where
1717
.map(|item| item.1.clone())
1818
.collect::<Vec<_>>()
1919
}
20-
21-
pub trait BuilderInner<'a, T> {
20+
pub trait Concat {
2221
fn concat(&self, fmts: &fmt::Formatter) -> String;
22+
}
23+
24+
pub trait Query: Concat {}
2325

26+
pub trait Raw<'a, T>: Concat {
2427
fn _raw(&self) -> &Vec<String>;
2528

2629
fn _raw_before(&self) -> &Vec<(T, String)>;

src/delete.rs

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
2-
behavior::{push_unique, BuilderInner},
2+
behavior::{push_unique, Concat, Query, Raw},
33
fmt,
44
structure::{DeleteBuilder, DeleteClause},
55
};
6+
use std::sync::Arc;
67

78
impl<'a> DeleteBuilder<'a> {
89
/// The same as `where_clause` method, useful to write more idiomatic SQL query
@@ -168,35 +169,35 @@ impl<'a> DeleteBuilder<'a> {
168169
push_unique(&mut self._where, condition.trim().to_owned());
169170
self
170171
}
172+
173+
/// The with clause, this method can be used enabling the feature flag `postgresql`
174+
#[cfg(feature = "postgresql")]
175+
pub fn with(mut self, name: &'a str, query: impl Query + 'static) -> Self {
176+
self._with.push((name.trim(), Arc::new(query)));
177+
self
178+
}
171179
}
172180

173-
impl BuilderInner<'_, DeleteClause> for DeleteBuilder<'_> {
181+
impl Query for DeleteBuilder<'_> {}
182+
183+
impl Concat for DeleteBuilder<'_> {
174184
fn concat(&self, fmts: &fmt::Formatter) -> String {
175185
let mut query = "".to_owned();
176186

177187
query = self.concat_raw(query, &fmts);
188+
#[cfg(feature = "postgresql")]
189+
{
190+
query = self.concat_with(query, &fmts);
191+
}
178192
query = self.concat_delete_from(query, &fmts);
179193
query = self.concat_where(query, &fmts);
180-
181194
#[cfg(feature = "postgresql")]
182195
{
183196
query = self.concat_returning(query, &fmts);
184197
}
185198

186199
query.trim_end().to_owned()
187200
}
188-
189-
fn _raw(&self) -> &Vec<String> {
190-
&self._raw
191-
}
192-
193-
fn _raw_after(&self) -> &Vec<(DeleteClause, String)> {
194-
&self._raw_after
195-
}
196-
197-
fn _raw_before(&self) -> &Vec<(DeleteClause, String)> {
198-
&self._raw_before
199-
}
200201
}
201202

202203
impl DeleteBuilder<'_> {
@@ -236,15 +237,61 @@ impl DeleteBuilder<'_> {
236237

237238
self.concat_raw_before_after(DeleteClause::Returning, query, fmts, sql)
238239
}
240+
241+
#[cfg(feature = "postgresql")]
242+
fn concat_with(&self, query: String, fmts: &fmt::Formatter) -> String {
243+
let fmt::Formatter {
244+
comma,
245+
lb,
246+
indent,
247+
space,
248+
} = fmts;
249+
let sql = if self._with.is_empty() == false {
250+
let with = self._with.iter().fold("".to_owned(), |acc, item| {
251+
let (name, query) = item;
252+
let inner_lb = format!("{lb}{indent}");
253+
let inner_fmts = fmt::Formatter {
254+
comma,
255+
lb: inner_lb.as_str(),
256+
indent,
257+
space,
258+
};
259+
let query_string = query.concat(&inner_fmts);
260+
261+
format!("{acc}{name}{space}AS{space}({lb}{indent}{query_string}{lb}){comma}")
262+
});
263+
let with = &with[..with.len() - comma.len()];
264+
265+
format!("WITH{space}{with}{space}{lb}")
266+
} else {
267+
"".to_owned()
268+
};
269+
270+
self.concat_raw_before_after(DeleteClause::With, query, fmts, sql)
271+
}
272+
}
273+
274+
impl Raw<'_, DeleteClause> for DeleteBuilder<'_> {
275+
fn _raw(&self) -> &Vec<String> {
276+
&self._raw
277+
}
278+
279+
fn _raw_after(&self) -> &Vec<(DeleteClause, String)> {
280+
&self._raw_after
281+
}
282+
283+
fn _raw_before(&self) -> &Vec<(DeleteClause, String)> {
284+
&self._raw_before
285+
}
239286
}
240287

241-
impl<'a> std::fmt::Display for DeleteBuilder<'a> {
288+
impl std::fmt::Display for DeleteBuilder<'_> {
242289
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243290
write!(f, "{}", self.as_string())
244291
}
245292
}
246293

247-
impl<'a> std::fmt::Debug for DeleteBuilder<'a> {
294+
impl std::fmt::Debug for DeleteBuilder<'_> {
248295
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249296
let fmts = fmt::Formatter::multi_line();
250297
write!(f, "{}", fmt::colorize(self.concat(&fmts)))

src/insert.rs

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
2-
behavior::{push_unique, BuilderInner},
2+
behavior::{push_unique, Concat, Query, Raw},
33
fmt,
44
structure::{InsertBuilder, InsertClause, SelectBuilder},
55
};
6+
use std::sync::Arc;
67

78
impl<'a> InsertBuilder<'a> {
89
/// Gets the current state of the InsertBuilder and returns it as string
@@ -182,13 +183,26 @@ impl<'a> InsertBuilder<'a> {
182183
push_unique(&mut self._values, value.trim().to_owned());
183184
self
184185
}
186+
187+
/// The with clause, this method can be used enabling the feature flag `postgresql`
188+
#[cfg(feature = "postgresql")]
189+
pub fn with(mut self, name: &'a str, query: impl Query + 'static) -> Self {
190+
self._with.push((name.trim(), Arc::new(query)));
191+
self
192+
}
185193
}
186194

187-
impl BuilderInner<'_, InsertClause> for InsertBuilder<'_> {
195+
impl Query for InsertBuilder<'_> {}
196+
197+
impl Concat for InsertBuilder<'_> {
188198
fn concat(&self, fmts: &fmt::Formatter) -> String {
189199
let mut query = "".to_owned();
190200

191201
query = self.concat_raw(query, &fmts);
202+
#[cfg(feature = "postgresql")]
203+
{
204+
query = self.concat_with(query, &fmts);
205+
}
192206
query = self.concat_insert_into(query, &fmts);
193207
query = self.concat_overriding(query, &fmts);
194208
query = self.concat_values(query, &fmts);
@@ -201,18 +215,6 @@ impl BuilderInner<'_, InsertClause> for InsertBuilder<'_> {
201215

202216
query.trim_end().to_owned()
203217
}
204-
205-
fn _raw(&self) -> &Vec<String> {
206-
&self._raw
207-
}
208-
209-
fn _raw_after(&self) -> &Vec<(InsertClause, String)> {
210-
&self._raw_after
211-
}
212-
213-
fn _raw_before(&self) -> &Vec<(InsertClause, String)> {
214-
&self._raw_before
215-
}
216218
}
217219

218220
impl InsertBuilder<'_> {
@@ -276,15 +278,61 @@ impl InsertBuilder<'_> {
276278

277279
self.concat_raw_before_after(InsertClause::Values, query, fmts, sql)
278280
}
281+
282+
#[cfg(feature = "postgresql")]
283+
fn concat_with(&self, query: String, fmts: &fmt::Formatter) -> String {
284+
let fmt::Formatter {
285+
comma,
286+
lb,
287+
indent,
288+
space,
289+
} = fmts;
290+
let sql = if self._with.is_empty() == false {
291+
let with = self._with.iter().fold("".to_owned(), |acc, item| {
292+
let (name, query) = item;
293+
let inner_lb = format!("{lb}{indent}");
294+
let inner_fmts = fmt::Formatter {
295+
comma,
296+
lb: inner_lb.as_str(),
297+
indent,
298+
space,
299+
};
300+
let query_string = query.concat(&inner_fmts);
301+
302+
format!("{acc}{name}{space}AS{space}({lb}{indent}{query_string}{lb}){comma}")
303+
});
304+
let with = &with[..with.len() - comma.len()];
305+
306+
format!("WITH{space}{with}{space}{lb}")
307+
} else {
308+
"".to_owned()
309+
};
310+
311+
self.concat_raw_before_after(InsertClause::With, query, fmts, sql)
312+
}
313+
}
314+
315+
impl Raw<'_, InsertClause> for InsertBuilder<'_> {
316+
fn _raw(&self) -> &Vec<String> {
317+
&self._raw
318+
}
319+
320+
fn _raw_after(&self) -> &Vec<(InsertClause, String)> {
321+
&self._raw_after
322+
}
323+
324+
fn _raw_before(&self) -> &Vec<(InsertClause, String)> {
325+
&self._raw_before
326+
}
279327
}
280328

281-
impl<'a> std::fmt::Display for InsertBuilder<'a> {
329+
impl std::fmt::Display for InsertBuilder<'_> {
282330
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283331
write!(f, "{}", self.as_string())
284332
}
285333
}
286334

287-
impl<'a> std::fmt::Debug for InsertBuilder<'a> {
335+
impl std::fmt::Debug for InsertBuilder<'_> {
288336
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289337
let fmts = fmt::Formatter::multi_line();
290338
write!(f, "{}", fmt::colorize(self.concat(&fmts)))

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod select;
88
mod structure;
99
mod update;
1010

11+
pub use crate::behavior::Query;
1112
pub use crate::structure::{
1213
DeleteBuilder, DeleteClause, InsertBuilder, InsertClause, SelectBuilder, SelectClause, UpdateBuilder, UpdateClause,
1314
};

src/select.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
2-
behavior::{push_unique, raw_queries, BuilderInner},
2+
behavior::{push_unique, raw_queries, Concat, Query, Raw},
33
fmt,
44
structure::{Combinator, SelectBuilder, SelectClause},
55
};
6+
use std::sync::Arc;
67

78
impl<'a> SelectBuilder<'a> {
89
/// The same as `where_clause` method, useful to write more idiomatic SQL query
@@ -287,23 +288,23 @@ impl<'a> SelectBuilder<'a> {
287288

288289
/// The with clause, this method can be used enabling the feature flag `postgresql`
289290
#[cfg(feature = "postgresql")]
290-
pub fn with(mut self, name: &'a str, select: Self) -> Self {
291-
self._with.push((name.trim(), select));
291+
pub fn with(mut self, name: &'a str, query: impl Query + 'static) -> Self {
292+
self._with.push((name.trim(), Arc::new(query)));
292293
self
293294
}
294295
}
295296

296-
impl BuilderInner<'_, SelectClause> for SelectBuilder<'_> {
297+
impl Query for SelectBuilder<'_> {}
298+
299+
impl Concat for SelectBuilder<'_> {
297300
fn concat(&self, fmts: &fmt::Formatter) -> String {
298301
let mut query = "".to_owned();
299302

300303
query = self.concat_raw(query, &fmts);
301-
302304
#[cfg(feature = "postgresql")]
303305
{
304306
query = self.concat_with(query, &fmts);
305307
}
306-
307308
query = self.concat_select(query, &fmts);
308309
query = self.concat_from(query, &fmts);
309310
query = self.concat_join(query, &fmts);
@@ -319,18 +320,6 @@ impl BuilderInner<'_, SelectClause> for SelectBuilder<'_> {
319320

320321
query.trim_end().to_owned()
321322
}
322-
323-
fn _raw(&self) -> &Vec<String> {
324-
&self._raw
325-
}
326-
327-
fn _raw_after(&self) -> &Vec<(SelectClause, String)> {
328-
&self._raw_after
329-
}
330-
331-
fn _raw_before(&self) -> &Vec<(SelectClause, String)> {
332-
&self._raw_before
333-
}
334323
}
335324

336325
impl SelectBuilder<'_> {
@@ -491,21 +480,21 @@ impl SelectBuilder<'_> {
491480
} = fmts;
492481
let sql = if self._with.is_empty() == false {
493482
let with = self._with.iter().fold("".to_owned(), |acc, item| {
494-
let (name, select) = item;
483+
let (name, query) = item;
495484
let inner_lb = format!("{lb}{indent}");
496485
let inner_fmts = fmt::Formatter {
497486
comma,
498487
lb: inner_lb.as_str(),
499488
indent,
500489
space,
501490
};
502-
let select_string = select.concat(&inner_fmts);
491+
let query_string = query.concat(&inner_fmts);
503492

504-
format!("{acc}{name} AS ({lb}{indent}{select_string}{lb}){comma}")
493+
format!("{acc}{name}{space}AS{space}({lb}{indent}{query_string}{lb}){comma}")
505494
});
506495
let with = &with[..with.len() - comma.len()];
507496

508-
format!("WITH {with}{space}{lb}")
497+
format!("WITH{space}{with}{space}{lb}")
509498
} else {
510499
"".to_owned()
511500
};
@@ -514,13 +503,27 @@ impl SelectBuilder<'_> {
514503
}
515504
}
516505

517-
impl<'a> std::fmt::Display for SelectBuilder<'a> {
506+
impl Raw<'_, SelectClause> for SelectBuilder<'_> {
507+
fn _raw(&self) -> &Vec<String> {
508+
&self._raw
509+
}
510+
511+
fn _raw_after(&self) -> &Vec<(SelectClause, String)> {
512+
&self._raw_after
513+
}
514+
515+
fn _raw_before(&self) -> &Vec<(SelectClause, String)> {
516+
&self._raw_before
517+
}
518+
}
519+
520+
impl std::fmt::Display for SelectBuilder<'_> {
518521
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
519522
write!(f, "{}", self.as_string())
520523
}
521524
}
522525

523-
impl<'a> std::fmt::Debug for SelectBuilder<'a> {
526+
impl std::fmt::Debug for SelectBuilder<'_> {
524527
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
525528
let fmts = fmt::Formatter::multi_line();
526529
write!(f, "{}", fmt::colorize(self.concat(&fmts)))

0 commit comments

Comments
 (0)