@@ -654,15 +654,15 @@ impl Model for Crate {
654
654
#[ allow( trivial_casts) ]
655
655
pub fn index ( req : & mut Request ) -> CargoResult < Response > {
656
656
use diesel:: expression:: dsl:: sql;
657
- use diesel:: types:: BigInt ;
657
+ use diesel:: types:: { BigInt , Bool } ;
658
658
659
659
let conn = req. db_conn ( ) ?;
660
660
let ( offset, limit) = req. pagination ( 10 , 100 ) ?;
661
661
let params = req. query ( ) ;
662
662
let sort = params. get ( "sort" ) . map ( |s| & * * s) . unwrap_or ( "alpha" ) ;
663
663
664
664
let mut query = crates:: table
665
- . select ( ( ALL_COLUMNS , sql :: < BigInt > ( "COUNT(*) OVER ()" ) ) )
665
+ . select ( ( ALL_COLUMNS , sql :: < BigInt > ( "COUNT(*) OVER ()" ) , sql :: < Bool > ( "false" ) ) )
666
666
. limit ( limit)
667
667
. offset ( offset)
668
668
. into_boxed ( ) ;
@@ -677,6 +677,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
677
677
let q = plainto_tsquery ( q_string) ;
678
678
query = query. filter ( q. matches ( crates:: textsearchable_index_col) ) ;
679
679
680
+ query = query. select ( ( ALL_COLUMNS , sql :: < BigInt > ( "COUNT(*) OVER()" ) , crates:: name. eq ( q_string) ) ) ;
680
681
let perfect_match = crates:: name. eq ( q_string) . desc ( ) ;
681
682
if sort == "downloads" {
682
683
query = query. order ( ( perfect_match, crates:: downloads. desc ( ) ) ) ;
@@ -714,22 +715,23 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
714
715
) ) ;
715
716
}
716
717
717
- let data = query. load :: < ( Crate , i64 ) > ( & * conn) ?;
718
- let total = data. get ( 0 ) . map ( |& ( _, t) | t) . unwrap_or ( 0 ) ;
719
- let crates = data. into_iter ( ) . map ( |( c, _) | c) . collect :: < Vec < _ > > ( ) ;
718
+ let data = query. load :: < ( Crate , i64 , bool ) > ( & * conn) ?;
719
+ let total = data. get ( 0 ) . map ( |& ( _, t, _) | t) . unwrap_or ( 0 ) ;
720
+ let crates = data. into_iter ( ) . map ( |( c, _, _) | c) . collect :: < Vec < _ > > ( ) ;
721
+ let perfect_matches = data. into_iter ( ) . map ( |( _, _, b) | b) . collect :: < Vec < _ > > ( ) ;
720
722
721
723
let versions = Version :: belonging_to ( & crates)
722
724
. load :: < Version > ( & * conn) ?
723
725
. grouped_by ( & crates)
724
726
. into_iter ( )
725
727
. map ( |versions| Version :: max ( versions. into_iter ( ) . map ( |v| v. num ) ) ) ;
726
728
727
- let crates = versions. zip ( crates) . map ( |( max_version, krate) | {
729
+ let crates = versions. zip ( crates) . zip ( perfect_matches ) . map ( |( ( max_version, krate) , perfect_match ) | {
728
730
// FIXME: If we add crate_id to the Badge enum we can eliminate
729
731
// this N+1
730
732
let badges = badges:: table. filter ( badges:: crate_id. eq ( krate. id ) )
731
733
. load :: < Badge > ( & * conn) ?;
732
- Ok ( krate. minimal_encodable ( max_version, Some ( badges) , false ) )
734
+ Ok ( krate. minimal_encodable ( max_version, Some ( badges) , perfect_match ) )
733
735
} ) . collect :: < Result < _ , :: diesel:: result:: Error > > ( ) ?;
734
736
735
737
#[ derive( RustcEncodable ) ]
0 commit comments