prices come from the csv globals now, a json cost is just an override. DATABASE_URL defaults to postgres:///scroll when unset.
73 lines
2.2 KiB
Rust
73 lines
2.2 KiB
Rust
use std::time::Duration;
|
|
use sqlx::postgres::{PgConnectOptions, PgPoolOptions};
|
|
use sqlx::{ConnectOptions, PgPool};
|
|
use crate::error::Result;
|
|
pub const DEFAULT_URL: &str = "postgres:///scroll";
|
|
#[derive(Debug, Clone)]
|
|
pub struct DatabaseConfig {
|
|
pub url: String,
|
|
pub max_connections: u32,
|
|
pub acquire_timeout: Duration,
|
|
pub statement_log_threshold: Duration,
|
|
}
|
|
impl Default for DatabaseConfig {
|
|
fn default() -> Self {
|
|
Self::new(DEFAULT_URL)
|
|
}
|
|
}
|
|
impl DatabaseConfig {
|
|
pub fn new(url: impl Into<String>) -> Self {
|
|
Self {
|
|
url: url.into(),
|
|
max_connections: 8,
|
|
acquire_timeout: Duration::from_secs(5),
|
|
statement_log_threshold: Duration::from_millis(250),
|
|
}
|
|
}
|
|
pub fn from_env() -> Option<Self> {
|
|
let url = std::env::var("DATABASE_URL")
|
|
.ok()
|
|
.filter(|value| !value.trim().is_empty())
|
|
.unwrap_or_else(|| DEFAULT_URL.to_owned());
|
|
let mut config = Self::new(url);
|
|
if let Some(max) = std::env::var("DATABASE_MAX_CONNECTIONS")
|
|
.ok()
|
|
.and_then(|value| value.parse().ok())
|
|
{
|
|
config.max_connections = max;
|
|
}
|
|
Some(config)
|
|
}
|
|
}
|
|
#[derive(Debug, Clone)]
|
|
pub struct Database {
|
|
pool: PgPool,
|
|
}
|
|
impl Database {
|
|
pub async fn connect(config: &DatabaseConfig) -> Result<Self> {
|
|
let options: PgConnectOptions =
|
|
config.url.parse::<PgConnectOptions>()?.log_slow_statements(
|
|
tracing::log::LevelFilter::Warn,
|
|
config.statement_log_threshold,
|
|
);
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(config.max_connections)
|
|
.acquire_timeout(config.acquire_timeout)
|
|
.connect_with(options)
|
|
.await?;
|
|
Ok(Self { pool })
|
|
}
|
|
pub async fn migrate(&self) -> Result<()> {
|
|
sqlx::migrate!("./migrations").run(&self.pool).await?;
|
|
Ok(())
|
|
}
|
|
pub fn pool(&self) -> &PgPool {
|
|
&self.pool
|
|
}
|
|
pub async fn server_version(&self) -> Result<String> {
|
|
let version: String = sqlx::query_scalar("select version()")
|
|
.fetch_one(&self.pool)
|
|
.await?;
|
|
Ok(version)
|
|
}
|
|
}
|