Skip to content

Commit b26dafc

Browse files
committed
Port versions/index to use Diesel
1 parent 878c082 commit b26dafc

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

src/tests/version.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,37 @@
1-
use std::collections::HashMap;
1+
extern crate diesel;
2+
23
use rustc_serialize::json::Json;
34

45
use conduit::{Handler, Method};
5-
use semver;
6+
use self::diesel::prelude::*;
67

7-
use cargo_registry::db::RequestTransaction;
8-
use cargo_registry::version::{EncodableVersion, Version};
8+
use cargo_registry::version::EncodableVersion;
9+
use cargo_registry::schema::versions;
910

1011
#[derive(RustcDecodable)]
1112
struct VersionList { versions: Vec<EncodableVersion> }
1213
#[derive(RustcDecodable)]
1314
struct VersionResponse { version: EncodableVersion }
1415

15-
fn sv(s: &str) -> semver::Version {
16-
semver::Version::parse(s).unwrap()
17-
}
18-
1916
#[test]
2017
fn index() {
2118
let (_b, app, middle) = ::app();
22-
let mut req = ::req(app, Method::Get, "/api/v1/versions");
19+
let mut req = ::req(app.clone(), Method::Get, "/api/v1/versions");
2320
let mut response = ok_resp!(middle.call(&mut req));
2421
let json: VersionList = ::json(&mut response);
2522
assert_eq!(json.versions.len(), 0);
2623

2724
let (v1, v2) = {
28-
::mock_user(&mut req, ::user("foo"));
29-
let (c, _) = ::mock_crate(&mut req, ::krate("foo_vers_index"));
30-
let tx = req.tx().unwrap();
31-
let m = HashMap::new();
32-
let v1 = Version::insert(tx, c.id, &sv("2.0.0"), &m, &[]).unwrap();
33-
let v2 = Version::insert(tx, c.id, &sv("2.0.1"), &m, &[]).unwrap();
34-
(v1, v2)
25+
let conn = app.diesel_database.get().unwrap();
26+
let u = ::new_user("foo").create_or_update(&conn).unwrap();
27+
::CrateBuilder::new("foo_vers_index", u.id)
28+
.version("2.0.0")
29+
.version("2.0.1")
30+
.expect_build(&conn);
31+
let ids = versions::table.select(versions::id).load::<i32>(&*conn).unwrap();
32+
(ids[0], ids[1])
3533
};
36-
req.with_query(&format!("ids[]={}&ids[]={}", v1.id, v2.id));
34+
req.with_query(&format!("ids[]={}&ids[]={}", v1, v2));
3735
let mut response = ok_resp!(middle.call(&mut req));
3836
let json: VersionList = ::json(&mut response);
3937
assert_eq!(json.versions.len(), 2);

src/version.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ impl Model for Version {
280280
/// Handles the `GET /versions` route.
281281
// FIXME: where/how is this used?
282282
pub fn index(req: &mut Request) -> CargoResult<Response> {
283-
let conn = req.tx()?;
283+
use diesel::expression::dsl::any;
284+
let conn = req.db_conn()?;
284285

285286
// Extract all ids requested.
286287
let query = url::form_urlencoded::parse(req.query_string().unwrap_or("")
@@ -293,23 +294,13 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
293294
}
294295
}).collect::<Vec<i32>>();
295296

296-
// Load all versions
297-
//
298-
// TODO: can rust-postgres do this for us?
299-
let mut versions = Vec::new();
300-
if !ids.is_empty() {
301-
let stmt = conn.prepare("\
302-
SELECT versions.*, crates.name AS crate_name
303-
FROM versions
304-
LEFT JOIN crates ON crates.id = versions.crate_id
305-
WHERE versions.id = ANY($1)
306-
")?;
307-
for row in stmt.query(&[&ids])?.iter() {
308-
let v: Version = Model::from_row(&row);
309-
let crate_name: String = row.get("crate_name");
310-
versions.push(v.encodable(&crate_name));
311-
}
312-
}
297+
let versions = versions::table.inner_join(crates::table)
298+
.select((versions::all_columns, crates::name))
299+
.filter(versions::id.eq(any(ids)))
300+
.load::<(Version, String)>(&*conn)?
301+
.into_iter()
302+
.map(|(version, crate_name)| version.encodable(&crate_name))
303+
.collect();
313304

314305
#[derive(RustcEncodable)]
315306
struct R { versions: Vec<EncodableVersion> }

0 commit comments

Comments
 (0)