Skip to content

Commit

Permalink
feat: [#799] get user profiles endpoint now supports searching
Browse files Browse the repository at this point in the history
  • Loading branch information
mario-nt committed Jan 24, 2025
1 parent b6e4adf commit 9759a0c
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
7 changes: 6 additions & 1 deletion src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,12 @@ pub trait Database: Sync + Send {
async fn get_user_profile_from_username(&self, username: &str) -> Result<UserProfile, Error>;

/// Get all user profiles in a paginated form as `UserProfilesResponse`.
async fn get_user_profiles_paginated(&self, offset: u64, page_size: u8) -> Result<UserProfilesResponse, Error>;
async fn get_user_profiles_search_paginated(
&self,
search: &Option<String>,
offset: u64,
page_size: u8,
) -> Result<UserProfilesResponse, Error>;

/// Get `UserCompact` from `user_id`.
async fn get_user_compact_from_id(&self, user_id: i64) -> Result<UserCompact, Error>;
Expand Down
16 changes: 14 additions & 2 deletions src/databases/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,23 @@ impl Database for Mysql {
.map_err(|_| database::Error::UserNotFound)
}

async fn get_user_profiles_paginated(&self, offset: u64, limit: u8) -> Result<UserProfilesResponse, database::Error> {
let mut query_string = "SELECT * FROM torrust_user_profiles".to_string();
async fn get_user_profiles_search_paginated(
&self,
search: &Option<String>,
offset: u64,
limit: u8,
) -> Result<UserProfilesResponse, database::Error> {
let user_name = match search {
None => "%".to_string(),
Some(v) => format!("%{v}%"),
};

let mut query_string = "SELECT * FROM torrust_user_profiles WHERE username LIKE ?".to_string();

let count_query = format!("SELECT COUNT(*) as count FROM ({query_string}) AS count_table");

let count_result: Result<i64, database::Error> = query_as(&count_query)
.bind(user_name.clone())
.fetch_one(&self.pool)
.await
.map(|(v,)| v)
Expand All @@ -171,6 +182,7 @@ impl Database for Mysql {
query_string = format!("{query_string} LIMIT ?, ?");

let res: Vec<UserProfile> = sqlx::query_as::<_, UserProfile>(&query_string)
.bind(user_name.clone())
.bind(i64::saturating_add_unsigned(0, offset))
.bind(limit)
.fetch_all(&self.pool)
Expand Down
16 changes: 14 additions & 2 deletions src/databases/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,23 @@ impl Database for Sqlite {
.map_err(|_| database::Error::UserNotFound)
}

async fn get_user_profiles_paginated(&self, offset: u64, limit: u8) -> Result<UserProfilesResponse, database::Error> {
let mut query_string = "SELECT * FROM torrust_user_profiles".to_string();
async fn get_user_profiles_search_paginated(
&self,
search: &Option<String>,
offset: u64,
limit: u8,
) -> Result<UserProfilesResponse, database::Error> {
let user_name = match search {
None => "%".to_string(),
Some(v) => format!("%{v}%"),
};

let mut query_string = "SELECT * FROM torrust_user_profiles WHERE username LIKE ?".to_string();

let count_query = format!("SELECT COUNT(*) as count FROM ({query_string}) AS count_table");

let count_result: Result<i64, database::Error> = query_as(&count_query)
.bind(user_name.clone())
.fetch_one(&self.pool)
.await
.map(|(v,)| v)
Expand All @@ -172,6 +183,7 @@ impl Database for Sqlite {
query_string = format!("{query_string} LIMIT ?, ?");

let res: Vec<UserProfile> = sqlx::query_as::<_, UserProfile>(&query_string)
.bind(user_name.clone())
.bind(i64::saturating_add_unsigned(0, offset))
.bind(limit)
.fetch_all(&self.pool)
Expand Down
1 change: 1 addition & 0 deletions src/services/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ impl Default for CasbinConfiguration {
guest, GetTorrentInfo
guest, GenerateTorrentInfoListing
guest, GetCanonicalInfoHash
guest, GenerateUserProfilesListing
",
),
}
Expand Down
10 changes: 8 additions & 2 deletions src/services/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ fn no_email() -> String {
pub struct ListingRequest {
pub page_size: Option<u8>,
pub page: Option<u32>,
pub search: Option<String>,
}

/// Internal specification for user profiles listings.
#[derive(Debug, Deserialize)]
pub struct ListingSpecification {
pub offset: u64,
pub page_size: u8,
pub search: Option<String>,
}

pub struct RegistrationService {
Expand Down Expand Up @@ -401,7 +403,11 @@ impl ListingService {

let offset = u64::from(page * u32::from(page_size));

ListingSpecification { offset, page_size }
ListingSpecification {
search: request.search.clone(),
offset,
page_size,
}
}
}

Expand Down Expand Up @@ -504,7 +510,7 @@ impl DbUserProfileRepository {
/// It returns an error if there is a database error.
pub async fn generate_listing(&self, specification: &ListingSpecification) -> Result<UserProfilesResponse, Error> {
self.database
.get_user_profiles_paginated(specification.offset, specification.page_size)
.get_user_profiles_search_paginated(&specification.search, specification.offset, specification.page_size)
.await
}
}
Expand Down

0 comments on commit 9759a0c

Please sign in to comment.