diff --git a/src/controllers/krate/downloads.rs b/src/controllers/krate/downloads.rs index ac141983fc3..48d61cef6b2 100644 --- a/src/controllers/krate/downloads.rs +++ b/src/controllers/krate/downloads.rs @@ -5,7 +5,8 @@ use crate::app::AppState; use crate::controllers::krate::CratePath; -use crate::models::{Version, VersionDownload}; +use crate::models::download::Version; +use crate::models::VersionDownload; use crate::schema::{version_downloads, versions}; use crate::util::errors::AppResult; use crate::views::EncodableVersionDownload; @@ -42,7 +43,7 @@ pub async fn get_crate_downloads(state: AppState, path: CratePath) -> AppResult< .load(&mut conn) .await?; - versions.sort_by_cached_key(|version| cmp::Reverse(semver::Version::parse(&version.num).ok())); + versions.sort_unstable_by(|a, b| b.num.cmp(&a.num)); let (latest_five, rest) = versions.split_at(cmp::min(5, versions.len())); let downloads = VersionDownload::belonging_to(latest_five) diff --git a/src/models.rs b/src/models.rs index 6c44a052356..fdb718e8ce8 100644 --- a/src/models.rs +++ b/src/models.rs @@ -26,7 +26,7 @@ pub mod crate_owner_invitation; pub mod default_versions; mod deleted_crate; pub mod dependency; -mod download; +pub mod download; mod email; mod follow; mod keyword; diff --git a/src/models/download.rs b/src/models/download.rs index 17f413e3396..cd2d562e318 100644 --- a/src/models/download.rs +++ b/src/models/download.rs @@ -1,9 +1,14 @@ -use crate::models::Version; -use crate::schema::version_downloads; +use crate::models::Version as FullVersion; +use crate::schema::{version_downloads, versions}; use chrono::NaiveDate; +use crates_io_diesel_helpers::SemverVersion; #[derive(Queryable, Identifiable, Associations, Debug, Clone, Copy)] -#[diesel(primary_key(version_id, date), belongs_to(Version))] +#[diesel( + primary_key(version_id, date), + belongs_to(FullVersion, foreign_key=version_id), + belongs_to(Version), +)] pub struct VersionDownload { pub version_id: i32, pub downloads: i32, @@ -11,3 +16,16 @@ pub struct VersionDownload { pub date: NaiveDate, pub processed: bool, } + +/// A subset of the columns of the `versions` table. +/// +/// This struct is used to load all versions of a crate from the database, +/// without loading the additional data that is unnecessary for download version resolution. +/// +#[derive(Queryable, Selectable, Identifiable)] +#[diesel(table_name = versions)] +pub struct Version { + pub id: i32, + #[diesel(deserialize_as = SemverVersion)] + pub num: semver::Version, +}