@@ -7,12 +7,8 @@ use crate::util::errors::AppResult;
77use crate :: views:: { EncodableCategory , EncodableCrate , EncodableKeyword } ;
88use axum_extra:: json;
99use axum_extra:: response:: ErasedJson ;
10- use diesel:: {
11- BelongingToDsl , ExpressionMethods , JoinOnDsl , NullableExpressionMethods , QueryDsl ,
12- SelectableHelper ,
13- } ;
14- use diesel_async:: AsyncPgConnection ;
15- use diesel_async:: RunQueryDsl ;
10+ use diesel:: prelude:: * ;
11+ use diesel_async:: { AsyncPgConnection , RunQueryDsl } ;
1612
1713/// Handles the `GET /summary` route.
1814pub async fn summary ( state : AppState ) -> AppResult < ErasedJson > {
@@ -30,58 +26,15 @@ pub async fn summary(state: AppState) -> AppResult<ErasedJson> {
3026 . get_result ( & mut conn)
3127 . await ?;
3228
33- async fn encode_crates (
34- conn : & mut AsyncPgConnection ,
35- data : Vec < Record > ,
36- ) -> AppResult < Vec < EncodableCrate > > {
37- use diesel:: GroupedBy ;
38- use diesel_async:: RunQueryDsl ;
39-
40- let krates = data. iter ( ) . map ( |( c, ..) | c) . collect :: < Vec < _ > > ( ) ;
41- let versions: Vec < Version > = Version :: belonging_to ( & krates)
42- . filter ( versions:: yanked. eq ( false ) )
43- . select ( Version :: as_select ( ) )
44- . load ( conn)
45- . await ?;
46-
47- versions
48- . grouped_by ( & krates)
49- . into_iter ( )
50- . map ( TopVersions :: from_versions)
51- . zip ( data)
52- . map (
53- |( top_versions, ( krate, total, recent, default_version, yanked) ) | {
54- Ok ( EncodableCrate :: from_minimal (
55- krate,
56- default_version. as_deref ( ) ,
57- yanked,
58- Some ( & top_versions) ,
59- false ,
60- total,
61- recent,
62- ) )
63- } ,
64- )
65- . collect ( )
66- }
67-
6829 let config = & state. config ;
6930
70- let selection = (
71- Crate :: as_select ( ) ,
72- crate_downloads:: downloads,
73- recent_crate_downloads:: downloads. nullable ( ) ,
74- versions:: num. nullable ( ) ,
75- versions:: yanked. nullable ( ) ,
76- ) ;
77-
7831 let new_crates = crates:: table
7932 . inner_join ( crate_downloads:: table)
8033 . left_join ( recent_crate_downloads:: table)
8134 . left_join ( default_versions:: table)
8235 . left_join ( versions:: table. on ( default_versions:: version_id. eq ( versions:: id) ) )
8336 . order ( crates:: created_at. desc ( ) )
84- . select ( selection )
37+ . select ( Record :: as_select ( ) )
8538 . limit ( 10 )
8639 . load ( & mut conn)
8740 . await ?;
@@ -92,7 +45,7 @@ pub async fn summary(state: AppState) -> AppResult<ErasedJson> {
9245 . left_join ( versions:: table. on ( default_versions:: version_id. eq ( versions:: id) ) )
9346 . filter ( crates:: updated_at. ne ( crates:: created_at) )
9447 . order ( crates:: updated_at. desc ( ) )
95- . select ( selection )
48+ . select ( Record :: as_select ( ) )
9649 . limit ( 10 )
9750 . load ( & mut conn)
9851 . await ?;
@@ -104,7 +57,7 @@ pub async fn summary(state: AppState) -> AppResult<ErasedJson> {
10457 . left_join ( versions:: table. on ( default_versions:: version_id. eq ( versions:: id) ) )
10558 . filter ( crates:: name. ne_all ( & config. excluded_crate_names ) )
10659 . then_order_by ( crate_downloads:: downloads. desc ( ) )
107- . select ( selection )
60+ . select ( Record :: as_select ( ) )
10861 . limit ( 10 )
10962 . load ( & mut conn)
11063 . await ?;
@@ -116,7 +69,7 @@ pub async fn summary(state: AppState) -> AppResult<ErasedJson> {
11669 . left_join ( versions:: table. on ( default_versions:: version_id. eq ( versions:: id) ) )
11770 . filter ( crates:: name. ne_all ( & config. excluded_crate_names ) )
11871 . then_order_by ( recent_crate_downloads:: downloads. desc ( ) )
119- . select ( selection )
72+ . select ( Record :: as_select ( ) )
12073 . limit ( 10 )
12174 . load ( & mut conn)
12275 . await ?;
@@ -130,16 +83,64 @@ pub async fn summary(state: AppState) -> AppResult<ErasedJson> {
13083 . map ( Keyword :: into)
13184 . collect :: < Vec < EncodableKeyword > > ( ) ;
13285
86+ let new_crates = encode_crates ( & mut conn, new_crates) . await ?;
87+ let most_downloaded = encode_crates ( & mut conn, most_downloaded) . await ?;
88+ let most_recently_downloaded = encode_crates ( & mut conn, most_recently_downloaded) . await ?;
89+ let just_updated = encode_crates ( & mut conn, just_updated) . await ?;
90+
13391 Ok ( json ! ( {
13492 "num_downloads" : num_downloads,
13593 "num_crates" : num_crates,
136- "new_crates" : encode_crates ( & mut conn , new_crates) . await ? ,
137- "most_downloaded" : encode_crates ( & mut conn , most_downloaded) . await ? ,
138- "most_recently_downloaded" : encode_crates ( & mut conn , most_recently_downloaded) . await ? ,
139- "just_updated" : encode_crates ( & mut conn , just_updated) . await ? ,
94+ "new_crates" : new_crates,
95+ "most_downloaded" : most_downloaded,
96+ "most_recently_downloaded" : most_recently_downloaded,
97+ "just_updated" : just_updated,
14098 "popular_keywords" : popular_keywords,
14199 "popular_categories" : popular_categories,
142100 } ) )
143101}
144102
145- type Record = ( Crate , i64 , Option < i64 > , Option < String > , Option < bool > ) ;
103+ #[ derive( Debug , Queryable , Selectable ) ]
104+ #[ diesel( check_for_backend( diesel:: pg:: Pg ) ) ]
105+ struct Record {
106+ #[ diesel( embed) ]
107+ krate : Crate ,
108+ #[ diesel( select_expression = crate_downloads:: columns:: downloads) ]
109+ total_downloads : i64 ,
110+ #[ diesel( select_expression = recent_crate_downloads:: columns:: downloads. nullable( ) ) ]
111+ recent_downloads : Option < i64 > ,
112+ #[ diesel( select_expression = versions:: columns:: num. nullable( ) ) ]
113+ default_version : Option < String > ,
114+ #[ diesel( select_expression = versions:: columns:: yanked. nullable( ) ) ]
115+ yanked : Option < bool > ,
116+ }
117+
118+ async fn encode_crates (
119+ conn : & mut AsyncPgConnection ,
120+ data : Vec < Record > ,
121+ ) -> AppResult < Vec < EncodableCrate > > {
122+ let krates = data. iter ( ) . map ( |record| & record. krate ) . collect :: < Vec < _ > > ( ) ;
123+ let versions: Vec < Version > = Version :: belonging_to ( & krates)
124+ . filter ( versions:: yanked. eq ( false ) )
125+ . select ( Version :: as_select ( ) )
126+ . load ( conn)
127+ . await ?;
128+
129+ versions
130+ . grouped_by ( & krates)
131+ . into_iter ( )
132+ . map ( TopVersions :: from_versions)
133+ . zip ( data)
134+ . map ( |( top_versions, record) | {
135+ Ok ( EncodableCrate :: from_minimal (
136+ record. krate ,
137+ record. default_version . as_deref ( ) ,
138+ record. yanked ,
139+ Some ( & top_versions) ,
140+ false ,
141+ record. total_downloads ,
142+ record. recent_downloads ,
143+ ) )
144+ } )
145+ . collect ( )
146+ }
0 commit comments