Skip to content

Commit

Permalink
feat: Add From impl to convert db config to ConnectOptions (#240)
Browse files Browse the repository at this point in the history
Add `From<Database>` impl for `ConnectOptions` to encapsulate the
conversion, which would make it easier if a consumer wants to override
the default `App#db_connection_options` method but keep some of our
defaults.
  • Loading branch information
spencewenski authored Jun 23, 2024
1 parent ef6e630 commit 46c9611
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 21 deletions.
25 changes: 6 additions & 19 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,18 @@ where
let mut service_registry = ServiceRegistry::new(&context);
A::services(&mut service_registry, &context).await?;

if service_registry.services.is_empty() {
warn!("No enabled services were registered, exiting.");
return Ok(());
}

#[cfg(feature = "cli")]
if crate::service::runner::handle_cli(&roadster_cli, &app_cli, &service_registry, &context)
.await?
{
return Ok(());
}

if service_registry.services.is_empty() {
warn!("No enabled services were registered, exiting.");
return Ok(());
}

#[cfg(feature = "db-sql")]
if context.config().database.auto_migrate {
A::M::up(context.db(), None).await?;
Expand Down Expand Up @@ -118,20 +118,7 @@ pub trait App: Send + Sync {

#[cfg(feature = "db-sql")]
fn db_connection_options(config: &AppConfig) -> RoadsterResult<ConnectOptions> {
let mut options = ConnectOptions::new(config.database.uri.to_string());
options
.connect_timeout(config.database.connect_timeout)
.acquire_timeout(config.database.acquire_timeout)
.min_connections(config.database.min_connections)
.max_connections(config.database.max_connections)
.sqlx_logging(false);
if let Some(idle_timeout) = config.database.idle_timeout {
options.idle_timeout(idle_timeout);
}
if let Some(max_lifetime) = config.database.max_lifetime {
options.max_lifetime(max_lifetime);
}
Ok(options)
Ok(ConnectOptions::from(&config.database))
}

/// Convert the [AppContext] to the custom [Self::State] that will be used throughout the app.
Expand Down
49 changes: 47 additions & 2 deletions src/config/database/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use sea_orm::ConnectOptions;
use serde_derive::{Deserialize, Serialize};
use serde_with::serde_as;
use std::time::Duration;
Expand All @@ -9,7 +10,7 @@ use validator::Validate;
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub struct Database {
/// This can be overridden with an environment variable, e.g. `ROADSTER.DATABASE.URI=postgres://example:example@example:1234/example_app`
/// This can be overridden with an environment variable, e.g. `ROADSTER__DATABASE__URI=postgres://example:example@example:1234/example_app`
pub uri: Url,
/// Whether to automatically apply migrations during the app's start up. Migrations can also
/// be manually performed via the `roadster migration [COMMAND]` CLI command.
Expand Down Expand Up @@ -39,11 +40,36 @@ impl Database {
}
}

impl From<Database> for ConnectOptions {
fn from(database: Database) -> Self {
ConnectOptions::from(&database)
}
}

impl From<&Database> for ConnectOptions {
fn from(database: &Database) -> Self {
let mut options = ConnectOptions::new(database.uri.to_string());
options
.connect_timeout(database.connect_timeout)
.acquire_timeout(database.acquire_timeout)
.min_connections(database.min_connections)
.max_connections(database.max_connections)
.sqlx_logging(false);
if let Some(idle_timeout) = database.idle_timeout {
options.idle_timeout(idle_timeout);
}
if let Some(max_lifetime) = database.max_lifetime {
options.max_lifetime(max_lifetime);
}
options
}
}

#[cfg(test)]
mod deserialize_tests {
use super::*;
use crate::util::test_util::TestCase;
use insta::assert_toml_snapshot;
use insta::{assert_debug_snapshot, assert_toml_snapshot};
use rstest::{fixture, rstest};

#[fixture]
Expand Down Expand Up @@ -77,4 +103,23 @@ mod deserialize_tests {

assert_toml_snapshot!(database);
}

#[test]
#[cfg_attr(coverage_nightly, coverage(off))]
fn db_config_to_connect_options() {
let db = Database {
uri: Url::parse("postgres://example:example@example:1234/example_app").unwrap(),
auto_migrate: true,
connect_timeout: Duration::from_secs(1),
acquire_timeout: Duration::from_secs(2),
idle_timeout: Some(Duration::from_secs(3)),
max_lifetime: Some(Duration::from_secs(4)),
min_connections: 10,
max_connections: 20,
};

let connect_options = ConnectOptions::from(&db);

assert_debug_snapshot!(connect_options);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
source: src/config/database/mod.rs
expression: connect_options
---
ConnectOptions {
url: "postgres://example:example@example:1234/example_app",
max_connections: Some(
20,
),
min_connections: Some(
10,
),
connect_timeout: Some(
1s,
),
idle_timeout: Some(
3s,
),
acquire_timeout: Some(
2s,
),
max_lifetime: Some(
4s,
),
sqlx_logging: false,
sqlx_logging_level: Info,
sqlx_slow_statements_logging_level: Off,
sqlx_slow_statements_logging_threshold: 1s,
sqlcipher_key: None,
schema_search_path: None,
test_before_acquire: true,
}

0 comments on commit 46c9611

Please sign in to comment.