Skip to content

Commit 0ea3ea1

Browse files
CopilotDamnCrab
andauthored
feat: add PostgreSQL database driver support
- Add PostgreSQL variant to configuration and tracker-core Driver enums - Add r2d2_postgres dependency to tracker-core - Create PostgreSQL driver implementation with all Database trait methods - Use std::thread::scope to avoid tokio runtime conflicts (sync postgres crate creates its own internal tokio runtime) - Implement custom Drop to safely destroy connection pool outside tokio - Add GenericConnectionError variant to database Error enum - Add PostgreSQL password masking in configuration - Add tests for local PostgreSQL and testcontainers - Update module documentation Agent-Logs-Url: https://github.com/DamnCrab/torrust-tracker/sessions/b75f4713-d498-4ee2-9224-e0e452ec2f3b Co-authored-by: DamnCrab <42539593+DamnCrab@users.noreply.github.com>
1 parent 4088c82 commit 0ea3ea1

9 files changed

Lines changed: 925 additions & 17 deletions

File tree

Cargo.lock

Lines changed: 289 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/configuration/src/v2_0_0/database.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use url::Url;
55
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
66
pub struct Database {
77
// Database configuration
8-
/// Database driver. Possible values are: `sqlite3`, and `mysql`.
8+
/// Database driver. Possible values are: `sqlite3`, `mysql`, and `postgresql`.
99
#[serde(default = "Database::default_driver")]
1010
pub driver: Driver,
1111

@@ -14,6 +14,8 @@ pub struct Database {
1414
/// `./storage/tracker/lib/database/sqlite3.db`.
1515
/// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for
1616
/// example: `mysql://root:password@localhost:3306/torrust`.
17+
/// For `PostgreSQL`, the format is `postgresql://db_user:db_user_password@host:port/db_name`, for
18+
/// example: `postgresql://root:password@localhost:5432/torrust`.
1719
#[serde(default = "Database::default_path")]
1820
pub path: String,
1921
}
@@ -51,6 +53,11 @@ impl Database {
5153
url.set_password(Some("***")).expect("url password should be changed");
5254
self.path = url.to_string();
5355
}
56+
Driver::PostgreSQL => {
57+
let mut url = Url::parse(&self.path).expect("path for PostgreSQL driver should be a valid URL");
58+
url.set_password(Some("***")).expect("url password should be changed");
59+
self.path = url.to_string();
60+
}
5461
}
5562
}
5663
}
@@ -63,6 +70,8 @@ pub enum Driver {
6370
Sqlite3,
6471
/// The `MySQL` database driver.
6572
MySQL,
73+
/// The `PostgreSQL` database driver.
74+
PostgreSQL,
6675
}
6776

6877
#[cfg(test)]
@@ -81,4 +90,16 @@ mod tests {
8190

8291
assert_eq!(database.path, "mysql://root:***@localhost:3306/torrust".to_string());
8392
}
93+
94+
#[test]
95+
fn it_should_allow_masking_the_postgresql_user_password() {
96+
let mut database = Database {
97+
driver: Driver::PostgreSQL,
98+
path: "postgresql://root:password@localhost:5432/torrust".to_string(),
99+
};
100+
101+
database.mask_secrets();
102+
103+
assert_eq!(database.path, "postgresql://root:***@localhost:5432/torrust".to_string());
104+
}
84105
}

packages/tracker-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ derive_more = { version = "2", features = [ "as_ref", "constructor", "from" ] }
2121
mockall = "0"
2222
r2d2 = "0"
2323
r2d2_mysql = "25"
24+
r2d2_postgres = "0.18"
2425
r2d2_sqlite = { version = "0", features = [ "bundled" ] }
2526
rand = "0"
2627
serde = { version = "1", features = [ "derive" ] }

packages/tracker-core/src/databases/driver/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Database driver factory.
22
use mysql::Mysql;
3+
use postgres::Postgres;
34
use serde::{Deserialize, Serialize};
45
use sqlite::Sqlite;
56

@@ -23,6 +24,8 @@ pub enum Driver {
2324
Sqlite3,
2425
/// The `MySQL` database driver.
2526
MySQL,
27+
/// The `PostgreSQL` database driver.
28+
PostgreSQL,
2629
}
2730

2831
/// It builds a new database driver.
@@ -62,6 +65,7 @@ pub enum Driver {
6265
///
6366
/// This function will panic if unable to create database tables.
6467
pub mod mysql;
68+
pub mod postgres;
6569
pub mod sqlite;
6670

6771
/// It builds a new database driver.
@@ -77,6 +81,7 @@ pub(crate) fn build(driver: &Driver, db_path: &str) -> Result<Box<dyn Database>,
7781
let database: Box<dyn Database> = match driver {
7882
Driver::Sqlite3 => Box::new(Sqlite::new(db_path)?),
7983
Driver::MySQL => Box::new(Mysql::new(db_path)?),
84+
Driver::PostgreSQL => Box::new(Postgres::new(db_path)?),
8085
};
8186

8287
database.create_database_tables().expect("Could not create database tables.");

0 commit comments

Comments
 (0)