You've already forked AstralRinth
forked from didirus/AstralRinth
More mod info (#104)
* More mod info * Downloading mods * Run prepare * User editing + icon editing * Finish * Some fixes * Fix clippy errors
This commit is contained in:
@@ -17,6 +17,18 @@ pub struct Category {
|
||||
pub category: String,
|
||||
}
|
||||
|
||||
pub struct License {
|
||||
pub id: LicenseId,
|
||||
pub short: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
pub struct DonationPlatform {
|
||||
pub id: DonationPlatformId,
|
||||
pub short: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
pub struct CategoryBuilder<'a> {
|
||||
pub name: Option<&'a str>,
|
||||
}
|
||||
@@ -453,3 +465,293 @@ impl<'a> GameVersionBuilder<'a> {
|
||||
Ok(GameVersionId(result.id))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LicenseBuilder<'a> {
|
||||
pub short: Option<&'a str>,
|
||||
pub name: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl License {
|
||||
pub fn builder() -> LicenseBuilder<'static> {
|
||||
LicenseBuilder::default()
|
||||
}
|
||||
|
||||
pub async fn get_id<'a, E>(id: &str, exec: E) -> Result<Option<LicenseId>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM licenses
|
||||
WHERE short = $1
|
||||
",
|
||||
id
|
||||
)
|
||||
.fetch_optional(exec)
|
||||
.await?;
|
||||
|
||||
Ok(result.map(|r| LicenseId(r.id)))
|
||||
}
|
||||
|
||||
pub async fn get<'a, E>(id: LicenseId, exec: E) -> Result<License, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT short, name FROM licenses
|
||||
WHERE id = $1
|
||||
",
|
||||
id as LicenseId
|
||||
)
|
||||
.fetch_one(exec)
|
||||
.await?;
|
||||
|
||||
Ok(License {
|
||||
id,
|
||||
short: result.short,
|
||||
name: result.name,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn list<'a, E>(exec: E) -> Result<Vec<License>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id, short, name FROM licenses
|
||||
"
|
||||
)
|
||||
.fetch_many(exec)
|
||||
.try_filter_map(|e| async {
|
||||
Ok(e.right().map(|c| License {
|
||||
id: LicenseId(c.id),
|
||||
short: c.short,
|
||||
name: c.name,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<License>>()
|
||||
.await?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn remove<'a, E>(short: &str, exec: E) -> Result<Option<()>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
use sqlx::Done;
|
||||
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
DELETE FROM licenses
|
||||
WHERE short = $1
|
||||
",
|
||||
short
|
||||
)
|
||||
.execute(exec)
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
// Nothing was deleted
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LicenseBuilder<'a> {
|
||||
/// The license's short name/abbreviation. Spaces must be replaced with '_' for it to be valid
|
||||
pub fn short(self, short: &'a str) -> Result<LicenseBuilder<'a>, DatabaseError> {
|
||||
if short
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || "-_.".contains(c))
|
||||
{
|
||||
Ok(Self {
|
||||
short: Some(short),
|
||||
..self
|
||||
})
|
||||
} else {
|
||||
Err(DatabaseError::InvalidIdentifier(short.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// The license's long name
|
||||
pub fn name(self, name: &'a str) -> Result<LicenseBuilder<'a>, DatabaseError> {
|
||||
Ok(Self {
|
||||
name: Some(name),
|
||||
..self
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn insert<'b, E>(self, exec: E) -> Result<LicenseId, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'b, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
INSERT INTO licenses (short, name)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (short) DO NOTHING
|
||||
RETURNING id
|
||||
",
|
||||
self.short,
|
||||
self.name,
|
||||
)
|
||||
.fetch_one(exec)
|
||||
.await?;
|
||||
|
||||
Ok(LicenseId(result.id))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DonationPlatformBuilder<'a> {
|
||||
pub short: Option<&'a str>,
|
||||
pub name: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl DonationPlatform {
|
||||
pub fn builder() -> DonationPlatformBuilder<'static> {
|
||||
DonationPlatformBuilder::default()
|
||||
}
|
||||
|
||||
pub async fn get_id<'a, E>(
|
||||
id: &str,
|
||||
exec: E,
|
||||
) -> Result<Option<DonationPlatformId>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM donation_platforms
|
||||
WHERE short = $1
|
||||
",
|
||||
id
|
||||
)
|
||||
.fetch_optional(exec)
|
||||
.await?;
|
||||
|
||||
Ok(result.map(|r| DonationPlatformId(r.id)))
|
||||
}
|
||||
|
||||
pub async fn get<'a, E>(
|
||||
id: DonationPlatformId,
|
||||
exec: E,
|
||||
) -> Result<DonationPlatform, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT short, name FROM donation_platforms
|
||||
WHERE id = $1
|
||||
",
|
||||
id as DonationPlatformId
|
||||
)
|
||||
.fetch_one(exec)
|
||||
.await?;
|
||||
|
||||
Ok(DonationPlatform {
|
||||
id,
|
||||
short: result.short,
|
||||
name: result.name,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn list<'a, E>(exec: E) -> Result<Vec<DonationPlatform>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id, short, name FROM donation_platforms
|
||||
"
|
||||
)
|
||||
.fetch_many(exec)
|
||||
.try_filter_map(|e| async {
|
||||
Ok(e.right().map(|c| DonationPlatform {
|
||||
id: DonationPlatformId(c.id),
|
||||
short: c.short,
|
||||
name: c.name,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<DonationPlatform>>()
|
||||
.await?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn remove<'a, E>(short: &str, exec: E) -> Result<Option<()>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
use sqlx::Done;
|
||||
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
DELETE FROM donation_platforms
|
||||
WHERE short = $1
|
||||
",
|
||||
short
|
||||
)
|
||||
.execute(exec)
|
||||
.await?;
|
||||
|
||||
if result.rows_affected() == 0 {
|
||||
// Nothing was deleted
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DonationPlatformBuilder<'a> {
|
||||
/// The donation platform short name. Spaces must be replaced with '_' for it to be valid
|
||||
pub fn short(self, short: &'a str) -> Result<DonationPlatformBuilder<'a>, DatabaseError> {
|
||||
if short
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || "-_.".contains(c))
|
||||
{
|
||||
Ok(Self {
|
||||
short: Some(short),
|
||||
..self
|
||||
})
|
||||
} else {
|
||||
Err(DatabaseError::InvalidIdentifier(short.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// The donation platform long name
|
||||
pub fn name(self, name: &'a str) -> Result<DonationPlatformBuilder<'a>, DatabaseError> {
|
||||
Ok(Self {
|
||||
name: Some(name),
|
||||
..self
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn insert<'b, E>(self, exec: E) -> Result<DonationPlatformId, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'b, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
INSERT INTO donation_platforms (short, name)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (short) DO NOTHING
|
||||
RETURNING id
|
||||
",
|
||||
self.short,
|
||||
self.name,
|
||||
)
|
||||
.fetch_one(exec)
|
||||
.await?;
|
||||
|
||||
Ok(DonationPlatformId(result.id))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,15 @@ pub struct ModId(pub i64);
|
||||
#[derive(Copy, Clone, Debug, Type)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct StatusId(pub i32);
|
||||
#[derive(Copy, Clone, Debug, Type)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct SideTypeId(pub i32);
|
||||
#[derive(Copy, Clone, Debug, Type)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct LicenseId(pub i32);
|
||||
#[derive(Copy, Clone, Debug, Type)]
|
||||
#[sqlx(transparent)]
|
||||
pub struct DonationPlatformId(pub i32);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Type)]
|
||||
#[sqlx(transparent)]
|
||||
|
||||
@@ -79,3 +79,44 @@ impl ids::StatusId {
|
||||
Ok(result.map(|r| ids::StatusId(r.id)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ids::SideTypeId {
|
||||
pub async fn get_id<'a, E>(
|
||||
side: &crate::models::mods::SideType,
|
||||
exec: E,
|
||||
) -> Result<Option<Self>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM side_types
|
||||
WHERE name = $1
|
||||
",
|
||||
side.as_str()
|
||||
)
|
||||
.fetch_optional(exec)
|
||||
.await?;
|
||||
|
||||
Ok(result.map(|r| ids::SideTypeId(r.id)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ids::DonationPlatformId {
|
||||
pub async fn get_id<'a, E>(id: &str, exec: E) -> Result<Option<Self>, DatabaseError>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM donation_platforms
|
||||
WHERE short = $1
|
||||
",
|
||||
id
|
||||
)
|
||||
.fetch_optional(exec)
|
||||
.await?;
|
||||
|
||||
Ok(result.map(|r| ids::DonationPlatformId(r.id)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
use super::ids::*;
|
||||
|
||||
pub struct DonationUrl {
|
||||
pub mod_id: ModId,
|
||||
pub platform_id: DonationPlatformId,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
impl DonationUrl {
|
||||
pub async fn insert(
|
||||
&self,
|
||||
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
|
||||
) -> Result<(), sqlx::error::Error> {
|
||||
sqlx::query!(
|
||||
"
|
||||
INSERT INTO mods_donations (
|
||||
joining_mod_id, joining_platform_id, url
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3
|
||||
)
|
||||
",
|
||||
self.mod_id as ModId,
|
||||
self.platform_id as DonationPlatformId,
|
||||
self.url,
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ModBuilder {
|
||||
pub mod_id: ModId,
|
||||
pub team_id: TeamId,
|
||||
@@ -10,9 +41,16 @@ pub struct ModBuilder {
|
||||
pub issues_url: Option<String>,
|
||||
pub source_url: Option<String>,
|
||||
pub wiki_url: Option<String>,
|
||||
pub license_url: Option<String>,
|
||||
pub discord_url: Option<String>,
|
||||
pub categories: Vec<CategoryId>,
|
||||
pub initial_versions: Vec<super::version_item::VersionBuilder>,
|
||||
pub status: StatusId,
|
||||
pub client_side: SideTypeId,
|
||||
pub server_side: SideTypeId,
|
||||
pub license: LicenseId,
|
||||
pub slug: Option<String>,
|
||||
pub donation_urls: Vec<DonationUrl>,
|
||||
}
|
||||
|
||||
impl ModBuilder {
|
||||
@@ -34,6 +72,12 @@ impl ModBuilder {
|
||||
issues_url: self.issues_url,
|
||||
source_url: self.source_url,
|
||||
wiki_url: self.wiki_url,
|
||||
license_url: self.license_url,
|
||||
discord_url: self.discord_url,
|
||||
client_side: self.client_side,
|
||||
server_side: self.server_side,
|
||||
license: self.license,
|
||||
slug: self.slug,
|
||||
};
|
||||
mod_struct.insert(&mut *transaction).await?;
|
||||
|
||||
@@ -42,6 +86,11 @@ impl ModBuilder {
|
||||
version.insert(&mut *transaction).await?;
|
||||
}
|
||||
|
||||
for mut donation in self.donation_urls {
|
||||
donation.mod_id = self.mod_id;
|
||||
donation.insert(&mut *transaction).await?;
|
||||
}
|
||||
|
||||
for category in self.categories {
|
||||
sqlx::query!(
|
||||
"
|
||||
@@ -73,6 +122,12 @@ pub struct Mod {
|
||||
pub issues_url: Option<String>,
|
||||
pub source_url: Option<String>,
|
||||
pub wiki_url: Option<String>,
|
||||
pub license_url: Option<String>,
|
||||
pub discord_url: Option<String>,
|
||||
pub client_side: SideTypeId,
|
||||
pub server_side: SideTypeId,
|
||||
pub license: LicenseId,
|
||||
pub slug: Option<String>,
|
||||
}
|
||||
|
||||
impl Mod {
|
||||
@@ -85,12 +140,16 @@ impl Mod {
|
||||
INSERT INTO mods (
|
||||
id, team_id, title, description, body_url,
|
||||
published, downloads, icon_url, issues_url,
|
||||
source_url, wiki_url, status
|
||||
source_url, wiki_url, status, discord_url,
|
||||
client_side, server_side, license_url, license,
|
||||
slug
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6, $7, $8, $9,
|
||||
$10, $11, $12
|
||||
$10, $11, $12, $13,
|
||||
$14, $15, $16, $17,
|
||||
$18
|
||||
)
|
||||
",
|
||||
self.id as ModId,
|
||||
@@ -104,7 +163,13 @@ impl Mod {
|
||||
self.issues_url.as_ref(),
|
||||
self.source_url.as_ref(),
|
||||
self.wiki_url.as_ref(),
|
||||
self.status.0
|
||||
self.status.0,
|
||||
self.discord_url.as_ref(),
|
||||
self.client_side as SideTypeId,
|
||||
self.server_side as SideTypeId,
|
||||
self.license_url.as_ref(),
|
||||
self.license as LicenseId,
|
||||
self.slug.as_ref()
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
@@ -121,8 +186,8 @@ impl Mod {
|
||||
SELECT title, description, downloads,
|
||||
icon_url, body_url, published,
|
||||
updated, status,
|
||||
issues_url, source_url, wiki_url,
|
||||
team_id
|
||||
issues_url, source_url, wiki_url, discord_url, license_url,
|
||||
team_id, client_side, server_side, license, slug
|
||||
FROM mods
|
||||
WHERE id = $1
|
||||
",
|
||||
@@ -145,7 +210,13 @@ impl Mod {
|
||||
issues_url: row.issues_url,
|
||||
source_url: row.source_url,
|
||||
wiki_url: row.wiki_url,
|
||||
license_url: row.license_url,
|
||||
discord_url: row.discord_url,
|
||||
client_side: SideTypeId(row.client_side),
|
||||
status: StatusId(row.status),
|
||||
server_side: SideTypeId(row.server_side),
|
||||
license: LicenseId(row.license),
|
||||
slug: row.slug,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -164,8 +235,8 @@ impl Mod {
|
||||
SELECT id, title, description, downloads,
|
||||
icon_url, body_url, published,
|
||||
updated, status,
|
||||
issues_url, source_url, wiki_url,
|
||||
team_id
|
||||
issues_url, source_url, wiki_url, discord_url, license_url,
|
||||
team_id, client_side, server_side, license, slug
|
||||
FROM mods
|
||||
WHERE id IN (SELECT * FROM UNNEST($1::bigint[]))
|
||||
",
|
||||
@@ -186,7 +257,13 @@ impl Mod {
|
||||
issues_url: m.issues_url,
|
||||
source_url: m.source_url,
|
||||
wiki_url: m.wiki_url,
|
||||
license_url: m.license_url,
|
||||
discord_url: m.discord_url,
|
||||
client_side: SideTypeId(m.client_side),
|
||||
status: StatusId(m.status),
|
||||
server_side: SideTypeId(m.server_side),
|
||||
license: LicenseId(m.license),
|
||||
slug: m.slug,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<Mod>>()
|
||||
@@ -227,6 +304,16 @@ impl Mod {
|
||||
.execute(exec)
|
||||
.await?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
DELETE FROM mods_donations
|
||||
WHERE joining_mod_id = $1
|
||||
",
|
||||
id as ModId,
|
||||
)
|
||||
.execute(exec)
|
||||
.await?;
|
||||
|
||||
use futures::TryStreamExt;
|
||||
let versions: Vec<VersionId> = sqlx::query!(
|
||||
"
|
||||
@@ -277,6 +364,30 @@ impl Mod {
|
||||
Ok(Some(()))
|
||||
}
|
||||
|
||||
pub async fn get_full_from_slug<'a, 'b, E>(
|
||||
slug: String,
|
||||
executor: E,
|
||||
) -> Result<Option<QueryMod>, sqlx::error::Error>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
{
|
||||
let id = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM mods
|
||||
WHERE slug = $1
|
||||
",
|
||||
slug
|
||||
)
|
||||
.fetch_optional(executor)
|
||||
.await?;
|
||||
|
||||
if let Some(mod_id) = id {
|
||||
Mod::get_full(ModId(mod_id.id), executor).await
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_full<'a, 'b, E>(
|
||||
id: ModId,
|
||||
executor: E,
|
||||
@@ -312,6 +423,24 @@ impl Mod {
|
||||
.try_collect::<Vec<VersionId>>()
|
||||
.await?;
|
||||
|
||||
let donations: Vec<DonationUrl> = sqlx::query!(
|
||||
"
|
||||
SELECT joining_platform_id, url FROM mods_donations
|
||||
WHERE joining_mod_id = $1
|
||||
",
|
||||
id as ModId,
|
||||
)
|
||||
.fetch_many(executor)
|
||||
.try_filter_map(|e| async {
|
||||
Ok(e.right().map(|c| DonationUrl {
|
||||
mod_id: id,
|
||||
platform_id: DonationPlatformId(c.joining_platform_id),
|
||||
url: c.url,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<DonationUrl>>()
|
||||
.await?;
|
||||
|
||||
let status = sqlx::query!(
|
||||
"
|
||||
SELECT status FROM statuses
|
||||
@@ -323,11 +452,48 @@ impl Mod {
|
||||
.await?
|
||||
.status;
|
||||
|
||||
let client_side = sqlx::query!(
|
||||
"
|
||||
SELECT name FROM side_types
|
||||
WHERE id = $1
|
||||
",
|
||||
inner.client_side.0,
|
||||
)
|
||||
.fetch_one(executor)
|
||||
.await?
|
||||
.name;
|
||||
|
||||
let server_side = sqlx::query!(
|
||||
"
|
||||
SELECT name FROM side_types
|
||||
WHERE id = $1
|
||||
",
|
||||
inner.server_side.0,
|
||||
)
|
||||
.fetch_one(executor)
|
||||
.await?
|
||||
.name;
|
||||
|
||||
let license = sqlx::query!(
|
||||
"
|
||||
SELECT short, name FROM licenses
|
||||
WHERE id = $1
|
||||
",
|
||||
inner.license.0,
|
||||
)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
||||
Ok(Some(QueryMod {
|
||||
inner,
|
||||
categories,
|
||||
versions,
|
||||
donation_urls: donations,
|
||||
status: crate::models::mods::ModStatus::from_str(&status),
|
||||
license_id: license.short,
|
||||
license_name: license.name,
|
||||
client_side: crate::models::mods::SideType::from_str(&client_side),
|
||||
server_side: crate::models::mods::SideType::from_str(&server_side)
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -351,5 +517,10 @@ pub struct QueryMod {
|
||||
|
||||
pub categories: Vec<String>,
|
||||
pub versions: Vec<VersionId>,
|
||||
pub donation_urls: Vec<DonationUrl>,
|
||||
pub status: crate::models::mods::ModStatus,
|
||||
pub license_id: String,
|
||||
pub license_name: String,
|
||||
pub client_side: crate::models::mods::SideType,
|
||||
pub server_side: crate::models::mods::SideType,
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ impl TeamMember {
|
||||
name: m.member_name,
|
||||
role: m.role,
|
||||
permissions: Permissions::from_bits(m.permissions as u64)
|
||||
.ok_or_else(|| super::DatabaseError::BitflagError)?,
|
||||
.ok_or(super::DatabaseError::BitflagError)?,
|
||||
accepted: m.accepted,
|
||||
}))
|
||||
} else {
|
||||
@@ -297,7 +297,7 @@ impl TeamMember {
|
||||
name: m.member_name,
|
||||
role: m.role,
|
||||
permissions: Permissions::from_bits(m.permissions as u64)
|
||||
.ok_or_else(|| super::DatabaseError::BitflagError)?,
|
||||
.ok_or(super::DatabaseError::BitflagError)?,
|
||||
accepted: m.accepted,
|
||||
}))
|
||||
} else {
|
||||
|
||||
@@ -113,6 +113,43 @@ impl User {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_from_username<'a, 'b, E>(
|
||||
username: String,
|
||||
executor: E,
|
||||
) -> Result<Option<Self>, sqlx::error::Error>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres>,
|
||||
{
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT u.id, u.github_id, u.name, u.email,
|
||||
u.avatar_url, u.bio,
|
||||
u.created, u.role
|
||||
FROM users u
|
||||
WHERE u.username = $1
|
||||
",
|
||||
username
|
||||
)
|
||||
.fetch_optional(executor)
|
||||
.await?;
|
||||
|
||||
if let Some(row) = result {
|
||||
Ok(Some(User {
|
||||
id: UserId(row.id),
|
||||
github_id: row.github_id,
|
||||
name: row.name,
|
||||
email: row.email,
|
||||
avatar_url: row.avatar_url,
|
||||
username,
|
||||
bio: row.bio,
|
||||
created: row.created,
|
||||
role: row.role,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_many<'a, E>(user_ids: Vec<UserId>, exec: E) -> Result<Vec<User>, sqlx::Error>
|
||||
where
|
||||
E: sqlx::Executor<'a, Database = sqlx::Postgres> + Copy,
|
||||
|
||||
@@ -13,12 +13,14 @@ pub struct VersionBuilder {
|
||||
pub game_versions: Vec<GameVersionId>,
|
||||
pub loaders: Vec<LoaderId>,
|
||||
pub release_channel: ChannelId,
|
||||
pub featured: bool,
|
||||
}
|
||||
|
||||
pub struct VersionFileBuilder {
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub hashes: Vec<HashBuilder>,
|
||||
pub primary: bool,
|
||||
}
|
||||
|
||||
impl VersionFileBuilder {
|
||||
@@ -81,6 +83,7 @@ impl VersionBuilder {
|
||||
downloads: 0,
|
||||
release_channel: self.release_channel,
|
||||
accepted: false,
|
||||
featured: self.featured,
|
||||
};
|
||||
|
||||
version.insert(&mut *transaction).await?;
|
||||
@@ -154,6 +157,7 @@ pub struct Version {
|
||||
pub downloads: i32,
|
||||
pub release_channel: ChannelId,
|
||||
pub accepted: bool,
|
||||
pub featured: bool,
|
||||
}
|
||||
|
||||
impl Version {
|
||||
@@ -166,13 +170,13 @@ impl Version {
|
||||
INSERT INTO versions (
|
||||
id, mod_id, author_id, name, version_number,
|
||||
changelog_url, date_published,
|
||||
downloads, release_channel, accepted
|
||||
downloads, release_channel, accepted, featured
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6, $7,
|
||||
$8, $9,
|
||||
$10
|
||||
$10, $11
|
||||
)
|
||||
",
|
||||
self.id as VersionId,
|
||||
@@ -184,7 +188,8 @@ impl Version {
|
||||
self.date_published,
|
||||
self.downloads,
|
||||
self.release_channel as ChannelId,
|
||||
self.accepted
|
||||
self.accepted,
|
||||
self.featured
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
@@ -234,7 +239,7 @@ impl Version {
|
||||
|
||||
let files = sqlx::query!(
|
||||
"
|
||||
SELECT files.id, files.url, files.filename FROM files
|
||||
SELECT files.id, files.url, files.filename, files.is_primary FROM files
|
||||
WHERE files.version_id = $1
|
||||
",
|
||||
id as VersionId,
|
||||
@@ -246,6 +251,7 @@ impl Version {
|
||||
version_id: id,
|
||||
url: c.url,
|
||||
filename: c.filename,
|
||||
primary: c.is_primary,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<VersionFile>>()
|
||||
@@ -367,7 +373,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.mod_id, v.author_id, v.name, v.version_number,
|
||||
v.changelog_url, v.date_published, v.downloads,
|
||||
v.release_channel, v.accepted
|
||||
v.release_channel, v.accepted, v.featured
|
||||
FROM versions v
|
||||
WHERE v.id = $1
|
||||
",
|
||||
@@ -388,6 +394,7 @@ impl Version {
|
||||
downloads: row.downloads,
|
||||
release_channel: ChannelId(row.release_channel),
|
||||
accepted: row.accepted,
|
||||
featured: row.featured,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -408,7 +415,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.id, v.mod_id, v.author_id, v.name, v.version_number,
|
||||
v.changelog_url, v.date_published, v.downloads,
|
||||
v.release_channel, accepted
|
||||
v.release_channel, v.accepted, v.featured
|
||||
FROM versions v
|
||||
WHERE v.id IN (SELECT * FROM UNNEST($1::bigint[]))
|
||||
",
|
||||
@@ -427,6 +434,7 @@ impl Version {
|
||||
downloads: v.downloads,
|
||||
release_channel: ChannelId(v.release_channel),
|
||||
accepted: v.accepted,
|
||||
featured: v.featured,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<Version>>()
|
||||
@@ -446,7 +454,7 @@ impl Version {
|
||||
"
|
||||
SELECT v.mod_id, v.author_id, v.name, v.version_number,
|
||||
v.changelog_url, v.date_published, v.downloads,
|
||||
release_channels.channel, v.accepted
|
||||
release_channels.channel, v.accepted, v.featured
|
||||
FROM versions v
|
||||
INNER JOIN release_channels ON v.release_channel = release_channels.id
|
||||
WHERE v.id = $1
|
||||
@@ -487,7 +495,7 @@ impl Version {
|
||||
|
||||
let mut files = sqlx::query!(
|
||||
"
|
||||
SELECT files.id, files.url, files.filename FROM files
|
||||
SELECT files.id, files.url, files.filename, files.is_primary FROM files
|
||||
WHERE files.version_id = $1
|
||||
",
|
||||
id as VersionId,
|
||||
@@ -499,6 +507,7 @@ impl Version {
|
||||
url: c.url,
|
||||
filename: c.filename,
|
||||
hashes: std::collections::HashMap::new(),
|
||||
primary: c.is_primary,
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<QueryFile>>()
|
||||
@@ -535,6 +544,7 @@ impl Version {
|
||||
loaders,
|
||||
game_versions,
|
||||
accepted: row.accepted,
|
||||
featured: row.featured,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -564,6 +574,7 @@ pub struct VersionFile {
|
||||
pub version_id: VersionId,
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub primary: bool,
|
||||
}
|
||||
|
||||
pub struct FileHash {
|
||||
@@ -587,6 +598,7 @@ pub struct QueryVersion {
|
||||
pub game_versions: Vec<String>,
|
||||
pub loaders: Vec<String>,
|
||||
pub accepted: bool,
|
||||
pub featured: bool,
|
||||
}
|
||||
|
||||
pub struct QueryFile {
|
||||
@@ -594,4 +606,5 @@ pub struct QueryFile {
|
||||
pub url: String,
|
||||
pub filename: String,
|
||||
pub hashes: std::collections::HashMap<String, Vec<u8>>,
|
||||
pub primary: bool,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user