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 not exposed at the
27//! `Connection` trait level; individual queries can be cancelled by dropping
28//! the `Future`.
29//! * Notification delivery via `LISTEN` is only available on connections
30//! created through [`PgConnection::connect`] (not `from_client`), because
31//! the background `Connection` driver that routes `NotificationResponse`
32//! messages is only spawned in that code path.
33//! * PostgreSQL protocol v2 (pre-7.4) servers are not supported.
34//!
35//! # Quick start (no TLS)
36//!
37//! ```rust,no_run
38//! # #[tokio::main]
39//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
40//! use oxisql_postgres::{PgConnection, TlsMode};
41//! use oxisql_core::Connection;
42//!
43//! let conn = PgConnection::connect(
44//! "host=localhost port=5432 user=postgres password=secret",
45//! TlsMode::Disabled,
46//! ).await?;
47//!
48//! conn.execute("CREATE TABLE IF NOT EXISTS t (id BIGINT)", &[]).await?;
49//! # Ok(())
50//! # }
51//! ```
52//!
53//! # Quick start (TLS via OxiTLS)
54//!
55//! ```rust,no_run
56//! # #[tokio::main]
57//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
58//! use oxisql_postgres::{PgConnection, TlsMode};
59//!
60//! // Build a ClientConfig trusting the Mozilla CA bundle.
61//! // Requires the "pure" + "webpki-roots" features of oxitls (the defaults).
62//! let root_store = oxitls::webpki_root_certs();
63//! let client_cfg = oxitls::client_config(root_store)
64//! .map_err(|e| format!("TLS cfg: {e}"))?;
65//!
66//! let conn = PgConnection::connect(
67//! "host=db.example.com port=5432 user=postgres sslmode=require",
68//! TlsMode::Rustls(client_cfg),
69//! ).await?;
70//! # Ok(())
71//! # }
72//! ```
73
74mod builder;
75mod connection;
76mod copy;
77mod error;
78mod notify;
79mod pipeline;
80mod prepared;
81mod tls;
82pub mod types;
83
84pub use builder::{PgConnectionBuilder, TlsMode};
85pub use connection::{
86 parse_pg_conn_str, ColumnDescription, PgConnParts, PgConnection, PgTransaction,
87};
88pub use error::PgError;
89pub use notify::{NotificationStream, PgNotification};
90pub use pipeline::{PgPipeline, PipelineResult};
91pub use prepared::PgPrepared;
92pub use types::{pg_row_to_row, value_to_param, OwnedParam};