@@ -186,6 +186,7 @@ impl Handler for CratesfyiHandler {
186
186
}
187
187
188
188
/// Represents the possible results of attempting to load a version requirement.
189
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
189
190
enum MatchVersion {
190
191
/// `match_version` was given an exact version, which matched a saved crate version.
191
192
Exact ( String ) ,
@@ -226,19 +227,15 @@ fn match_version(conn: &Connection, name: &str, version: Option<&str>) -> MatchV
226
227
. map ( |v| if v == "newest" || v == "latest" { "*" . to_owned ( ) } else { v } )
227
228
. unwrap_or ( "*" . to_string ( ) ) ;
228
229
229
- let versions = {
230
- let mut versions = Vec :: new ( ) ;
231
- let rows = conn. query ( "SELECT versions FROM crates WHERE name = $1" , & [ & name] ) . unwrap ( ) ;
230
+ let versions: Vec < String > = {
231
+ let query = "SELECT version
232
+ FROM releases INNER JOIN crates ON releases.crate_id = crates.id
233
+ WHERE name = $1 AND yanked = false" ;
234
+ let rows = conn. query ( query, & [ & name] ) . unwrap ( ) ;
232
235
if rows. len ( ) == 0 {
233
236
return MatchVersion :: None ;
234
237
}
235
- let versions_json: Json = rows. get ( 0 ) . get ( 0 ) ;
236
- for version in versions_json. as_array ( ) . unwrap ( ) {
237
- let version: String = version. as_string ( ) . unwrap ( ) . to_owned ( ) ;
238
- versions. push ( version) ;
239
- }
240
-
241
- versions
238
+ rows. iter ( ) . map ( |row| row. get ( 0 ) ) . collect ( )
242
239
} ;
243
240
244
241
// first check for exact match
@@ -274,18 +271,18 @@ fn match_version(conn: &Connection, name: &str, version: Option<&str>) -> MatchV
274
271
versions_sem
275
272
} ;
276
273
277
- // semver is acting weird for '*' (any) range if a crate only have pre-release versions
278
- // return first version if requested version is '*'
279
- if req_version == "*" && !versions_sem. is_empty ( ) {
280
- return MatchVersion :: Semver ( format ! ( "{}" , versions_sem[ 0 ] ) ) ;
281
- }
282
-
283
274
for version in & versions_sem {
284
275
if req_sem_ver. matches ( & version) {
285
276
return MatchVersion :: Semver ( format ! ( "{}" , version) ) ;
286
277
}
287
278
}
288
279
280
+ // semver is acting weird for '*' (any) range if a crate only have pre-release versions
281
+ // return first version if requested version is '*'
282
+ if req_version == "*" && !versions_sem. is_empty ( ) {
283
+ return MatchVersion :: Semver ( format ! ( "{}" , versions_sem[ 0 ] ) ) ;
284
+ }
285
+
289
286
MatchVersion :: None
290
287
}
291
288
@@ -517,4 +514,43 @@ mod test {
517
514
Ok ( ( ) )
518
515
} ) ;
519
516
}
517
+
518
+ #[ test]
519
+ fn test_match_version ( ) {
520
+ use web:: { match_version, MatchVersion } ;
521
+
522
+ crate :: test:: wrapper ( |env| {
523
+ let db = env. db ( ) ;
524
+ let version = |v| match_version ( & db. conn ( ) , "foo" , v) ;
525
+ let release = |v| db. fake_release ( ) . name ( "foo" ) . version ( v) . create ( ) . unwrap ( ) ;
526
+
527
+ release ( "0.3.1-pre" ) ;
528
+ assert_eq ! ( version( Some ( "*" ) ) , MatchVersion :: Semver ( "0.3.1-pre" . into( ) ) ) ;
529
+
530
+ release ( "0.3.1-alpha" ) ;
531
+ assert_eq ! ( version( Some ( "0.3.1-alpha" ) ) , MatchVersion :: Exact ( "0.3.1-alpha" . into( ) ) ) ;
532
+
533
+ let release_id = release ( "0.3.0" ) ;
534
+ let three = MatchVersion :: Semver ( "0.3.0" . into ( ) ) ;
535
+ assert_eq ! ( version( Some ( "*" ) ) , three) ;
536
+ // same thing but make sure None behaves like we think it does
537
+ assert_eq ! ( version( None ) , three) ;
538
+ // make sure exact matches still work
539
+ assert_eq ! ( version( Some ( "0.3.0" ) ) , MatchVersion :: Exact ( "0.3.0" . into( ) ) ) ;
540
+
541
+ // https://github.com/rust-lang/docs.rs/issues/395
542
+ let query = "UPDATE releases SET yanked = true WHERE id = $1 AND version = '0.3.0'" ;
543
+ db. conn ( ) . query ( query, & [ & release_id] ) . unwrap ( ) ;
544
+ release ( "0.1.0+4.1" ) ;
545
+ assert_eq ! ( version( Some ( "0.1.0+4.1" ) ) , MatchVersion :: Exact ( "0.1.0+4.1" . into( ) ) ) ;
546
+ assert_eq ! ( version( None ) , MatchVersion :: Semver ( "0.1.0+4.1" . into( ) ) ) ;
547
+ release ( "0.1.1" ) ;
548
+ assert_eq ! ( version( None ) , MatchVersion :: Semver ( "0.1.1" . into( ) ) ) ;
549
+ release ( "0.5.1+zstd.1.4.4" ) ;
550
+ assert_eq ! ( version( None ) , MatchVersion :: Semver ( "0.5.1+zstd.1.4.4" . into( ) ) ) ;
551
+ assert_eq ! ( version( Some ( "0.5.1+zstd.1.4.4" ) ) , MatchVersion :: Exact ( "0.5.1+zstd.1.4.4" . into( ) ) ) ;
552
+
553
+ Ok ( ( ) )
554
+ } )
555
+ }
520
556
}
0 commit comments