@@ -72,6 +72,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
72
72
let selection = (
73
73
ALL_COLUMNS ,
74
74
false . into_sql :: < Bool > ( ) ,
75
+ crate_downloads:: downloads,
75
76
recent_crate_downloads:: downloads. nullable ( ) ,
76
77
0_f32 . into_sql :: < Float > ( ) ,
77
78
) ;
@@ -80,6 +81,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
80
81
let mut seek: Option < Seek > = None ;
81
82
let mut query = filter_params
82
83
. make_query ( & req, conn) ?
84
+ . inner_join ( crate_downloads:: table)
83
85
. left_join ( recent_crate_downloads:: table)
84
86
. select ( selection) ;
85
87
@@ -97,6 +99,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
97
99
query = query. select ( (
98
100
ALL_COLUMNS ,
99
101
Crate :: with_name ( q_string) ,
102
+ crate_downloads:: downloads,
100
103
recent_crate_downloads:: downloads. nullable ( ) ,
101
104
rank. clone ( ) ,
102
105
) ) ;
@@ -106,6 +109,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
106
109
query = query. select ( (
107
110
ALL_COLUMNS ,
108
111
Crate :: with_name ( q_string) ,
112
+ crate_downloads:: downloads,
109
113
recent_crate_downloads:: downloads. nullable ( ) ,
110
114
0_f32 . into_sql :: < Float > ( ) ,
111
115
) ) ;
@@ -121,7 +125,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
121
125
// to ensure predictable pagination behavior.
122
126
if sort == Some ( "downloads" ) {
123
127
seek = Some ( Seek :: Downloads ) ;
124
- query = query. order ( ( crates :: downloads. desc ( ) , crates:: id. desc ( ) ) )
128
+ query = query. order ( ( crate_downloads :: downloads. desc ( ) , crates:: id. desc ( ) ) )
125
129
} else if sort == Some ( "recent-downloads" ) {
126
130
seek = Some ( Seek :: RecentDownloads ) ;
127
131
query = query. order ( (
@@ -170,7 +174,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
170
174
pagination,
171
175
filter_params. make_query ( & req, conn) ?. count ( ) ,
172
176
) ;
173
- let data: Paginated < ( Crate , bool , Option < i64 > , f32 ) > =
177
+ let data: Paginated < ( Crate , bool , i64 , Option < i64 > , f32 ) > =
174
178
info_span ! ( "db.query" , message = "SELECT ..., COUNT(*) FROM crates" )
175
179
. in_scope ( || query. load ( conn) ) ?;
176
180
@@ -187,7 +191,7 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
187
191
pagination,
188
192
filter_params. make_query ( & req, conn) ?. count ( ) ,
189
193
) ;
190
- let data: Paginated < ( Crate , bool , Option < i64 > , f32 ) > =
194
+ let data: Paginated < ( Crate , bool , i64 , Option < i64 > , f32 ) > =
191
195
info_span ! ( "db.query" , message = "SELECT ..., COUNT(*) FROM crates" )
192
196
. in_scope ( || query. load ( conn) ) ?;
193
197
(
@@ -199,12 +203,15 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
199
203
)
200
204
} ;
201
205
202
- let perfect_matches = data. iter ( ) . map ( |& ( _, b, _, _) | b) . collect :: < Vec < _ > > ( ) ;
203
- let recent_downloads = data
206
+ let perfect_matches = data. iter ( ) . map ( |& ( _, b, _, _, _ ) | b) . collect :: < Vec < _ > > ( ) ;
207
+ let downloads = data
204
208
. iter ( )
205
- . map ( |& ( _, _, s, _) | s. unwrap_or ( 0 ) )
209
+ . map ( |& ( _, _, total, recent, _) | ( total, recent. unwrap_or ( 0 ) ) )
210
+ . collect :: < Vec < _ > > ( ) ;
211
+ let crates = data
212
+ . into_iter ( )
213
+ . map ( |( c, _, _, _, _) | c)
206
214
. collect :: < Vec < _ > > ( ) ;
207
- let crates = data. into_iter ( ) . map ( |( c, _, _, _) | c) . collect :: < Vec < _ > > ( ) ;
208
215
209
216
let versions: Vec < Version > = info_span ! ( "db.query" , message = "SELECT ... FROM versions" )
210
217
. in_scope ( || crates. versions ( ) . load ( conn) ) ?;
@@ -216,20 +223,17 @@ pub async fn search(app: AppState, req: Parts) -> AppResult<Json<Value>> {
216
223
let crates = versions
217
224
. zip ( crates)
218
225
. zip ( perfect_matches)
219
- . zip ( recent_downloads)
220
- . map (
221
- |( ( ( max_version, krate) , perfect_match) , recent_downloads) | {
222
- let downloads = krate. downloads as i64 ;
223
- EncodableCrate :: from_minimal (
224
- krate,
225
- Some ( & max_version) ,
226
- Some ( vec ! [ ] ) ,
227
- perfect_match,
228
- downloads,
229
- Some ( recent_downloads) ,
230
- )
231
- } ,
232
- )
226
+ . zip ( downloads)
227
+ . map ( |( ( ( max_version, krate) , perfect_match) , ( total, recent) ) | {
228
+ EncodableCrate :: from_minimal (
229
+ krate,
230
+ Some ( & max_version) ,
231
+ Some ( vec ! [ ] ) ,
232
+ perfect_match,
233
+ total,
234
+ Some ( recent) ,
235
+ )
236
+ } )
233
237
. collect :: < Vec < _ > > ( ) ;
234
238
235
239
Ok ( Json ( json ! ( {
@@ -478,12 +482,12 @@ impl<'a> FilterParams<'a> {
478
482
// `WHERE (downloads = downloads' AND id < id') OR downloads < downloads'`
479
483
vec ! [
480
484
Box :: new(
481
- crates :: downloads
485
+ crate_downloads :: downloads
482
486
. eq( downloads)
483
487
. and( crates:: id. lt( id) )
484
488
. nullable( ) ,
485
489
) ,
486
- Box :: new( crates :: downloads. lt( downloads) . nullable( ) ) ,
490
+ Box :: new( crate_downloads :: downloads. lt( downloads) . nullable( ) ) ,
487
491
]
488
492
}
489
493
SeekPayload :: Query ( Query ( exact_match, id) ) => {
@@ -553,29 +557,30 @@ mod seek {
553
557
New ( #[ serde( with="ts_microseconds" ) ] chrono:: NaiveDateTime , i32 )
554
558
RecentUpdates ( #[ serde( with="ts_microseconds" ) ] chrono:: NaiveDateTime , i32 )
555
559
RecentDownloads ( Option <i64 >, i32 )
556
- Downloads ( i32 , i32 )
560
+ Downloads ( i64 , i32 )
557
561
Query ( bool , i32 )
558
562
Relevance ( bool , f32 , i32 )
559
563
}
560
564
}
561
565
562
566
impl Seek {
563
- pub ( crate ) fn to_payload ( & self , record : & ( Crate , bool , Option < i64 > , f32 ) ) -> SeekPayload {
567
+ pub ( crate ) fn to_payload (
568
+ & self ,
569
+ record : & ( Crate , bool , i64 , Option < i64 > , f32 ) ,
570
+ ) -> SeekPayload {
564
571
match * self {
565
572
Seek :: Name => SeekPayload :: Name ( Name ( record. 0 . id ) ) ,
566
573
Seek :: New => SeekPayload :: New ( New ( record. 0 . created_at , record. 0 . id ) ) ,
567
574
Seek :: RecentUpdates => {
568
575
SeekPayload :: RecentUpdates ( RecentUpdates ( record. 0 . updated_at , record. 0 . id ) )
569
576
}
570
577
Seek :: RecentDownloads => {
571
- SeekPayload :: RecentDownloads ( RecentDownloads ( record. 2 , record. 0 . id ) )
572
- }
573
- Seek :: Downloads => {
574
- SeekPayload :: Downloads ( Downloads ( record. 0 . downloads , record. 0 . id ) )
578
+ SeekPayload :: RecentDownloads ( RecentDownloads ( record. 3 , record. 0 . id ) )
575
579
}
580
+ Seek :: Downloads => SeekPayload :: Downloads ( Downloads ( record. 2 , record. 0 . id ) ) ,
576
581
Seek :: Query => SeekPayload :: Query ( Query ( record. 1 , record. 0 . id ) ) ,
577
582
Seek :: Relevance => {
578
- SeekPayload :: Relevance ( Relevance ( record. 1 , record. 3 , record. 0 . id ) )
583
+ SeekPayload :: Relevance ( Relevance ( record. 1 , record. 4 , record. 0 . id ) )
579
584
}
580
585
}
581
586
}
@@ -584,7 +589,10 @@ mod seek {
584
589
585
590
type BoxedCondition < ' a > = Box <
586
591
dyn BoxableExpression <
587
- LeftJoinQuerySource < crates:: table , recent_crate_downloads:: table > ,
592
+ LeftJoinQuerySource <
593
+ InnerJoinQuerySource < crates:: table , crate_downloads:: table > ,
594
+ recent_crate_downloads:: table ,
595
+ > ,
588
596
diesel:: pg:: Pg ,
589
597
SqlType = diesel:: sql_types:: Nullable < Bool > ,
590
598
> + ' a ,
0 commit comments