@@ -44,7 +44,6 @@ pub struct Crate {
44
44
pub updated_at : Timespec ,
45
45
pub created_at : Timespec ,
46
46
pub downloads : i32 ,
47
- pub max_version : semver:: Version ,
48
47
pub description : Option < String > ,
49
48
pub homepage : Option < String > ,
50
49
pub documentation : Option < String > ,
@@ -232,18 +231,20 @@ impl Crate {
232
231
}
233
232
234
233
pub fn minimal_encodable ( self ,
234
+ max_version : semver:: Version ,
235
235
badges : Option < Vec < Badge > > ) -> EncodableCrate {
236
- self . encodable ( None , None , None , badges)
236
+ self . encodable ( max_version , None , None , None , badges)
237
237
}
238
238
239
239
pub fn encodable ( self ,
240
+ max_version : semver:: Version ,
240
241
versions : Option < Vec < i32 > > ,
241
242
keywords : Option < & [ Keyword ] > ,
242
243
categories : Option < & [ Category ] > ,
243
244
badges : Option < Vec < Badge > > )
244
245
-> EncodableCrate {
245
246
let Crate {
246
- name, created_at, updated_at, downloads, max_version , description,
247
+ name, created_at, updated_at, downloads, description,
247
248
homepage, documentation, license, repository,
248
249
readme : _, id : _, max_upload_size : _,
249
250
} = self ;
@@ -254,7 +255,7 @@ impl Crate {
254
255
let keyword_ids = keywords. map ( |kws| kws. iter ( ) . map ( |kw| kw. keyword . clone ( ) ) . collect ( ) ) ;
255
256
let category_ids = categories. map ( |cats| cats. iter ( ) . map ( |cat| cat. slug . clone ( ) ) . collect ( ) ) ;
256
257
let badges = badges. map ( |bs| {
257
- bs. iter ( ) . map ( |b| b. clone ( ) . encodable ( ) ) . collect ( )
258
+ bs. into_iter ( ) . map ( |b| b. encodable ( ) ) . collect ( )
258
259
} ) ;
259
260
EncodableCrate {
260
261
id : name. clone ( ) ,
@@ -281,6 +282,16 @@ impl Crate {
281
282
}
282
283
}
283
284
285
+ pub fn max_version ( & self , conn : & GenericConnection ) -> CargoResult < semver:: Version > {
286
+ let stmt = conn. prepare ( "SELECT num FROM versions WHERE crate_id = $1
287
+ AND yanked = 'f'" ) ?;
288
+ let rows = stmt. query ( & [ & self . id ] ) ?;
289
+ Ok ( rows. iter ( )
290
+ . map ( |r| semver:: Version :: parse ( & r. get :: < _ , String > ( "num" ) ) . unwrap ( ) )
291
+ . max ( )
292
+ . unwrap_or_else ( || semver:: Version :: parse ( "0.0.0" ) . unwrap ( ) ) )
293
+ }
294
+
284
295
pub fn versions ( & self , conn : & GenericConnection ) -> CargoResult < Vec < Version > > {
285
296
let stmt = conn. prepare ( "SELECT * FROM versions \
286
297
WHERE crate_id = $1") ?;
@@ -383,14 +394,6 @@ impl Crate {
383
394
}
384
395
None => { }
385
396
}
386
- let zero = semver:: Version :: parse ( "0.0.0" ) . unwrap ( ) ;
387
- if * ver > self . max_version || self . max_version == zero {
388
- self . max_version = ver. clone ( ) ;
389
- }
390
- let stmt = conn. prepare ( "UPDATE crates SET max_version = $1
391
- WHERE id = $2 RETURNING updated_at" ) ?;
392
- let rows = stmt. query ( & [ & self . max_version . to_string ( ) , & self . id ] ) ?;
393
- self . updated_at = rows. get ( 0 ) . get ( "updated_at" ) ;
394
397
Version :: insert ( conn, self . id , ver, features, authors)
395
398
}
396
399
@@ -433,34 +436,34 @@ impl Crate {
433
436
INNER JOIN crates
434
437
ON crates.id = versions.crate_id
435
438
WHERE dependencies.crate_id = $1
436
- AND versions.num = crates.max_version
439
+ AND versions.num = $2
437
440
" ;
438
441
let fetch_sql = format ! ( "SELECT DISTINCT ON (crate_downloads, crate_name)
439
442
dependencies.*,
440
443
crates.downloads AS crate_downloads,
441
444
crates.name AS crate_name
442
445
{}
443
446
ORDER BY crate_downloads DESC
444
- OFFSET $2
445
- LIMIT $3 " ,
447
+ OFFSET $3
448
+ LIMIT $4 " ,
446
449
select_sql) ;
447
450
let count_sql = format ! ( "SELECT COUNT(DISTINCT(crates.id)) {}" , select_sql) ;
448
451
449
452
let stmt = conn. prepare ( & fetch_sql) ?;
450
- let vec: Vec < _ > = stmt. query ( & [ & self . id , & offset, & limit] ) ?
453
+ let max_version = self . max_version ( conn) ?. to_string ( ) ;
454
+ let vec: Vec < _ > = stmt. query ( & [ & self . id , & max_version, & offset, & limit] ) ?
451
455
. iter ( )
452
456
. map ( |r| ( Model :: from_row ( & r) , r. get ( "crate_name" ) , r. get ( "crate_downloads" ) ) )
453
457
. collect ( ) ;
454
458
let stmt = conn. prepare ( & count_sql) ?;
455
- let cnt: i64 = stmt. query ( & [ & self . id ] ) ?. iter ( ) . next ( ) . unwrap ( ) . get ( 0 ) ;
459
+ let cnt: i64 = stmt. query ( & [ & self . id , & max_version ] ) ?. iter ( ) . next ( ) . unwrap ( ) . get ( 0 ) ;
456
460
457
461
Ok ( ( vec, cnt) )
458
462
}
459
463
}
460
464
461
465
impl Model for Crate {
462
466
fn from_row ( row : & Row ) -> Crate {
463
- let max: String = row. get ( "max_version" ) ;
464
467
Crate {
465
468
id : row. get ( "id" ) ,
466
469
name : row. get ( "name" ) ,
@@ -471,7 +474,6 @@ impl Model for Crate {
471
474
documentation : row. get ( "documentation" ) ,
472
475
homepage : row. get ( "homepage" ) ,
473
476
readme : row. get ( "readme" ) ,
474
- max_version : semver:: Version :: parse ( & max) . unwrap ( ) ,
475
477
license : row. get ( "license" ) ,
476
478
repository : row. get ( "repository" ) ,
477
479
max_upload_size : row. get ( "max_upload_size" ) ,
@@ -602,8 +604,9 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
602
604
let mut crates = Vec :: new ( ) ;
603
605
for row in stmt. query ( & args) ?. iter ( ) {
604
606
let krate: Crate = Model :: from_row ( & row) ;
605
- let badges = krate. badges ( conn) ;
606
- crates. push ( krate. minimal_encodable ( badges. ok ( ) ) ) ;
607
+ let badges = krate. badges ( conn) ?;
608
+ let max_version = krate. max_version ( conn) ?;
609
+ crates. push ( krate. minimal_encodable ( max_version, Some ( badges) ) ) ;
607
610
}
608
611
609
612
// Query for the total count of crates
@@ -636,10 +639,11 @@ pub fn summary(req: &mut Request) -> CargoResult<Response> {
636
639
637
640
let to_crates = |stmt : pg:: stmt:: Statement | -> CargoResult < Vec < _ > > {
638
641
let rows = stmt. query ( & [ ] ) ?;
639
- Ok ( rows. iter ( ) . map ( |r| {
642
+ rows. iter ( ) . map ( |r| {
640
643
let krate: Crate = Model :: from_row ( & r) ;
641
- krate. minimal_encodable ( None )
642
- } ) . collect :: < Vec < EncodableCrate > > ( ) )
644
+ let max_version = krate. max_version ( tx) ?;
645
+ Ok ( krate. minimal_encodable ( max_version, None ) )
646
+ } ) . collect ( )
643
647
} ;
644
648
let new_crates = tx. prepare ( "SELECT * FROM crates \
645
649
ORDER BY created_at DESC LIMIT 10") ?;
@@ -691,6 +695,7 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
691
695
let kws = krate. keywords ( conn) ?;
692
696
let cats = krate. categories ( conn) ?;
693
697
let badges = krate. badges ( conn) ?;
698
+ let max_version = krate. max_version ( conn) ?;
694
699
695
700
#[ derive( RustcEncodable ) ]
696
701
struct R {
@@ -701,7 +706,7 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
701
706
}
702
707
Ok ( req. json ( & R {
703
708
krate : krate. clone ( ) . encodable (
704
- Some ( ids) , Some ( & kws) , Some ( & cats) , Some ( badges)
709
+ max_version , Some ( ids) , Some ( & kws) , Some ( & cats) , Some ( badges)
705
710
) ,
706
711
versions : versions. into_iter ( ) . map ( |v| {
707
712
v. encodable ( & krate. name )
@@ -784,6 +789,7 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
784
789
& krate,
785
790
new_crate. badges . unwrap_or_else ( HashMap :: new)
786
791
) ?;
792
+ let max_version = krate. max_version ( req. tx ( ) ?) ?;
787
793
788
794
// Upload the crate to S3
789
795
let mut handle = req. app ( ) . handle ( ) ;
@@ -854,7 +860,7 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
854
860
#[ derive( RustcEncodable ) ]
855
861
struct R { krate : EncodableCrate , warnings : Warnings }
856
862
Ok ( req. json ( & R {
857
- krate : krate. minimal_encodable ( None ) ,
863
+ krate : krate. minimal_encodable ( max_version , None ) ,
858
864
warnings : warnings
859
865
} ) )
860
866
}
0 commit comments