diff --git a/app/models/dependency.js b/app/models/dependency.js index 5368a69b6ae..15bc44588d7 100644 --- a/app/models/dependency.js +++ b/app/models/dependency.js @@ -15,6 +15,7 @@ export default DS.Model.extend({ default_features: DS.attr('boolean'), features: DS.attr('string'), kind: DS.attr('string'), + downloads: DS.attr('number'), featureList: computed('features', function() { return this.get('features').split(','); diff --git a/app/styles/crate.scss b/app/styles/crate.scss index 05e2b453280..e8d0ab0b69c 100644 --- a/app/styles/crate.scss +++ b/app/styles/crate.scss @@ -127,6 +127,8 @@ } .downloads { @include display-flex; @include align-items(center); } + .rev-dep-downloads {padding-left: 7px} + .quick-links { ul { @include display-flex; diff --git a/app/templates/crate/reverse-dependencies.hbs b/app/templates/crate/reverse-dependencies.hbs index a1d2fcc9813..b5b0d3f6e4c 100644 --- a/app/templates/crate/reverse-dependencies.hbs +++ b/app/templates/crate/reverse-dependencies.hbs @@ -13,15 +13,16 @@ -
+
{{#each model as |dependency|}} -
+
{{#link-to 'crate' dependency.crate_id}}{{dependency.crate_id}}{{/link-to}} requires {{dependency.req}}
- {{#link-to 'crate' dependency.crate_id class='arrow'}} - - {{/link-to}} +
+ + {{ format-num dependency.downloads }} +
{{/each}}
diff --git a/src/dependency.rs b/src/dependency.rs index 66827e6c5f1..78db2f8afd5 100644 --- a/src/dependency.rs +++ b/src/dependency.rs @@ -29,6 +29,7 @@ pub struct EncodableDependency { pub features: String, pub target: Option, pub kind: Kind, + pub downloads: i32, } #[derive(Copy, Clone)] @@ -76,9 +77,17 @@ impl Dependency { } } - pub fn encodable(self, crate_name: &str) -> EncodableDependency { - let Dependency { id, version_id, crate_id: _, req, optional, - default_features, features, target, kind } = self; + // `downloads` need only be specified when generating a reverse dependency + pub fn encodable(self, crate_name: &str, downloads: Option) -> EncodableDependency { + let Dependency { id, + version_id, + crate_id: _, + req, + optional, + default_features, + features, + target, + kind } = self; EncodableDependency { id: id, version_id: version_id, @@ -89,6 +98,7 @@ impl Dependency { features: features.join(","), target: target, kind: kind, + downloads: downloads.unwrap_or(0), } } } diff --git a/src/krate.rs b/src/krate.rs index 1fc5a486a79..202d7404626 100644 --- a/src/krate.rs +++ b/src/krate.rs @@ -420,12 +420,12 @@ impl Crate { Ok(rows.iter().map(|r| Model::from_row(&r)).collect()) } - /// Returns (dependency, dependent crate name) + /// Returns (dependency, dependent crate name, dependent crate downloads) pub fn reverse_dependencies(&self, conn: &GenericConnection, offset: i64, limit: i64) - -> CargoResult<(Vec<(Dependency, String)>, i64)> { + -> CargoResult<(Vec<(Dependency, String, i32)>, i64)> { let select_sql = " FROM dependencies INNER JOIN versions @@ -435,21 +435,22 @@ impl Crate { WHERE dependencies.crate_id = $1 AND versions.num = crates.max_version "; - let fetch_sql = format!("SELECT DISTINCT ON (crate_name) + let fetch_sql = format!("SELECT DISTINCT ON (crate_downloads, crate_name) dependencies.*, + crates.downloads AS crate_downloads, crates.name AS crate_name {} - ORDER BY crate_name ASC + ORDER BY crate_downloads DESC OFFSET $2 - LIMIT $3", select_sql); - let count_sql = format!("SELECT COUNT(DISTINCT(crates.id)) {}", + LIMIT $3", select_sql); + let count_sql = format!("SELECT COUNT(DISTINCT(crates.id)) {}", select_sql); let stmt = try!(conn.prepare(&fetch_sql)); let vec: Vec<_> = try!(stmt.query(&[&self.id, &offset, &limit])) - .iter().map(|r| { - (Model::from_row(&r), r.get("crate_name")) - }).collect(); + .iter() + .map(|r| (Model::from_row(&r), r.get("crate_name"), r.get("crate_downloads"))) + .collect(); let stmt = try!(conn.prepare(&count_sql)); let cnt: i64 = try!(stmt.query(&[&self.id])).iter().next().unwrap().get(0); @@ -1172,12 +1173,11 @@ pub fn reverse_dependencies(req: &mut Request) -> CargoResult { let name = &req.params()["crate_id"]; let conn = try!(req.tx()); let krate = try!(Crate::find_by_name(conn, &name)); - let tx = try!(req.tx()); let (offset, limit) = try!(req.pagination(10, 100)); - let (rev_deps, total) = try!(krate.reverse_dependencies(tx, offset, limit)); - let rev_deps = rev_deps.into_iter().map(|(dep, crate_name)| { - dep.encodable(&crate_name) - }).collect(); + let (rev_deps, total) = try!(krate.reverse_dependencies(conn, offset, limit)); + let rev_deps = rev_deps.into_iter() + .map(|(dep, crate_name, downloads)| dep.encodable(&crate_name, Some(downloads))) + .collect(); #[derive(RustcEncodable)] struct R { dependencies: Vec, meta: Meta } diff --git a/src/version.rs b/src/version.rs index 2265d445db8..98c27b758b8 100644 --- a/src/version.rs +++ b/src/version.rs @@ -296,7 +296,7 @@ pub fn dependencies(req: &mut Request) -> CargoResult { let tx = try!(req.tx()); let deps = try!(version.dependencies(tx)); let deps = deps.into_iter().map(|(dep, crate_name)| { - dep.encodable(&crate_name) + dep.encodable(&crate_name, None) }).collect(); #[derive(RustcEncodable)]