blob: c4ff2530851a437f73439c8b46554dc2d2a36a46 [file] [log] [blame]
//! Traits that construct SELECT statements
//!
//! Traits in this module have methods that generally map to the keyword for the corresponding clause in SQL,
//! unless it conflicts with a Rust keyword (such as `WHERE`/`where`).
//!
//! Methods for constructing queries lives on the [`QueryDsl`] trait.
//! Methods for executing queries live on [`RunQueryDsl`].
//!
//! See also [`expression_methods`][expression_methods] and [`dsl`][dsl].
//!
//! [expression_methods]: super::expression_methods
//! [dsl]: super::dsl
use crate::backend::Backend;
use crate::connection::Connection;
use crate::expression::count::CountStar;
use crate::expression::Expression;
use crate::helper_types::*;
use crate::query_builder::locking_clause as lock;
use crate::query_source::{joins, Table};
use crate::result::QueryResult;
mod belonging_to_dsl;
#[doc(hidden)]
pub mod boxed_dsl;
mod combine_dsl;
mod distinct_dsl;
#[doc(hidden)]
pub mod filter_dsl;
mod group_by_dsl;
mod having_dsl;
mod join_dsl;
#[doc(hidden)]
pub mod limit_dsl;
#[doc(hidden)]
pub mod load_dsl;
mod locking_dsl;
mod nullable_select_dsl;
mod offset_dsl;
pub(crate) mod order_dsl;
#[doc(hidden)]
pub mod positional_order_dsl;
mod save_changes_dsl;
#[doc(hidden)]
pub mod select_dsl;
mod single_value_dsl;
pub use self::belonging_to_dsl::BelongingToDsl;
pub use self::combine_dsl::CombineDsl;
pub use self::join_dsl::{InternalJoinDsl, JoinOnDsl, JoinWithImplicitOnClause};
#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::load_dsl::CompatibleType;
#[doc(hidden)]
pub use self::load_dsl::LoadQuery;
pub use self::save_changes_dsl::{SaveChangesDsl, UpdateAndFetchResults};
/// The traits used by `QueryDsl`.
///
/// Each trait in this module represents exactly one method from `QueryDsl`.
/// Apps should general rely on `QueryDsl` directly, rather than these traits.
/// However, generic code may need to include a where clause that references
/// these traits.
pub mod methods {
pub use super::boxed_dsl::BoxedDsl;
pub use super::distinct_dsl::*;
#[doc(inline)]
pub use super::filter_dsl::*;
pub use super::group_by_dsl::GroupByDsl;
pub use super::having_dsl::HavingDsl;
pub use super::limit_dsl::LimitDsl;
pub use super::load_dsl::{ExecuteDsl, LoadQuery};
pub use super::locking_dsl::{LockingDsl, ModifyLockDsl};
pub use super::nullable_select_dsl::SelectNullableDsl;
pub use super::offset_dsl::OffsetDsl;
pub use super::order_dsl::{OrderDsl, ThenOrderDsl};
pub use super::select_dsl::SelectDsl;
pub use super::single_value_dsl::SingleValueDsl;
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[doc(hidden)]
#[allow(deprecated)]
#[deprecated(note = "Use `LoadQuery::RowIter` directly")]
pub use super::load_dsl::LoadRet;
}
/// Methods used to construct select statements.
pub trait QueryDsl: Sized {
/// Adds the `DISTINCT` keyword to a query.
///
/// This method will override any previous distinct clause that was present.
/// For example, on PostgreSQL, `foo.distinct_on(bar).distinct()` will
/// create the same query as `foo.distinct()`.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM users").execute(connection).unwrap();
/// diesel::insert_into(users)
/// .values(&vec![name.eq("Sean"); 3])
/// .execute(connection)?;
/// let names = users.select(name).load::<String>(connection)?;
/// let distinct_names = users.select(name).distinct().load::<String>(connection)?;
///
/// assert_eq!(vec!["Sean"; 3], names);
/// assert_eq!(vec!["Sean"; 1], distinct_names);
/// # Ok(())
/// # }
/// ```
fn distinct(self) -> Distinct<Self>
where
Self: methods::DistinctDsl,
{
methods::DistinctDsl::distinct(self)
}
/// Adds the `DISTINCT ON` clause to a query.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::animals;
/// #
/// # #[derive(Queryable, Debug, PartialEq)]
/// # struct Animal {
/// # species: String,
/// # name: Option<String>,
/// # legs: i32,
/// # }
/// #
/// # impl Animal {
/// # fn new<S: Into<String>>(species: S, name: Option<&str>, legs: i32) -> Self {
/// # Animal {
/// # species: species.into(),
/// # name: name.map(Into::into),
/// # legs
/// # }
/// # }
/// # }
/// #
/// # fn main() {
/// # use self::animals::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM animals").execute(connection).unwrap();
/// diesel::insert_into(animals)
/// .values(&vec![
/// (species.eq("dog"), name.eq(Some("Jack")), legs.eq(4)),
/// (species.eq("dog"), name.eq(None), legs.eq(4)),
/// (species.eq("spider"), name.eq(None), legs.eq(8)),
/// ])
/// .execute(connection)
/// .unwrap();
/// let all_animals = animals.select((species, name, legs)).load(connection);
/// let distinct_animals = animals
/// .select((species, name, legs))
/// .order_by((species, 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);
/// # }
/// ```
#[cfg(feature = "postgres_backend")]
fn distinct_on<Expr>(self, expr: Expr) -> DistinctOn<Self, Expr>
where
Self: methods::DistinctOnDsl<Expr>,
{
methods::DistinctOnDsl::distinct_on(self, expr)
}
// FIXME: Needs usage example and doc rewrite
/// Adds a `SELECT` clause to the query.
///
/// If there was already a select clause present, it will be overridden.
/// For example, `foo.select(bar).select(baz)` will produce the same
/// query as `foo.select(baz)`.
///
/// By default, the select clause will be roughly equivalent to `SELECT *`
/// (however, Diesel will list all columns to ensure that they are in the
/// order we expect).
///
/// `select` has slightly stricter bounds on its arguments than other
/// methods. In particular, when used with a left outer join, `.nullable`
/// must be called on columns that come from the right side of a join. It
/// can be called on the column itself, or on an expression containing that
/// column. `title.nullable()`, `lower(title).nullable()`, and `(id,
/// title).nullable()` would all be valid.
///
/// In order to use this method with columns from different tables
/// a method like [`.inner_join`] or [`.left_join`] needs to be called before
/// calling [`.select`] (See examples below).
/// This is because you can only access columns from tables
/// that appear in your query before that function call.
///
/// [`.inner_join`]: QueryDsl::inner_join()
/// [`.left_join`]: QueryDsl::left_join()
/// [`.select`]: QueryDsl::select()
///
/// # Examples
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use self::users::dsl::*;
/// # let connection = &mut establish_connection();
/// // By default, all columns will be selected
/// let all_users = users.load::<(i32, String)>(connection)?;
/// assert_eq!(vec![(1, String::from("Sean")), (2, String::from("Tess"))], all_users);
///
/// let all_names = users.select(name).load::<String>(connection)?;
/// assert_eq!(vec!["Sean", "Tess"], all_names);
/// # Ok(())
/// # }
/// ```
///
/// ### When used with a left join
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::{users, posts};
/// #
/// # #[derive(Queryable, PartialEq, Eq, Debug)]
/// # struct User {
/// # id: i32,
/// # name: String,
/// # }
/// #
/// # impl User {
/// # fn new(id: i32, name: &str) -> Self {
/// # User {
/// # id,
/// # name: name.into(),
/// # }
/// # }
/// # }
/// #
/// # #[derive(Queryable, PartialEq, Eq, Debug)]
/// # struct Post {
/// # id: i32,
/// # user_id: i32,
/// # title: String,
/// # }
/// #
/// # impl Post {
/// # fn new(id: i32, user_id: i32, title: &str) -> Self {
/// # Post {
/// # id,
/// # user_id,
/// # title: title.into(),
/// # }
/// # }
/// # }
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM posts").execute(connection)?;
/// # diesel::insert_into(posts::table)
/// # .values((posts::user_id.eq(1), posts::title.eq("Sean's Post")))
/// # .execute(connection)?;
/// # let post_id = posts::table.select(posts::id)
/// # .first::<i32>(connection)?;
/// let join = users::table.left_join(posts::table);
///
/// // By default, all columns from both tables are selected.
/// // If no explicit select clause is used this means that the result
/// // type of this query must contain all fields from the original schema in order.
/// let all_data = join.load::<(User, Option<Post>)>(connection)?;
/// let expected_data = vec![
/// (User::new(1, "Sean"), Some(Post::new(post_id, 1, "Sean's Post"))),
/// (User::new(2, "Tess"), None),
/// ];
/// assert_eq!(expected_data, all_data);
///
/// // Since `posts` is on the right side of a left join, `.nullable` is
/// // needed.
/// let names_and_titles = join.select((users::name, posts::title.nullable()))
/// .load::<(String, Option<String>)>(connection)?;
/// let expected_data = vec![
/// (String::from("Sean"), Some(String::from("Sean's Post"))),
/// (String::from("Tess"), None),
/// ];
/// assert_eq!(expected_data, names_and_titles);
/// # Ok(())
/// # }
/// ```
fn select<Selection>(self, selection: Selection) -> Select<Self, Selection>
where
Selection: Expression,
Self: methods::SelectDsl<Selection>,
{
methods::SelectDsl::select(self, selection)
}
/// Get the count of a query. This is equivalent to `.select(count_star())`
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let count = users.count().get_result(connection);
/// assert_eq!(Ok(2), count);
/// # }
/// ```
fn count(self) -> Select<Self, CountStar>
where
Self: methods::SelectDsl<CountStar>,
{
use crate::dsl::count_star;
QueryDsl::select(self, count_star())
}
/// 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.
///
/// [`joinable!`]: crate::joinable!
/// [`.on`]: JoinOnDsl::on()
///
/// 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. For
/// tables that appear more than once in a single query the usage of [`alias!`](crate::alias!)
/// is required.
///
/// You will also need to call [`allow_tables_to_appear_in_same_query!`].
/// If you are using `diesel print-schema`, this will
/// have been generated for you.
/// 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:
///
/// ```sql
/// SELECT * FROM users
/// INNER JOIN (
/// posts
/// INNER JOIN comments ON comments.post_id = posts.id
/// ) ON posts.user_id = users.id
///
/// ```
///
/// While the second query would deserialize into `(User, Post, Comment)` and
/// generate the following SQL:
///
/// ```sql
/// SELECT * FROM users
/// INNER JOIN posts ON posts.user_id = users.id
/// INNER JOIN comments ON comments.user_id = users.id
/// ```
///
/// The exact generated SQL may change in future diesel version as long as the
/// generated query continues to produce same results. The currently generated
/// SQL is referred as ["explicit join"](https://www.postgresql.org/docs/current/explicit-joins.html)
/// by the PostgreSQL documentation and may have implications on the chosen query plan
/// for large numbers of joins in the same query. Checkout the documentation of the
/// [`join_collapse_limit` parameter](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT)
/// to control this behaviour.
///
/// [associations]: crate::associations
/// [`allow_tables_to_appear_in_same_query!`]: crate::allow_tables_to_appear_in_same_query!
///
/// Note that in order to use this method with [`.select`], you will need to use it before calling
/// [`.select`] (See examples below). This is because you can only access columns from tables
/// that appear in your query before the call to [`.select`].
///
/// [`.select`]: QueryDsl::select()
///
/// # Examples
///
/// ### With implicit `ON` clause
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::{users, posts};
/// # /*
/// joinable!(posts -> users (user_id));
/// allow_tables_to_appear_in_same_query!(users, posts);
/// # */
///
/// # fn main() {
/// # use self::users::dsl::{users, name};
/// # use self::posts::dsl::{posts, user_id, title};
/// # let connection = &mut establish_connection();
/// let data = users.inner_join(posts)
/// .select((name, title))
/// .load(connection);
///
/// let expected_data = vec![
/// (String::from("Sean"), String::from("My first post")),
/// (String::from("Sean"), String::from("About Rust")),
/// (String::from("Tess"), String::from("My first post too")),
/// ];
/// assert_eq!(Ok(expected_data), data);
/// # }
/// ```
///
/// ### With explicit `ON` clause
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::{users, posts};
/// #
/// # /*
/// allow_tables_to_appear_in_same_query!(users, posts);
/// # */
///
/// # fn main() {
/// # use self::users::dsl::{users, name};
/// # use self::posts::dsl::{posts, user_id, title};
/// # let connection = &mut establish_connection();
/// diesel::insert_into(posts)
/// .values(&vec![
/// (user_id.eq(1), title.eq("Sean's post")),
/// (user_id.eq(2), title.eq("Sean is a jerk")),
/// ])
/// .execute(connection)
/// .unwrap();
///
/// let data = users
/// .inner_join(posts.on(title.like(name.concat("%"))))
/// .select((name, title))
/// .load(connection);
/// let expected_data = vec![
/// (String::from("Sean"), String::from("Sean's post")),
/// (String::from("Sean"), String::from("Sean is a jerk")),
/// ];
/// assert_eq!(Ok(expected_data), data);
/// # }
/// ```
///
/// ### With explicit `ON` clause (struct)
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::{users, posts};
/// #
/// # /*
/// allow_tables_to_appear_in_same_query!(users, posts);
/// # */
///
/// # fn main() {
/// # use self::users::dsl::{users, name};
/// # use self::posts::dsl::{posts, user_id, title};
/// # let connection = &mut establish_connection();
/// #[derive(Debug, PartialEq, Queryable)]
/// struct User {
/// id: i32,
/// name: String,
/// }
///
/// #[derive(Debug, PartialEq, Queryable)]
/// struct Post {
/// id: i32,
/// user_id: i32,
/// title: String,
/// }
///
/// diesel::insert_into(posts)
/// .values(&vec![
/// (user_id.eq(1), title.eq("Sean's post")),
/// (user_id.eq(2), title.eq("Sean is a jerk")),
/// ])
/// .execute(connection)
/// .unwrap();
///
/// // By default, all columns from both tables are selected.
/// // If no explicit select clause is used this means that the
/// // result type of this query must contain all fields from the
/// // original schema in order.
/// let data = users
/// .inner_join(posts.on(title.like(name.concat("%"))))
/// .load::<(User, Post)>(connection); // type could be elided
/// let expected_data = vec![
/// (
/// User { id: 1, name: String::from("Sean") },
/// Post { id: 4, user_id: 1, title: String::from("Sean's post") },
/// ),
/// (
/// User { id: 1, name: String::from("Sean") },
/// Post { id: 5, user_id: 2, title: String::from("Sean is a jerk") },
/// ),
/// ];
/// assert_eq!(Ok(expected_data), data);
/// # }
/// ```
fn inner_join<Rhs>(self, rhs: Rhs) -> InnerJoin<Self, Rhs>
where
Self: JoinWithImplicitOnClause<Rhs, joins::Inner>,
{
self.join_with_implicit_on_clause(rhs, joins::Inner)
}
/// Join two tables using a SQL `LEFT OUTER JOIN`.
///
/// Behaves similarly to [`inner_join`], but will produce a left join
/// instead. See [`inner_join`] for usage examples.
///
/// [`inner_join`]: QueryDsl::inner_join()
///
/// Columns in the right hand table will become `Nullable` which means
/// you must call `nullable()` on the corresponding fields in the select
/// clause:
///
/// ### Selecting after a left join
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::{users, posts};
/// #
/// # #[derive(Queryable, PartialEq, Eq, Debug)]
/// # struct User {
/// # id: i32,
/// # name: String,
/// # }
/// #
/// # impl User {
/// # fn new(id: i32, name: &str) -> Self {
/// # User {
/// # id,
/// # name: name.into(),
/// # }
/// # }
/// # }
/// #
/// # #[derive(Queryable, PartialEq, Eq, Debug)]
/// # struct Post {
/// # id: i32,
/// # user_id: i32,
/// # title: String,
/// # }
/// #
/// # impl Post {
/// # fn new(id: i32, user_id: i32, title: &str) -> Self {
/// # Post {
/// # id,
/// # user_id,
/// # title: title.into(),
/// # }
/// # }
/// # }
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM posts").execute(connection)?;
/// # diesel::insert_into(posts::table)
/// # .values((posts::user_id.eq(1), posts::title.eq("Sean's Post")))
/// # .execute(connection)?;
/// # let post_id = posts::table.select(posts::id)
/// # .first::<i32>(connection)?;
/// let join = users::table.left_join(posts::table);
///
/// // Since `posts` is on the right side of a left join, `.nullable` is
/// // needed.
/// let names_and_titles = join.select((users::name, posts::title.nullable()))
/// .load::<(String, Option<String>)>(connection)?;
/// let expected_data = vec![
/// (String::from("Sean"), Some(String::from("Sean's Post"))),
/// (String::from("Tess"), None),
/// ];
/// assert_eq!(expected_data, names_and_titles);
/// # Ok(())
/// # }
/// ```
fn left_outer_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>
where
Self: JoinWithImplicitOnClause<Rhs, joins::LeftOuter>,
{
self.join_with_implicit_on_clause(rhs, joins::LeftOuter)
}
/// Alias for [`left_outer_join`].
///
/// [`left_outer_join`]: QueryDsl::left_outer_join()
fn left_join<Rhs>(self, rhs: Rhs) -> LeftJoin<Self, Rhs>
where
Self: JoinWithImplicitOnClause<Rhs, joins::LeftOuter>,
{
self.left_outer_join(rhs)
}
/// Adds to the `WHERE` clause of a query.
///
/// If there is already a `WHERE` clause, the result will be `old AND new`.
///
/// Note that in order to use this method with columns from different tables, you need to call
/// [`.inner_join`] or [`.left_join`] beforehand.
/// This is because you can only access columns from tables
/// that appear in your query before the call to [`.filter`].
///
/// [`.inner_join`]: QueryDsl::inner_join()
/// [`.left_join`]: QueryDsl::left_join()
/// [`.filter`]: QueryDsl::filter()
///
/// # Example:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # use schema::users::dsl::*;
/// # let connection = &mut 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);
/// # }
/// ```
#[doc(alias = "where")]
fn filter<Predicate>(self, predicate: Predicate) -> Filter<Self, Predicate>
where
Self: methods::FilterDsl<Predicate>,
{
methods::FilterDsl::filter(self, predicate)
}
/// Adds to the `WHERE` clause of a query using `OR`
///
/// If there is already a `WHERE` clause, the result will be `(old OR new)`.
/// Calling `foo.filter(bar).or_filter(baz)`
/// is identical to `foo.filter(bar.or(baz))`.
/// However, the second form is much harder to do dynamically.
///
/// # Example:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use schema::animals::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::delete(animals).execute(connection)?;
/// diesel::insert_into(animals)
/// .values(&vec![
/// (species.eq("cat"), legs.eq(4), name.eq("Sinatra")),
/// (species.eq("dog"), legs.eq(3), name.eq("Fido")),
/// (species.eq("spider"), legs.eq(8), name.eq("Charlotte")),
/// ])
/// .execute(connection)?;
///
/// let good_animals = animals
/// .filter(name.eq("Fido"))
/// .or_filter(legs.eq(4))
/// .select(name)
/// .get_results::<Option<String>>(connection)?;
/// let expected = vec![
/// Some(String::from("Sinatra")),
/// Some(String::from("Fido")),
/// ];
/// assert_eq!(expected, good_animals);
/// # Ok(())
/// # }
/// ```
#[doc(alias = "where")]
fn or_filter<Predicate>(self, predicate: Predicate) -> OrFilter<Self, Predicate>
where
Self: methods::OrFilterDsl<Predicate>,
{
methods::OrFilterDsl::or_filter(self, predicate)
}
/// Attempts to find a single record from the given table by primary key.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # use schema::users::dsl::*;
/// # use diesel::result::Error::NotFound;
/// # let connection = &mut 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));
/// # }
/// ```
fn find<PK>(self, id: PK) -> Find<Self, PK>
where
Self: methods::FindDsl<PK>,
{
methods::FindDsl::find(self, id)
}
/// Sets the order clause of a query.
///
/// If there was already an order clause, it will be overridden. See
/// also:
/// [`.desc()`](crate::expression_methods::ExpressionMethods::desc())
/// and
/// [`.asc()`](crate::expression_methods::ExpressionMethods::asc())
///
/// Ordering by multiple columns can be achieved by passing a tuple of those
/// columns.
/// To construct an order clause of an unknown number of columns,
/// see [`QueryDsl::then_order_by`](QueryDsl::then_order_by())
///
/// # Examples
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM users").execute(connection)?;
/// diesel::insert_into(users)
/// .values(&vec![
/// name.eq("Saul"),
/// name.eq("Steve"),
/// name.eq("Stan"),
/// ])
/// .execute(connection)?;
///
/// let ordered_names = users.select(name)
/// .order(name.desc())
/// .load::<String>(connection)?;
/// assert_eq!(vec!["Steve", "Stan", "Saul"], ordered_names);
///
/// diesel::insert_into(users).values(name.eq("Stan")).execute(connection)?;
///
/// let data = users.select((name, id))
/// .order((name.asc(), id.desc()))
/// .load(connection)?;
/// let expected_data = vec![
/// (String::from("Saul"), 3),
/// (String::from("Stan"), 6),
/// (String::from("Stan"), 5),
/// (String::from("Steve"), 4),
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
fn order<Expr>(self, expr: Expr) -> Order<Self, Expr>
where
Expr: Expression,
Self: methods::OrderDsl<Expr>,
{
methods::OrderDsl::order(self, expr)
}
/// Alias for `order`
fn order_by<Expr>(self, expr: Expr) -> Order<Self, Expr>
where
Expr: Expression,
Self: methods::OrderDsl<Expr>,
{
QueryDsl::order(self, expr)
}
/// Appends to the `ORDER BY` clause of this SQL query.
///
/// Unlike `.order`, this method will append rather than replace.
/// In other words,
/// `.order_by(foo).order_by(bar)` is equivalent to `.order_by(bar)`.
/// In contrast,
/// `.order_by(foo).then_order_by(bar)` is equivalent to `.order((foo, bar))`.
/// This method is only present on boxed queries.
///
/// # Examples
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::sql_query("DELETE FROM users").execute(connection)?;
/// diesel::insert_into(users)
/// .values(&vec![
/// name.eq("Saul"),
/// name.eq("Steve"),
/// name.eq("Stan"),
/// name.eq("Stan"),
/// ])
/// .execute(connection)?;
///
/// let data = users.select((name, id))
/// .order_by(name.asc())
/// .then_order_by(id.desc())
/// .load(connection)?;
/// let expected_data = vec![
/// (String::from("Saul"), 3),
/// (String::from("Stan"), 6),
/// (String::from("Stan"), 5),
/// (String::from("Steve"), 4),
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
fn then_order_by<Order>(self, order: Order) -> ThenOrderBy<Self, Order>
where
Self: methods::ThenOrderDsl<Order>,
{
methods::ThenOrderDsl::then_order_by(self, order)
}
/// Sets the limit clause of the query.
///
/// If there was already a limit clause, it will be overridden.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use self::users::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::delete(users).execute(connection)?;
/// # diesel::insert_into(users)
/// # .values(&vec![
/// # name.eq("Sean"),
/// # name.eq("Bastien"),
/// # name.eq("Pascal"),
/// # ])
/// # .execute(connection)?;
/// #
/// // Using a limit
/// let limited = users.select(name)
/// .order(id)
/// .limit(1)
/// .load::<String>(connection)?;
///
/// // Without a limit
/// let no_limit = users.select(name)
/// .order(id)
/// .load::<String>(connection)?;
///
/// assert_eq!(vec!["Sean"], limited);
/// assert_eq!(vec!["Sean", "Bastien", "Pascal"], no_limit);
/// # Ok(())
/// # }
/// ```
fn limit(self, limit: i64) -> Limit<Self>
where
Self: methods::LimitDsl,
{
methods::LimitDsl::limit(self, limit)
}
/// Sets the offset clause of the query.
///
/// If there was already a offset clause, it will be overridden.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use self::users::dsl::*;
/// # let connection = &mut establish_connection();
/// # diesel::delete(users).execute(connection)?;
/// # diesel::insert_into(users)
/// # .values(&vec![
/// # name.eq("Sean"),
/// # name.eq("Bastien"),
/// # name.eq("Pascal"),
/// # ])
/// # .execute(connection)?;
/// #
/// // Using an offset
/// let offset = users.select(name)
/// .order(id)
/// .limit(2)
/// .offset(1)
/// .load::<String>(connection)?;
///
/// // No Offset
/// let no_offset = users.select(name)
/// .order(id)
/// .limit(2)
/// .load::<String>(connection)?;
///
/// assert_eq!(vec!["Bastien", "Pascal"], offset);
/// assert_eq!(vec!["Sean", "Bastien"], no_offset);
/// # Ok(())
/// # }
/// ```
fn offset(self, offset: i64) -> Offset<Self>
where
Self: methods::OffsetDsl,
{
methods::OffsetDsl::offset(self, offset)
}
/// Sets the `group by` clause of a query.
///
/// **Note:** Queries having a `group by` clause require a custom select clause.
/// Use [`QueryDsl::select()`] to specify one.
///
/// If there was already a group by clause, it will be overridden.
/// Grouping by multiple columns can be achieved by passing a tuple of those
/// columns.
///
/// Diesel follows postgresql's group by semantic, this means any column
/// appearing in a group by clause is considered to be aggregated. If a
/// primary key is part of the group by clause every column from the
/// corresponding table is considered to be aggregated. Select clauses
/// cannot mix aggregated and non aggregated expressions.
///
/// For group by clauses containing columns from more than one table it
/// is required to call [`allow_columns_to_appear_in_same_group_by_clause!`]
///
/// [`allow_columns_to_appear_in_same_group_by_clause!`]: crate::allow_columns_to_appear_in_same_group_by_clause!
///
/// # Examples
/// ```rust
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::{users, posts};
/// # use diesel::dsl::count;
/// # let connection = &mut establish_connection();
/// let data = users::table.inner_join(posts::table)
/// .group_by(users::id)
/// .select((users::name, count(posts::id)))
/// # .order_by(users::id.asc())
/// .load::<(String, i64)>(connection)?;
///
/// assert_eq!(vec![(String::from("Sean"), 2), (String::from("Tess"), 1)], data);
/// # Ok(())
/// # }
/// ```
fn group_by<GB>(self, group_by: GB) -> GroupBy<Self, GB>
where
GB: Expression,
Self: methods::GroupByDsl<GB>,
{
methods::GroupByDsl::group_by(self, group_by)
}
/// Adds to the `HAVING` clause of a query.
///
/// # Examples
/// ```rust
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::{users, posts};
/// # use diesel::dsl::count;
/// # let connection = &mut establish_connection();
/// let data = users::table.inner_join(posts::table)
/// .group_by(users::id)
/// .having(count(posts::id).gt(1))
/// .select((users::name, count(posts::id)))
/// .load::<(String, i64)>(connection)?;
///
/// assert_eq!(vec![(String::from("Sean"), 2)], data);
/// # Ok(())
/// # }
/// ```
fn having<Predicate>(self, predicate: Predicate) -> Having<Self, Predicate>
where
Self: methods::HavingDsl<Predicate>,
{
methods::HavingDsl::having(self, predicate)
}
/// 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
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(any(feature = "mysql", feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR UPDATE`
/// let users_for_update = users::table.for_update().load(connection)?;
/// # let u: Vec<(i32, String)> = users_for_update;
/// # Ok(())
/// # }
/// # #[cfg(feature = "sqlite")]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn for_update(self) -> ForUpdate<Self>
where
Self: methods::LockingDsl<lock::ForUpdate>,
{
methods::LockingDsl::with_lock(self, lock::ForUpdate)
}
/// Adds `FOR NO KEY UPDATE` to the end of the select statement.
///
/// This method is only available for PostgreSQL. SQLite does not
/// provide any form of row locking, and MySQL does not support anything
/// finer than row-level locking.
///
/// Additionally, `.for_no_key_update` cannot be used on queries with a distinct
/// clause, group by clause, having clause, or any unions. Queries with
/// a `FOR NO KEY UPDATE` clause cannot be boxed.
///
/// # Example
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR NO KEY UPDATE`
/// let users_for_no_key_update = users::table.for_no_key_update().load(connection)?;
/// # let u: Vec<(i32, String)> = users_for_no_key_update;
/// # Ok(())
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn for_no_key_update(self) -> ForNoKeyUpdate<Self>
where
Self: methods::LockingDsl<lock::ForNoKeyUpdate>,
{
methods::LockingDsl::with_lock(self, lock::ForNoKeyUpdate)
}
/// Adds `FOR SHARE` 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_share` cannot be used on queries with a distinct
/// clause, group by clause, having clause, or any unions. Queries with
/// a `FOR SHARE` clause cannot be boxed.
///
/// # Example
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(any(feature = "mysql", feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR SHARE`
/// let users_for_share = users::table.for_share().load(connection)?;
/// # let u: Vec<(i32, String)> = users_for_share;
/// # Ok(())
/// # }
/// # #[cfg(feature = "sqlite")]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn for_share(self) -> ForShare<Self>
where
Self: methods::LockingDsl<lock::ForShare>,
{
methods::LockingDsl::with_lock(self, lock::ForShare)
}
/// Adds `FOR KEY SHARE` to the end of the select statement.
///
/// This method is only available for PostgreSQL. SQLite does not
/// provide any form of row locking, and MySQL does not support anything
/// finer than row-level locking.
///
/// Additionally, `.for_key_share` cannot be used on queries with a distinct
/// clause, group by clause, having clause, or any unions. Queries with
/// a `FOR KEY SHARE` clause cannot be boxed.
///
/// # Example
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
///
/// # #[cfg(feature = "postgres")]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR KEY SHARE`
/// let users_for_key_share = users::table.for_key_share().load(connection)?;
/// # let u: Vec<(i32, String)> = users_for_key_share;
/// # Ok(())
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn for_key_share(self) -> ForKeyShare<Self>
where
Self: methods::LockingDsl<lock::ForKeyShare>,
{
methods::LockingDsl::with_lock(self, lock::ForKeyShare)
}
/// Adds `SKIP LOCKED` to the end of a `FOR UPDATE` clause.
///
/// This modifier is only supported in PostgreSQL 9.5+ and MySQL 8+.
///
/// # Example
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(any(feature = "postgres", feature = "mysql"))]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR UPDATE SKIP LOCKED`
/// let user_skipped_locked = users::table.for_update().skip_locked().load(connection)?;
/// # let u: Vec<(i32, String)> = user_skipped_locked;
/// # Ok(())
/// # }
/// # #[cfg(feature = "sqlite")]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn skip_locked(self) -> SkipLocked<Self>
where
Self: methods::ModifyLockDsl<lock::SkipLocked>,
{
methods::ModifyLockDsl::modify_lock(self, lock::SkipLocked)
}
/// Adds `NOWAIT` to the end of a `FOR UPDATE` clause.
///
/// This modifier is only supported in PostgreSQL 9.5+ and MySQL 8+.
///
/// # Example
///
/// ```
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(any(feature = "mysql", feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// # use crate::schema::users;
/// # let connection = &mut establish_connection();
/// // Executes `SELECT * FROM users FOR UPDATE NOWAIT`
/// let users_no_wait = users::table.for_update().no_wait().load(connection)?;
/// # let u: Vec<(i32, String)> = users_no_wait;
/// # Ok(())
/// # }
/// # #[cfg(feature = "sqlite")]
/// # fn run_test() -> QueryResult<()> { Ok(()) }
/// ```
fn no_wait(self) -> NoWait<Self>
where
Self: methods::ModifyLockDsl<lock::NoWait>,
{
methods::ModifyLockDsl::modify_lock(self, lock::NoWait)
}
/// 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
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// # fn main() {
/// # use std::collections::HashMap;
/// # let connection = &mut establish_connection();
/// # let mut params = HashMap::new();
/// # params.insert("name", "Sean");
/// 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);
/// # let expected = vec![(1, String::from("Sean"))];
/// # assert_eq!(Ok(expected), users);
/// # }
/// ```
///
/// 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`][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.
///
/// [helper_types]: crate::helper_types
///
/// ### Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// # fn main() {
/// # let connection = &mut establish_connection();
/// fn users_by_name(name: &str) -> users::BoxedQuery<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));
/// # }
/// ```
fn into_boxed<'a, DB>(self) -> IntoBoxed<'a, Self, DB>
where
DB: Backend,
Self: methods::BoxedDsl<'a, DB>,
{
methods::BoxedDsl::internal_into_boxed(self)
}
/// Wraps this select statement in parenthesis, allowing it to be used
/// as an expression.
///
/// SQL allows queries such as `foo = (SELECT ...)`, as long as the
/// subselect returns only a single column, and 0 or 1 rows. This method
/// indicates that you expect the query to only return a single value (this
/// will be enforced by adding `LIMIT 1`).
///
/// The SQL type of this will always be `Nullable`, as the query returns
/// `NULL` if the table is empty or it otherwise returns 0 rows.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # use schema::posts;
/// # let connection = &mut establish_connection();
/// insert_into(posts::table)
/// .values(posts::user_id.eq(1))
/// .execute(connection)?;
/// let last_post = posts::table
/// .order(posts::id.desc());
/// let most_recently_active_user = users.select(name)
/// .filter(id.nullable().eq(last_post.select(posts::user_id).single_value()))
/// .first::<String>(connection)?;
/// assert_eq!("Sean", most_recently_active_user);
/// # Ok(())
/// # }
/// ```
fn single_value(self) -> SingleValue<Self>
where
Self: methods::SingleValueDsl,
{
methods::SingleValueDsl::single_value(self)
}
/// Coerce the SQL type of the select clause to it's nullable equivalent.
///
/// This is useful for writing queries that contain subselects on non null
/// fields comparing them to nullable fields.
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # let connection = &mut establish_connection();
/// table! {
/// users {
/// id -> Integer,
/// name -> Text,
/// }
/// }
///
/// table! {
/// posts {
/// id -> Integer,
/// by_user -> Nullable<Text>,
/// }
/// }
///
/// allow_tables_to_appear_in_same_query!(users, posts);
///
/// # let _: Vec<(i32, Option<String>)> =
/// posts::table.filter(
/// posts::by_user.eq_any(users::table.select(users::name).nullable())
/// ).load(connection)?;
/// # Ok(())
/// # }
fn nullable(self) -> NullableSelect<Self>
where
Self: methods::SelectNullableDsl,
{
methods::SelectNullableDsl::nullable(self)
}
}
impl<T: Table> QueryDsl for T {}
/// Methods used to execute queries.
pub trait RunQueryDsl<Conn>: Sized {
/// Executes the given command, returning the number of rows affected.
///
/// `execute` is usually used in conjunction with [`insert_into`](crate::insert_into()),
/// [`update`](crate::update()) and [`delete`](crate::delete()) where the number of
/// affected rows is often enough information.
///
/// When asking the database to return data from a query, [`load`](crate::query_dsl::RunQueryDsl::load()) should
/// probably be used instead.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let inserted_rows = insert_into(users)
/// .values(name.eq("Ruby"))
/// .execute(connection)?;
/// assert_eq!(1, inserted_rows);
///
/// let inserted_rows = insert_into(users)
/// .values(&vec![name.eq("Jim"), name.eq("James")])
/// .execute(connection)?;
/// assert_eq!(2, inserted_rows);
/// # Ok(())
/// # }
/// ```
fn execute(self, conn: &mut Conn) -> QueryResult<usize>
where
Conn: Connection,
Self: methods::ExecuteDsl<Conn>,
{
methods::ExecuteDsl::execute(self, conn)
}
/// Executes the given query, returning a [`Vec`] with the returned rows.
///
/// When using the query builder, the return type can be
/// a tuple of the values, or a struct which implements [`Queryable`].
///
/// When this method is called on [`sql_query`],
/// the return type can only be a struct which implements [`QueryableByName`]
///
/// For insert, update, and delete operations where only a count of affected is needed,
/// [`execute`] should be used instead.
///
/// [`Queryable`]: crate::deserialize::Queryable
/// [`QueryableByName`]: crate::deserialize::QueryableByName
/// [`execute`]: crate::query_dsl::RunQueryDsl::execute()
/// [`sql_query`]: crate::sql_query()
///
/// ## How to resolve compiler errors while loading data from the database
///
/// In case you getting uncomprehensable compiler errors while loading data
/// from the database into a type using [`#[derive(Queryable)]`](derive@crate::prelude::Queryable)
/// you might want to consider
/// using [`#[derive(Selectable)]`](derive@crate::prelude::Selectable) +
/// `#[diesel(check_for_backend(YourBackendType))]`
/// to check for mismatching fields at compile time. This drastically improves
/// the quality of the generated error messages by pointing to concrete type mismatches at
/// field level.You need to specify the concrete database backend
/// this specific struct is indented to be used with, as otherwise rustc cannot correctly
/// identify the required deserialization implementation.
///
/// # Examples
///
/// ## Returning a single field
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let data = users.select(name)
/// .load::<String>(connection)?;
/// assert_eq!(vec!["Sean", "Tess"], data);
/// # Ok(())
/// # }
/// ```
///
/// ## Returning a tuple
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let data = users
/// .load::<(i32, String)>(connection)?;
/// let expected_data = vec![
/// (1, String::from("Sean")),
/// (2, String::from("Tess")),
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
///
/// ## Returning a struct
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// #[derive(Queryable, PartialEq, Debug)]
/// struct User {
/// id: i32,
/// name: String,
/// }
///
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let data = users
/// .load::<User>(connection)?;
/// let expected_data = vec![
/// User { id: 1, name: String::from("Sean") },
/// User { id: 2, name: String::from("Tess") },
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
fn load<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
where
Self: LoadQuery<'query, Conn, U>,
{
self.internal_load(conn)?.collect()
}
/// Executes the given query, returning an [`Iterator`] with the returned rows.
///
/// The iterator's item is [`QueryResult<U>`](crate::result::QueryResult).
///
/// You should normally prefer to use [`RunQueryDsl::load`] instead. This method
/// is provided for situations where the result needs to be collected into a different
/// container than a [`Vec`]
///
/// When using the query builder, the return type can be
/// a tuple of the values, or a struct which implements [`Queryable`].
/// This type is specified by the first generic type of this function.
///
/// The second generic type parameter specifies the so called loading mode,
/// which describes how the connection implementation loads data from the database.
/// All connections should provide a implementation for
/// [`DefaultLoadingMode`](crate::connection::DefaultLoadingMode).
///
/// They may provide additional modes. Checkout the documentation of the concrete
/// connection types for details. For connection implementations that provide
/// more than one loading mode it is **required** to specify this generic paramater.
/// This is currently true for `PgConnection`.
///
/// When this method is called on [`sql_query`],
/// the return type can only be a struct which implements [`QueryableByName`]
///
/// For insert, update, and delete operations where only a count of affected is needed,
/// [`execute`] should be used instead.
///
/// [`Queryable`]: crate::deserialize::Queryable
/// [`QueryableByName`]: crate::deserialize::QueryableByName
/// [`execute`]: crate::query_dsl::RunQueryDsl::execute()
/// [`sql_query`]: crate::sql_query()
///
/// # Examples
///
/// ## Returning a single field
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// use diesel::connection::DefaultLoadingMode;
///
/// let data = users.select(name)
/// .load_iter::<String, DefaultLoadingMode>(connection)?
/// .collect::<QueryResult<Vec<_>>>()?;
/// assert_eq!(vec!["Sean", "Tess"], data);
/// # Ok(())
/// # }
/// ```
///
/// ## Returning a tuple
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// use diesel::connection::DefaultLoadingMode;
///
/// let data = users
/// .load_iter::<(i32, String), DefaultLoadingMode>(connection)?
/// .collect::<QueryResult<Vec<_>>>()?;
/// let expected_data = vec![
/// (1, String::from("Sean")),
/// (2, String::from("Tess")),
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
///
/// ## Returning a struct
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// #[derive(Queryable, PartialEq, Debug)]
/// struct User {
/// id: i32,
/// name: String,
/// }
///
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::insert_into;
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// use diesel::connection::DefaultLoadingMode;
///
/// let data = users
/// .load_iter::<User, DefaultLoadingMode>(connection)?
/// .collect::<QueryResult<Vec<_>>>()?;
/// let expected_data = vec![
/// User { id: 1, name: String::from("Sean") },
/// User { id: 2, name: String::from("Tess") },
/// ];
/// assert_eq!(expected_data, data);
/// # Ok(())
/// # }
/// ```
fn load_iter<'conn, 'query: 'conn, U, B>(
self,
conn: &'conn mut Conn,
) -> QueryResult<Self::RowIter<'conn>>
where
U: 'conn,
Self: LoadQuery<'query, Conn, U, B> + 'conn,
{
self.internal_load(conn)
}
/// Runs the command, and returns the affected row.
///
/// `Err(NotFound)` will be returned if the query affected 0 rows. You can
/// call `.optional()` on the result of this if the command was optional to
/// get back a `Result<Option<U>>`
///
/// When this method is called on an insert, update, or delete statement,
/// it will implicitly add a `RETURNING *` to the query,
/// unless a returning clause was already specified.
///
/// This method only returns the first row that was affected, even if more
/// rows are affected.
///
/// # Example
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::{insert_into, update};
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// let inserted_row = insert_into(users)
/// .values(name.eq("Ruby"))
/// .get_result(connection)?;
/// assert_eq!((3, String::from("Ruby")), inserted_row);
///
/// // This will return `NotFound`, as there is no user with ID 4
/// let update_result = update(users.find(4))
/// .set(name.eq("Jim"))
/// .get_result::<(i32, String)>(connection);
/// assert_eq!(Err(diesel::NotFound), update_result);
/// # Ok(())
/// # }
/// #
/// # #[cfg(not(feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// # Ok(())
/// # }
/// ```
fn get_result<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
where
Self: LoadQuery<'query, Conn, U>,
{
match self.internal_load(conn)?.next() {
Some(v) => v,
None => Err(crate::result::Error::NotFound),
}
}
/// Runs the command, returning an `Vec` with the affected rows.
///
/// This method is an alias for [`load`], but with a name that makes more
/// sense for insert, update, and delete statements.
///
/// [`load`]: crate::query_dsl::RunQueryDsl::load()
fn get_results<'query, U>(self, conn: &mut Conn) -> QueryResult<Vec<U>>
where
Self: LoadQuery<'query, Conn, U>,
{
self.load(conn)
}
/// Attempts to load a single record.
///
/// This method is equivalent to `.limit(1).get_result()`
///
/// Returns `Ok(record)` if found, and `Err(NotFound)` if no results are
/// returned. If the query truly is optional, you can call `.optional()` on
/// the result of this to get a `Result<Option<U>>`.
///
/// # Example:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// # fn main() {
/// # run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use schema::users::dsl::*;
/// # let connection = &mut establish_connection();
/// diesel::insert_into(users)
/// .values(&vec![name.eq("Sean"), name.eq("Pascal")])
/// .execute(connection)?;
///
/// let first_name = users.order(id).select(name).first(connection);
/// assert_eq!(Ok(String::from("Sean")), first_name);
///
/// let not_found = users
/// .filter(name.eq("Foo"))
/// .first::<(i32, String)>(connection);
/// assert_eq!(Err(diesel::NotFound), not_found);
/// # Ok(())
/// # }
/// ```
fn first<'query, U>(self, conn: &mut Conn) -> QueryResult<U>
where
Self: methods::LimitDsl,
Limit<Self>: LoadQuery<'query, Conn, U>,
{
methods::LimitDsl::limit(self, 1).get_result(conn)
}
}
// Note: We could have a blanket `AsQuery` impl here, which would apply to
// everything we want it to. However, when a query is invalid, we specifically
// want the error to happen on the where clause of the method instead of trait
// resolution. Otherwise our users will get an error saying `<3 page long type>:
// ExecuteDsl is not satisfied` instead of a specific error telling them what
// part of their query is wrong.
impl<T, Conn> RunQueryDsl<Conn> for T where T: Table {}