Skip to content

Commit fee3a4b

Browse files
author
Marco Napetti
committed
move deletion to single versions
1 parent 7d71570 commit fee3a4b

File tree

5 files changed

+74
-54
lines changed

5 files changed

+74
-54
lines changed

src/controllers/krate.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
pub mod delete;
21
pub mod downloads;
32
pub mod follow;
43
pub mod metadata;

src/controllers/krate/delete.rs

Lines changed: 0 additions & 52 deletions
This file was deleted.

src/controllers/version.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod delete;
12
pub mod deprecated;
23
pub mod downloads;
34
pub mod metadata;

src/controllers/version/delete.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Functionality related to deleting a crate.
2+
3+
use std::sync::Arc;
4+
5+
use chrono::{Duration, Utc};
6+
use diesel::dsl::count_star;
7+
8+
use crate::controllers::cargo_prelude::*;
9+
10+
use crate::schema::*;
11+
use crate::util::errors::internal;
12+
use crate::views::{EncodableCrate, GoodCrate, PublishWarnings};
13+
14+
use super::{extract_crate_name_and_semver, version_and_crate};
15+
16+
/// Handles the `DELETE /crates/:crate_id/:version` route.
17+
///
18+
/// Actually deletion is allowed only in the first 24 hours from creation
19+
pub fn delete(req: &mut dyn RequestExt) -> EndpointResult {
20+
let app = Arc::clone(req.app());
21+
let (crate_name, semver) = extract_crate_name_and_semver(req)?;
22+
let conn = req.db_read()?;
23+
let (version, krate) = version_and_crate(&conn, crate_name, semver)?;
24+
25+
if Utc::now()
26+
.naive_utc()
27+
.signed_duration_since(version.created_at)
28+
> Duration::hours(24)
29+
{
30+
return Err(cargo_err(
31+
"Version deletion is allowed only in the first 24 hours from creation",
32+
));
33+
}
34+
35+
// Create a transaction on the database, if there are no errors,
36+
// commit the transactions to delete the version.
37+
// If there are no remaining versions, delete the crate
38+
conn.transaction(|| {
39+
diesel::delete(versions::table.find(version.id)).execute(&*conn)?;
40+
41+
let top_versions = krate.top_versions(&conn)?;
42+
43+
// we can't check top_versions to know if there aren't remaining versions
44+
// because it excludes yanked versions
45+
let remaining: i64 = versions::table
46+
.filter(versions::crate_id.eq(krate.id))
47+
.select(count_star())
48+
.first(&*conn)
49+
.optional()?
50+
.unwrap_or_default();
51+
if remaining <= 0 {
52+
diesel::delete(crates::table.find(krate.id)).execute(&*conn)?;
53+
54+
let uploader = app.config.uploader();
55+
uploader
56+
.delete_index(app.http_client(), &krate.name)
57+
.map_err(|e| internal(&format_args!("failed to delete crate: {}", e)))?;
58+
}
59+
60+
Ok(req.json(&GoodCrate {
61+
krate: EncodableCrate::from_minimal(krate, Some(&top_versions), None, true, None),
62+
warnings: PublishWarnings {
63+
invalid_categories: vec![],
64+
invalid_badges: vec![],
65+
other: vec![],
66+
},
67+
}))
68+
})
69+
}

src/router.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ pub fn build_router(app: &App) -> RouteBuilder {
2727
"/api/v1/crates/:crate_id/owners",
2828
C(krate::owners::remove_owners),
2929
);
30+
router.delete(
31+
"/api/v1/crates/:crate_id/:version",
32+
C(version::delete::delete),
33+
);
3034
router.delete(
3135
"/api/v1/crates/:crate_id/:version/yank",
3236
C(version::yank::yank),
@@ -98,7 +102,6 @@ pub fn build_router(app: &App) -> RouteBuilder {
98102
"/api/v1/crates/:crate_id/reverse_dependencies",
99103
C(krate::metadata::reverse_dependencies),
100104
);
101-
router.delete("/api/v1/crates/:crate_id", C(krate::delete::delete));
102105
router.get("/api/v1/keywords", C(keyword::index));
103106
router.get("/api/v1/keywords/:keyword_id", C(keyword::show));
104107
router.get("/api/v1/categories", C(category::index));

0 commit comments

Comments
 (0)