1
- use std:: collections:: hashmap :: { HashMap , Occupied , Vacant } ;
1
+ use std:: collections:: HashMap ;
2
2
use std:: sync:: Arc ;
3
3
use std:: time:: Duration ;
4
4
use serialize:: hex:: ToHex ;
@@ -39,8 +39,8 @@ pub struct Crate {
39
39
pub struct EncodableCrate {
40
40
pub id : String ,
41
41
pub name : String ,
42
- pub versions : Vec < i32 > ,
43
42
pub updated_at : String ,
43
+ pub versions : Option < Vec < i32 > > ,
44
44
pub created_at : String ,
45
45
pub downloads : i32 ,
46
46
pub max_version : String ,
@@ -50,6 +50,7 @@ pub struct EncodableCrate {
50
50
#[ deriving( Encodable , Decodable ) ]
51
51
pub struct CrateLinks {
52
52
pub version_downloads : String ,
53
+ pub versions : Option < String > ,
53
54
}
54
55
55
56
impl Crate {
@@ -93,19 +94,24 @@ impl Crate {
93
94
name. chars ( ) . all ( |c| c. is_alphanumeric ( ) || c == '_' || c == '-' )
94
95
}
95
96
96
- fn encodable ( self , versions : Vec < i32 > ) -> EncodableCrate {
97
+ fn encodable ( self , versions : Option < Vec < i32 > > ) -> EncodableCrate {
97
98
let Crate { name, created_at, updated_at, downloads,
98
- max_version, .. } = self ;
99
+ max_version, .. } = self ;
100
+ let versions_link = match versions {
101
+ Some ( ..) => None ,
102
+ None => Some ( format ! ( "/crates/{}/versions" , name) ) ,
103
+ } ;
99
104
EncodableCrate {
100
105
id : name. clone ( ) ,
101
106
name : name. clone ( ) ,
102
- versions : versions,
103
107
updated_at : :: encode_time ( updated_at) ,
104
108
created_at : :: encode_time ( created_at) ,
105
109
downloads : downloads,
110
+ versions : versions,
106
111
max_version : max_version. to_string ( ) ,
107
112
links : CrateLinks {
108
113
version_downloads : format ! ( "/crates/{}/downloads" , name) ,
114
+ versions : versions_link,
109
115
} ,
110
116
}
111
117
}
@@ -121,29 +127,6 @@ impl Crate {
121
127
format ! ( "/pkg/{}/{}-{}.tar.gz" , self . name, self . name, version)
122
128
}
123
129
124
- pub fn encode_many ( conn : & Connection , crates : Vec < Crate > )
125
- -> CargoResult < Vec < EncodableCrate > > {
126
- if crates. len ( ) == 0 { return Ok ( Vec :: new ( ) ) }
127
-
128
- // TODO: can rust-postgres do this escaping?
129
- let crateids: Vec < i32 > = crates. iter ( ) . map ( |p| p. id ) . collect ( ) ;
130
- let mut map = HashMap :: new ( ) ;
131
- let stmt = try!( conn. prepare ( format ! ( "SELECT id, crate_id FROM versions \
132
- WHERE crate_id IN({:#})",
133
- crateids) . as_slice ( ) ) ) ;
134
- for row in try!( stmt. query ( & [ ] ) ) {
135
- match map. entry ( row. get ( "crate_id" ) ) {
136
- Occupied ( e) => e. into_mut ( ) ,
137
- Vacant ( e) => e. set ( Vec :: new ( ) ) ,
138
- } . push ( row. get ( "id" ) ) ;
139
- }
140
-
141
- Ok ( crates. into_iter ( ) . map ( |p| {
142
- let id = p. id ;
143
- p. encodable ( map. pop ( & id) . unwrap ( ) )
144
- } ) . collect ( ) )
145
- }
146
-
147
130
pub fn add_version ( & mut self , conn : & Connection , ver : & semver:: Version ,
148
131
features : & HashMap < String , Vec < String > > )
149
132
-> CargoResult < Version > {
@@ -256,9 +239,9 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
256
239
let stmt = try!( conn. prepare ( q. as_slice ( ) ) ) ;
257
240
let mut crates = Vec :: new ( ) ;
258
241
for row in try!( stmt. query ( args. as_slice ( ) ) ) {
259
- crates. push ( Model :: from_row ( & row) ) ;
242
+ let krate: Crate = Model :: from_row ( & row) ;
243
+ crates. push ( krate. encodable ( None ) ) ;
260
244
}
261
- let crates = try!( Crate :: encode_many ( conn, crates) ) ;
262
245
263
246
// Query for the total count of crates
264
247
let stmt = try!( conn. prepare ( cnt) ) ;
@@ -291,8 +274,11 @@ pub fn summary(req: &mut Request) -> CargoResult<Response> {
291
274
} ;
292
275
293
276
let to_crates = |stmt : PostgresStatement | {
294
- let rows = try!( stmt. query ( [ ] ) ) ;
295
- Crate :: encode_many ( tx, rows. map ( |r| Model :: from_row ( & r) ) . collect ( ) )
277
+ let rows = raw_try ! ( stmt. query( [ ] ) ) ;
278
+ Ok ( rows. map ( |r| {
279
+ let krate: Crate = Model :: from_row ( & r) ;
280
+ krate. encodable ( None )
281
+ } ) . collect :: < Vec < EncodableCrate > > ( ) )
296
282
} ;
297
283
let new_crates = try!( tx. prepare ( "SELECT * FROM crates \
298
284
ORDER BY created_at DESC LIMIT 10") ) ;
@@ -323,11 +309,12 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
323
309
let conn = try!( req. tx ( ) ) ;
324
310
let krate = try!( Crate :: find_by_name ( & * conn, name. as_slice ( ) ) ) ;
325
311
let versions = try!( krate. versions ( & * conn) ) ;
312
+ let ids = versions. iter ( ) . map ( |v| v. id ) . collect ( ) ;
326
313
327
314
#[ deriving( Encodable ) ]
328
315
struct R { krate : EncodableCrate , versions : Vec < EncodableVersion > , }
329
316
Ok ( req. json ( & R {
330
- krate : krate. clone ( ) . encodable ( versions . iter ( ) . map ( |v| v . id ) . collect ( ) ) ,
317
+ krate : krate. clone ( ) . encodable ( Some ( ids ) ) ,
331
318
versions : versions. into_iter ( ) . map ( |v| {
332
319
v. encodable ( krate. name . as_slice ( ) )
333
320
} ) . collect ( ) ,
@@ -421,7 +408,7 @@ pub fn new(req: &mut Request) -> CargoResult<Response> {
421
408
422
409
#[ deriving( Encodable ) ]
423
410
struct R { krate : EncodableCrate }
424
- Ok ( req. json ( & R { krate : krate. encodable ( Vec :: new ( ) ) } ) )
411
+ Ok ( req. json ( & R { krate : krate. encodable ( None ) } ) )
425
412
}
426
413
427
414
fn parse_new_headers ( req : & mut Request ) -> CargoResult < ( upload:: NewCrate , User ) > {
0 commit comments