use crate::sql::config::Engine;
pub enum ConnectionPool {
Postgres(sqlx::PgPool),
Mysql(sqlx::MySqlPool),
Sqlite(sqlx::SqlitePool),
}
pub async fn build(engine: Engine, dsn: &str, read_only: bool) -> Result<ConnectionPool, String> {
match engine {
Engine::Postgres => sqlx::postgres::PgPoolOptions::new()
.max_connections(5)
.connect(dsn)
.await
.map(ConnectionPool::Postgres)
.map_err(|e| format!("postgres connect: {e}")),
Engine::Mysql => sqlx::mysql::MySqlPoolOptions::new()
.max_connections(5)
.connect(dsn)
.await
.map(ConnectionPool::Mysql)
.map_err(|e| format!("mysql connect: {e}")),
Engine::Sqlite => {
let opts = dsn
.parse::<sqlx::sqlite::SqliteConnectOptions>()
.map_err(|e| format!("sqlite dsn: {e}"))?
.read_only(read_only);
sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(5)
.connect_with(opts)
.await
.map(ConnectionPool::Sqlite)
.map_err(|e| format!("sqlite connect: {e}"))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn builds_sqlite_pool_readonly() {
let dir = std::env::temp_dir();
let path = dir.join(format!("sqlgw_pool_test_{}.db", std::process::id()));
let rw_url = format!("sqlite://{}?mode=rwc", path.display());
{
let rw = sqlx::sqlite::SqlitePool::connect(&rw_url).await.unwrap();
sqlx::query("CREATE TABLE IF NOT EXISTS t (id INTEGER)")
.execute(&rw)
.await
.unwrap();
rw.close().await;
}
let ro_url = format!("sqlite://{}", path.display());
let pool = build(Engine::Sqlite, &ro_url, true).await.unwrap();
assert!(matches!(pool, ConnectionPool::Sqlite(_)));
let _ = std::fs::remove_file(&path);
}
#[tokio::test]
async fn builds_sqlite_pool_in_memory() {
let pool = build(Engine::Sqlite, "sqlite::memory:", false)
.await
.unwrap();
assert!(matches!(pool, ConnectionPool::Sqlite(_)));
}
}