Skip to content

Commit 7aa1db0

Browse files
committed
Backend support for paginating reverse dependencies
1 parent 01f1bf7 commit 7aa1db0

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

src/krate.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -338,19 +338,33 @@ impl Crate {
338338
}
339339

340340
/// Returns (dependency, dependent crate name)
341-
pub fn reverse_dependencies(&self, conn: &Connection) -> CargoResult<Vec<(Dependency, String)>> {
342-
let stmt = try!(conn.prepare("SELECT dependencies.*,
343-
crates.name AS crate_name
344-
FROM dependencies
345-
INNER JOIN versions
346-
ON versions.id = dependencies.version_id
347-
INNER JOIN crates
348-
ON crates.id = versions.crate_id
349-
WHERE dependencies.crate_id = $1
350-
AND versions.num = crates.max_version"));
351-
Ok(try!(stmt.query(&[&self.id])).map(|r| {
341+
pub fn reverse_dependencies(&self, conn: &Connection, offset: i64, limit: i64)
342+
-> CargoResult<(Vec<(Dependency, String)>, i64)> {
343+
let select_sql = "
344+
FROM dependencies
345+
INNER JOIN versions
346+
ON versions.id = dependencies.version_id
347+
INNER JOIN crates
348+
ON crates.id = versions.crate_id
349+
WHERE dependencies.crate_id = $1
350+
AND versions.num = crates.max_version
351+
";
352+
let fetch_sql = format!("SELECT dependencies.*,
353+
crates.name AS crate_name
354+
{}
355+
ORDER BY crate_name ASC
356+
OFFSET $2
357+
LIMIT $3", select_sql);
358+
let count_sql = format!("SELECT COUNT(dependencies.*) {}", select_sql);
359+
360+
let stmt = try!(conn.prepare(fetch_sql.as_slice()));
361+
let vec: Vec<_> = try!(stmt.query(&[&self.id, &offset, &limit])).map(|r| {
352362
(Model::from_row(&r), r.get("crate_name"))
353-
}).collect())
363+
}).collect();
364+
let stmt = try!(conn.prepare(count_sql.as_slice()));
365+
let cnt: i64 = try!(stmt.query(&[&self.id])).next().unwrap().get(0);
366+
367+
Ok((vec, cnt))
354368
}
355369
}
356370

@@ -885,12 +899,16 @@ pub fn reverse_dependencies(req: &mut Request) -> CargoResult<Response> {
885899
let conn = try!(req.tx());
886900
let krate = try!(Crate::find_by_name(conn, name.as_slice()));
887901
let tx = try!(req.tx());
888-
let rev_deps = try!(krate.reverse_dependencies(tx));
902+
let (offset, limit) = try!(req.pagination(10, 100));
903+
let (rev_deps, total) = try!(krate.reverse_dependencies(tx, offset, limit));
889904
let rev_deps = rev_deps.into_iter().map(|(dep, crate_name)| {
890905
dep.encodable(crate_name.as_slice())
891906
}).collect();
892907

893908
#[deriving(Encodable)]
894-
struct R { dependencies: Vec<EncodableDependency> }
895-
Ok(req.json(&R{ dependencies: rev_deps }))
909+
struct R { dependencies: Vec<EncodableDependency>, meta: Meta }
910+
#[deriving(Encodable)]
911+
struct Meta { total: i64 }
912+
Ok(req.json(&R{ dependencies: rev_deps, meta: Meta { total: total } }))
896913
}
914+

src/tests/krate.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct CrateResponse { krate: EncodableCrate, versions: Vec<EncodableVersion> }
3232
#[deriving(Decodable)]
3333
struct Deps { dependencies: Vec<EncodableDependency> }
3434
#[deriving(Decodable)]
35-
struct RevDeps { reverse_dependencies: Vec<EncodableDependency> }
35+
struct RevDeps { dependencies: Vec<EncodableDependency>, meta: CrateMeta }
3636
#[deriving(Decodable)]
3737
struct Downloads { version_downloads: Vec<EncodableVersionDownload> }
3838

@@ -719,15 +719,17 @@ fn reverse_dependencies() {
719719
let mut req = MockRequest::new(conduit::Get, rel.as_slice());
720720
let mut response = ok_resp!(middle.call(&mut req));
721721
let deps = ::json::<RevDeps>(&mut response);
722-
assert_eq!(deps.reverse_dependencies.len(), 1);
723-
assert_eq!(deps.reverse_dependencies[0].crate_id.as_slice(), &*c1.name);
722+
assert_eq!(deps.dependencies.len(), 1);
723+
assert_eq!(deps.meta.total, 1);
724+
assert_eq!(deps.dependencies[0].crate_id.as_slice(), &*c1.name);
724725
drop(req);
725726

726727
// c1 has no dependent crates.
727728
let rel = format!("/api/v1/crates/{}/reverse_dependencies", c1.name);
728729
let mut req = MockRequest::new(conduit::Get, rel.as_slice());
729730
let mut response = ok_resp!(middle.call(&mut req));
730731
let deps = ::json::<RevDeps>(&mut response);
731-
assert_eq!(deps.reverse_dependencies.len(), 0);
732+
assert_eq!(deps.dependencies.len(), 0);
733+
assert_eq!(deps.meta.total, 0);
732734
drop(req);
733735
}

0 commit comments

Comments
 (0)