Skip to main content

postgresql/
query.rs

1//! The query builder surface used by the `query!` / `query_as!` macros, and
2//! the [`Executor`] marker implemented by connections, pools and transactions.
3
4use std::{future::Future, marker::PhantomData};
5
6use futures_util::StreamExt;
7
8use crate::{connection::RowStream, encode::ToSql, error::Error, row::FromRow};
9
10pub(crate) mod sealed {
11    pub trait Sealed {}
12}
13
14/// Internal execution capability. Not part of the public API.
15///
16/// Sealed: only this crate implements it. Query execution is reached through
17/// the `query!` / `query_as!` macros, never by calling these methods directly.
18#[doc(hidden)]
19pub trait Capable: sealed::Sealed + Send + Sync {
20    /// Runs a statement without collecting rows and returns the number of
21    /// affected rows.
22    fn execute<'a>(
23        &'a self,
24        sql: &'a str,
25        params: &'a [&'a dyn ToSql],
26    ) -> impl Future<Output = Result<u64, Error>> + Send + 'a;
27
28    /// Runs a statement and returns a stream of rows.
29    ///
30    /// `max_rows` limits the number of rows the server sends (`0` means no
31    /// limit).
32    fn fetch_rows<'a>(
33        &'a self,
34        sql: &'a str,
35        params: &'a [&'a dyn ToSql],
36        max_rows: i32,
37    ) -> impl Future<Output = Result<RowStream, Error>> + Send + 'a;
38}
39
40/// Anything a query can run against: a connection, a pooled connection, a
41/// pool, or a transaction.
42///
43/// This is a sealed marker trait, so generic helpers can accept
44/// `E: Executor`, but queries themselves are only run through the `query!` /
45/// `query_as!` macros.
46pub trait Executor: Capable {}
47
48impl<T: Capable + ?Sized> Executor for T {}
49
50/// Runs multi-statement SQL scripts via the simple query protocol.
51///
52/// This is the unchecked, parameterless path (for migrations, `SET` scripts and
53/// statements the extended protocol cannot express, such as `VACUUM`). Use
54/// `query!` / `query_as!` for anything parameterized or typed.
55pub trait ScriptExecutor: sealed::Sealed {
56    /// Runs one or more statements and returns the affected-row count of the
57    /// last command.
58    ///
59    /// # Errors
60    ///
61    /// Returns an error if the connection is closed or the server rejects a
62    /// statement.
63    fn execute_script<'a>(&'a self, sql: &'a str) -> impl Future<Output = Result<u64, Error>> + Send + 'a;
64}
65
66/// A prepared query returning untyped [`crate::Row`]s.
67pub struct Query<'a> {
68    sql: &'a str,
69    params: &'a [&'a dyn ToSql],
70}
71
72impl<'a> Query<'a> {
73    /// Builds a query from SQL and already-built parameters.
74    pub fn new(sql: &'a str, params: &'a [&'a dyn ToSql]) -> Self {
75        Query {
76            sql,
77            params,
78        }
79    }
80
81    /// Runs the statement and returns the number of affected rows.
82    ///
83    /// Use this for statements that change data (`INSERT`, `UPDATE`, `DELETE`,
84    /// DDL). Any rows the statement produces are read and **discarded**; the
85    /// returned count is the command tag's affected-row count (for example the
86    /// number of inserted or updated rows).
87    ///
88    /// # Errors
89    ///
90    /// Returns a server error if the statement fails, or [`Error::Closed`] if
91    /// the connection is gone.
92    pub async fn execute<E: Executor>(&self, executor: &E) -> Result<u64, Error> {
93        executor.execute(self.sql, self.params).await
94    }
95
96    /// Runs the statement and returns a stream of rows.
97    pub async fn fetch_rows<E: Executor>(&self, executor: &E) -> Result<RowStream, Error> {
98        executor.fetch_rows(self.sql, self.params, 0).await
99    }
100
101    /// Collects all rows into a `Vec<T>`.
102    ///
103    /// The result is unbounded: use [`Query::fetch_rows`] to process a large
104    /// result without holding it all in memory.
105    pub async fn fetch_all<E: Executor, T: FromRow>(&self, executor: &E) -> Result<Vec<T>, Error> {
106        let mut rows = executor.fetch_rows(self.sql, self.params, 0).await?;
107        let mut out = Vec::new();
108        while let Some(row) = rows.next().await {
109            out.push(T::from_row(&row?)?);
110        }
111        Ok(out)
112    }
113
114    /// Returns exactly one row, or [`Error::RowNotFound`].
115    pub async fn fetch_one<E: Executor, T: FromRow>(&self, executor: &E) -> Result<T, Error> {
116        let mut rows = executor.fetch_rows(self.sql, self.params, 1).await?;
117        match rows.next().await {
118            Some(row) => T::from_row(&row?),
119            None => Err(Error::RowNotFound),
120        }
121    }
122
123    /// Returns the first row, if any.
124    pub async fn fetch_optional<E: Executor, T: FromRow>(&self, executor: &E) -> Result<Option<T>, Error> {
125        let mut rows = executor.fetch_rows(self.sql, self.params, 1).await?;
126        match rows.next().await {
127            Some(row) => Ok(Some(T::from_row(&row?)?)),
128            None => Ok(None),
129        }
130    }
131}
132
133/// A prepared query decoded into `T`.
134pub struct QueryAs<'a, T> {
135    query: Query<'a>,
136    _marker: PhantomData<fn() -> T>,
137}
138
139impl<'a, T: FromRow> QueryAs<'a, T> {
140    /// Builds a typed query from SQL and already-built parameters.
141    pub fn new(sql: &'a str, params: &'a [&'a dyn ToSql]) -> Self {
142        QueryAs {
143            query: Query::new(sql, params),
144            _marker: PhantomData,
145        }
146    }
147
148    /// Runs the statement and returns the number of affected rows.
149    ///
150    /// See [`Query::execute`]: rows produced by the statement are discarded.
151    pub async fn execute<E: Executor>(&self, executor: &E) -> Result<u64, Error> {
152        self.query.execute(executor).await
153    }
154
155    /// Runs the statement and returns a stream of rows.
156    pub async fn fetch_rows<E: Executor>(&self, executor: &E) -> Result<RowStream, Error> {
157        self.query.fetch_rows(executor).await
158    }
159
160    /// Collects all rows into a `Vec<T>`.
161    pub async fn fetch_all<E: Executor>(&self, executor: &E) -> Result<Vec<T>, Error> {
162        self.query.fetch_all::<E, T>(executor).await
163    }
164
165    /// Returns exactly one row, or [`Error::RowNotFound`].
166    pub async fn fetch_one<E: Executor>(&self, executor: &E) -> Result<T, Error> {
167        self.query.fetch_one::<E, T>(executor).await
168    }
169
170    /// Returns the first row, if any.
171    pub async fn fetch_optional<E: Executor>(&self, executor: &E) -> Result<Option<T>, Error> {
172        self.query.fetch_optional::<E, T>(executor).await
173    }
174}