Skip to content

Commit

Permalink
refactor: [#599] extract types for torrust_index::config::v1::databas…
Browse files Browse the repository at this point in the history
…e::Database
  • Loading branch information
josecelano committed May 23, 2024
1 parent c7c9225 commit 28617b6
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub async fn run(configuration: Configuration, api_version: &Version) -> Running
settings.validate().expect("invalid settings");

// From [database] config
let database_connect_url = settings.database.connect_url.clone();
let database_connect_url = settings.database.connect_url.clone().to_string();
// From [importer] config
let importer_torrent_info_update_interval = settings.tracker_statistics_importer.torrent_info_update_interval;
let importer_port = settings.tracker_statistics_importer.port;
Expand Down
76 changes: 73 additions & 3 deletions src/config/v1/database.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,86 @@
use std::fmt;

use serde::{Deserialize, Serialize};

/// Database configuration.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Database {
/// The connection string for the database. For example: `sqlite://data.db?mode=rwc`.
pub connect_url: String,
/// The connection string for the database. For example:
///
/// Masked: `***`.
/// Sqlite: `sqlite://data.db?mode=rwc`.
/// Mysql: `mysql://root:root_secret_password@mysql:3306/torrust_index_e2e_testing`.
pub connect_url: ConnectOptions,
}

impl Default for Database {
fn default() -> Self {
Self {
connect_url: "sqlite://data.db?mode=rwc".to_string(),
connect_url: ConnectOptions::new("sqlite://data.db?mode=rwc"),
}
}
}

/// This allows a particular case when we want to hide the connection options
/// because it contains secrets we don't want to show.
const DB_CONNECT_MASKED: &str = "***";

/// Prefix for connection to `SQLite` database.
const DB_CONNECT_SQLITE_PREFIX: &str = "sqlite://";

/// Prefix for connection to `MySQL` database.
const DB_CONNECT_MYSQL_PREFIX: &str = "mysql://";

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ConnectOptions(String);

impl ConnectOptions {
/// # Panics
///
/// Will panic if the connect options are empty.
#[must_use]
pub fn new(connect_options: &str) -> Self {
assert!(!connect_options.is_empty(), "database connect options cannot be empty");
assert!(
connect_options.starts_with(DB_CONNECT_SQLITE_PREFIX)
|| connect_options.starts_with(DB_CONNECT_MYSQL_PREFIX)
|| connect_options.starts_with(DB_CONNECT_MASKED),
"database driver not supported"
);

Self(connect_options.to_owned())
}

#[must_use]
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}

impl fmt::Display for ConnectOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

#[cfg(test)]
mod tests {
use super::ConnectOptions;

#[test]
#[should_panic(expected = "database connect options cannot be empty")]
fn database_connect_options_can_not_be_empty() {
drop(ConnectOptions::new(""));
}

#[test]
#[should_panic(expected = "database driver not supported")]
fn database_connect_options_only_supports_sqlite_and_mysql() {
drop(ConnectOptions::new("not-supported://"));
}

#[test]
fn database_connect_options_can_be_masked() {
drop(ConnectOptions::new("***"));
}
}
4 changes: 2 additions & 2 deletions src/config/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};

use self::api::Api;
use self::auth::{Auth, SecretKey};
use self::database::Database;
use self::database::{ConnectOptions, Database};
use self::image_cache::ImageCache;
use self::mail::Mail;
use self::net::Network;
Expand Down Expand Up @@ -58,7 +58,7 @@ impl Settings {

pub fn remove_secrets(&mut self) {
"***".clone_into(&mut self.tracker.token);
"***".clone_into(&mut self.database.connect_url);
self.database.connect_url = ConnectOptions::new("***");
"***".clone_into(&mut self.mail.password);
self.auth.secret_key = SecretKey::new("***");
}
Expand Down
2 changes: 1 addition & 1 deletion src/console/commands/tracker_statistics_importer/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub async fn import() {
eprintln!("Tracker url: {}", tracker_url.green());

let database = Arc::new(
database::connect(&settings.database.connect_url)
database::connect(&settings.database.connect_url.to_string())
.await
.expect("unable to connect to db"),
);
Expand Down
2 changes: 1 addition & 1 deletion src/web/api/client/v1/contexts/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl From<DomainAuth> for Auth {
impl From<DomainDatabase> for Database {
fn from(database: DomainDatabase) -> Self {
Self {
connect_url: database.connect_url,
connect_url: database.connect_url.to_string(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/common/contexts/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl From<DomainAuth> for Auth {
impl From<DomainDatabase> for Database {
fn from(database: DomainDatabase) -> Self {
Self {
connect_url: database.connect_url,
connect_url: database.connect_url.to_string(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/environments/app_starter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl AppStarter {

#[must_use]
pub fn database_connect_url(&self) -> String {
self.configuration.database.connect_url.clone()
self.configuration.database.connect_url.clone().to_string()
}
}

Expand Down
4 changes: 3 additions & 1 deletion tests/environments/isolated.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use tempfile::TempDir;
use torrust_index::config;
use torrust_index::config::v1::database::ConnectOptions;
use torrust_index::config::FREE_PORT;
use torrust_index::web::api::Version;

Expand Down Expand Up @@ -82,7 +83,8 @@ fn ephemeral(temp_dir: &TempDir) -> config::Settings {
configuration.tracker_statistics_importer.port = FREE_PORT;

// Ephemeral SQLite database
configuration.database.connect_url = format!("sqlite://{}?mode=rwc", random_database_file_path_in(temp_dir));
configuration.database.connect_url =
ConnectOptions::new(&format!("sqlite://{}?mode=rwc", random_database_file_path_in(temp_dir)));

configuration
}
Expand Down

0 comments on commit 28617b6

Please sign in to comment.