Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ torrust-tracker-rest-api-core = { version = "3.0.0-develop", path = "packages/re
torrust-server-lib = { version = "3.0.0-develop", path = "packages/server-lib" }
torrust-clock = "3.0.0"
torrust-tracker-configuration = { version = "3.0.0-develop", path = "packages/configuration" }
torrust-tracker-primitives = { version = "3.0.0-develop", path = "packages/primitives" }
torrust-tracker-swarm-coordination-registry = { version = "3.0.0-develop", path = "packages/swarm-coordination-registry" }
torrust-tracker-udp-server = { version = "3.0.0-develop", path = "packages/udp-server" }
tracing = "0"
Expand Down
54 changes: 54 additions & 0 deletions docs/issues/open/1669-overhaul-packages/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,60 @@ the proposal, the reasoning, and a reference to any supporting artifact.

---

## DEC-14 — Move `Driver` enum from `configuration` to `primitives`

**Date**: 2026-06-18
**Status**: Adopted
**Related issue**: [#1908](https://github.com/torrust/torrust-tracker/issues/1908)

### Proposal considered

The `Driver` enum (`Sqlite3`, `MySQL`, `PostgreSQL`) was defined in
`torrust-tracker-configuration` as a TOML deserialization type, with a duplicate
copy living in `torrust-tracker-core::databases::driver`. The duplication required
pointless mapping code between two semantically identical enums.

### Alternative chosen

Move the `Driver` enum to `torrust-tracker-primitives`, eliminate the duplicate in
`tracker-core`, and remove the `configuration` re-export. All consumers import
`torrust_tracker_primitives::Driver` directly.

### Why this alternative was adopted

1. **Cross-cutting domain concept**: `Driver` is used by `configuration` (deserialization),
`tracker-core` (database initialization), and `persistence-benchmark` (CLI argument).
Placement in `primitives` reflects that it is a shared domain type, not
configuration plumbing.
2. **Eliminates duplication**: the `tracker-core` copy was a perfect duplicate of the
`configuration` enum. Removing it eliminates a maintenance hazard.
3. **Eliminates mapping code**: `setup.rs` previously had a `match` that converted
`configuration::Driver` → `tracker_core::databases::driver::Driver` — a pointless
identity mapping.
4. **`tracker-core` no longer needs `configuration` just for `Driver`**: the dependency
on `torrust-tracker-configuration` from `tracker-core` was partially due to `Driver`.
After the move, only the `Core` config type remains as a dependency.
5. **Shared parsing helpers**: `primitives::Driver` provides `FromStr` and `as_str()`,
making the CLI `--driver` argument easy to consume in `persistence-benchmark`
without manual string-to-enum mapping.

### Trade-offs accepted

- `torrust-tracker-primitives` gains one new dev-dependency: `serde_json`
(for serialization tests on the `Driver` enum).
- Breakage: all consumers that imported `torrust_tracker_configuration::Driver` or
`torrust_tracker_core::databases::driver::Driver` must be updated.

### Supporting artifacts

- `packages/primitives/src/driver.rs` — new module with the unified `Driver` enum
- `packages/tracker-core/src/databases/driver/mod.rs` — removed (duplicate)
- `packages/configuration/src/lib.rs` — removed `pub type Driver` re-export
- `packages/configuration/src/v2_0_0/database.rs` — `Driver` definition removed, now
imported from primitives

---

## DEC-10 — Move peer-count cap from a global constant to `AnnouncePolicy::max_peers_per_announce`

**Date**: 2026-06-09
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ keep that dependency. But the coupling for `Driver` specifically is eliminated.

## Verification

- [ ] DEC-XX added to `docs/issues/open/1669-overhaul-packages/DECISIONS.md`
- [ ] `Driver` defined in `primitives`, re-exported from `configuration`
- [ ] Duplicate in `tracker-core` removed
- [ ] Mapping in `setup.rs` simplified
- [ ] `cargo test --workspace` — pass
- [ ] `cargo machete` — pass
- [ ] `linter all` — pass
- [x] DEC-14 added to `docs/issues/open/1669-overhaul-packages/DECISIONS.md`
- [x] `Driver` defined in `primitives`, all consumers import it directly
- [x] Duplicate in `tracker-core` removed
- [x] Mapping in `setup.rs` simplified
- [x] `cargo test --workspace` — pass
- [x] `cargo machete` — pass (no new unused deps)
- [x] `linter all` — pass
1 change: 0 additions & 1 deletion packages/configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub type HttpApi = v2_0_0::tracker_api::HttpApi;
pub type HttpTracker = v2_0_0::http_tracker::HttpTracker;
pub type UdpTracker = v2_0_0::udp_tracker::UdpTracker;
pub type Database = v2_0_0::database::Database;
pub type Driver = v2_0_0::database::Driver;
pub type Threshold = v2_0_0::logging::Threshold;

pub type AccessTokens = HashMap<String, String>;
Expand Down
13 changes: 1 addition & 12 deletions packages/configuration/src/v2_0_0/database.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use torrust_tracker_primitives::Driver;
use url::Url;

#[allow(clippy::struct_excessive_bools)]
Expand Down Expand Up @@ -59,18 +60,6 @@ impl Database {
}
}

/// The database management system used by the tracker.
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Driver {
/// The `Sqlite3` database driver.
Sqlite3,
/// The `MySQL` database driver.
MySQL,
/// The `PostgreSQL` database driver.
PostgreSQL,
}

#[cfg(test)]
mod tests {

Expand Down
1 change: 1 addition & 0 deletions packages/persistence-benchmark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ testcontainers = "0"
tokio = { version = "1", features = [ "macros", "rt-multi-thread" ] }
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
torrust-tracker-core = { path = "../tracker-core" }
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use std::time::Duration;
use anyhow::{Context, Result, anyhow};
use testcontainers::{ContainerAsync, GenericImage};
use torrust_tracker_core::databases::SchemaMigrator;
use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_core::databases::setup::DatabaseStores;
use torrust_tracker_primitives::Driver;

mod mysql;
mod postgres;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub(super) async fn initialize(db_version: &str) -> Result<ActiveDatabase> {
.context("mysql container did not accept connections in time")?;

let mut config = configuration::Core::default();
config.database.driver = configuration::Driver::MySQL;
config.database.driver = torrust_tracker_primitives::Driver::MySQL;
config.database.path = mysql_database_url;
let database = initialize_database(&config).await;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub(super) async fn initialize(db_version: &str) -> Result<ActiveDatabase> {
.context("postgres container did not accept connections in time")?;

let mut config = configuration::Core::default();
config.database.driver = configuration::Driver::PostgreSQL;
config.database.driver = torrust_tracker_primitives::Driver::PostgreSQL;
config.database.path = postgres_database_url;
let database = initialize_database(&config).await;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(super) async fn initialize() -> ActiveDatabase {
));
let sqlite_db_path_as_string = sqlite_db_path.to_string_lossy().to_string();
let mut config = configuration::Core::default();
config.database.driver = configuration::Driver::Sqlite3;
config.database.driver = torrust_tracker_primitives::Driver::Sqlite3;
config.database.path = sqlite_db_path_as_string;

let database = initialize_database(&config).await;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::time::Duration;

use anyhow::Result;
use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_primitives::Driver;

use super::types::OpsCount;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::Result;
use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_primitives::Driver;

use super::types::{DbVersion, OpsCount};
use super::{driver_bench, metrics};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_primitives::Driver;

use super::types::DbVersion;
use super::{metrics, report};
Expand Down Expand Up @@ -30,7 +30,7 @@ mod tests {
use std::str::FromStr;
use std::time::Duration;

use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_primitives::Driver;

use super::build_report;
use crate::persistence_benchmark::metrics::OperationStats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::time::Instant;

use anyhow::Result;
use clap::Parser;
use torrust_tracker_core::databases::driver::Driver;
use torrust_tracker_primitives::Driver;

use super::types::{DbVersion, OpsCount};
use super::{operations, report, reporting};
Expand Down
5 changes: 4 additions & 1 deletion packages/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ version.workspace = true
torrust-peer-id = "0.1.0"
binascii = "0"
torrust-info-hash = "=0.2.0"
derive_more = { version = "2", features = [ "constructor" ] }
derive_more = { version = "2", features = [ "constructor", "display" ] }
serde = { version = "1", features = [ "derive" ] }
tdyne-peer-id = "1"
tdyne-peer-id-registry = "0"
thiserror = "2"
torrust-net-primitives = "0.1.0"
torrust-clock = "3.0.0"

[dev-dependencies]
serde_json = "1"
125 changes: 125 additions & 0 deletions packages/primitives/src/driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//! Database driver types.
//!
//! This module defines the [`Driver`] enum which identifies the database
//! management system used by the tracker. It is a cross-cutting domain
//! concept shared by configuration deserialization, database initialization,
//! and CLI tooling.

use std::str::FromStr;

use derive_more::Display;
use serde::{Deserialize, Serialize};

/// The database management system used by the tracker.
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Display, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Driver {
/// The `Sqlite3` database driver.
Sqlite3,
/// The `MySQL` database driver.
MySQL,
/// The `PostgreSQL` database driver.
PostgreSQL,
}

impl Driver {
/// Returns the stable lowercase identifier used by CLI and reports.
#[must_use]
pub fn as_str(&self) -> &'static str {
match self {
Self::Sqlite3 => "sqlite3",
Self::MySQL => "mysql",
Self::PostgreSQL => "postgresql",
}
}
}

impl FromStr for Driver {
type Err = String;

fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"sqlite3" => Ok(Self::Sqlite3),
"mysql" => Ok(Self::MySQL),
"postgresql" => Ok(Self::PostgreSQL),
_ => Err("driver must be one of: sqlite3, mysql, postgresql".to_string()),
}
}
}

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

#[test]
fn it_should_display_sqlite3() {
assert_eq!(Driver::Sqlite3.to_string(), "Sqlite3");
}

#[test]
fn it_should_display_mysql() {
assert_eq!(Driver::MySQL.to_string(), "MySQL");
}

#[test]
fn it_should_display_postgresql() {
assert_eq!(Driver::PostgreSQL.to_string(), "PostgreSQL");
}

#[test]
fn it_should_return_as_str_sqlite3() {
assert_eq!(Driver::Sqlite3.as_str(), "sqlite3");
}

#[test]
fn it_should_return_as_str_mysql() {
assert_eq!(Driver::MySQL.as_str(), "mysql");
}

#[test]
fn it_should_return_as_str_postgresql() {
assert_eq!(Driver::PostgreSQL.as_str(), "postgresql");
}

#[test]
fn it_should_parse_sqlite3() {
let driver: Result<Driver, _> = "sqlite3".parse();
assert_eq!(driver.unwrap(), Driver::Sqlite3);
}

#[test]
fn it_should_parse_mysql() {
let driver: Result<Driver, _> = "mysql".parse();
assert_eq!(driver.unwrap(), Driver::MySQL);
}

#[test]
fn it_should_parse_postgresql() {
let driver: Result<Driver, _> = "postgresql".parse();
assert_eq!(driver.unwrap(), Driver::PostgreSQL);
}

#[test]
fn it_should_fail_parsing_invalid_driver() {
let driver: Result<Driver, _> = "invalid".parse();
assert!(driver.is_err());
}

#[test]
fn it_should_serialize_sqlite3_to_lowercase() {
let serialized = serde_json::to_string(&Driver::Sqlite3).unwrap();
assert_eq!(serialized, "\"sqlite3\"");
}

#[test]
fn it_should_serialize_mysql_to_lowercase() {
let serialized = serde_json::to_string(&Driver::MySQL).unwrap();
assert_eq!(serialized, "\"mysql\"");
}

#[test]
fn it_should_serialize_postgresql_to_lowercase() {
let serialized = serde_json::to_string(&Driver::PostgreSQL).unwrap();
assert_eq!(serialized, "\"postgresql\"");
}
}
2 changes: 2 additions & 0 deletions packages/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! by the tracker server crate, but also by other crates in the Torrust
//! ecosystem.
pub mod announce;
pub mod driver;
pub mod mode;
pub mod number_of_bytes;
pub mod pagination;
Expand All @@ -22,6 +23,7 @@ pub mod swarm_metadata;
use std::collections::BTreeMap;

pub use announce::{AnnounceData, AnnounceEvent, AnnouncePolicy};
pub use driver::Driver;
pub use mode::PrivateMode;
pub use number_of_bytes::NumberOfBytes;
pub use policy::TrackerPolicy;
Expand Down
Loading
Loading