1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use crate::ast::{Query, Select};
use std::fmt;
#[derive(Debug, PartialEq, Clone, Copy)]
pub(crate) enum UnionType {
All,
Distinct,
}
impl fmt::Display for UnionType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UnionType::All => write!(f, "UNION ALL"),
UnionType::Distinct => write!(f, "UNION"),
}
}
}
/// A builder for a `UNION`s over multiple `SELECT` statements.
#[derive(Debug, PartialEq, Clone, Default)]
pub struct Union<'a> {
pub(crate) selects: Vec<Select<'a>>,
pub(crate) types: Vec<UnionType>,
}
impl<'a> From<Union<'a>> for Query<'a> {
#[inline]
fn from(ua: Union<'a>) -> Self {
Query::Union(ua)
}
}
impl<'a> Union<'a> {
pub fn new(q: Select<'a>) -> Self {
Self {
selects: vec![q],
types: Vec::new(),
}
}
/// Creates a union with previous selection and the given `SELECT`
/// statement, allowing duplicates.
///
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
/// let s1 = Select::default().value(1);
/// let s2 = Select::default().value(2);
/// let (sql, params) = Sqlite::build(Union::new(s1).all(s2));
///
/// assert_eq!("(SELECT ?) UNION ALL (SELECT ?)", sql);
///
/// assert_eq!(vec![
/// ParameterizedValue::from(1),
/// ParameterizedValue::from(2)
/// ], params);
/// ```
pub fn all(mut self, q: Select<'a>) -> Self {
self.selects.push(q);
self.types.push(UnionType::All);
self
}
/// Creates a union with previous selection and the given `SELECT`
/// statement, selecting only distinct values.
///
/// ```rust
/// # use quaint::{ast::*, visitor::{Visitor, Sqlite}};
/// let s1 = Select::default().value(1);
/// let s2 = Select::default().value(2);
/// let (sql, params) = Sqlite::build(Union::new(s1).distinct(s2));
///
/// assert_eq!("(SELECT ?) UNION (SELECT ?)", sql);
///
/// assert_eq!(vec![
/// ParameterizedValue::from(1),
/// ParameterizedValue::from(2)
/// ], params);
/// ```
pub fn distinct(mut self, q: Select<'a>) -> Self {
self.selects.push(q);
self.types.push(UnionType::Distinct);
self
}
}