oxisql_postgres/lib.rs
1#![forbid(unsafe_code)]
2#![warn(missing_docs)]
3//! `oxisql-postgres` — Pure-Rust PostgreSQL backend for OxiSQL.
4//!
5//! Provides [`PgConnection`], which implements [`oxisql_core::Connection`]
6//! over `tokio-postgres` (no `libpq`, no C bindings) with TLS support via
7//! `rustls` + `rustls-rustcrypto` (no `ring`, no `openssl-sys`).
8//!
9//! # Wire protocol compliance
10//!
11//! This crate uses the PostgreSQL **Frontend/Backend Protocol version 3**
12//! (introduced in PostgreSQL 7.4) as implemented by `tokio-postgres`. All
13//! client–server communication is framed according to that specification:
14//!
15//! | API path | Wire mode |
16//! |-----------------------------------|---------------------------------------|
17//! | `execute` / `query` | Extended-query protocol (`Parse` → `Bind` → `Execute` → `Sync`) |
18//! | `execute_batch` / `begin_txn` | Simple-query protocol (`Query` message) |
19//! | `query_binary` | Extended-query with explicit type OIDs; results decoded in **binary format** (format code 1) |
20//! | `prepare` / `describe` | Extended-query `Parse` + `Describe` only (no `Execute`) |
21//! | `pipeline` | Multiple extended-query cycles flushed as a single send buffer |
22//!
23//! ## Limitations
24//!
25//! * **Logical replication** (Streaming Replication Protocol) is not supported.
26//! * **Cancellation** via the `CancelRequest` flow is available through
27//! [`PgConnection::cancel_token`] → [`PostgresCancelToken::cancel_query`].
28//! It is not exposed at the `Connection` trait level; individual queries can
29//! also be cancelled by dropping the `Future`.
30//! * Notification delivery via `LISTEN` is only available on connections
31//! created through [`PgConnection::connect`] (not `from_client`), because
32//! the background `Connection` driver that routes `NotificationResponse`
33//! messages is only spawned in that code path.
34//! * PostgreSQL protocol v2 (pre-7.4) servers are not supported.
35//!
36//! # Quick start (no TLS)
37//!
38//! ```rust,no_run
39//! # #[tokio::main]
40//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
41//! use oxisql_postgres::{PgConnection, TlsMode};
42//! use oxisql_core::Connection;
43//!
44//! let conn = PgConnection::connect(
45//! "host=localhost port=5432 user=postgres password=secret",
46//! TlsMode::Disabled,
47//! ).await?;
48//!
49//! conn.execute("CREATE TABLE IF NOT EXISTS t (id BIGINT)", &[]).await?;
50//! # Ok(())
51//! # }
52//! ```
53//!
54//! # Quick start (TLS via OxiTLS)
55//!
56//! ```rust,no_run
57//! # #[tokio::main]
58//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
59//! use oxisql_postgres::{PgConnection, TlsMode};
60//!
61//! // Build a ClientConfig trusting the Mozilla CA bundle.
62//! // Requires the "pure" + "webpki-roots" features of oxitls (the defaults).
63//! let root_store = oxitls::webpki_root_certs();
64//! let client_cfg = oxitls::client_config(root_store)
65//! .map_err(|e| format!("TLS cfg: {e}"))?;
66//!
67//! let conn = PgConnection::connect(
68//! "host=db.example.com port=5432 user=postgres sslmode=require",
69//! TlsMode::Rustls(client_cfg),
70//! ).await?;
71//! # Ok(())
72//! # }
73//! ```
74
75mod builder;
76mod connection;
77mod copy;
78mod error;
79mod notify;
80mod pipeline;
81mod prepared;
82mod tls;
83pub mod types;
84
85pub use builder::{PgConnectionBuilder, TlsMode};
86pub use connection::{
87 parse_pg_conn_str, ColumnDescription, PgConnParts, PgConnection, PgTransaction,
88 PostgresCancelToken,
89};
90pub use error::PgError;
91pub use notify::{NotificationStream, PgNotification};
92pub use pipeline::{PgPipeline, PipelineResult};
93pub use prepared::PgPrepared;
94pub use types::{pg_row_to_row, value_to_param, OwnedParam};