You've already forked AstralRinth
forked from didirus/AstralRinth
Initial work on new status sys + scheduling releases (#489)
* Initial work on new status sys + scheduling releases * Finish project statuses + begin work on version statuses * Finish version statuses * Regenerate prepare * Run fmt + clippy
This commit is contained in:
@@ -18,9 +18,7 @@ pub use project_item::Project;
|
||||
pub use team_item::Team;
|
||||
pub use team_item::TeamMember;
|
||||
pub use user_item::User;
|
||||
pub use version_item::FileHash;
|
||||
pub use version_item::Version;
|
||||
pub use version_item::VersionFile;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DatabaseError {
|
||||
@@ -32,28 +30,6 @@ pub enum DatabaseError {
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl ids::StatusId {
|
||||
pub async fn get_id<'a, E>(
|
||||
status: &crate::models::projects::ProjectStatus,
|
||||
exec: E,
|
||||
) -> Result<Option<Self>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM statuses
|
||||
WHERE status = $1
|
||||
",
|
||||
status.as_str()
|
||||
)
|
||||
.fetch_optional(exec)
|
||||
.await?;
|
||||
|
||||
Ok(result.map(|r| ids::StatusId(r.id)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ids::SideTypeId {
|
||||
pub async fn get_id<'a, E>(
|
||||
side: &crate::models::projects::SideType,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::ids::*;
|
||||
use crate::database::models::convert_postgres_date;
|
||||
use crate::models::projects::ProjectStatus;
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -89,7 +90,8 @@ pub struct ProjectBuilder {
|
||||
pub categories: Vec<CategoryId>,
|
||||
pub additional_categories: Vec<CategoryId>,
|
||||
pub initial_versions: Vec<super::version_item::VersionBuilder>,
|
||||
pub status: StatusId,
|
||||
pub status: ProjectStatus,
|
||||
pub requested_status: Option<ProjectStatus>,
|
||||
pub client_side: SideTypeId,
|
||||
pub server_side: SideTypeId,
|
||||
pub license: String,
|
||||
@@ -115,6 +117,7 @@ impl ProjectBuilder {
|
||||
updated: Utc::now(),
|
||||
approved: None,
|
||||
status: self.status,
|
||||
requested_status: self.requested_status,
|
||||
downloads: 0,
|
||||
follows: 0,
|
||||
icon_url: self.icon_url,
|
||||
@@ -190,7 +193,8 @@ pub struct Project {
|
||||
pub published: DateTime<Utc>,
|
||||
pub updated: DateTime<Utc>,
|
||||
pub approved: Option<DateTime<Utc>>,
|
||||
pub status: StatusId,
|
||||
pub status: ProjectStatus,
|
||||
pub requested_status: Option<ProjectStatus>,
|
||||
pub downloads: i32,
|
||||
pub follows: i32,
|
||||
pub icon_url: Option<String>,
|
||||
@@ -219,16 +223,16 @@ impl Project {
|
||||
INSERT INTO mods (
|
||||
id, team_id, title, description, body,
|
||||
published, downloads, icon_url, issues_url,
|
||||
source_url, wiki_url, status, discord_url,
|
||||
source_url, wiki_url, status, requested_status, discord_url,
|
||||
client_side, server_side, license_url, license,
|
||||
slug, project_type
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6, $7, $8, $9,
|
||||
$10, $11, $12, $13,
|
||||
$14, $15, $16, $17,
|
||||
LOWER($18), $19
|
||||
$10, $11, $12, $13, $14,
|
||||
$15, $16, $17, $18,
|
||||
LOWER($19), $20
|
||||
)
|
||||
",
|
||||
self.id as ProjectId,
|
||||
@@ -242,7 +246,8 @@ impl Project {
|
||||
self.issues_url.as_ref(),
|
||||
self.source_url.as_ref(),
|
||||
self.wiki_url.as_ref(),
|
||||
self.status.0,
|
||||
self.status.as_str(),
|
||||
self.requested_status.map(|x| x.as_str()),
|
||||
self.discord_url.as_ref(),
|
||||
self.client_side as SideTypeId,
|
||||
self.server_side as SideTypeId,
|
||||
@@ -268,7 +273,7 @@ impl Project {
|
||||
"
|
||||
SELECT project_type, title, description, downloads, follows,
|
||||
icon_url, body, body_url, published,
|
||||
updated, approved, status,
|
||||
updated, approved, status, requested_status,
|
||||
issues_url, source_url, wiki_url, discord_url, license_url,
|
||||
team_id, client_side, server_side, license, slug,
|
||||
moderation_message, moderation_message_body, flame_anvil_project,
|
||||
@@ -299,7 +304,10 @@ impl Project {
|
||||
license_url: row.license_url,
|
||||
discord_url: row.discord_url,
|
||||
client_side: SideTypeId(row.client_side),
|
||||
status: StatusId(row.status),
|
||||
status: ProjectStatus::from_str(&row.status),
|
||||
requested_status: row
|
||||
.requested_status
|
||||
.map(|x| ProjectStatus::from_str(&x)),
|
||||
server_side: SideTypeId(row.server_side),
|
||||
license: row.license,
|
||||
slug: row.slug,
|
||||
@@ -331,7 +339,7 @@ impl Project {
|
||||
"
|
||||
SELECT id, project_type, title, description, downloads, follows,
|
||||
icon_url, body, body_url, published,
|
||||
updated, approved, status,
|
||||
updated, approved, status, requested_status,
|
||||
issues_url, source_url, wiki_url, discord_url, license_url,
|
||||
team_id, client_side, server_side, license, slug,
|
||||
moderation_message, moderation_message_body, flame_anvil_project,
|
||||
@@ -360,7 +368,12 @@ impl Project {
|
||||
license_url: m.license_url,
|
||||
discord_url: m.discord_url,
|
||||
client_side: SideTypeId(m.client_side),
|
||||
status: StatusId(m.status),
|
||||
status: ProjectStatus::from_str(
|
||||
&m.status,
|
||||
),
|
||||
requested_status: m.requested_status.map(|x| ProjectStatus::from_str(
|
||||
&x,
|
||||
)),
|
||||
server_side: SideTypeId(m.server_side),
|
||||
license: m.license,
|
||||
slug: m.slug,
|
||||
@@ -370,7 +383,7 @@ impl Project {
|
||||
moderation_message_body: m.moderation_message_body,
|
||||
approved: m.approved,
|
||||
flame_anvil_project: m.flame_anvil_project,
|
||||
flame_anvil_user: m.flame_anvil_user.map(UserId)
|
||||
flame_anvil_user: m.flame_anvil_user.map(UserId),
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<Project>>()
|
||||
@@ -646,29 +659,29 @@ impl Project {
|
||||
"
|
||||
SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,
|
||||
m.icon_url icon_url, m.body body, m.body_url body_url, m.published published,
|
||||
m.updated updated, m.approved approved, m.status status,
|
||||
m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,
|
||||
m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,
|
||||
m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,
|
||||
s.status status_name, cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user,
|
||||
cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user,
|
||||
ARRAY_AGG(DISTINCT c.category || ' |||| ' || mc.is_additional) filter (where c.category is not null) categories,
|
||||
ARRAY_AGG(DISTINCT v.id || ' |||| ' || v.date_published) filter (where v.id is not null) versions,
|
||||
ARRAY_AGG(DISTINCT mg.image_url || ' |||| ' || mg.featured || ' |||| ' || mg.created || ' |||| ' || COALESCE(mg.title, ' ') || ' |||| ' || COALESCE(mg.description, ' ')) filter (where mg.image_url is not null) gallery,
|
||||
ARRAY_AGG(DISTINCT md.joining_platform_id || ' |||| ' || dp.short || ' |||| ' || dp.name || ' |||| ' || md.url) filter (where md.joining_platform_id is not null) donations
|
||||
FROM mods m
|
||||
INNER JOIN project_types pt ON pt.id = m.project_type
|
||||
INNER JOIN statuses s ON s.id = m.status
|
||||
INNER JOIN side_types cs ON m.client_side = cs.id
|
||||
INNER JOIN side_types ss ON m.server_side = ss.id
|
||||
LEFT JOIN mods_donations md ON md.joining_mod_id = m.id
|
||||
LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id
|
||||
LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id
|
||||
LEFT JOIN categories c ON mc.joining_category_id = c.id
|
||||
LEFT JOIN versions v ON v.mod_id = m.id
|
||||
LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)
|
||||
LEFT JOIN mods_gallery mg ON mg.mod_id = m.id
|
||||
WHERE m.id = $1
|
||||
GROUP BY pt.id, s.id, cs.id, ss.id, m.id;
|
||||
GROUP BY pt.id, cs.id, ss.id, m.id;
|
||||
",
|
||||
id as ProjectId,
|
||||
&*crate::models::projects::VersionStatus::iterator().filter(|x| x.is_listed()).map(|x| x.to_string()).collect::<Vec<String>>()
|
||||
)
|
||||
.fetch_optional(executor)
|
||||
.await?;
|
||||
@@ -709,7 +722,10 @@ impl Project {
|
||||
license_url: m.license_url.clone(),
|
||||
discord_url: m.discord_url.clone(),
|
||||
client_side: SideTypeId(m.client_side),
|
||||
status: StatusId(m.status),
|
||||
status: ProjectStatus::from_str(&m.status),
|
||||
requested_status: m
|
||||
.requested_status
|
||||
.map(|x| ProjectStatus::from_str(&x)),
|
||||
server_side: SideTypeId(m.server_side),
|
||||
license: m.license.clone(),
|
||||
slug: m.slug.clone(),
|
||||
@@ -802,9 +818,6 @@ impl Project {
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
status: crate::models::projects::ProjectStatus::from_str(
|
||||
&m.status_name,
|
||||
),
|
||||
client_side: crate::models::projects::SideType::from_str(
|
||||
&m.client_side_type,
|
||||
),
|
||||
@@ -832,29 +845,29 @@ impl Project {
|
||||
"
|
||||
SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,
|
||||
m.icon_url icon_url, m.body body, m.body_url body_url, m.published published,
|
||||
m.updated updated, m.approved approved, m.status status,
|
||||
m.updated updated, m.approved approved, m.status status, m.requested_status requested_status,
|
||||
m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,
|
||||
m.team_id team_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,
|
||||
s.status status_name, cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user,
|
||||
cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.flame_anvil_project flame_anvil_project, m.flame_anvil_user flame_anvil_user,
|
||||
ARRAY_AGG(DISTINCT c.category || ' |||| ' || mc.is_additional) filter (where c.category is not null) categories,
|
||||
ARRAY_AGG(DISTINCT v.id || ' |||| ' || v.date_published) filter (where v.id is not null) versions,
|
||||
ARRAY_AGG(DISTINCT mg.image_url || ' |||| ' || mg.featured || ' |||| ' || mg.created || ' |||| ' || COALESCE(mg.title, ' ') || ' |||| ' || COALESCE(mg.description, ' ')) filter (where mg.image_url is not null) gallery,
|
||||
ARRAY_AGG(DISTINCT md.joining_platform_id || ' |||| ' || dp.short || ' |||| ' || dp.name || ' |||| ' || md.url) filter (where md.joining_platform_id is not null) donations
|
||||
FROM mods m
|
||||
INNER JOIN project_types pt ON pt.id = m.project_type
|
||||
INNER JOIN statuses s ON s.id = m.status
|
||||
INNER JOIN side_types cs ON m.client_side = cs.id
|
||||
INNER JOIN side_types ss ON m.server_side = ss.id
|
||||
LEFT JOIN mods_donations md ON md.joining_mod_id = m.id
|
||||
LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id
|
||||
LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id
|
||||
LEFT JOIN categories c ON mc.joining_category_id = c.id
|
||||
LEFT JOIN versions v ON v.mod_id = m.id
|
||||
LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($2)
|
||||
LEFT JOIN mods_gallery mg ON mg.mod_id = m.id
|
||||
WHERE m.id = ANY($1)
|
||||
GROUP BY pt.id, s.id, cs.id, ss.id, m.id;
|
||||
GROUP BY pt.id, cs.id, ss.id, m.id;
|
||||
",
|
||||
&project_ids_parsed
|
||||
&project_ids_parsed,
|
||||
&*crate::models::projects::VersionStatus::iterator().filter(|x| x.is_listed()).map(|x| x.to_string()).collect::<Vec<String>>()
|
||||
)
|
||||
.fetch_many(exec)
|
||||
.try_filter_map(|e| async {
|
||||
@@ -897,7 +910,12 @@ impl Project {
|
||||
license_url: m.license_url.clone(),
|
||||
discord_url: m.discord_url.clone(),
|
||||
client_side: SideTypeId(m.client_side),
|
||||
status: StatusId(m.status),
|
||||
status: ProjectStatus::from_str(
|
||||
&m.status,
|
||||
),
|
||||
requested_status: m.requested_status.map(|x| ProjectStatus::from_str(
|
||||
&x,
|
||||
)),
|
||||
server_side: SideTypeId(m.server_side),
|
||||
license: m.license.clone(),
|
||||
slug: m.slug.clone(),
|
||||
@@ -978,7 +996,6 @@ impl Project {
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
status: crate::models::projects::ProjectStatus::from_str(&m.status_name),
|
||||
client_side: crate::models::projects::SideType::from_str(&m.client_side_type),
|
||||
server_side: crate::models::projects::SideType::from_str(&m.server_side_type),
|
||||
}}))
|
||||
@@ -997,7 +1014,6 @@ pub struct QueryProject {
|
||||
pub versions: Vec<VersionId>,
|
||||
pub donation_urls: Vec<DonationUrl>,
|
||||
pub gallery_items: Vec<GalleryItem>,
|
||||
pub status: crate::models::projects::ProjectStatus,
|
||||
pub client_side: crate::models::projects::SideType,
|
||||
pub server_side: crate::models::projects::SideType,
|
||||
}
|
||||
|
||||
@@ -255,34 +255,6 @@ impl User {
|
||||
}
|
||||
|
||||
pub async fn get_projects<'a, E>(
|
||||
user_id: UserId,
|
||||
status: &str,
|
||||
exec: E,
|
||||
) -> Result<Vec<ProjectId>, sqlx::Error>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
use futures::stream::TryStreamExt;
|
||||
|
||||
let projects = sqlx::query!(
|
||||
"
|
||||
SELECT m.id FROM mods m
|
||||
INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.accepted = TRUE
|
||||
WHERE tm.user_id = $1 AND m.status = (SELECT s.id FROM statuses s WHERE s.status = $2)
|
||||
ORDER BY m.downloads DESC
|
||||
",
|
||||
user_id as UserId,
|
||||
status,
|
||||
)
|
||||
.fetch_many(exec)
|
||||
.try_filter_map(|e| async { Ok(e.right().map(|m| ProjectId(m.id))) })
|
||||
.try_collect::<Vec<ProjectId>>()
|
||||
.await?;
|
||||
|
||||
Ok(projects)
|
||||
}
|
||||
|
||||
pub async fn get_projects_private<'a, E>(
|
||||
user_id: UserId,
|
||||
exec: E,
|
||||
) -> Result<Vec<ProjectId>, sqlx::Error>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::ids::*;
|
||||
use super::DatabaseError;
|
||||
use crate::database::models::convert_postgres_date;
|
||||
use crate::models::projects::VersionStatus;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
@@ -18,6 +19,8 @@ pub struct VersionBuilder {
|
||||
pub loaders: Vec<LoaderId>,
|
||||
pub version_type: String,
|
||||
pub featured: bool,
|
||||
pub status: VersionStatus,
|
||||
pub requested_status: Option<VersionStatus>,
|
||||
}
|
||||
|
||||
pub struct DependencyBuilder {
|
||||
@@ -149,6 +152,8 @@ impl VersionBuilder {
|
||||
downloads: 0,
|
||||
featured: self.featured,
|
||||
version_type: self.version_type,
|
||||
status: self.status,
|
||||
requested_status: self.requested_status,
|
||||
};
|
||||
|
||||
version.insert(&mut *transaction).await?;
|
||||
@@ -237,6 +242,7 @@ impl VersionBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Version {
|
||||
pub id: VersionId,
|
||||
pub project_id: ProjectId,
|
||||
@@ -249,6 +255,8 @@ pub struct Version {
|
||||
pub downloads: i32,
|
||||
pub version_type: String,
|
||||
pub featured: bool,
|
||||
pub status: VersionStatus,
|
||||
pub requested_status: Option<VersionStatus>,
|
||||
}
|
||||
|
||||
impl Version {
|
||||
@@ -261,13 +269,13 @@ impl Version {
|
||||
INSERT INTO versions (
|
||||
id, mod_id, author_id, name, version_number,
|
||||
changelog, changelog_url, date_published,
|
||||
downloads, version_type, featured
|
||||
downloads, version_type, featured, status
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6, $7,
|
||||
$8, $9,
|
||||
$10, $11
|
||||
$10, $11, $12
|
||||
)
|
||||
",
|
||||
self.id as VersionId,
|
||||
@@ -280,7 +288,8 @@ impl Version {
|
||||
self.date_published,
|
||||
self.downloads,
|
||||
&self.version_type,
|
||||
self.featured
|
||||
self.featured,
|
||||
self.status.as_str()
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
@@ -361,37 +370,6 @@ impl Version {
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
let files = sqlx::query!(
|
||||
"
|
||||
SELECT files.id, files.url, files.filename, files.is_primary FROM files
|
||||
WHERE files.version_id = $1
|
||||
",
|
||||
id as VersionId,
|
||||
)
|
||||
.fetch_many(&mut *transaction)
|
||||
.try_filter_map(|e| async {
|
||||
Ok(e.right().map(|c| VersionFile {
|
||||
id: FileId(c.id),
|
||||
version_id: id,
|
||||
url: c.url,
|
||||
filename: c.filename,
|
||||
primary: c.is_primary,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<VersionFile>>()
|
||||
.await?;
|
||||
|
||||
for file in files {
|
||||
// TODO: store backblaze id in database so that we can delete the files here
|
||||
// For now, we can't delete the files since we don't have the backblaze id
|
||||
log::warn!(
|
||||
"Can't delete version file id: {} (url: {}, name: {})",
|
||||
file.id.0,
|
||||
file.url,
|
||||
file.filename
|
||||
)
|
||||
}
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM hashes
|
||||
@@ -531,7 +509,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.mod_id, v.author_id, v.name, v.version_number,
|
||||
v.changelog, v.changelog_url, v.date_published, v.downloads,
|
||||
v.version_type, v.featured
|
||||
v.version_type, v.featured, v.status, v.requested_status
|
||||
FROM versions v
|
||||
WHERE v.id = $1
|
||||
",
|
||||
@@ -553,6 +531,10 @@ impl Version {
|
||||
downloads: row.downloads,
|
||||
version_type: row.version_type,
|
||||
featured: row.featured,
|
||||
status: VersionStatus::from_str(&row.status),
|
||||
requested_status: row
|
||||
.requested_status
|
||||
.map(|x| VersionStatus::from_str(&x)),
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -574,7 +556,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.id, v.mod_id, v.author_id, v.name, v.version_number,
|
||||
v.changelog, v.changelog_url, v.date_published, v.downloads,
|
||||
v.version_type, v.featured
|
||||
v.version_type, v.featured, v.status, v.requested_status
|
||||
FROM versions v
|
||||
WHERE v.id = ANY($1)
|
||||
ORDER BY v.date_published ASC
|
||||
@@ -595,6 +577,10 @@ impl Version {
|
||||
downloads: v.downloads,
|
||||
featured: v.featured,
|
||||
version_type: v.version_type,
|
||||
status: VersionStatus::from_str(&v.status),
|
||||
requested_status: v
|
||||
.requested_status
|
||||
.map(|x| VersionStatus::from_str(&x)),
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<Version>>()
|
||||
@@ -614,7 +600,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,
|
||||
v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads,
|
||||
v.version_type version_type, v.featured featured,
|
||||
v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,
|
||||
ARRAY_AGG(DISTINCT gv.version || ' |||| ' || gv.created) filter (where gv.version is not null) game_versions, ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,
|
||||
ARRAY_AGG(DISTINCT f.id || ' |||| ' || f.is_primary || ' |||| ' || f.size || ' |||| ' || f.url || ' |||| ' || f.filename) filter (where f.id is not null) files,
|
||||
ARRAY_AGG(DISTINCT h.algorithm || ' |||| ' || encode(h.hash, 'escape') || ' |||| ' || h.file_id) filter (where h.hash is not null) hashes,
|
||||
@@ -637,15 +623,23 @@ impl Version {
|
||||
|
||||
if let Some(v) = result {
|
||||
Ok(Some(QueryVersion {
|
||||
id: VersionId(v.id),
|
||||
project_id: ProjectId(v.mod_id),
|
||||
author_id: UserId(v.author_id),
|
||||
name: v.version_name,
|
||||
version_number: v.version_number,
|
||||
changelog: v.changelog,
|
||||
changelog_url: v.changelog_url,
|
||||
date_published: v.date_published,
|
||||
downloads: v.downloads,
|
||||
inner: Version {
|
||||
id: VersionId(v.id),
|
||||
project_id: ProjectId(v.mod_id),
|
||||
author_id: UserId(v.author_id),
|
||||
name: v.version_name,
|
||||
version_number: v.version_number,
|
||||
changelog: v.changelog,
|
||||
changelog_url: v.changelog_url,
|
||||
date_published: v.date_published,
|
||||
downloads: v.downloads,
|
||||
version_type: v.version_type,
|
||||
featured: v.featured,
|
||||
status: VersionStatus::from_str(&v.status),
|
||||
requested_status: v
|
||||
.requested_status
|
||||
.map(|x| VersionStatus::from_str(&x)),
|
||||
},
|
||||
files: {
|
||||
let hashes: Vec<(FileId, String, Vec<u8>)> = v
|
||||
.hashes
|
||||
@@ -737,7 +731,6 @@ impl Version {
|
||||
gv.into_iter().map(|x| x.0).collect()
|
||||
},
|
||||
loaders: v.loaders.unwrap_or_default(),
|
||||
featured: v.featured,
|
||||
dependencies: v
|
||||
.dependencies
|
||||
.unwrap_or_default()
|
||||
@@ -773,7 +766,6 @@ impl Version {
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
version_type: v.version_type,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -795,7 +787,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,
|
||||
v.changelog changelog, v.changelog_url changelog_url, v.date_published date_published, v.downloads downloads,
|
||||
v.version_type version_type, v.featured featured,
|
||||
v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,
|
||||
ARRAY_AGG(DISTINCT gv.version || ' |||| ' || gv.created) filter (where gv.version is not null) game_versions, ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,
|
||||
ARRAY_AGG(DISTINCT f.id || ' |||| ' || f.is_primary || ' |||| ' || f.size || ' |||| ' || f.url || ' |||| ' || f.filename) filter (where f.id is not null) files,
|
||||
ARRAY_AGG(DISTINCT h.algorithm || ' |||| ' || encode(h.hash, 'escape') || ' |||| ' || h.file_id) filter (where h.hash is not null) hashes,
|
||||
@@ -818,15 +810,22 @@ impl Version {
|
||||
.try_filter_map(|e| async {
|
||||
Ok(e.right().map(|v|
|
||||
QueryVersion {
|
||||
id: VersionId(v.id),
|
||||
project_id: ProjectId(v.mod_id),
|
||||
author_id: UserId(v.author_id),
|
||||
name: v.version_name,
|
||||
version_number: v.version_number,
|
||||
changelog: v.changelog,
|
||||
changelog_url: v.changelog_url,
|
||||
date_published: v.date_published,
|
||||
downloads: v.downloads,
|
||||
inner: Version {
|
||||
id: VersionId(v.id),
|
||||
project_id: ProjectId(v.mod_id),
|
||||
author_id: UserId(v.author_id),
|
||||
name: v.version_name,
|
||||
version_number: v.version_number,
|
||||
changelog: v.changelog,
|
||||
changelog_url: v.changelog_url,
|
||||
date_published: v.date_published,
|
||||
downloads: v.downloads,
|
||||
version_type: v.version_type,
|
||||
featured: v.featured,
|
||||
status: VersionStatus::from_str(&v.status),
|
||||
requested_status: v.requested_status
|
||||
.map(|x| VersionStatus::from_str(&x)),
|
||||
},
|
||||
files: {
|
||||
let hashes: Vec<(FileId, String, Vec<u8>)> = v.hashes.unwrap_or_default()
|
||||
.into_iter()
|
||||
@@ -909,7 +908,6 @@ impl Version {
|
||||
.collect()
|
||||
},
|
||||
loaders: v.loaders.unwrap_or_default(),
|
||||
featured: v.featured,
|
||||
dependencies: v.dependencies
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
@@ -944,7 +942,6 @@ impl Version {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
version_type: v.version_type
|
||||
}
|
||||
))
|
||||
})
|
||||
@@ -953,37 +950,13 @@ impl Version {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VersionFile {
|
||||
pub id: FileId,
|
||||
pub version_id: VersionId,
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub primary: bool,
|
||||
}
|
||||
|
||||
pub struct FileHash {
|
||||
pub file_id: FileId,
|
||||
pub algorithm: String,
|
||||
pub hash: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct QueryVersion {
|
||||
pub id: VersionId,
|
||||
pub project_id: ProjectId,
|
||||
pub author_id: UserId,
|
||||
pub name: String,
|
||||
pub version_number: String,
|
||||
pub changelog: String,
|
||||
pub changelog_url: Option<String>,
|
||||
pub date_published: DateTime<Utc>,
|
||||
pub downloads: i32,
|
||||
pub inner: Version,
|
||||
|
||||
pub version_type: String,
|
||||
pub files: Vec<QueryFile>,
|
||||
pub game_versions: Vec<String>,
|
||||
pub loaders: Vec<String>,
|
||||
pub featured: bool,
|
||||
pub dependencies: Vec<QueryDependency>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user