@@ -20,13 +20,14 @@ use semver;
20
20
use time:: { Timespec , Duration } ;
21
21
use url:: Url ;
22
22
23
- use { Model , User , Keyword , Version } ;
23
+ use { Model , User , Keyword , Version , Category } ;
24
24
use app:: { App , RequestApp } ;
25
25
use db:: RequestTransaction ;
26
26
use dependency:: { Dependency , EncodableDependency } ;
27
27
use download:: { VersionDownload , EncodableVersionDownload } ;
28
28
use git;
29
29
use keyword:: EncodableKeyword ;
30
+ use category:: EncodableCategory ;
30
31
use upload;
31
32
use user:: RequestUser ;
32
33
use owner:: { EncodableOwner , Owner , Rights , OwnerKind , Team , rights} ;
@@ -59,6 +60,7 @@ pub struct EncodableCrate {
59
60
pub updated_at : String ,
60
61
pub versions : Option < Vec < i32 > > ,
61
62
pub keywords : Option < Vec < String > > ,
63
+ pub categories : Option < Vec < String > > ,
62
64
pub created_at : String ,
63
65
pub downloads : i32 ,
64
66
pub max_version : String ,
@@ -229,7 +231,8 @@ impl Crate {
229
231
230
232
pub fn encodable ( self ,
231
233
versions : Option < Vec < i32 > > ,
232
- keywords : Option < & [ Keyword ] > )
234
+ keywords : Option < & [ Keyword ] > ,
235
+ categories : Option < & [ Category ] > )
233
236
-> EncodableCrate {
234
237
let Crate {
235
238
name, created_at, updated_at, downloads, max_version, description,
@@ -241,6 +244,7 @@ impl Crate {
241
244
None => Some ( format ! ( "/api/v1/crates/{}/versions" , name) ) ,
242
245
} ;
243
246
let keyword_ids = keywords. map ( |kws| kws. iter ( ) . map ( |kw| kw. keyword . clone ( ) ) . collect ( ) ) ;
247
+ let category_ids = categories. map ( |cats| cats. iter ( ) . map ( |cat| cat. category . clone ( ) ) . collect ( ) ) ;
244
248
EncodableCrate {
245
249
id : name. clone ( ) ,
246
250
name : name. clone ( ) ,
@@ -249,6 +253,7 @@ impl Crate {
249
253
downloads : downloads,
250
254
versions : versions,
251
255
keywords : keyword_ids,
256
+ categories : category_ids,
252
257
max_version : max_version. to_string ( ) ,
253
258
documentation : documentation,
254
259
homepage : homepage,
@@ -386,6 +391,16 @@ impl Crate {
386
391
Ok ( rows. iter ( ) . map ( |r| Model :: from_row ( & r) ) . collect ( ) )
387
392
}
388
393
394
+ pub fn categories ( & self , conn : & GenericConnection ) -> CargoResult < Vec < Category > > {
395
+ let stmt = try!( conn. prepare ( "SELECT categories.* FROM categories \
396
+ LEFT JOIN crates_categories \
397
+ ON categories.id = \
398
+ crates_categories.category_id \
399
+ WHERE crates_categories.crate_id = $1") ) ;
400
+ let rows = try!( stmt. query ( & [ & self . id ] ) ) ;
401
+ Ok ( rows. iter ( ) . map ( |r| Model :: from_row ( & r) ) . collect ( ) )
402
+ }
403
+
389
404
/// Returns (dependency, dependent crate name)
390
405
pub fn reverse_dependencies ( & self ,
391
406
conn : & GenericConnection ,
@@ -567,7 +582,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
567
582
let mut crates = Vec :: new ( ) ;
568
583
for row in try!( stmt. query ( & args) ) . iter ( ) {
569
584
let krate: Crate = Model :: from_row ( & row) ;
570
- crates. push ( krate. encodable ( None , None ) ) ;
585
+ crates. push ( krate. encodable ( None , None , None ) ) ;
571
586
}
572
587
573
588
// Query for the total count of crates
@@ -602,7 +617,7 @@ pub fn summary(req: &mut Request) -> CargoResult<Response> {
602
617
let rows = try!( stmt. query ( & [ ] ) ) ;
603
618
Ok ( rows. iter ( ) . map ( |r| {
604
619
let krate: Crate = Model :: from_row ( & r) ;
605
- krate. encodable ( None , None )
620
+ krate. encodable ( None , None , None )
606
621
} ) . collect :: < Vec < EncodableCrate > > ( ) )
607
622
} ;
608
623
let new_crates = try!( tx. prepare ( "SELECT * FROM crates \
@@ -639,19 +654,22 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
639
654
let versions = try!( krate. versions ( conn) ) ;
640
655
let ids = versions. iter ( ) . map ( |v| v. id ) . collect ( ) ;
641
656
let kws = try!( krate. keywords ( conn) ) ;
657
+ let cats = try!( krate. categories ( conn) ) ;
642
658
643
659
#[ derive( RustcEncodable ) ]
644
660
struct R {
645
661
krate : EncodableCrate ,
646
662
versions : Vec < EncodableVersion > ,
647
663
keywords : Vec < EncodableKeyword > ,
664
+ categories : Vec < EncodableCategory > ,
648
665
}
649
666
Ok ( req. json ( & R {
650
- krate : krate. clone ( ) . encodable ( Some ( ids) , Some ( & kws) ) ,
667
+ krate : krate. clone ( ) . encodable ( Some ( ids) , Some ( & kws) , Some ( & cats ) ) ,
651
668
versions : versions. into_iter ( ) . map ( |v| {
652
669
v. encodable ( & krate. name )
653
670
} ) . collect ( ) ,
654
671
keywords : kws. into_iter ( ) . map ( |k| k. encodable ( ) ) . collect ( ) ,
672
+ categories : cats. into_iter ( ) . map ( |k| k. encodable ( ) ) . collect ( ) ,
655
673
} ) )
656
674
}
657
675
@@ -669,6 +687,10 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
669
687
. unwrap_or ( & [ ] ) ;
670
688
let keywords = keywords. iter ( ) . map ( |k| k[ ..] . to_string ( ) ) . collect :: < Vec < _ > > ( ) ;
671
689
690
+ let categories = new_crate. categories . as_ref ( ) . map ( |s| & s[ ..] )
691
+ . unwrap_or ( & [ ] ) ;
692
+ let categories = categories. iter ( ) . map ( |k| k[ ..] . to_string ( ) ) . collect :: < Vec < _ > > ( ) ;
693
+
672
694
// Persist the new crate, if it doesn't already exist
673
695
let mut krate = try!( Crate :: find_or_insert ( try!( req. tx ( ) ) , name, user. id ,
674
696
& new_crate. description ,
@@ -713,6 +735,9 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
713
735
// Update all keywords for this crate
714
736
try!( Keyword :: update_crate ( try!( req. tx ( ) ) , & krate, & keywords) ) ;
715
737
738
+ // Update all categories for this crate
739
+ try!( Category :: update_crate ( try!( req. tx ( ) ) , & krate, & categories) ) ;
740
+
716
741
// Upload the crate to S3
717
742
let mut handle = req. app ( ) . handle ( ) ;
718
743
let path = krate. s3_path ( & vers. to_string ( ) ) ;
@@ -769,7 +794,7 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
769
794
770
795
#[ derive( RustcEncodable ) ]
771
796
struct R { krate : EncodableCrate }
772
- Ok ( req. json ( & R { krate : krate. encodable ( None , None ) } ) )
797
+ Ok ( req. json ( & R { krate : krate. encodable ( None , None , None ) } ) )
773
798
}
774
799
775
800
fn parse_new_headers ( req : & mut Request ) -> CargoResult < ( upload:: NewCrate , User ) > {
0 commit comments