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
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use expression::{Expression, NonAggregate};
use query_builder::AsQuery;
use query_source::filter::FilteredQuerySource;
use query_source::{Table, InnerJoinSource, LeftOuterJoinSource};
use types::Bool;

/// Adds to the `WHERE` clause of a query. If there is already a `WHERE` clause,
/// the result will be `old AND new`. This is automatically implemented for the
/// various query builder types.
///
/// # Example:
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("src/doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #     }
/// # }
/// #
/// # fn main() {
/// #     use self::users::dsl::*;
/// #     let connection = establish_connection();
/// let seans_id = users.filter(name.eq("Sean")).select(id)
///     .first(&connection);
/// assert_eq!(Ok(1), seans_id);
/// let tess_id = users.filter(name.eq("Tess")).select(id)
///     .first(&connection);
/// assert_eq!(Ok(2), tess_id);
/// # }
/// ```
pub trait FilterDsl<Predicate>: AsQuery {
    type Output: AsQuery<SqlType=Self::SqlType>;

    fn filter(self, predicate: Predicate) -> Self::Output;
}

pub trait NotFiltered {
}

impl<T, Predicate, ST> FilterDsl<Predicate> for T where
    Predicate: Expression<SqlType=Bool> + NonAggregate,
    FilteredQuerySource<T, Predicate>: AsQuery<SqlType=ST>,
    T: AsQuery<SqlType=ST> + NotFiltered,
{
    type Output = FilteredQuerySource<Self, Predicate>;

    fn filter(self, predicate: Predicate) -> Self::Output {
        FilteredQuerySource::new(self, predicate)
    }
}

impl<T: Table> NotFiltered for T {}
impl<Left, Right> NotFiltered for InnerJoinSource<Left, Right> {}
impl<Left, Right> NotFiltered for LeftOuterJoinSource<Left, Right> {}

use expression::AsExpression;
use expression::expression_methods::*;
use expression::helper_types::Eq;
use helper_types::FindBy;

/// Attempts to find a single record from the given table by primary key.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("src/doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #     }
/// # }
/// #
/// # fn main() {
/// #     use self::users::dsl::*;
/// #     use diesel::result::Error::NotFound;
/// #     let connection = establish_connection();
/// let sean = (1, "Sean".to_string());
/// let tess = (2, "Tess".to_string());
/// assert_eq!(Ok(sean), users.find(1).first(&connection));
/// assert_eq!(Ok(tess), users.find(2).first(&connection));
/// assert_eq!(Err::<(i32, String), _>(NotFound), users.find(3).first(&connection));
/// # }
/// ```
pub trait FindDsl<PK>: AsQuery {
    type Output: AsQuery<SqlType=Self::SqlType>;

    fn find(self, id: PK) -> Self::Output;
}

impl<T, PK> FindDsl<PK> for T where
    T: Table + FilterDsl<Eq<<T as Table>::PrimaryKey, PK>>,
    PK: AsExpression<<T::PrimaryKey as Expression>::SqlType>,
{
    type Output = FindBy<Self, T::PrimaryKey, PK>;

    fn find(self, id: PK) -> Self::Output {
        let primary_key = self.primary_key();
        self.filter(primary_key.eq(id))
    }
}