Skip to content

Commit 7649d01

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 2ee930f commit 7649d01

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;
@@ -318,6 +319,21 @@ impl Crate {
318319
let rows = try!(stmt.query(&[&self.id]));
319320
Ok(rows.map(|r| Model::from_row(&r)).collect())
320321
}
322+
323+
/// Returns (dependency, dependent crate name)
324+
pub fn reverse_dependencies(&self, conn: &Connection) -> CargoResult<Vec<(Dependency, String)>> {
325+
let stmt = try!(conn.prepare("SELECT dependencies.*,
326+
crates.name AS crate_name
327+
FROM dependencies
328+
LEFT JOIN versions
329+
ON versions.id = dependencies.version_id
330+
LEFT JOIN crates
331+
ON crates.id = versions.crate_id
332+
WHERE dependencies.crate_id = $1"));
333+
Ok(try!(stmt.query(&[&self.id])).map(|r| {
334+
(Model::from_row(&r), r.get("crate_name"))
335+
}).collect())
336+
}
321337
}
322338

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

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)