tank-postgres 0.44.0

Postgres driver implementation for Tank: the Rust data layer
Documentation
mod init;

#[cfg(test)]
mod tests {
    use super::init::init;
    use std::{env, path::PathBuf, sync::Mutex};
    use tank_core::{
        Connection, ConnectionPool, Driver, Executor, PoolConfig, Value, stream::StreamExt as _,
    };
    use tank_postgres::{PostgresConnection, PostgresDriver};
    use tank_tests::{execute_tests, init_logs, silent_logs};
    use url::Url;

    static MUTEX: Mutex<()> = Mutex::new(());
    static DRIVER: PostgresDriver = PostgresDriver::new();

    #[tokio::test]
    pub async fn postgres() {
        init_logs();
        let _guard = MUTEX.lock().unwrap();

        // Unencrypted
        let (url, container) = init(false).await;
        let container = container.expect("Could not launch the container");
        let mut pool = DRIVER
            .connect_pool(url.into(), PoolConfig::new())
            .await
            .expect("Failed to connect");
        execute_tests(&mut pool).await;
        drop(container);

        // SSL
        let (url, container) = init(true).await;
        let container = container.expect("Could not launch the SSL container");
        let mut pool = DRIVER
            .connect_pool(url.into(), PoolConfig::new())
            .await
            .expect("Failed to connect");
        execute_tests(&mut pool).await;
        drop(container);
    }

    #[tokio::test]
    async fn empty_array() {
        init_logs();
        let _guard = MUTEX.lock().unwrap();

        let (url, container) = init(false).await;
        let container = container.expect("Could not launch the container");
        let pool = DRIVER
            .connect_pool(url.into(), PoolConfig::new())
            .await
            .expect("Failed to connect");
        let mut connection = pool.get().await.expect("Could not get a connection");

        let mut stream = std::pin::pin!(connection.fetch("SELECT ARRAY[]::int[]"));
        let row = stream
            .next()
            .await
            .expect("No row returned")
            .expect("Could not decode the empty array");
        assert_eq!(
            row.values[0],
            Value::Array(Some(vec![].into()), Box::new(Value::Int32(None)), 0)
        );

        drop(container);
    }

    #[tokio::test]
    async fn wrong_url() {
        init_logs();
        silent_logs! {
            let pool = DRIVER.connect_pool("mysql://some_url".into(), PoolConfig::new()).await;
            assert!(pool.is_err() || pool.unwrap().get().await.is_err());
        }
    }

    #[tokio::test]
    async fn postgresql_url_scheme() {
        init_logs();
        let _guard = MUTEX.lock().unwrap();

        let (url, container) = init(false).await;
        let container = container.expect("Could not launch the container");
        let url = url.replacen("postgres://", "postgresql://", 1);
        let pool = DRIVER
            .connect_pool(url.into(), PoolConfig::new())
            .await
            .expect("Failed to build the pool");
        pool.get()
            .await
            .expect("Failed to connect using postgresql://");
        drop(container);
    }

    #[tokio::test]
    async fn check_tls() {
        init_logs();
        let _guard = MUTEX.lock().unwrap();

        let (url_full, container) = init(true).await;
        let url_full = Url::parse(&url_full).expect("Could not parse the url returned from init");
        let mut url_base = url_full.clone();
        url_base.set_query(None);
        let _container = container.expect("Could not launch container");
        let _ = PostgresConnection::connect(&PostgresDriver::new(), url_full.to_string().into())
            .await
            .expect("Connection should succeed");
        let url = url_base
            .query_pairs_mut()
            .extend_pairs(url_full.query_pairs().filter(|(k, _)| k != "sslrootcert"))
            .finish();
        let _ = PostgresConnection::connect(&PostgresDriver::new(), url.to_string().into())
            .await
            .expect_err("Connection should fail without sslrootcert");
        let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        unsafe {
            env::set_var(
                "PGSSLROOTCERT",
                path.join("tests/assets/root.crt").to_str().unwrap(),
            );
        }
        PostgresDriver::new()
            .connect_pool(url.to_string().into(), PoolConfig::new())
            .await
            .expect("Connection should succeed with environment variable replacing sslrootcert");
        unsafe {
            env::remove_var("PGSSLROOTCERT");
        }
        let _ = PostgresConnection::connect(&PostgresDriver::new(), url.to_string().into())
            .await
            .expect_err("Connection should fail again without sslrootcert");
    }
}