Skip to content

Touch a crate whenever its versions are changed #931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TRIGGER touch_crate ON versions;
DROP FUNCTION touch_crate_on_version_modified();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE OR REPLACE FUNCTION touch_crate_on_version_modified() RETURNS trigger AS $$
BEGIN
IF (
TG_OP = 'INSERT' OR
NEW.updated_at IS DISTINCT FROM OLD.updated_at
) THEN
UPDATE crates SET updated_at = CURRENT_TIMESTAMP WHERE
crates.id = NEW.crate_id;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER touch_crate BEFORE INSERT OR UPDATE ON versions
FOR EACH ROW EXECUTE PROCEDURE touch_crate_on_version_modified();
2 changes: 2 additions & 0 deletions src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,5 @@ table! {
license -> Nullable<Varchar>,
}
}

operator_allowed!(crates::updated_at, Sub, sub);
3 changes: 2 additions & 1 deletion src/tests/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,11 @@ fn sign_in_as(req: &mut Request, user: &User) {
);
}

fn sign_in(req: &mut Request, app: &App) {
fn sign_in(req: &mut Request, app: &App) -> User {
let conn = app.diesel_database.get().unwrap();
let user = ::new_user("foo").create_or_update(&conn).unwrap();
sign_in_as(req, &user);
user
}

fn new_dependency(conn: &PgConnection, version: &Version, krate: &Crate) -> Dependency {
Expand Down
42 changes: 42 additions & 0 deletions src/tests/http-data/krate_uploading_new_version_touches_crate
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
===REQUEST 371
PUT http://alexcrichton-test.s3.amazonaws.com/crates/foo_versions_updated_at/foo_versions_updated_at-1.0.0.crate HTTP/1.1
Accept: */*
Proxy-Connection: Keep-Alive
Date: Sun, 28 Jun 2015 14:07:18 -0700
Content-Type: application/x-tar
Content-Length: 0
Host: alexcrichton-test.s3.amazonaws.com
Authorization: AWS AKIAJF3GEK7N44BACDZA:B6cKWtg9t24ej4DljrlsMnkgtdg=


===RESPONSE 258
HTTP/1.1 200
x-amz-request-id: D72B3AB3755D34E3
etag: "d41d8cd98f00b204e9800998ecf8427e"
date: Sun, 28 Jun 2015 21:07:51 GMT
x-amz-id-2: 4MEDTSaUXJ7J70JfbXTcfI2m1qoriY+OEOxVAmj2oARpllZTI+vCT52o9FZnVUzJzkchRL407nI=
content-length: 0
server: AmazonS3


===REQUEST 371
PUT http://alexcrichton-test.s3.amazonaws.com/crates/foo_versions_updated_at/foo_versions_updated_at-2.0.0.crate HTTP/1.1
Accept: */*
Proxy-Connection: Keep-Alive
Date: Sun, 28 Jun 2015 14:07:18 -0700
Content-Type: application/x-tar
Content-Length: 0
Host: alexcrichton-test.s3.amazonaws.com
Authorization: AWS AKIAJF3GEK7N44BACDZA:B6cKWtg9t24ej4DljrlsMnkgtdg=


===RESPONSE 258
HTTP/1.1 200
x-amz-request-id: D72B3AB3755D34E3
etag: "d41d8cd98f00b204e9800998ecf8427e"
date: Sun, 28 Jun 2015 21:07:51 GMT
x-amz-id-2: 4MEDTSaUXJ7J70JfbXTcfI2m1qoriY+OEOxVAmj2oARpllZTI+vCT52o9FZnVUzJzkchRL407nI=
content-length: 0
server: AmazonS3


40 changes: 39 additions & 1 deletion src/tests/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use cargo_registry::krate::{Crate, EncodableCrate, MAX_NAME_LENGTH};

use cargo_registry::token::ApiToken;
use cargo_registry::owner::EncodableOwner;
use cargo_registry::schema::versions;
use cargo_registry::schema::{versions, crates};

use cargo_registry::upload as u;
use cargo_registry::user::EncodableUser;
Expand Down Expand Up @@ -463,6 +463,44 @@ fn versions() {
assert_eq!(json.versions[2].num, "0.5.0");
}

#[test]
fn uploading_new_version_touches_crate() {
use diesel::expression::dsl::*;

let (_b, app, middle) = ::app();

let mut upload_req = ::new_req(app.clone(), "foo_versions_updated_at", "1.0.0");
let u = ::sign_in(&mut upload_req, &app);
ok_resp!(middle.call(&mut upload_req));

{
let conn = app.diesel_database.get().unwrap();
diesel::update(crates::table)
.set(crates::updated_at.eq(crates::updated_at - 1.hour()))
.execute(&*conn)
.unwrap();
}

let mut show_req = ::req(
app.clone(),
Method::Get,
"/api/v1/crates/foo_versions_updated_at",
);
let mut response = ok_resp!(middle.call(&mut show_req));
let json: CrateResponse = ::json(&mut response);
let updated_at_before = json.krate.updated_at;

let mut upload_req = ::new_req(app.clone(), "foo_versions_updated_at", "2.0.0");
::sign_in_as(&mut upload_req, &u);
ok_resp!(middle.call(&mut upload_req));

let mut response = ok_resp!(middle.call(&mut show_req));
let json: CrateResponse = ::json(&mut response);
let updated_at_after = json.krate.updated_at;

assert_ne!(updated_at_before, updated_at_after);
}

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