#![doc = include_str!("../README.md")]
#![forbid(unsafe_code)]
#![cfg_attr(any(feature = "io-uring", feature = "compio"), feature(async_iterator, gen_blocks))]
#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
mod cancel;
mod client;
mod column;
mod config;
mod driver;
mod execute;
mod from_sql;
mod prepare;
mod protocol;
mod query;
mod session;
pub mod copy;
pub mod error;
pub mod iter;
pub mod pool;
pub mod row;
pub mod statement;
pub mod transaction;
pub mod types;
#[cfg(feature = "quic")]
pub mod proxy;
#[cfg(feature = "quic")]
pub use driver::quic::QuicStream;
#[cfg(feature = "compio")]
pub use driver::compio::CompIoDriver;
pub use self::{
client::Client,
column::Column,
config::Config,
driver::Driver,
error::Error,
execute::{Execute, ExecuteBlocking},
from_sql::FromSqlExt,
query::{RowSimpleStream, RowSimpleStreamOwned, RowStream, RowStreamOwned},
session::Session,
statement::Statement,
};
#[cfg(feature = "compat")]
pub mod compat {
}
pub mod dev {
pub use crate::client::{ClientBorrow, ClientBorrowMut};
pub use crate::copy::r#Copy;
pub use crate::driver::codec::{Response, encode::Encode, response::IntoResponse};
}
use core::{future::Future, pin::Pin, sync::atomic::AtomicUsize};
use xitca_io::io::AsyncIo;
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug)]
pub struct Postgres {
cfg: Result<Config, Error>,
}
impl Postgres {
pub fn new<C>(cfg: C) -> Self
where
Config: TryFrom<C>,
Error: From<<Config as TryFrom<C>>::Error>,
{
Self {
cfg: Config::try_from(cfg).map_err(Into::into),
}
}
}
impl Postgres {
pub async fn connect(self) -> Result<(Client, Driver), Error> {
let mut cfg = self.cfg?;
driver::connect(&mut cfg).await
}
pub async fn connect_io<Io>(self, io: Io) -> Result<(Client, Driver), Error>
where
Io: AsyncIo + Send + 'static,
{
let mut cfg = self.cfg?;
driver::connect_io(io, &mut cfg).await
}
#[cfg(feature = "quic")]
pub async fn connect_quic(self) -> Result<(Client, Driver), Error> {
use config::Host;
let mut cfg = self.cfg?;
cfg.host = cfg
.host
.into_iter()
.map(|host| match host {
Host::Tcp(host) => Host::Quic(host),
host => host,
})
.collect();
driver::connect(&mut cfg).await
}
}
type BoxedFuture<'a, O> = Pin<Box<dyn Future<Output = O> + Send + 'a>>;
fn _assert_send<F: Send>(_: F) {}
fn _assert_send2<F: Send>() {}
fn _assert_connect_send() {
_assert_send(Postgres::new("postgres://postgres:postgres@localhost/postgres").connect());
}
fn _assert_driver_send() {
_assert_send2::<Driver>();
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
async fn config_error() {
let mut cfg = Config::new();
cfg.dbname("postgres").user("postgres").password("postgres");
let mut cfg1 = cfg.clone();
cfg1.host("localhost");
Postgres::new(cfg1).connect().await.err().unwrap();
cfg.port(5432);
Postgres::new(cfg).connect().await.err().unwrap();
}
}