Skip to content

Commit ab18c44

Browse files
committed
Funnel all crate listings through /crates
1 parent 1fc1ca9 commit ab18c44

File tree

5 files changed

+57
-57
lines changed

5 files changed

+57
-57
lines changed

src/krate.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,13 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
189189
let query = req.query();
190190
let sort = query.find_equiv(&"sort").map(|s| s.as_slice()).unwrap_or("alpha");
191191
let sort_sql = match sort {
192-
"downloads" => "ORDER BY downloads DESC",
193-
_ => "ORDER BY name ASC",
192+
"downloads" => "ORDER BY crates.downloads DESC",
193+
_ => "ORDER BY crates.name ASC",
194194
};
195195

196196
// Different queries for different parameters
197197
let mut pattern;
198+
let mut id;
198199
let mut args = vec![&limit as &ToSql, &offset as &ToSql];
199200
let (q, cnt) = match (query.find_equiv(&"q"), query.find_equiv(&"letter")) {
200201
(Some(query), _) => {
@@ -219,8 +220,38 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
219220
"SELECT COUNT(*) FROM crates WHERE name LIKE $1")
220221
},
221222
(None, None) => {
222-
(format!("SELECT * FROM crates {} LIMIT $1 OFFSET $2", sort_sql),
223-
"SELECT COUNT(*) FROM crates")
223+
let user_id = query.find_equiv(&"user_id").map(|s| s.as_slice())
224+
.and_then(from_str::<i32>);
225+
let following = query.find_equiv(&"following").is_some();
226+
match (user_id, following) {
227+
(Some(user_id), _) => {
228+
id = user_id;
229+
args.insert(0, &id as &ToSql);
230+
(format!("SELECT * FROM crates WHERE user_id = $1 {} \
231+
LIMIT $2 OFFSET $3",
232+
sort_sql),
233+
"SELECT COUNT(*) FROM crates WHERE user_id = $1")
234+
}
235+
(None, true) => {
236+
let me = try!(req.user());
237+
id = me.id;
238+
args.insert(0, &id as &ToSql);
239+
(format!("SELECT crates.* FROM crates
240+
INNER JOIN follows
241+
ON follows.crate_id = crates.id AND
242+
follows.user_id = $1
243+
{} LIMIT $2 OFFSET $3", sort_sql),
244+
"SELECT COUNT(crates.*) FROM crates
245+
INNER JOIN follows
246+
ON follows.crate_id = crates.id AND
247+
follows.user_id = $1")
248+
}
249+
(None, false) => {
250+
(format!("SELECT * FROM crates {} LIMIT $1 OFFSET $2",
251+
sort_sql),
252+
"SELECT COUNT(*) FROM crates")
253+
}
254+
}
224255
}
225256
};
226257

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
7373
router.get("/logout", C(user::logout));
7474
router.get("/me", C(user::me));
7575
router.put("/me/reset_token", C(user::reset_token));
76-
router.get("/me/crates", C(user::my_crates));
77-
router.get("/me/following", C(user::my_following));
7876
router.get("/summary", C(krate::summary));
7977
router.get("/crates", C(krate::index));
8078
router.get("/crates/:crate_id", C(krate::show));

src/tests/krate.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ use cargo_registry::download::EncodableVersionDownload;
1414
use cargo_registry::version::EncodableVersion;
1515
use cargo_registry::upload as u;
1616

17-
#[deriving(Decodable)]
18-
struct Crates { crates: Vec<EncodableCrate> }
1917
#[deriving(Decodable)]
2018
struct CrateList { crates: Vec<EncodableCrate>, meta: CrateMeta }
2119
#[deriving(Decodable)]
@@ -444,27 +442,40 @@ fn following() {
444442
let mut response = ok_resp!(middle.call(&mut req));
445443
assert!(!::json::<F>(&mut response).following);
446444

447-
req.with_path("/crates/foo/follow");
445+
req.with_path("/crates/foo/follow")
446+
.with_method(conduit::Put);
448447
let mut response = ok_resp!(middle.call(&mut req));
449448
assert!(::json::<O>(&mut response).ok);
450449
let mut response = ok_resp!(middle.call(&mut req));
451450
assert!(::json::<O>(&mut response).ok);
452451

453-
req.with_path("/crates/foo/following");
452+
req.with_path("/crates/foo/following")
453+
.with_method(conduit::Get);
454454
let mut response = ok_resp!(middle.call(&mut req));
455455
assert!(::json::<F>(&mut response).following);
456456

457-
req.with_path("/me/following");
457+
req.with_path("/crates")
458+
.with_query("following=1");
458459
let mut response = ok_resp!(middle.call(&mut req));
459-
assert_eq!(::json::<Crates>(&mut response).crates.len(), 1);
460+
let l = ::json::<CrateList>(&mut response);
461+
println!("{} {}", l.crates.len(), l.meta.total);
462+
assert_eq!(l.crates.len(), 1);
460463

461-
req.with_path("/crates/foo/unfollow");
464+
req.with_path("/crates/foo/unfollow")
465+
.with_method(conduit::Put);
462466
let mut response = ok_resp!(middle.call(&mut req));
463467
assert!(::json::<O>(&mut response).ok);
464468
let mut response = ok_resp!(middle.call(&mut req));
465469
assert!(::json::<O>(&mut response).ok);
466470

467-
req.with_path("/crates/foo/following");
471+
req.with_path("/crates/foo/following")
472+
.with_method(conduit::Get);
468473
let mut response = ok_resp!(middle.call(&mut req));
469474
assert!(!::json::<F>(&mut response).following);
475+
476+
req.with_path("/crates")
477+
.with_query("following=1")
478+
.with_method(conduit::Get);
479+
let mut response = ok_resp!(middle.call(&mut req));
480+
assert_eq!(::json::<CrateList>(&mut response).crates.len(), 0);
470481
}

src/tests/user.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ fn reset_token() {
9595
#[test]
9696
fn my_packages() {
9797
let (_b, app, middle) = ::app();
98-
let mut req = ::req(app, conduit::Get, "/me/crates");
99-
::mock_user(&mut req, ::user());
98+
let mut req = ::req(app, conduit::Get, "/crates");
99+
let u = ::mock_user(&mut req, ::user());
100100
::mock_crate(&mut req, "foo");
101+
req.with_query(format!("user_id={}", u.id));
101102
let mut response = ok_resp!(middle.call(&mut req));
102103

103104
#[deriving(Decodable)]

src/user/mod.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ use oauth2::Authorization;
1010
use pg::PostgresRow;
1111
use pg::types::ToSql;
1212

13-
use Model;
1413
use app::RequestApp;
1514
use db::{Connection, RequestTransaction};
16-
use krate::{Crate, EncodableCrate};
1715
use util::{RequestUtils, CargoResult, internal, Require, ChainError, human};
1816
use util::errors::NotFound;
1917

@@ -227,42 +225,3 @@ pub fn me(req: &mut Request) -> CargoResult<Response> {
227225
let token = user.api_token.clone();
228226
Ok(req.json(&R{ user: user.clone().encodable(), api_token: token }))
229227
}
230-
231-
pub fn my_crates(req: &mut Request) -> CargoResult<Response> {
232-
let user = try!(req.user());
233-
let (offset, limit) = try!(req.pagination(10, 100));
234-
235-
let tx = try!(req.tx());
236-
let stmt = try!(tx.prepare("SELECT * FROM crates WHERE user_id = $1
237-
ORDER BY downloads DESC
238-
OFFSET $2 LIMIT $3"));
239-
let mut crates = Vec::new();
240-
for row in try!(stmt.query(&[&user.id, &offset, &limit])) {
241-
crates.push(Model::from_row(&row));
242-
}
243-
244-
#[deriving(Encodable)]
245-
struct R { crates: Vec<EncodableCrate> }
246-
Ok(req.json(&R{ crates: try!(Crate::encode_many(tx, crates)) }))
247-
}
248-
249-
pub fn my_following(req: &mut Request) -> CargoResult<Response> {
250-
let user = try!(req.user());
251-
let (offset, limit) = try!(req.pagination(10, 100));
252-
253-
let tx = try!(req.tx());
254-
let stmt = try!(tx.prepare("SELECT crates.* FROM crates
255-
INNER JOIN follows
256-
ON follows.crate_id = crates.id
257-
WHERE follows.user_id = $1
258-
ORDER BY crates.downloads DESC
259-
OFFSET $2 LIMIT $3"));
260-
let mut crates = Vec::new();
261-
for row in try!(stmt.query(&[&user.id, &offset, &limit])) {
262-
crates.push(Model::from_row(&row));
263-
}
264-
265-
#[deriving(Encodable)]
266-
struct R { crates: Vec<EncodableCrate> }
267-
Ok(req.json(&R{ crates: try!(Crate::encode_many(tx, crates)) }))
268-
}

0 commit comments

Comments
 (0)