darkwing/database/user/repository.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
//! User repository module providing database access layer for user-related
//! operations.
//!
//! This module implements the repository pattern for user data access,
//! providing a trait-based abstraction over the actual database implementation.
use anyhow::Context;
use std::sync::Arc;
use crate::database::Database;
use async_trait::async_trait;
use mockall::automock;
use sqlx::query_as;
use super::User;
/// A thread-safe reference-counted pointer to a dynamic `UsersRepository` trait
/// object.
///
/// This type alias provides a convenient way to handle user repository
/// instances across multiple threads while maintaining proper reference
/// counting.
pub type DynUsersRepository = Arc<dyn UsersRepository + Send + Sync>;
/// Defines the interface for user-related database operations.
///
/// This trait provides a contract for implementing user repository operations,
/// allowing for different implementations (like production database, mock for
/// testing).
#[automock]
#[async_trait]
pub trait UsersRepository {
/// Retrieves a user by their unique identifier.
async fn get_user_by_id(&self, id: u64) -> anyhow::Result<User>;
}
/// Implementation of `UsersRepository` for the main database.
///
/// This implementation provides the actual database operations using SQLx
/// to interact with the underlying database.
#[async_trait]
impl UsersRepository for Database {
async fn get_user_by_id(&self, id: u64) -> anyhow::Result<User> {
query_as!(
User,
r#"
SELECT id, teamId, username, role
FROM users
WHERE id = ?
AND deleted_at IS NULL
"#,
id,
)
.fetch_one(&self.pool)
.await
.context("user was not found")
}
}