Skip to content

Commit

Permalink
Require hyphens and underscores don't clash
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Mar 20, 2015
1 parent 3506971 commit 89bc5dd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
22 changes: 22 additions & 0 deletions src/bin/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,28 @@ fn migrations() -> Vec<Migration> {
crate_owners_unique_user_per_crate", &[]));
Ok(())
}),
Migration::new(20150319224700, |tx| {
try!(tx.execute("
CREATE FUNCTION canon_crate_name(text) RETURNS text AS $$
SELECT replace(lower($1), '-', '_')
$$ LANGUAGE SQL
", &[]));
Ok(())
}, |tx| {
try!(tx.execute("DROP FUNCTION canon_crate_name(text)", &[]));
Ok(())
}),
Migration::new(20150319224701, |tx| {
try!(tx.execute("DROP INDEX index_crates_name", &[]));
try!(tx.execute("CREATE UNIQUE INDEX index_crates_name \
ON crates (canon_crate_name(name))", &[]));
Ok(())
}, |tx| {
try!(tx.execute("DROP INDEX index_crates_name", &[]));
try!(tx.execute("CREATE UNIQUE INDEX index_crates_name \
ON crates (lower(name))", &[]));
Ok(())
}),
];
// NOTE: Generate a new id via `date +"%Y%m%d%H%M%S"`

Expand Down
16 changes: 10 additions & 6 deletions src/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ impl Crate {

pub fn find_by_name(conn: &Connection, name: &str) -> CargoResult<Crate> {
let stmt = try!(conn.prepare("SELECT * FROM crates \
WHERE lower(name) = lower($1) LIMIT 1"));
WHERE canon_crate_name(name) =
canon_crate_name($1) LIMIT 1"));
let row = try!(stmt.query(&[&name as &ToSql])).into_iter().next();
let row = try!(row.chain_error(|| NotFound));
Ok(Model::from_row(&row))
Expand Down Expand Up @@ -136,7 +137,8 @@ impl Crate {
keywords = $5,
license = $6,
repository = $7
WHERE lower(name) = lower($8)
WHERE canon_crate_name(name) =
canon_crate_name($8)
RETURNING *"));
let rows = try!(stmt.query(&[&documentation, &homepage,
&description, &readme, &keywords,
Expand Down Expand Up @@ -448,9 +450,10 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
pattern = format!("{}%", letter.as_slice().char_at(0)
.to_lowercase().collect::<String>());
needs_pattern = true;
(format!("SELECT * FROM crates WHERE lower(name) LIKE $1 {}
LIMIT $2 OFFSET $3", sort_sql),
"SELECT COUNT(*) FROM crates WHERE lower(name) LIKE $1".to_string())
(format!("SELECT * FROM crates WHERE canon_crate_name(name) \
LIKE $1 {} LIMIT $2 OFFSET $3", sort_sql),
"SELECT COUNT(*) FROM crates WHERE canon_crate_name(name) \
LIKE $1".to_string())
})
}).or_else(|| {
query.get("keyword").map(|kw| {
Expand Down Expand Up @@ -789,7 +792,8 @@ pub fn download(req: &mut Request) -> CargoResult<Response> {
FROM crates
INNER JOIN versions ON
crates.id = versions.crate_id
WHERE lower(crates.name) = lower($1)
WHERE canon_crate_name(crates.name) =
canon_crate_name($1)
AND versions.num = $2
LIMIT 1"));
let rows = try!(stmt.query(&[&crate_name as &ToSql, &version as &ToSql]));
Expand Down
22 changes: 22 additions & 0 deletions src/tests/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,28 @@ fn new_crate_similar_name() {
"{:?}", json.errors);
}

#[test]
fn new_crate_similar_name_hyphen() {
{
let (_b, app, middle) = ::app();
let mut req = new_req(app, "foo-bar", "1.1.0");
::mock_user(&mut req, ::user("foo"));
::mock_crate(&mut req, ::krate("foo_bar"));
let json = bad_resp!(middle.call(&mut req));
assert!(json.errors[0].detail.as_slice().contains("previously named"),
"{:?}", json.errors);
}
{
let (_b, app, middle) = ::app();
let mut req = new_req(app, "foo_bar", "1.1.0");
::mock_user(&mut req, ::user("foo"));
::mock_crate(&mut req, ::krate("foo-bar"));
let json = bad_resp!(middle.call(&mut req));
assert!(json.errors[0].detail.as_slice().contains("previously named"),
"{:?}", json.errors);
}
}

#[test]
fn new_krate_git_upload() {
let (_b, app, middle) = ::app();
Expand Down

0 comments on commit 89bc5dd

Please sign in to comment.