Trait diesel::query_dsl::QueryDsl
[−]
[src]
pub trait QueryDsl: Sized { fn distinct(self) -> Distinct<Self>
where
Self: DistinctDsl, { ... } fn distinct_on<Expr>(self, expr: Expr) -> DistinctOn<Self, Expr>
where
Self: DistinctOnDsl<Expr>, { ... } fn select<Selection>(self, selection: Selection) -> Select<Self, Selection>
where
Selection: Expression,
Self: SelectDsl<Selection>, { ... } fn count(self) -> Select<Self, CountStar>
where
Self: SelectDsl<CountStar>, { ... } fn inner_join<Rhs>(self, rhs: Rhs) -> Self::Output
where
Self: JoinWithImplicitOnClause<Rhs, Inner>, { ... } fn left_outer_join<Rhs>(self, rhs: Rhs) -> Self::Output
where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>, { ... } fn left_join<Rhs>(self, rhs: Rhs) -> Self::Output
where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>, { ... } fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>
where
Self: FilterDsl<Predicate>, { ... } fn find<PK>(self, id: PK) -> Find<Self, PK>
where
Self: FindDsl<PK>, { ... } fn order<Expr>(self, expr: Expr) -> Order<Self, Expr>
where
Expr: Expression,
Self: OrderDsl<Expr>, { ... } fn limit(self, limit: i64) -> Limit<Self>
where
Self: LimitDsl, { ... } fn offset(self, offset: i64) -> Offset<Self>
where
Self: OffsetDsl, { ... } fn for_update(self) -> ForUpdate<Self>
where
Self: ForUpdateDsl, { ... } fn into_boxed<'a, DB>(self) -> IntoBoxed<'a, Self, DB>
where
DB: Backend,
Self: BoxedDsl<'a, DB>, { ... } }
Provided Methods
fn distinct(self) -> Distinct<Self> where
Self: DistinctDsl,
Self: DistinctDsl,
Adds the DISTINCT
keyword to a query.
Example
connection.execute("INSERT INTO users (name) VALUES ('Sean'), ('Sean'), ('Sean')") .unwrap(); let names = users.select(name).load(&connection); let distinct_names = users.select(name).distinct().load(&connection); let sean = String::from("Sean"); assert_eq!(Ok(vec![sean.clone(), sean.clone(), sean.clone()]), names); assert_eq!(Ok(vec![sean.clone()]), distinct_names);
fn distinct_on<Expr>(self, expr: Expr) -> DistinctOn<Self, Expr> where
Self: DistinctOnDsl<Expr>,
Self: DistinctOnDsl<Expr>,
Adds the DISTINCT ON
clause to a query.
Example
connection.execute("INSERT INTO animals (species, name, legs) VALUES ('dog', 'Jack', 4), ('dog', Null, 4), ('spider', Null, 8)") .unwrap(); let all_animals = animals.select((species, name, legs)).load(&connection); let distinct_animals = animals.select((species, name, legs)).distinct_on(species).load(&connection); assert_eq!(Ok(vec![Animal::new("dog", Some("Jack"), 4), Animal::new("dog", None, 4), Animal::new("spider", None, 8)]), all_animals); assert_eq!(Ok(vec![Animal::new("dog", Some("Jack"), 4), Animal::new("spider", None, 8)]), distinct_animals);
fn select<Selection>(self, selection: Selection) -> Select<Self, Selection> where
Selection: Expression,
Self: SelectDsl<Selection>,
Selection: Expression,
Self: SelectDsl<Selection>,
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).
fn count(self) -> Select<Self, CountStar> where
Self: SelectDsl<CountStar>,
Self: SelectDsl<CountStar>,
Get the count of a query. This is equivalent to .select(count_star())
Example
let count = users.count().get_result(&connection); assert_eq!(Ok(2), count);
fn inner_join<Rhs>(self, rhs: Rhs) -> Self::Output where
Self: JoinWithImplicitOnClause<Rhs, Inner>,
Self: JoinWithImplicitOnClause<Rhs, Inner>,
Join two tables using a SQL INNER JOIN
.
If you have invoked joinable!
for the two tables, you can pass that
table directly. Otherwise you will need to use .on
to specify the ON
clause.
You can join to as many tables as you'd like in a query, with the restriction that no table can appear in the query more than once. The reason for this restriction is that one of the appearances would require aliasing, and we do not currently have a fleshed out story for dealing with table aliases.
You may also need to call allow_tables_to_appear_in_same_query!
(particularly if
you see an unexpected error about AppearsInFromClause
). See the
documentation for allow_tables_to_appear_in_same_query!
for details.
Diesel expects multi-table joins to be semantically grouped based on the
relationships. For example, users.inner_join(posts.inner_join(comments))
is not the same as users.inner_join(posts).inner_join(comments)
. The first
would deserialize into (User, (Post, Comment))
and generate the following
SQL:
SELECT * FROM users
INNER JOIN posts ON posts.user_id = users.id
INNER JOIN comments ON comments.post_id = posts.id
While the second query would deserialize into (User, Post, Comment)
and
generate the following SQL:
SELECT * FROM users
INNER JOIN posts ON posts.user_id = users.id
INNER JOIN comments ON comments.user_id = users.id
fn left_outer_join<Rhs>(self, rhs: Rhs) -> Self::Output where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Join two tables using a SQL LEFT OUTER JOIN
. The ON
clause is defined
via the associations API.
fn left_join<Rhs>(self, rhs: Rhs) -> Self::Output where
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Self: JoinWithImplicitOnClause<Rhs, LeftOuter>,
Alias for left_outer_join
fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate> where
Self: FilterDsl<Predicate>,
Self: FilterDsl<Predicate>,
Adds to the WHERE
clause of a query.
If there is already a WHERE
clause, the result will be old AND new
.
Example:
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);
fn find<PK>(self, id: PK) -> Find<Self, PK> where
Self: FindDsl<PK>,
Self: FindDsl<PK>,
Attempts to find a single record from the given table by primary key.
Example
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));
fn order<Expr>(self, expr: Expr) -> Order<Self, Expr> where
Expr: Expression,
Self: OrderDsl<Expr>,
Expr: Expression,
Self: OrderDsl<Expr>,
Sets the order clause of a query.
If there was already a order clause, it will be overridden. The
expression passed to order
must actually be valid for the query. See
also:
.desc()
and
.asc()
Ordering by multiple columns can be achieved by passing a tuple of those columns.
Examples
use self::users::dsl::{users, id, name}; let connection = establish_connection(); connection.execute("INSERT INTO users (name) VALUES ('Saul'), ('Steve'), ('Stan')").unwrap(); // load all users' names, ordered by their name descending let ordered_names: Vec<String> = users.select(name).order(name.desc()).load(&connection).unwrap(); assert_eq!(vec![String::from("Steve"), String::from("Stan"), String::from("Saul")], ordered_names); connection.execute("INSERT INTO users (name) VALUES ('Stan')").unwrap(); let ordered_name_id_pairs = users.select((name, id)).order((name.asc(), id.desc())).load(&connection).unwrap(); assert_eq!(vec![(String::from("Saul"), 3), (String::from("Stan"), 6), (String::from("Stan"), 5), (String::from("Steve"), 4)], ordered_name_id_pairs);
fn limit(self, limit: i64) -> Limit<Self> where
Self: LimitDsl,
Self: LimitDsl,
Sets the limit clause of the query.
If there was already a limit clause, it will be overridden.
Example
// Using a limit let limited = users.select(name) .order(id) .limit(1) .load::<String>(&connection) .unwrap(); // Without a limit let no_limit = users.select(name) .order(id) .load::<String>(&connection) .unwrap(); assert_eq!(vec!["Sean".to_string()], limited); assert_eq!(vec!["Sean".to_string(), "Bastien".to_string(), "Pascal".to_string()], no_limit);
fn offset(self, offset: i64) -> Offset<Self> where
Self: OffsetDsl,
Self: OffsetDsl,
Sets the offset clause of the query.
If there was already a offset clause, it will be overridden.
Example
// Using an offset let offset = users.select(name) .order(id) .limit(2) .offset(1) .load::<String>(&connection) .unwrap(); // No Offset let no_offset = users.select(name) .order(id) .limit(2) .load::<String>(&connection) .unwrap(); assert_eq!(vec!["Bastien".to_string(), "Pascal".to_string()], offset); assert_eq!(vec!["Sean".to_string(), "Bastien".to_string()], no_offset);
fn for_update(self) -> ForUpdate<Self> where
Self: ForUpdateDsl,
Self: ForUpdateDsl,
Adds FOR UPDATE
to the end of the select statement.
This method is only available for MySQL and PostgreSQL. SQLite does not provide any form of row locking.
Additionally, .for_update
cannot be used on queries with a distinct
clause, group by clause, having clause, or any unions. Queries with
a FOR UPDATE
clause cannot be boxed.
Example
// Executes `SELECT * FROM users FOR UPDATE` users.for_update().load(&connection)
fn into_boxed<'a, DB>(self) -> IntoBoxed<'a, Self, DB> where
DB: Backend,
Self: BoxedDsl<'a, DB>,
DB: Backend,
Self: BoxedDsl<'a, DB>,
Boxes the pieces of a query into a single type.
This is useful for cases where you want to conditionally modify a query, but need the type to remain the same. The backend must be specified as part of this. It is not possible to box a query and have it be useable on multiple backends.
A boxed query will incur a minor performance penalty, as the query builder can no longer be inlined by the compiler. For most applications this cost will be minimal.
Example
let mut query = users::table.into_boxed(); if let Some(name) = params.get("name") { query = query.filter(users::name.eq(name)); } let users = query.load(&connection);
Diesel queries also have a similar problem to Iterator
, where
returning them from a function requires exposing the implementation of that
function. The helper_types
module exists to help with this,
but you might want to hide the return type or have it conditionally change.
Boxing can achieve both.
Example
fn users_by_name<'a>(name: &'a str) -> users::BoxedQuery<'a, DB> { users::table.filter(users::name.eq(name)).into_boxed() } assert_eq!(Ok(1), users_by_name("Sean").select(users::id).first(&connection)); assert_eq!(Ok(2), users_by_name("Tess").select(users::id).first(&connection));
Implementors
impl<T: Table> QueryDsl for T