1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
//! This module contains functions and structures related to handling the
//! PostgreSQL database, specially regarding connections and database creation.
use bb8::Pool;
use bb8_diesel::DieselConnection;
use bb8_diesel::DieselConnectionManager;
use diesel::{Connection, PgConnection};
mod create;
/// Type representing a Diesel connection to a database.
pub type DBConnection = DieselConnection<PgConnection>;
/// Type representing a Diesel connection pool to a database.
pub type DBPool = Pool<DieselConnectionManager<PgConnection>>;
pub use create::create_database;
/// Generates a string to connect to PostgreSQL RDBMS, given a tenant name and
/// the database server endpoint (e.g. `localhost:5432`). This function
/// assumes a user `postgres` with a password `postgres`.
///
/// # TODO
/// The default configuration for user and password could open a security
/// hole if not accessing an RDBMS spawned using Docker Compose or Kubernetes.
/// Consider changing this on the future.
pub fn build_database_string(tenant: &str, server: &str) -> String {
format!("postgres://postgres:postgres@{}/{}", server, tenant)
}
/// Attempts to generate a single connection to the PostgreSQL RDBMS, without
/// error checks. This could be used to perform connections and evaluate if they
/// could actually be established.
///
/// This function needs the tenant name, which is equal to the database name,
/// and the server endpoint for the database (e.g. `localhost:5432`).
pub fn try_make_single_connection(
tenant: &str,
server: &str,
) -> Result<PgConnection, diesel::ConnectionError> {
let url = build_database_string(tenant, server);
PgConnection::establish(&url)
}
/// Creates a single connection to the PostgreSQL RDBMS, and panics if the
/// connection could not be established.
///
/// This function needs the tenant name, which is equal to the database name,
/// and the server endpoint for the database (e.g. `localhost:5432`).
pub fn make_single_connection(tenant: &str, server: &str) -> PgConnection {
try_make_single_connection(tenant, server)
.map_err(|e| panic!("Error establishing relational database connection: {}", e))
.unwrap()
}
/// Creates a connection pool to the PostgreSQL RDBMS, given a maximum number of
/// connections, and panics if the connections could not be established.
///
/// This function needs the tenant name, which is equal to the database name,
/// and the server endpoint for the database (e.g. `localhost:5432`).
pub async fn make_connection_pool(tenant: &str, server: &str, max_connections: u32) -> DBPool {
let url = build_database_string(tenant, server);
let manager = DieselConnectionManager::<PgConnection>::new(&url);
Pool::builder()
.max_size(max_connections)
.build(manager)
.await
.map_err(|e| panic!("Error creating database connection pool: {}", e))
.unwrap()
}