Skip to content

Commit 4556126

Browse files
committed
dependencyies!
1 parent 3280e3e commit 4556126

File tree

2 files changed

+119
-32
lines changed

2 files changed

+119
-32
lines changed

src/types/models/dependency.rs

+102-27
Original file line numberDiff line numberDiff line change
@@ -125,36 +125,103 @@ impl Dependency {
125125
Ok(())
126126
}
127127

128-
pub async fn get_for_mod_version(
129-
id: i32,
130-
pool: &mut PgConnection,
131-
) -> Result<Vec<FetchedDependency>, ApiError> {
132-
match sqlx::query_as!(
133-
FetchedDependency,
134-
r#"SELECT dp.dependent_id as mod_version_id, dp.dependency_id,
135-
dp.version, dp.compare AS "compare: _", dp.importance AS "importance: _"
136-
FROM dependencies dp
137-
WHERE dp.dependent_id = $1"#,
138-
id
139-
)
140-
.fetch_all(&mut *pool)
141-
.await
142-
{
143-
Ok(d) => Ok(d),
144-
Err(e) => {
145-
log::error!("{}", e);
146-
Err(ApiError::DbError)
147-
}
148-
}
149-
}
150-
151128
pub async fn get_for_mod_versions(
152129
ids: &Vec<i32>,
153130
pool: &mut PgConnection,
154131
) -> Result<HashMap<i32, Vec<FetchedDependency>>, ApiError> {
155-
let result = match sqlx::query_as!(FetchedDependency,
156-
r#"SELECT dp.dependent_id as mod_version_id, dp.dependency_id, dp.version, dp.compare AS "compare: _", dp.importance AS "importance: _" FROM dependencies dp
157-
WHERE dp.dependent_id = ANY($1)"#,
132+
// Fellow developer, I am sorry for what you're about to see :)
133+
134+
let result = match sqlx::query!(
135+
r#"
136+
WITH RECURSIVE dep_tree AS (
137+
SELECT * FROM (
138+
SELECT
139+
m.id AS id,
140+
mv.id AS mod_version_id,
141+
mv.name AS name,
142+
mv.version AS version,
143+
dp.compare AS "needs_compare: ModVersionCompare",
144+
dp.importance as "importance: DependencyImportance",
145+
dp.version AS needs_version,
146+
dp.dependency_id AS dependency,
147+
dpcy_version.id AS dependency_vid,
148+
dpcy_version.name AS depedency_name,
149+
dpcy_version.version AS dependency_version,
150+
mv.id AS start_node,
151+
ROW_NUMBER() OVER(
152+
PARTITION BY dp.dependency_id, mv.id
153+
ORDER BY dpcy_version.version DESC, mv.version DESC
154+
) rn
155+
FROM mod_versions mv
156+
INNER JOIN mods m ON mv.mod_id = m.id
157+
INNER JOIN dependencies dp ON dp.dependent_id = mv.id
158+
INNER JOIN mods dpcy ON dp.dependency_id = dpcy.id
159+
INNER JOIN mod_versions dpcy_version ON dpcy_version.mod_id = dpcy.id
160+
INNER JOIN mod_version_statuses dpcy_status ON dpcy_version.status_id = dpcy_status.id
161+
WHERE dpcy_status.status = 'accepted'
162+
AND mv.id = ANY($1)
163+
AND CASE
164+
WHEN dp.version = '*' THEN 1
165+
WHEN SPLIT_PART(dpcy_version.version, '.', 1) = SPLIT_PART(dp.version, '.', 1) THEN 1
166+
ELSE 0
167+
END = 1
168+
AND CASE
169+
WHEN dp.version = '*' THEN 1
170+
WHEN dp.compare = '<' AND dpcy_version.version < dp.version THEN 1
171+
WHEN dp.compare = '>' AND dpcy_version.version > dp.version THEN 1
172+
WHEN dp.compare = '<=' AND dpcy_version.version <= dp.version THEN 1
173+
WHEN dp.compare = '>=' AND dpcy_version.version >= dp.version THEN 1
174+
WHEN dp.compare = '=' AND dpcy_version.version = dp.version THEN 1
175+
ELSE 0
176+
END = 1
177+
) as q
178+
WHERE q.rn = 1
179+
UNION
180+
SELECT * FROM (
181+
SELECT
182+
m2.id AS id,
183+
mv2.id AS mod_version_id,
184+
mv2.name AS name,
185+
mv2.version AS version,
186+
dp2.compare AS "needs_compare: ModVersionCompare",
187+
dp2.importance as "importance: DependencyImportance",
188+
dp2.version AS needs_version,
189+
dp2.dependency_id AS dependency,
190+
dpcy_version2.id AS dependency_vid,
191+
dpcy_version2.name AS depedency_name,
192+
dpcy_version2.version AS dependency_version,
193+
dt.start_node AS start_node,
194+
ROW_NUMBER() OVER(
195+
PARTITION BY dp2.dependency_id, mv2.id
196+
ORDER BY dpcy_version2.version DESC, mv2.version DESC
197+
) rn
198+
FROM mod_versions mv2
199+
INNER JOIN mods m2 ON mv2.mod_id = m2.id
200+
INNER JOIN dependencies dp2 ON dp2.dependent_id = mv2.id
201+
INNER JOIN mods dpcy2 ON dp2.dependency_id = dpcy2.id
202+
INNER JOIN mod_versions dpcy_version2 ON dpcy_version2.mod_id = dpcy2.id
203+
INNER JOIN mod_version_statuses dpcy_status2 ON dpcy_version2.status_id = dpcy_status2.id
204+
INNER JOIN dep_tree dt ON dt.dependency_vid = mv2.id
205+
WHERE dpcy_status2.status = 'accepted'
206+
AND CASE
207+
WHEN dp2.version = '*' THEN 1
208+
WHEN SPLIT_PART(dpcy_version2.version, '.', 1) = SPLIT_PART(dp2.version, '.', 1) THEN 1
209+
ELSE 0
210+
END = 1
211+
AND CASE
212+
WHEN dp2.version = '*' THEN 1
213+
WHEN dp2.compare = '<' AND dpcy_version2.version < dp2.version THEN 1
214+
WHEN dp2.compare = '>' AND dpcy_version2.version > dp2.version THEN 1
215+
WHEN dp2.compare = '<=' AND dpcy_version2.version <= dp2.version THEN 1
216+
WHEN dp2.compare = '>=' AND dpcy_version2.version >= dp2.version THEN 1
217+
WHEN dp2.compare = '=' AND dpcy_version2.version = dp2.version THEN 1
218+
ELSE 0
219+
END = 1
220+
) as q2
221+
WHERE q2.rn = 1
222+
)
223+
SELECT * FROM dep_tree;
224+
"#,
158225
&ids
159226
)
160227
.fetch_all(&mut *pool)
@@ -169,7 +236,15 @@ impl Dependency {
169236

170237
let mut ret: HashMap<i32, Vec<FetchedDependency>> = HashMap::new();
171238
for i in result {
172-
ret.entry(i.mod_version_id).or_default().push(i);
239+
ret.entry(i.start_node.unwrap())
240+
.or_default()
241+
.push(FetchedDependency {
242+
mod_version_id: i.dependency_vid.unwrap(),
243+
version: i.dependency_version.clone().unwrap(),
244+
dependency_id: i.dependency.clone().unwrap(),
245+
compare: ModVersionCompare::Exact,
246+
importance: i.importance.unwrap(),
247+
});
173248
}
174249
Ok(ret)
175250
}

src/types/models/mod_version.rs

+17-5
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,
1414
developer::Developer,
1515
incompatibility::{Incompatibility, ResponseIncompatibility},
1616
mod_gd_version::{DetailedGDVersion, GDVersionEnum, ModGDVersion, VerPlatform},
@@ -280,7 +280,6 @@ impl ModVersion {
280280
}
281281
separated.push_unseparated(")");
282282
query_builder.push(") q WHERE q.rn = 1");
283-
log::info!("{}", query_builder.sql());
284283
let records = query_builder
285284
.build_query_as::<ModVersionGetOne>()
286285
.fetch_all(&mut *pool)
@@ -410,10 +409,14 @@ impl ModVersion {
410409
}
411410
};
412411

412+
let ids: Vec<i32> = vec![version.id];
413413
version.gd = ModGDVersion::get_for_mod_version(version.id, pool).await?;
414414
version.dependencies = Some(
415-
Dependency::get_for_mod_version(version.id, pool)
415+
Dependency::get_for_mod_versions(&ids, pool)
416416
.await?
417+
.get(&version.id)
418+
.cloned()
419+
.unwrap_or_default()
417420
.into_iter()
418421
.map(|x| x.to_response())
419422
.collect(),
@@ -570,8 +573,17 @@ impl ModVersion {
570573
let mut version = result.into_mod_version();
571574
if fetch_extras {
572575
version.gd = ModGDVersion::get_for_mod_version(version.id, pool).await?;
573-
let deps = Dependency::get_for_mod_version(version.id, pool).await?;
574-
version.dependencies = Some(deps.into_iter().map(|x| x.to_response()).collect());
576+
let ids = vec![version.id];
577+
version.dependencies = Some(
578+
Dependency::get_for_mod_versions(&ids, pool)
579+
.await?
580+
.get(&version.id)
581+
.cloned()
582+
.unwrap_or_default()
583+
.into_iter()
584+
.map(|x| x.to_response())
585+
.collect(),
586+
);
575587
let incompat = Incompatibility::get_for_mod_version(version.id, pool).await?;
576588
version.incompatibilities =
577589
Some(incompat.into_iter().map(|x| x.to_response()).collect());

0 commit comments

Comments
 (0)