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
use expression::*;
use query_builder::{Query, AsQuery};
use query_source::QuerySource;
use types::NativeSqlType;

/// Sets the select clause of a query. If there was already a select clause, it
/// will be overridden. The expression passed to `select` must actually be valid
/// for the query (only contains columns from the target table, doesn't mix
/// aggregate + non-aggregate expressions, etc).
pub trait SelectDsl<
    Selection: Expression,
    Type: NativeSqlType = <Selection as Expression>::SqlType,
> {
    type Output: Query<SqlType=Type>;

    fn select(self, selection: Selection) -> Self::Output;
}

impl<T, Selection, Type> SelectDsl<Selection, Type> for T where
    Selection: Expression,
    Type: NativeSqlType,
    T: QuerySource + AsQuery,
    T::Query: SelectDsl<Selection, Type>,
{
    type Output = <T::Query as SelectDsl<Selection, Type>>::Output;

    fn select(self, selection: Selection) -> Self::Output {
        self.as_query().select(selection)
    }
}

#[doc(hidden)]
pub trait SelectSqlDsl: Sized {
    fn select_sql<A>(self, columns: &str)
        -> <Self as SelectDsl<SqlLiteral<A>>>::Output where
        A: NativeSqlType,
        Self: SelectDsl<SqlLiteral<A>>,
    {
        self.select_sql_inner(columns)
    }

    fn select_sql_inner<A, S>(self, columns: S)
        -> <Self as SelectDsl<SqlLiteral<A>>>::Output where
        A: NativeSqlType,
        S: Into<String>,
        Self: SelectDsl<SqlLiteral<A>>,
    {
        self.select(SqlLiteral::new(columns.into()))
    }
}

impl<T> SelectSqlDsl for T {}