From 8bc9f7ea3516e30fb040e49a379be9bca29578c4 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Fri, 10 Mar 2017 02:20:46 -0500 Subject: [PATCH 1/4] use pagination for version downloads --- src/version.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/version.rs b/src/version.rs index 6815074db85..a5b5d40e68b 100644 --- a/src/version.rs +++ b/src/version.rs @@ -300,16 +300,17 @@ pub fn dependencies(req: &mut Request) -> CargoResult { /// Handles the `GET /crates/:crate_id/:version/downloads` route. pub fn downloads(req: &mut Request) -> CargoResult { + let (offset, limit) = req.pagination(90, 100)?; let (version, _) = version_and_crate(req)?; let tx = req.tx()?; - let cutoff_date = ::now() + Duration::days(-90); + let cutoff_end_date = ::now() + Duration::days(-offset); + let cutoff_start_date = cutoff_end_date + Duration::days(-limit); let stmt = tx.prepare("SELECT * FROM version_downloads - WHERE date > $1 AND version_id = $2 + WHERE date > $1 AND date <= $2 AND version_id = $3 ORDER BY date ASC")?; - let downloads = stmt.query(&[&cutoff_date, &version.id])?.iter().map(|row| { - VersionDownload::from_row(&row).encodable() - }).collect(); + let downloads = stmt.query(&[&cutoff_start_date, &cutoff_end_date, &version.id])? + .iter().map(|row| { VersionDownload::from_row(&row).encodable() }).collect(); #[derive(RustcEncodable)] struct R { version_downloads: Vec } From 0fc072cde92c90158ce4835ff324d4862a8b7fb0 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sun, 12 Mar 2017 22:46:56 -0400 Subject: [PATCH 2/4] use before_date for version downloads --- src/tests/krate.rs | 10 ++++++++++ src/version.rs | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/tests/krate.rs b/src/tests/krate.rs index f2f73239bbd..a5583647910 100644 --- a/src/tests/krate.rs +++ b/src/tests/krate.rs @@ -677,6 +677,7 @@ fn summary_doesnt_die() { #[test] fn download() { + use ::time::{Duration, now_utc, strftime}; let (_b, app, middle) = ::app(); let mut req = ::req(app, Method::Get, "/api/v1/crates/foo_download/1.0.0/download"); ::mock_user(&mut req, ::user("foo")); @@ -697,6 +698,15 @@ fn download() { let mut resp = ok_resp!(middle.call(&mut req)); let downloads = ::json::(&mut resp); assert_eq!(downloads.version_downloads.len(), 1); + + let yesterday = now_utc() + Duration::days(-1); + let yesterday = "before_date=".to_string() + &strftime("%Y-%m-%d", &yesterday).unwrap(); + req.with_path("/api/v1/crates/FOO_DOWNLOAD/1.0.0/downloads"); + req.with_query(&yesterday); + let mut resp = ok_resp!(middle.call(&mut req)); + let downloads = ::json::(&mut resp); + assert_eq!(downloads.version_downloads.len(), 0); + } #[test] diff --git a/src/version.rs b/src/version.rs index a5b5d40e68b..e4781dcf143 100644 --- a/src/version.rs +++ b/src/version.rs @@ -6,8 +6,7 @@ use pg::GenericConnection; use pg::rows::Row; use rustc_serialize::json; use semver; -use time::Duration; -use time::Timespec; +use time::{Duration, Timespec, now_utc, strptime}; use url; use {Model, Crate}; @@ -300,17 +299,18 @@ pub fn dependencies(req: &mut Request) -> CargoResult { /// Handles the `GET /crates/:crate_id/:version/downloads` route. pub fn downloads(req: &mut Request) -> CargoResult { - let (offset, limit) = req.pagination(90, 100)?; let (version, _) = version_and_crate(req)?; + let cutoff_end_date = req.query().get("before_date") + .and_then(|d| strptime(d, "%Y-%m-%d").ok()) + .unwrap_or(now_utc()).to_timespec(); + let cutoff_start_date = cutoff_end_date + Duration::days(-90); let tx = req.tx()?; - let cutoff_end_date = ::now() + Duration::days(-offset); - let cutoff_start_date = cutoff_end_date + Duration::days(-limit); let stmt = tx.prepare("SELECT * FROM version_downloads WHERE date > $1 AND date <= $2 AND version_id = $3 ORDER BY date ASC")?; let downloads = stmt.query(&[&cutoff_start_date, &cutoff_end_date, &version.id])? - .iter().map(|row| { VersionDownload::from_row(&row).encodable() }).collect(); + .iter().map(|row| VersionDownload::from_row(&row).encodable()).collect(); #[derive(RustcEncodable)] struct R { version_downloads: Vec } From 6af3460f06c3fb53d0e2dfd4381dbb2ebfafc9ae Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sun, 12 Mar 2017 22:50:27 -0400 Subject: [PATCH 3/4] BETWEEN in sql --- src/version.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.rs b/src/version.rs index e4781dcf143..a6f0cb356c0 100644 --- a/src/version.rs +++ b/src/version.rs @@ -303,11 +303,11 @@ pub fn downloads(req: &mut Request) -> CargoResult { let cutoff_end_date = req.query().get("before_date") .and_then(|d| strptime(d, "%Y-%m-%d").ok()) .unwrap_or(now_utc()).to_timespec(); - let cutoff_start_date = cutoff_end_date + Duration::days(-90); + let cutoff_start_date = cutoff_end_date + Duration::days(-89); let tx = req.tx()?; let stmt = tx.prepare("SELECT * FROM version_downloads - WHERE date > $1 AND date <= $2 AND version_id = $3 + WHERE date BETWEEN $1 AND $2 AND version_id = $3 ORDER BY date ASC")?; let downloads = stmt.query(&[&cutoff_start_date, &cutoff_end_date, &version.id])? .iter().map(|row| VersionDownload::from_row(&row).encodable()).collect(); From 890a4755d1602fa8e87503ced25b84550c78ff4c Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Mon, 13 Mar 2017 13:15:26 -0400 Subject: [PATCH 4/4] Add test for before_date for version downloads --- src/tests/krate.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tests/krate.rs b/src/tests/krate.rs index a5583647910..e37960180c1 100644 --- a/src/tests/krate.rs +++ b/src/tests/krate.rs @@ -700,13 +700,19 @@ fn download() { assert_eq!(downloads.version_downloads.len(), 1); let yesterday = now_utc() + Duration::days(-1); - let yesterday = "before_date=".to_string() + &strftime("%Y-%m-%d", &yesterday).unwrap(); req.with_path("/api/v1/crates/FOO_DOWNLOAD/1.0.0/downloads"); - req.with_query(&yesterday); + req.with_query(&("before_date=".to_string() + &strftime("%Y-%m-%d", &yesterday).unwrap())); let mut resp = ok_resp!(middle.call(&mut req)); let downloads = ::json::(&mut resp); assert_eq!(downloads.version_downloads.len(), 0); + let tomorrow = now_utc() + Duration::days(1); + req.with_path("/api/v1/crates/FOO_DOWNLOAD/1.0.0/downloads"); + req.with_query(&("before_date=".to_string() + &strftime("%Y-%m-%d", &tomorrow).unwrap())); + let mut resp = ok_resp!(middle.call(&mut req)); + let downloads = ::json::(&mut resp); + assert_eq!(downloads.version_downloads.len(), 1); + } #[test]