From c76b527b93bade0b24dc9deeb43a86afe31d3086 Mon Sep 17 00:00:00 2001 From: Geometrically <18202329+Geometrically@users.noreply.github.com> Date: Sat, 13 Aug 2022 18:53:12 -0700 Subject: [PATCH] Make maven support duplicate versions (#418) --- sqlx-data.json | 101 +++++++++++++++++++++++--------------------- src/routes/maven.rs | 83 +++++++++++++++++++++++++----------- 2 files changed, 113 insertions(+), 71 deletions(-) diff --git a/sqlx-data.json b/sqlx-data.json index c690ff000..d3553a70d 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -318,27 +318,6 @@ }, "query": "\n UPDATE mods_gallery\n SET description = $2\n WHERE id = $1\n " }, - "153100dc632392c4d446cc768235d071bac26a0818a4a72d203d8e549f969eea": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - } - }, - "query": "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2" - }, "15b8ea323c2f6d03c2e385d9c46d7f13460764f2f106fd638226c42ae0217f75": { "describe": { "columns": [], @@ -3072,6 +3051,38 @@ }, "query": "\n SELECT u.id, u.github_id, u.name, u.email,\n u.avatar_url, u.username, u.bio,\n u.created, u.role\n FROM users u\n WHERE LOWER(u.username) = LOWER($1)\n " }, + "7f4fef104bdff9036c83499268c6b22406f8d7e5502607ed6ff47d5a0979ede2": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "version_number", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "version_type", + "ordinal": 2, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + false + ], + "parameters": { + "Left": [ + "Int8" + ] + } + }, + "query": "\n SELECT id, version_number, version_type\n FROM versions\n WHERE mod_id = $1\n ORDER BY date_published ASC\n " + }, "8129255d25bf0624d83f50558b668ed7b7f9c264e380d276522fc82bc871939b": { "describe": { "columns": [], @@ -4790,6 +4801,28 @@ }, "query": "\n INSERT INTO reports (\n id, report_type_id, mod_id, version_id, user_id,\n body, reporter\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7\n )\n " }, + "c44e260a1f7712b14ac521fd301fea1b3f92238da62aeaf819997aecc365be43": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + } + ], + "nullable": [ + false + ], + "parameters": { + "Left": [ + "Int8", + "Text", + "Int8" + ] + } + }, + "query": "SELECT id FROM versions WHERE mod_id = $1 AND (version_number = $2 OR id = $3) ORDER BY date_published ASC" + }, "c545a74e902c5c63bca1057b76e94b9547ee21fadbc61964f45837915d5f4608": { "describe": { "columns": [], @@ -5897,32 +5930,6 @@ }, "query": "\n SELECT u.id, u.name, u.email,\n u.avatar_url, u.username, u.bio,\n u.created, u.role\n FROM users u\n WHERE u.github_id = $1\n " }, - "ea92ca7efdb8ba621729ce35b2ba5bf3fd0bb1ccd23a2875509eb90c6bcfee08": { - "describe": { - "columns": [ - { - "name": "version_number", - "ordinal": 0, - "type_info": "Varchar" - }, - { - "name": "version_type", - "ordinal": 1, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT version_number, version_type\n FROM versions\n WHERE mod_id = $1\n " - }, "ebef881a0dae70e990814e567ed3de9565bb29b772782bc974c953af195fd6d7": { "describe": { "columns": [ diff --git a/src/routes/maven.rs b/src/routes/maven.rs index bb3892a68..5c6e7cde9 100644 --- a/src/routes/maven.rs +++ b/src/routes/maven.rs @@ -1,11 +1,12 @@ use crate::database::models::project_item::QueryProject; use crate::database::models::version_item::{QueryFile, QueryVersion}; -use crate::models::projects::ProjectId; +use crate::models::projects::{ProjectId, VersionId}; use crate::routes::ApiError; use crate::util::auth::get_user_from_headers; use crate::{database, util::auth::is_authorized}; use actix_web::{get, route, web, HttpRequest, HttpResponse}; use sqlx::PgPool; +use std::collections::HashSet; use yaserde_derive::YaSerialize; #[derive(Default, Debug, Clone, YaSerialize)] @@ -78,35 +79,48 @@ pub async fn maven_metadata( let version_names = sqlx::query!( " - SELECT version_number, version_type - FROM versions - WHERE mod_id = $1 - ", + SELECT id, version_number, version_type + FROM versions + WHERE mod_id = $1 + ORDER BY date_published ASC + ", data.inner.id as database::models::ids::ProjectId ) .fetch_all(&**pool) .await?; + let mut new_versions = Vec::new(); + let mut vals = HashSet::new(); + let mut latest_release = None; + + for row in version_names { + let value = if vals.contains(&row.version_number) { + format!("{}", VersionId(row.id as u64)) + } else { + row.version_number + }; + + vals.insert(value.clone()); + if row.version_type == "release" { + latest_release = Some(value.clone()) + } + + new_versions.push(value); + } + let project_id: ProjectId = data.inner.id.into(); let respdata = Metadata { group_id: "maven.modrinth".to_string(), artifact_id: format!("{}", project_id), versioning: Versioning { - latest: version_names + latest: new_versions .last() - .map_or("release", |x| &x.version_number) - .to_string(), - release: version_names - .iter() - .rfind(|x| x.version_type == "release") - .map_or("", |x| &x.version_number) + .unwrap_or(&"release".to_string()) .to_string(), + release: latest_release.unwrap_or_default().to_string(), versions: Versions { - versions: version_names - .iter() - .map(|x| x.version_number.clone()) - .collect::>(), + versions: new_versions, }, last_updated: data.inner.updated.format("%Y%m%d%H%M%S").to_string(), }, @@ -135,8 +149,11 @@ fn find_file<'a>( _ => return None, }; + let version_id: VersionId = version.id.into(); + if file == format!("{}-{}.{}", &project_id, &version.version_number, fileext) + || file == format!("{}-{}.{}", &project_id, &version_id, fileext) { version .files @@ -178,10 +195,15 @@ pub async fn version_file( return Ok(HttpResponse::NotFound().body("")); } + let id_option = crate::models::ids::base62_impl::parse_base62(&vnum) + .ok() + .map(|x| x as i64); + let vid = if let Some(vid) = sqlx::query!( - "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", + "SELECT id FROM versions WHERE mod_id = $1 AND (version_number = $2 OR id = $3) ORDER BY date_published ASC", project.inner.id as database::models::ids::ProjectId, - vnum + vnum, + id_option ) .fetch_optional(&**pool) .await? @@ -202,7 +224,10 @@ pub async fn version_file( return Ok(HttpResponse::NotFound().body("")); }; - if file == format!("{}-{}.pom", &project_id, &version.version_number) { + let version_id: VersionId = version.id.into(); + if file == format!("{}-{}.pom", &project_id, &version.version_number) + || file == format!("{}-{}.pom", &project_id, version_id) + { let respdata = MavenPom { schema_location: "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" @@ -211,7 +236,7 @@ pub async fn version_file( model_version: "4.0.0".to_string(), group_id: "maven.modrinth".to_string(), artifact_id: project_id, - version: version.version_number, + version: vnum, name: project.inner.title, description: project.inner.description, }; @@ -255,10 +280,15 @@ pub async fn version_file_sha1( return Ok(HttpResponse::NotFound().body("")); } + let id_option = crate::models::ids::base62_impl::parse_base62(&vnum) + .ok() + .map(|x| x as i64); + let vid = if let Some(vid) = sqlx::query!( - "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", + "SELECT id FROM versions WHERE mod_id = $1 AND (version_number = $2 OR id = $3) ORDER BY date_published ASC", project.inner.id as database::models::ids::ProjectId, - vnum + vnum, + id_option ) .fetch_optional(&**pool) .await? @@ -312,10 +342,15 @@ pub async fn version_file_sha512( return Ok(HttpResponse::NotFound().body("")); } + let id_option = crate::models::ids::base62_impl::parse_base62(&vnum) + .ok() + .map(|x| x as i64); + let vid = if let Some(vid) = sqlx::query!( - "SELECT id FROM versions WHERE mod_id = $1 AND version_number = $2", + "SELECT id FROM versions WHERE mod_id = $1 AND (version_number = $2 OR id = $3) ORDER BY date_published ASC", project.inner.id as database::models::ids::ProjectId, - vnum + vnum, + id_option ) .fetch_optional(&**pool) .await?