1+ use crate :: database:: DatabaseError ;
12use crate :: types:: api:: { ApiError , PaginatedData } ;
23use crate :: types:: models:: developer:: { Developer , ModDeveloper } ;
34use sqlx:: PgConnection ;
45use std:: collections:: HashMap ;
56use uuid:: Uuid ;
67
78pub async fn index (
8- query : & str ,
9+ query : Option < & str > ,
910 page : i64 ,
1011 per_page : i64 ,
1112 conn : & mut PgConnection ,
12- ) -> Result < PaginatedData < Developer > , ApiError > {
13+ ) -> Result < PaginatedData < Developer > , DatabaseError > {
1314 let limit = per_page;
1415 let offset = ( page - 1 ) * per_page;
1516
16- let display_name_query = {
17- if query. is_empty ( ) {
18- "" . into ( )
19- } else {
20- format ! ( "%{}%" , query)
21- }
22- } ;
23-
2417 let result = sqlx:: query_as!(
2518 Developer ,
2619 "SELECT
@@ -32,23 +25,19 @@ pub async fn index(
3225 github_user_id as github_id
3326 FROM developers
3427 WHERE (
35- ($1 = '' OR username = $1)
36- OR ($2 = '' OR display_name ILIKE $2 )
28+ ($1::text IS NULL OR username = $1)
29+ OR ($1::text IS NULL OR display_name ILIKE '%' || $1 || '%' )
3730 )
3831 GROUP BY id
39- LIMIT $3
40- OFFSET $4 " ,
32+ LIMIT $2
33+ OFFSET $3 " ,
4134 query,
42- & display_name_query,
4335 limit,
4436 offset
4537 )
4638 . fetch_all ( & mut * conn)
4739 . await
48- . map_err ( |e| {
49- log:: error!( "Failed to fetch developers: {}" , e) ;
50- ApiError :: DbError
51- } ) ?;
40+ . inspect_err ( |e| log:: error!( "Failed to fetch developers: {}" , e) ) ?;
5241
5342 let count = index_count ( query, & mut * conn) . await ?;
5443
@@ -58,33 +47,24 @@ pub async fn index(
5847 } )
5948}
6049
61- pub async fn index_count ( query : & str , conn : & mut PgConnection ) -> Result < i64 , ApiError > {
62- let display_name_query = {
63- if query. is_empty ( ) {
64- "" . into ( )
65- } else {
66- format ! ( "%{}%" , query)
67- }
68- } ;
69-
70- Ok ( sqlx:: query!(
50+ pub async fn index_count (
51+ query : Option < & str > ,
52+ conn : & mut PgConnection ,
53+ ) -> Result < i64 , DatabaseError > {
54+ sqlx:: query!(
7155 "SELECT COUNT(id)
7256 FROM developers
7357 WHERE (
74- ($1 = '' OR username = $1)
75- OR ($2 = '' OR display_name ILIKE $2 )
58+ ($1::text IS NULL OR username = $1)
59+ OR ($1::text IS NULL OR display_name ILIKE '%' || $1 || '%' )
7660 )" ,
77- query,
78- display_name_query
61+ query
7962 )
8063 . fetch_one ( & mut * conn)
8164 . await
82- . map_err ( |e| {
83- log:: error!( "Failed to fetch developer count: {}" , e) ;
84- ApiError :: DbError
85- } ) ?
86- . count
87- . unwrap_or ( 0 ) )
65+ . inspect_err ( |e| log:: error!( "Failed to fetch developer count: {}" , e) )
66+ . map ( |x| x. count . unwrap_or ( 0 ) )
67+ . map_err ( |e| e. into ( ) )
8868}
8969
9070pub async fn fetch_or_insert_github (
@@ -168,7 +148,7 @@ pub async fn get_one(id: i32, conn: &mut PgConnection) -> Result<Option<Develope
168148pub async fn get_one_by_username (
169149 username : & str ,
170150 conn : & mut PgConnection ,
171- ) -> Result < Option < Developer > , ApiError > {
151+ ) -> Result < Option < Developer > , DatabaseError > {
172152 sqlx:: query_as!(
173153 Developer ,
174154 "SELECT
@@ -184,16 +164,14 @@ pub async fn get_one_by_username(
184164 )
185165 . fetch_optional ( & mut * conn)
186166 . await
187- . map_err ( |e| {
188- log:: error!( "Failed to fetch developer {}: {}" , username, e) ;
189- ApiError :: DbError
190- } )
167+ . inspect_err ( |e| log:: error!( "Failed to fetch developer {}: {}" , username, e) )
168+ . map_err ( |x| x. into ( ) )
191169}
192170
193171pub async fn get_all_for_mod (
194172 mod_id : & str ,
195173 conn : & mut PgConnection ,
196- ) -> Result < Vec < ModDeveloper > , ApiError > {
174+ ) -> Result < Vec < ModDeveloper > , DatabaseError > {
197175 sqlx:: query_as!(
198176 ModDeveloper ,
199177 "SELECT
@@ -209,16 +187,14 @@ pub async fn get_all_for_mod(
209187 )
210188 . fetch_all ( conn)
211189 . await
212- . map_err ( |e| {
213- log:: error!( "Failed to fetch developers for mod {}: {}" , mod_id, e) ;
214- ApiError :: DbError
215- } )
190+ . inspect_err ( |e| log:: error!( "Failed to fetch developers for mod {}: {}" , mod_id, e) )
191+ . map_err ( |e| e. into ( ) )
216192}
217193
218194pub async fn get_all_for_mods (
219195 mod_ids : & [ String ] ,
220196 conn : & mut PgConnection ,
221- ) -> Result < HashMap < String , Vec < ModDeveloper > > , ApiError > {
197+ ) -> Result < HashMap < String , Vec < ModDeveloper > > , DatabaseError > {
222198 if mod_ids. is_empty ( ) {
223199 return Ok ( HashMap :: new ( ) ) ;
224200 }
@@ -246,10 +222,7 @@ pub async fn get_all_for_mods(
246222 )
247223 . fetch_all ( conn)
248224 . await
249- . map_err ( |e| {
250- log:: error!( "Failed to fetch developers for mods: {}" , e) ;
251- ApiError :: DbError
252- } ) ?;
225+ . inspect_err ( |e| log:: error!( "Failed to fetch developers for mods: {}" , e) ) ?;
253226
254227 let mut ret: HashMap < String , Vec < ModDeveloper > > = HashMap :: new ( ) ;
255228
@@ -271,8 +244,8 @@ pub async fn has_access_to_mod(
271244 dev_id : i32 ,
272245 mod_id : & str ,
273246 conn : & mut PgConnection ,
274- ) -> Result < bool , ApiError > {
275- Ok ( sqlx:: query!(
247+ ) -> Result < bool , DatabaseError > {
248+ sqlx:: query!(
276249 "SELECT developer_id FROM mods_developers
277250 WHERE developer_id = $1
278251 AND mod_id = $2" ,
@@ -281,23 +254,23 @@ pub async fn has_access_to_mod(
281254 )
282255 . fetch_optional ( & mut * conn)
283256 . await
284- . map_err ( |e| {
257+ . inspect_err ( |e| {
285258 log:: error!(
286259 "Failed to find mod {} access for developer {}: {}" ,
287260 mod_id,
288261 dev_id,
289262 e
290263 ) ;
291- ApiError :: DbError
292- } ) ?
293- . is_some ( ) )
264+ } )
265+ . map ( |x| x . is_some ( ) )
266+ . map_err ( |e| e . into ( ) )
294267}
295268
296269pub async fn owns_mod (
297270 dev_id : i32 ,
298271 mod_id : & str ,
299272 conn : & mut PgConnection ,
300- ) -> Result < bool , ApiError > {
273+ ) -> Result < bool , DatabaseError > {
301274 Ok ( sqlx:: query!(
302275 "SELECT developer_id FROM mods_developers
303276 WHERE developer_id = $1
@@ -308,14 +281,13 @@ pub async fn owns_mod(
308281 )
309282 . fetch_optional ( & mut * conn)
310283 . await
311- . map_err ( |e| {
284+ . inspect_err ( |e| {
312285 log:: error!(
313286 "Failed to check mod {} owner for developer {}: {}" ,
314287 mod_id,
315288 dev_id,
316289 e
317- ) ;
318- ApiError :: DbError
290+ )
319291 } ) ?
320292 . is_some ( ) )
321293}
@@ -439,3 +411,32 @@ pub async fn find_by_refresh_token(
439411 ApiError :: DbError
440412 } )
441413}
414+
415+ pub async fn find_by_token (
416+ token : & Uuid ,
417+ conn : & mut PgConnection ,
418+ ) -> Result < Option < Developer > , DatabaseError > {
419+ let hash = sha256:: digest ( token. to_string ( ) ) ;
420+ sqlx:: query_as!(
421+ Developer ,
422+ "SELECT
423+ d.id,
424+ d.username,
425+ d.display_name,
426+ d.verified,
427+ d.admin,
428+ d.github_user_id as github_id
429+ FROM developers d
430+ INNER JOIN auth_tokens a ON d.id = a.developer_id
431+ WHERE a.token = $1
432+ AND (
433+ expires_at IS NULL
434+ OR expires_at > NOW()
435+ )" ,
436+ hash
437+ )
438+ . fetch_optional ( & mut * conn)
439+ . await
440+ . inspect_err ( |e| log:: error!( "{}" , e) )
441+ . map_err ( |e| e. into ( ) )
442+ }
0 commit comments