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
85
86
87
use std::fmt::Write;

/**
Trait representing a column builder.
*/
pub trait SelectColumn {
    /**
    Build the column selector in the provided String.
    */
    fn build(&self, s: &mut String);
}

/**
Representation of a select identifier.

This is due to the presence of join expressions and some reserved keywords in postgres.
 */
#[derive(Debug, Clone, Copy)]
pub struct SelectColumnData<'until_build> {
    /// Optional name of the table
    pub table_name: Option<&'until_build str>,
    /// Name of the column
    pub column_name: &'until_build str,
    /// Optional alias to set for the column
    pub select_alias: Option<&'until_build str>,
}

/**
Representation of the column selector and implementation of the [SelectColumn] trait.

Should only be constructed via [DBImpl::select_column].
 */
#[derive(Clone, Debug)]
pub enum SelectColumnImpl<'until_build> {
    /// SQLite representation of a column selector expression.
    #[cfg(feature = "sqlite")]
    SQLite(SelectColumnData<'until_build>),
    /// MySQL representation of a column selector expression.
    #[cfg(feature = "mysql")]
    MySQL(SelectColumnData<'until_build>),
    /// Postgres representation of a column selector expression.
    #[cfg(feature = "postgres")]
    Postgres(SelectColumnData<'until_build>),
}

impl<'until_build> SelectColumn for SelectColumnImpl<'until_build> {
    fn build(&self, s: &mut String) {
        match self {
            #[cfg(feature = "sqlite")]
            SelectColumnImpl::SQLite(d) => {
                if let Some(table_name) = d.table_name {
                    write!(s, "{}.", table_name).unwrap();
                }

                write!(s, "{}", d.column_name).unwrap();

                if let Some(alias) = d.select_alias {
                    write!(s, " AS {}", alias).unwrap();
                }
            }
            #[cfg(feature = "mysql")]
            SelectColumnImpl::MySQL(d) => {
                if let Some(table_name) = d.table_name {
                    write!(s, "{}.", table_name).unwrap();
                }

                write!(s, "{}", d.column_name).unwrap();

                if let Some(alias) = d.select_alias {
                    write!(s, " AS {}", alias).unwrap();
                }
            }
            #[cfg(feature = "postgres")]
            SelectColumnImpl::Postgres(d) => {
                if let Some(table_name) = d.table_name {
                    write!(s, "\"{}\".", table_name).unwrap();
                }

                write!(s, "{}", d.column_name).unwrap();

                if let Some(alias) = d.select_alias {
                    write!(s, " AS {}", alias).unwrap();
                }
            }
        }
    }
}