@@ -8,7 +8,7 @@ use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
88use sqlx:: { query, query_as, Acquire , ConnectOptions , SqlitePool } ;
99use url:: Url ;
1010
11- use super :: database:: TABLES_TO_TRUNCATE ;
11+ use super :: database:: { UsersFilters , UsersSorting , TABLES_TO_TRUNCATE } ;
1212use crate :: databases:: database;
1313use crate :: databases:: database:: { Category , Database , Driver , Sorting , TorrentCompact } ;
1414use crate :: models:: category:: CategoryId ;
@@ -19,7 +19,7 @@ use crate::models::torrent_file::{
1919} ;
2020use crate :: models:: torrent_tag:: { TagId , TorrentTag } ;
2121use crate :: models:: tracker_key:: TrackerKey ;
22- use crate :: models:: user:: { User , UserAuthentication , UserCompact , UserId , UserProfile } ;
22+ use crate :: models:: user:: { User , UserAuthentication , UserCompact , UserId , UserListing , UserProfile } ;
2323use crate :: services:: torrent:: { CanonicalInfoHashGroup , DbTorrentInfoHash } ;
2424use crate :: utils:: clock:: { self , datetime_now, DATETIME_FORMAT } ;
2525use crate :: utils:: hex:: from_bytes;
@@ -159,6 +159,8 @@ impl Database for Sqlite {
159159 async fn get_user_profiles_search_paginated (
160160 & self ,
161161 search : & Option < String > ,
162+ filters : & Option < Vec < UsersFilters > > ,
163+ sort : Option < UsersSorting > ,
162164 offset : u64 ,
163165 limit : u8 ,
164166 ) -> Result < UserProfilesResponse , database:: Error > {
@@ -167,7 +169,46 @@ impl Database for Sqlite {
167169 Some ( v) => format ! ( "%{v}%" ) ,
168170 } ;
169171
170- let mut query_string = "SELECT * FROM torrust_user_profiles WHERE username LIKE ?" . to_string ( ) ;
172+ let sort_query: String = match sort {
173+ Some ( UsersSorting :: DateRegisteredNewest ) => "date_registered ASC" . to_string ( ) ,
174+ Some ( UsersSorting :: DateRegisteredOldest ) => "date_registered DESC" . to_string ( ) ,
175+ Some ( UsersSorting :: UsernameAZ ) | None => "username ASC" . to_string ( ) ,
176+ Some ( UsersSorting :: UsernameZA ) => "username DESC" . to_string ( ) ,
177+ } ;
178+
179+ let ( join_filters, where_filters) = if let Some ( filters) = filters {
180+ let ( mut join_filters_query, mut where_filters_query) = ( String :: new ( ) , String :: new ( ) ) ;
181+ for filter in filters {
182+ match filter {
183+ UsersFilters :: TorrentUploader => join_filters_query. push_str (
184+ "INNER JOIN torrust_torrents tt
185+ ON tu.user_id = tt.uploader_id " ,
186+ ) ,
187+ UsersFilters :: EmailNotVerified => where_filters_query. push_str ( " AND email_verified = false" ) ,
188+ UsersFilters :: EmailVerified => where_filters_query. push_str ( " AND email_verified = true" ) ,
189+ }
190+ }
191+ ( join_filters_query, where_filters_query)
192+ } else {
193+ ( String :: new ( ) , String :: new ( ) )
194+ } ;
195+
196+ let mut query_string = format ! (
197+ "SELECT
198+ tp.user_id,
199+ tp.username,
200+ tp.email,
201+ tp.email_verified,
202+ tu.date_registered,
203+ tu.administrator
204+ FROM torrust_user_profiles tp
205+ INNER JOIN torrust_users tu
206+ ON tp.user_id = tu.user_id
207+ {join_filters}
208+ WHERE username LIKE ?
209+ {where_filters}
210+ "
211+ ) ;
171212
172213 let count_query = format ! ( "SELECT COUNT(*) as count FROM ({query_string}) AS count_table" ) ;
173214
@@ -180,9 +221,9 @@ impl Database for Sqlite {
180221
181222 let count = count_result?;
182223
183- query_string = format ! ( "{query_string} LIMIT ?, ?" ) ;
224+ query_string = format ! ( "{query_string} ORDER BY {sort_query} LIMIT ?, ?" ) ;
184225
185- let res: Vec < UserProfile > = sqlx:: query_as :: < _ , UserProfile > ( & query_string)
226+ let res: Vec < UserListing > = sqlx:: query_as :: < _ , UserListing > ( & query_string)
186227 . bind ( user_name. clone ( ) )
187228 . bind ( i64:: saturating_add_unsigned ( 0 , offset) )
188229 . bind ( limit)
0 commit comments