Skip to content

Commit da5bfeb

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 da5bfeb

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/krate.rs

+32
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,22 @@ 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+
INNER JOIN versions
330+
ON versions.id = dependencies.version_id
331+
INNER JOIN crates
332+
ON crates.id = versions.crate_id
333+
WHERE dependencies.crate_id = $1
334+
AND versions.num = crates.max_version"));
335+
Ok(try!(stmt.query(&[&self.id])).map(|r| {
336+
(Model::from_row(&r), r.get("crate_name"))
337+
}).collect())
338+
}
322339
}
323340

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

src/lib.rs

100644100755
+1
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)