@@ -3,7 +3,7 @@ use std::collections::{hash_map::Entry, HashMap};
3
3
use serde:: { Deserialize , Serialize } ;
4
4
use sqlx:: { PgConnection , Postgres , QueryBuilder } ;
5
5
6
- use crate :: types:: api:: ApiError ;
6
+ use crate :: types:: api:: { ApiError , PaginatedData } ;
7
7
8
8
#[ derive( Deserialize , Serialize , Clone , Debug ) ]
9
9
pub struct Developer {
@@ -22,7 +22,7 @@ pub struct DeveloperProfile {
22
22
pub admin : bool ,
23
23
}
24
24
25
- #[ derive( Clone ) ]
25
+ #[ derive( sqlx :: FromRow , Clone ) ]
26
26
pub struct FetchedDeveloper {
27
27
pub id : i32 ,
28
28
pub username : String ,
@@ -32,6 +32,98 @@ pub struct FetchedDeveloper {
32
32
}
33
33
34
34
impl Developer {
35
+ pub async fn get_index (
36
+ query : & Option < String > ,
37
+ page : i64 ,
38
+ per_page : i64 ,
39
+ pool : & mut PgConnection ,
40
+ ) -> Result < PaginatedData < DeveloperProfile > , ApiError > {
41
+ let limit = per_page;
42
+ let offset = ( page - 1 ) * per_page;
43
+
44
+ let name_query: Option < String > = query. as_ref ( ) . map ( |q| format ! ( "%{}%" , q) ) ;
45
+
46
+ let mut builder: QueryBuilder < Postgres > = QueryBuilder :: new (
47
+ r#"
48
+ SELECT
49
+ id,
50
+ username,
51
+ display_name,
52
+ verified,
53
+ admin
54
+ FROM developers
55
+ "# ,
56
+ ) ;
57
+
58
+ let mut counter: QueryBuilder < Postgres > = QueryBuilder :: new (
59
+ r#"
60
+ SELECT COUNT(id)
61
+ FROM developers
62
+ "# ,
63
+ ) ;
64
+
65
+ if name_query. is_some ( ) {
66
+ let sql = "WHERE username LIKE " ;
67
+ builder. push ( sql) ;
68
+ counter. push ( sql) ;
69
+ builder. push_bind ( name_query. clone ( ) . unwrap ( ) ) ;
70
+ counter. push ( name_query. clone ( ) . unwrap ( ) ) ;
71
+ let sql = " OR WHERE display_name LIKE " ;
72
+ builder. push ( sql) ;
73
+ counter. push ( sql) ;
74
+ builder. push ( name_query. clone ( ) . unwrap ( ) ) ;
75
+ counter. push ( name_query. clone ( ) . unwrap ( ) ) ;
76
+ }
77
+
78
+ builder. push ( " GROUP BY id" ) ;
79
+ let sql = " LIMIT " ;
80
+ builder. push ( sql) ;
81
+ builder. push_bind ( limit) ;
82
+ let sql = " OFFSET " ;
83
+ builder. push ( sql) ;
84
+ builder. push_bind ( offset) ;
85
+
86
+ let result = match builder
87
+ . build_query_as :: < FetchedDeveloper > ( )
88
+ . fetch_all ( & mut * pool)
89
+ . await
90
+ {
91
+ Ok ( r) => r,
92
+ Err ( e) => {
93
+ log:: error!( "{}" , e) ;
94
+ return Err ( ApiError :: DbError ) ;
95
+ }
96
+ } ;
97
+
98
+ let result: Vec < DeveloperProfile > = result
99
+ . into_iter ( )
100
+ . map ( |x| DeveloperProfile {
101
+ id : x. id ,
102
+ username : x. username ,
103
+ display_name : x. display_name ,
104
+ verified : x. verified ,
105
+ admin : x. admin ,
106
+ } )
107
+ . collect ( ) ;
108
+
109
+ let count = match counter
110
+ . build_query_scalar ( )
111
+ . fetch_optional ( & mut * pool)
112
+ . await
113
+ {
114
+ Ok ( Some ( c) ) => c,
115
+ Ok ( None ) => 0 ,
116
+ Err ( e) => {
117
+ log:: error!( "{}" , e) ;
118
+ return Err ( ApiError :: DbError ) ;
119
+ }
120
+ } ;
121
+
122
+ Ok ( PaginatedData {
123
+ data : result,
124
+ count,
125
+ } )
126
+ }
35
127
pub async fn create (
36
128
github_id : i64 ,
37
129
username : String ,
0 commit comments