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
use backend::Backend; use expression::{Expression, SelectableExpression}; use query_builder::*; use result::QueryResult; use types::{Foldable, HasSqlType}; macro_rules! fold_function { ($fn_name:ident, $type_name:ident, $operator:expr, $docs:expr) => { #[doc=$docs] pub fn $fn_name<ST, T>(t: T) -> $type_name<T> where ST: Foldable, T: Expression<SqlType=ST>, { $type_name { target: t, } } #[derive(Debug, Clone, Copy)] pub struct $type_name<T> { target: T, } impl<ST, T> Expression for $type_name<T> where ST: Foldable, T: Expression<SqlType=ST> { type SqlType = <<T as Expression>::SqlType as Foldable>::$type_name; } impl<T, DB> QueryFragment<DB> for $type_name<T> where T: Expression + QueryFragment<DB>, DB: Backend + HasSqlType<T::SqlType>, { fn to_sql(&self, out: &mut DB::QueryBuilder) -> BuildQueryResult { out.push_sql(concat!($operator, "(")); try!(self.target.to_sql(out)); out.push_sql(")"); Ok(()) } fn collect_binds(&self, out: &mut DB::BindCollector) -> QueryResult<()> { try!(self.target.collect_binds(out)); Ok(()) } fn is_safe_to_cache_prepared(&self) -> bool { self.target.is_safe_to_cache_prepared() } } impl_query_id!($type_name<T>); impl<T, QS> SelectableExpression<QS> for $type_name<T> where $type_name<T>: Expression, T: SelectableExpression<QS>, { type SqlTypeForSelect = Self::SqlType; } } } fold_function!(sum, Sum, "SUM", "Represents a SQL `SUM` function. This function can only take types which are Foldable."); fold_function!(avg, Avg, "AVG", "Represents a SQL `AVG` function. This function can only take types which are Foldable.");