tokio_postgres/
lib.rs

1//! An asynchronous, pipelined, PostgreSQL client.
2//!
3//! # Example
4//!
5//! ```no_run
6//! use tokio_postgres::{NoTls, Error};
7//!
8//! # #[cfg(not(feature = "runtime"))] fn main() {}
9//! # #[cfg(feature = "runtime")]
10//! #[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
11//! async fn main() -> Result<(), Error> {
12//!     // Connect to the database.
13//!     let (client, connection) =
14//!         tokio_postgres::connect("host=localhost user=postgres", NoTls).await?;
15//!
16//!     // The connection object performs the actual communication with the database,
17//!     // so spawn it off to run on its own.
18//!     tokio::spawn(async move {
19//!         if let Err(e) = connection.await {
20//!             eprintln!("connection error: {}", e);
21//!         }
22//!     });
23//!
24//!     // Now we can execute a simple statement that just returns its parameter.
25//!     let rows = client
26//!         .query("SELECT $1::TEXT", &[&"hello world"])
27//!         .await?;
28//!
29//!     // And then check that we got back the same string we sent over.
30//!     let value: &str = rows[0].get(0);
31//!     assert_eq!(value, "hello world");
32//!
33//!     Ok(())
34//! }
35//! ```
36//!
37//! # Behavior
38//!
39//! Calling a method like `Client::query` on its own does nothing. The associated request is not sent to the database
40//! until the future returned by the method is first polled. Requests are executed in the order that they are first
41//! polled, not in the order that their futures are created.
42//!
43//! # Pipelining
44//!
45//! The client supports *pipelined* requests. Pipelining can improve performance in use cases in which multiple,
46//! independent queries need to be executed. In a traditional workflow, each query is sent to the server after the
47//! previous query completes. In contrast, pipelining allows the client to send all of the queries to the server up
48//! front, minimizing time spent by one side waiting for the other to finish sending data:
49//!
50//! ```not_rust
51//!             Sequential                              Pipelined
52//! | Client         | Server          |    | Client         | Server          |
53//! |----------------|-----------------|    |----------------|-----------------|
54//! | send query 1   |                 |    | send query 1   |                 |
55//! |                | process query 1 |    | send query 2   | process query 1 |
56//! | receive rows 1 |                 |    | send query 3   | process query 2 |
57//! | send query 2   |                 |    | receive rows 1 | process query 3 |
58//! |                | process query 2 |    | receive rows 2 |                 |
59//! | receive rows 2 |                 |    | receive rows 3 |                 |
60//! | send query 3   |                 |
61//! |                | process query 3 |
62//! | receive rows 3 |                 |
63//! ```
64//!
65//! In both cases, the PostgreSQL server is executing the queries sequentially - pipelining just allows both sides of
66//! the connection to work concurrently when possible.
67//!
68//! Pipelining happens automatically when futures are polled concurrently (for example, by using the futures `join`
69//! combinator):
70//!
71//! ```rust
72//! use futures_util::future;
73//! use std::future::Future;
74//! use tokio_postgres::{Client, Error, Statement};
75//!
76//! async fn pipelined_prepare(
77//!     client: &Client,
78//! ) -> Result<(Statement, Statement), Error>
79//! {
80//!     future::try_join(
81//!         client.prepare("SELECT * FROM foo"),
82//!         client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)")
83//!     ).await
84//! }
85//! ```
86//!
87//! # Runtime
88//!
89//! The client works with arbitrary `AsyncRead + AsyncWrite` streams. Convenience APIs are provided to handle the
90//! connection process, but these are gated by the `runtime` Cargo feature, which is enabled by default. If disabled,
91//! all dependence on the tokio runtime is removed.
92//!
93//! # SSL/TLS support
94//!
95//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
96//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
97//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
98//! crates, respectively.
99//!
100//! # Features
101//!
102//! The following features can be enabled from `Cargo.toml`:
103//!
104//! | Feature | Description | Extra dependencies | Default |
105//! | ------- | ----------- | ------------------ | ------- |
106//! | `runtime` | Enable convenience API for the connection process based on the `tokio` crate. | [tokio](https://crates.io/crates/tokio) 1.0 with the features `net` and `time` | yes |
107//! | `array-impls` | Enables `ToSql` and `FromSql` trait impls for arrays | - | no |
108//! | `with-bit-vec-0_6` | Enable support for the `bit-vec` crate. | [bit-vec](https://crates.io/crates/bit-vec) 0.6 | no |
109//! | `with-chrono-0_4` | Enable support for the `chrono` crate. | [chrono](https://crates.io/crates/chrono) 0.4 | no |
110//! | `with-eui48-0_4` | Enable support for the 0.4 version of the `eui48` crate. This is deprecated and will be removed. | [eui48](https://crates.io/crates/eui48) 0.4 | no |
111//! | `with-eui48-1` | Enable support for the 1.0 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 1.0 | no |
112//! | `with-geo-types-0_6` | Enable support for the 0.6 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.6.0) 0.6 | no |
113//! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no |
114//! | `with-jiff-0_1` | Enable support for the 0.1 version of the `jiff` crate. | [jiff](https://crates.io/crates/jiff/0.1.0) 0.1 | no |
115//! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no |
116//! | `with-uuid-0_8` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 0.8 | no |
117//! | `with-uuid-1` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 1.0 | no |
118//! | `with-time-0_2` | Enable support for the 0.2 version of the `time` crate. | [time](https://crates.io/crates/time/0.2.0) 0.2 | no |
119//! | `with-time-0_3` | Enable support for the 0.3 version of the `time` crate. | [time](https://crates.io/crates/time/0.3.0) 0.3 | no |
120#![warn(rust_2018_idioms, clippy::all, missing_docs)]
121
122pub use crate::cancel_token::CancelToken;
123pub use crate::client::Client;
124pub use crate::config::Config;
125pub use crate::connection::Connection;
126pub use crate::copy_in::CopyInSink;
127pub use crate::copy_out::CopyOutStream;
128use crate::error::DbError;
129pub use crate::error::Error;
130pub use crate::generic_client::GenericClient;
131pub use crate::portal::Portal;
132pub use crate::query::RowStream;
133pub use crate::row::{Row, SimpleQueryRow};
134pub use crate::simple_query::{SimpleColumn, SimpleQueryStream};
135#[cfg(feature = "runtime")]
136pub use crate::socket::Socket;
137pub use crate::statement::{Column, Statement};
138#[cfg(feature = "runtime")]
139use crate::tls::MakeTlsConnect;
140pub use crate::tls::NoTls;
141pub use crate::to_statement::ToStatement;
142pub use crate::transaction::Transaction;
143pub use crate::transaction_builder::{IsolationLevel, TransactionBuilder};
144use crate::types::ToSql;
145use std::sync::Arc;
146
147pub mod binary_copy;
148mod bind;
149#[cfg(feature = "runtime")]
150mod cancel_query;
151mod cancel_query_raw;
152mod cancel_token;
153mod client;
154mod codec;
155pub mod config;
156#[cfg(feature = "runtime")]
157mod connect;
158mod connect_raw;
159#[cfg(feature = "runtime")]
160mod connect_socket;
161mod connect_tls;
162mod connection;
163mod copy_in;
164mod copy_out;
165pub mod error;
166mod generic_client;
167#[cfg(not(target_arch = "wasm32"))]
168mod keepalive;
169mod maybe_tls_stream;
170mod portal;
171mod prepare;
172mod query;
173pub mod row;
174mod simple_query;
175#[cfg(feature = "runtime")]
176mod socket;
177mod statement;
178pub mod tls;
179mod to_statement;
180mod transaction;
181mod transaction_builder;
182pub mod types;
183
184/// A convenience function which parses a connection string and connects to the database.
185///
186/// See the documentation for [`Config`] for details on the connection string format.
187///
188/// Requires the `runtime` Cargo feature (enabled by default).
189///
190/// [`Config`]: config/struct.Config.html
191#[cfg(feature = "runtime")]
192pub async fn connect<T>(
193    config: &str,
194    tls: T,
195) -> Result<(Client, Connection<Socket, T::Stream>), Error>
196where
197    T: MakeTlsConnect<Socket>,
198{
199    let config = config.parse::<Config>()?;
200    config.connect(tls).await
201}
202
203/// An asynchronous notification.
204#[derive(Clone, Debug)]
205pub struct Notification {
206    process_id: i32,
207    channel: String,
208    payload: String,
209}
210
211impl Notification {
212    /// The process ID of the notifying backend process.
213    pub fn process_id(&self) -> i32 {
214        self.process_id
215    }
216
217    /// The name of the channel that the notify has been raised on.
218    pub fn channel(&self) -> &str {
219        &self.channel
220    }
221
222    /// The "payload" string passed from the notifying process.
223    pub fn payload(&self) -> &str {
224        &self.payload
225    }
226}
227
228/// An asynchronous message from the server.
229#[allow(clippy::large_enum_variant)]
230#[derive(Debug, Clone)]
231#[non_exhaustive]
232pub enum AsyncMessage {
233    /// A notice.
234    ///
235    /// Notices use the same format as errors, but aren't "errors" per-se.
236    Notice(DbError),
237    /// A notification.
238    ///
239    /// Connections can subscribe to notifications with the `LISTEN` command.
240    Notification(Notification),
241}
242
243/// Message returned by the `SimpleQuery` stream.
244#[derive(Debug)]
245#[non_exhaustive]
246pub enum SimpleQueryMessage {
247    /// A row of data.
248    Row(SimpleQueryRow),
249    /// A statement in the query has completed.
250    ///
251    /// The number of rows modified or selected is returned.
252    CommandComplete(u64),
253    /// Column values of the proceeding row values
254    RowDescription(Arc<[SimpleColumn]>),
255}
256
257fn slice_iter<'a>(
258    s: &'a [&'a (dyn ToSql + Sync)],
259) -> impl ExactSizeIterator<Item = &'a dyn ToSql> + 'a {
260    s.iter().map(|s| *s as _)
261}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy