Skip to content

Commit 31a1ad2

Browse files
committed
add compare to /v1/mods/{id}/versions
1 parent 2132e77 commit 31a1ad2

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

src/endpoints/mod_versions.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
use std::str::FromStr;
22

33
use actix_web::{dev::ConnectionInfo, get, post, put, web, HttpResponse, Responder};
4+
use semver::Version;
45
use serde::Deserialize;
56
use sqlx::{types::ipnetwork::IpNetwork, Acquire};
67

78
use crate::{
89
extractors::auth::Auth,
910
types::{
1011
api::{ApiError, ApiResponse},
11-
mod_json::ModJson,
12+
mod_json::{split_version_and_compare, ModJson},
1213
models::{
14+
dependency::ModVersionCompare,
1315
developer::Developer,
1416
download,
1517
mod_entity::{download_geode_file, Mod},
@@ -69,6 +71,7 @@ struct IndexQuery {
6971
gd: Option<GDVersionEnum>,
7072
platforms: Option<String>,
7173
status: Option<ModVersionStatusEnum>,
74+
compare: Option<String>,
7275
}
7376

7477
#[get("v1/mods/{id}/versions")]
@@ -78,12 +81,25 @@ pub async fn get_version_index(
7881
query: web::Query<IndexQuery>,
7982
) -> Result<impl Responder, ApiError> {
8083
let platforms = VerPlatform::parse_query_string(&query.platforms.clone().unwrap_or_default());
84+
let compare = query.compare.as_ref().map(|c| split_version_and_compare(c));
85+
86+
if compare.is_some() && compare.as_ref().unwrap().is_err() {
87+
return Err(ApiError::BadRequest(format!(
88+
"Bad compare string {}",
89+
query.compare.as_ref().unwrap()
90+
)));
91+
}
92+
93+
let compare = compare.map(|x| x.unwrap());
94+
8195
let mut pool = data.db.acquire().await.or(Err(ApiError::DbAcquireError))?;
96+
8297
let mut result = ModVersion::get_index(
8398
mod_version::IndexQuery {
8499
mod_id: path.id.clone(),
85100
page: query.page.unwrap_or(1),
86101
per_page: query.per_page.unwrap_or(10),
102+
compare,
87103
gd: query.gd,
88104
platforms,
89105
status: query.status.unwrap_or(ModVersionStatusEnum::Accepted),

src/types/mod_json.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ fn validate_dependency_version_str(ver: &str) -> bool {
385385
result.is_ok()
386386
}
387387

388-
fn split_version_and_compare(ver: &str) -> Result<(Version, ModVersionCompare), ()> {
388+
pub fn split_version_and_compare(ver: &str) -> Result<(Version, ModVersionCompare), ()> {
389389
let mut copy = ver.to_string();
390390
let mut compare = ModVersionCompare::MoreEq;
391391
if ver.starts_with("<=") {

src/types/models/mod_version.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::types::{
1010
};
1111

1212
use super::{
13-
dependency::{Dependency, ResponseDependency},
13+
dependency::{Dependency, ModVersionCompare, ResponseDependency},
1414
developer::Developer,
1515
incompatibility::{Incompatibility, ResponseIncompatibility},
1616
mod_gd_version::{DetailedGDVersion, GDVersionEnum, ModGDVersion, VerPlatform},
@@ -61,6 +61,7 @@ pub struct IndexQuery {
6161
pub page: i64,
6262
pub per_page: i64,
6363
pub gd: Option<GDVersionEnum>,
64+
pub compare: Option<(semver::Version, ModVersionCompare)>,
6465
pub platforms: Vec<VerPlatform>,
6566
pub status: ModVersionStatusEnum,
6667
}
@@ -165,7 +166,31 @@ impl ModVersion {
165166
q.push(") ");
166167
counter_q.push(") ");
167168
}
168-
let sql = "GROUP BY mv.id, mvs.status LIMIT ";
169+
170+
if let Some(c) = query.compare {
171+
let sql = "AND SPLIT_PART(mv.version, '.', 1) = ";
172+
q.push(sql);
173+
counter_q.push(sql);
174+
let major = c.0.major.to_string();
175+
q.push_bind(major.clone());
176+
counter_q.push_bind(major.clone());
177+
let sql = " AND semver_compare(mv.version, ";
178+
q.push(sql);
179+
counter_q.push(sql);
180+
q.push_bind(c.0.to_string());
181+
counter_q.push_bind(c.0.to_string());
182+
let sql = match c.1 {
183+
ModVersionCompare::Exact => ") = 0",
184+
ModVersionCompare::Less => ") = -1",
185+
ModVersionCompare::LessEq => ") <= 0",
186+
ModVersionCompare::More => ") = 1",
187+
ModVersionCompare::MoreEq => ") >= 0",
188+
};
189+
q.push(sql);
190+
counter_q.push(sql);
191+
}
192+
193+
let sql = "GROUP BY mv.id, mvs.status ORDER BY mv.id DESC LIMIT ";
169194
q.push(sql);
170195
q.push_bind(limit);
171196
let sql = " OFFSET ";

0 commit comments

Comments
 (0)