Skip to content

Commit 1c348d8

Browse files
committed
Add API endpoint to retrieve the reverse dependencies.
This /api/v1/crates/foo/reverse_dependencies gives the full dependency information about each crate that depends on foo (i.e. crates with `[dependencies] foo = "..."`).
1 parent 68b01d6 commit 1c348d8

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/krate.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use url::{mod, Url};
1717
use {Model, User, Keyword, Version};
1818
use app::{App, RequestApp};
1919
use db::{Connection, RequestTransaction};
20+
use dependency::{Dependency, EncodableDependency};
2021
use download::{VersionDownload, EncodableVersionDownload};
2122
use git;
2223
use keyword::EncodableKeyword;
@@ -319,6 +320,21 @@ impl Crate {
319320
let rows = try!(stmt.query(&[&self.id]));
320321
Ok(rows.map(|r| Model::from_row(&r)).collect())
321322
}
323+
324+
/// Returns (dependency, dependent crate name)
325+
pub fn reverse_dependencies(&self, conn: &Connection) -> CargoResult<Vec<(Dependency, String)>> {
326+
let stmt = try!(conn.prepare("SELECT dependencies.*,
327+
crates.name AS crate_name
328+
FROM dependencies
329+
LEFT JOIN versions
330+
ON versions.id = dependencies.version_id
331+
LEFT JOIN crates
332+
ON crates.id = versions.crate_id
333+
WHERE dependencies.crate_id = $1"));
334+
Ok(try!(stmt.query(&[&self.id])).map(|r| {
335+
(Model::from_row(&r), r.get("crate_name"))
336+
}).collect())
337+
}
322338
}
323339

324340
impl Model for Crate {
@@ -846,3 +862,18 @@ fn modify_owners(req: &mut Request, add: bool) -> CargoResult<Response> {
846862
struct R { ok: bool }
847863
Ok(req.json(&R{ ok: true }))
848864
}
865+
866+
pub fn reverse_dependencies(req: &mut Request) -> CargoResult<Response> {
867+
let name = &req.params()["crate_id"];
868+
let conn = try!(req.tx());
869+
let krate = try!(Crate::find_by_name(conn, name.as_slice()));
870+
let tx = try!(req.tx());
871+
let rev_deps = try!(krate.reverse_dependencies(tx));
872+
let rev_deps = rev_deps.into_iter().map(|(dep, crate_name)| {
873+
dep.encodable(crate_name.as_slice())
874+
}).collect();
875+
876+
#[deriving(Encodable)]
877+
struct R { reverse_dependencies: Vec<EncodableDependency> }
878+
Ok(req.json(&R{ reverse_dependencies: rev_deps }))
879+
}

src/lib.rs

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
8989
api_router.delete("/crates/:crate_id/owners", C(krate::remove_owners));
9090
api_router.delete("/crates/:crate_id/:version/yank", C(version::yank));
9191
api_router.put("/crates/:crate_id/:version/unyank", C(version::unyank));
92+
api_router.get("/crates/:crate_id/reverse_dependencies", C(krate::reverse_dependencies));
9293
api_router.get("/versions", C(version::index));
9394
api_router.get("/versions/:version_id", C(version::show));
9495
api_router.get("/keywords", C(keyword::index));

0 commit comments

Comments
 (0)