Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
Batch the remaining ones except those requiring deduplication
Browse files Browse the repository at this point in the history
  • Loading branch information
OmegaJak committed Oct 9, 2023
1 parent d3e9eda commit 2d01a5f
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 102 deletions.
3 changes: 0 additions & 3 deletions src/database/models/collection_item.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use std::iter;

use super::ids::*;
use crate::database::models;
use crate::database::models::DatabaseError;
use crate::database::redis::RedisPool;
use crate::models::collections::CollectionStatus;
use chrono::{DateTime, Utc};
use itertools::Itertools;
use serde::{Deserialize, Serialize};

const COLLECTIONS_NAMESPACE: &str = "collections";
Expand Down
122 changes: 71 additions & 51 deletions src/database/models/project_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::database::redis::RedisPool;
use crate::models::ids::base62_impl::{parse_base62, to_base62};
use crate::models::projects::{MonetizationStatus, ProjectStatus};
use chrono::{DateTime, Utc};
use itertools::Itertools;
use serde::{Deserialize, Serialize};

pub const PROJECTS_NAMESPACE: &str = "projects";
Expand All @@ -20,23 +21,25 @@ pub struct DonationUrl {
}

impl DonationUrl {
pub async fn insert_project(
&self,
pub async fn insert_many_projects(
donation_urls: Vec<Self>,
project_id: ProjectId,
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<(), sqlx::error::Error> {
let (project_ids, platform_ids, urls): (Vec<_>, Vec<_>, Vec<_>) = donation_urls
.into_iter()
.map(|url| (project_id.0, url.platform_id.0, url.url))
.multiunzip();
sqlx::query!(
"
INSERT INTO mods_donations (
joining_mod_id, joining_platform_id, url
)
VALUES (
$1, $2, $3
)
SELECT * FROM UNNEST($1::bigint[], $2::int[], $3::varchar[])
",
project_id as ProjectId,
self.platform_id as DonationPlatformId,
self.url,
&project_ids[..],
&platform_ids[..],
&urls[..],
)
.execute(&mut *transaction)
.await?;
Expand All @@ -56,26 +59,44 @@ pub struct GalleryItem {
}

impl GalleryItem {
pub async fn insert(
&self,
pub async fn insert_many(
items: Vec<Self>,
project_id: ProjectId,
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<(), sqlx::error::Error> {
let (project_ids, image_urls, featureds, titles, descriptions, orderings): (
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
) = items
.into_iter()
.map(|gi| {
(
project_id.0,
gi.image_url,
gi.featured,
gi.title,
gi.description,
gi.ordering,
)
})
.multiunzip();
sqlx::query!(
"
INSERT INTO mods_gallery (
mod_id, image_url, featured, title, description, ordering
)
VALUES (
$1, $2, $3, $4, $5, $6
)
SELECT * FROM UNNEST ($1::bigint[], $2::varchar[], $3::bool[], $4::varchar[], $5::varchar[], $6::bigint[])
",
project_id as ProjectId,
self.image_url,
self.featured,
self.title,
self.description,
self.ordering
&project_ids[..],
&image_urls[..],
&featureds[..],
&titles[..] as &[Option<String>],
&descriptions[..] as &[Option<String>],
&orderings[..]
)
.execute(&mut *transaction)
.await?;
Expand Down Expand Up @@ -160,46 +181,45 @@ impl ProjectBuilder {
};
project_struct.insert(&mut *transaction).await?;

let ProjectBuilder {
donation_urls,
gallery_items,
categories,
additional_categories,
..
} = self;

for mut version in self.initial_versions {
version.project_id = self.project_id;
version.insert(&mut *transaction).await?;
}

for donation in self.donation_urls {
donation
.insert_project(self.project_id, &mut *transaction)
.await?;
}

for gallery in self.gallery_items {
gallery.insert(self.project_id, &mut *transaction).await?;
}

for category in self.categories {
sqlx::query!(
"
INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)
VALUES ($1, $2, FALSE)
",
self.project_id as ProjectId,
category as CategoryId,
)
.execute(&mut *transaction)
DonationUrl::insert_many_projects(donation_urls, self.project_id, &mut *transaction)
.await?;
}

for category in self.additional_categories {
sqlx::query!(
"
INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)
VALUES ($1, $2, TRUE)
",
self.project_id as ProjectId,
category as CategoryId,
GalleryItem::insert_many(gallery_items, self.project_id, &mut *transaction).await?;

let project_id = self.project_id.0;
let (project_ids, category_ids, is_additionals): (Vec<_>, Vec<_>, Vec<_>) = categories
.into_iter()
.map(|c| (project_id, c.0, false))
.chain(
additional_categories
.into_iter()
.map(|c| (project_id, c.0, true)),
)
.execute(&mut *transaction)
.await?;
}
.multiunzip();
sqlx::query!(
"
INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)
SELECT * FROM UNNEST ($1::bigint[], $2::int[], $3::bool[])
",
&project_ids[..],
&category_ids[..],
&is_additionals[..]
)
.execute(&mut *transaction)
.await?;

Project::update_game_versions(self.project_id, &mut *transaction).await?;
Project::update_loaders(self.project_id, &mut *transaction).await?;
Expand Down
73 changes: 54 additions & 19 deletions src/database/models/team_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,61 @@ impl TeamBuilder {
.execute(&mut *transaction)
.await?;

for member in self.members {
let team_member_id = generate_team_member_id(&mut *transaction).await?;
sqlx::query!(
"
INSERT INTO team_members (id, team_id, user_id, role, permissions, organization_permissions, accepted, payouts_split, ordering)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
",
team_member_id as TeamMemberId,
team.id as TeamId,
member.user_id as UserId,
member.role,
member.permissions.bits() as i64,
member.organization_permissions.map(|p| p.bits() as i64),
member.accepted,
member.payouts_split,
member.ordering,
)
.execute(&mut *transaction)
.await?;
let mut team_member_ids = Vec::new();
for _ in self.members.iter() {
team_member_ids.push(generate_team_member_id(&mut *transaction).await?.0);
}
let TeamBuilder { members } = self;
let (
team_ids,
user_ids,
roles,
permissions,
organization_permissions,
accepteds,
payouts_splits,
orderings,
): (
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
Vec<_>,
) = members
.into_iter()
.map(|m| {
(
team.id.0,
m.user_id.0,
m.role,
m.permissions.bits() as i64,
m.organization_permissions.map(|p| p.bits() as i64),
m.accepted,
m.payouts_split,
m.ordering,
)
})
.multiunzip();
sqlx::query!(
"
INSERT INTO team_members (id, team_id, user_id, role, permissions, organization_permissions, accepted, payouts_split, ordering)
SELECT * FROM UNNEST ($1::int8[], $2::int8[], $3::int8[], $4::varchar[], $5::int8[], $6::int8[], $7::bool[], $8::numeric[], $9::int8[])
",
&team_member_ids[..],
&team_ids[..],
&user_ids[..],
&roles[..],
&permissions[..],
&organization_permissions[..] as &[Option<i64>],
&accepteds[..],
&payouts_splits[..],
&orderings[..],
)
.execute(&mut *transaction)
.await?;

Ok(team_id)
}
Expand Down
24 changes: 12 additions & 12 deletions src/database/models/thread_item.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::os::unix::thread;

use super::ids::*;
use crate::database::models::DatabaseError;
use crate::models::threads::{MessageBody, ThreadType};
Expand Down Expand Up @@ -90,22 +92,20 @@ impl ThreadBuilder {
.execute(&mut *transaction)
.await?;

for member in &self.members {
sqlx::query!(
"
let (thread_ids, members): (Vec<_>, Vec<_>) =
self.members.iter().map(|m| (thread_id.0, m.0)).unzip();
sqlx::query!(
"
INSERT INTO threads_members (
thread_id, user_id
)
VALUES (
$1, $2
)
SELECT * FROM UNNEST ($1::int8[], $2::int8[])
",
thread_id as ThreadId,
*member as UserId,
)
.execute(&mut *transaction)
.await?;
}
&thread_ids[..],
&members[..],
)
.execute(&mut *transaction)
.await?;

Ok(thread_id)
}
Expand Down
32 changes: 19 additions & 13 deletions src/routes/v2/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{database, models};
use actix_web::web::Data;
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
use chrono::Utc;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use std::sync::Arc;
Expand Down Expand Up @@ -301,6 +302,11 @@ pub async fn collection_edit(
.execute(&mut *transaction)
.await?;

let collection_item_ids = new_project_ids
.iter()
.map(|_| collection_item.id.0)
.collect_vec();
let mut validated_project_ids = Vec::new();
for project_id in new_project_ids {
let project = database::models::Project::get(project_id, &**pool, &redis)
.await?
Expand All @@ -309,20 +315,20 @@ pub async fn collection_edit(
"The specified project {project_id} does not exist!"
))
})?;

// Insert- don't throw an error if it already exists
sqlx::query!(
"
INSERT INTO collections_mods (collection_id, mod_id)
VALUES ($1, $2)
ON CONFLICT DO NOTHING
",
collection_item.id as database::models::ids::CollectionId,
project.inner.id as database::models::ids::ProjectId,
)
.execute(&mut *transaction)
.await?;
validated_project_ids.push(project.inner.id.0);
}
// Insert- don't throw an error if it already exists
sqlx::query!(
"
INSERT INTO collections_mods (collection_id, mod_id)
SELECT * FROM UNNEST ($1::int8[], $2::int8[])
ON CONFLICT DO NOTHING
",
&collection_item_ids[..],
&validated_project_ids[..],
)
.execute(&mut *transaction)
.await?;
}

database::models::Collection::clear_cache(collection_item.id, &redis).await?;
Expand Down
8 changes: 4 additions & 4 deletions src/routes/v2/projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::auth::{filter_authorized_projects, get_user_from_headers, is_authoriz
use crate::database;
use crate::database::models::image_item;
use crate::database::models::notification_item::NotificationBuilder;
use crate::database::models::project_item::GalleryItem;
use crate::database::models::thread_item::ThreadMessageBuilder;
use crate::database::redis::RedisPool;
use crate::file_hosting::FileHost;
Expand Down Expand Up @@ -2047,16 +2048,15 @@ pub async fn add_gallery_item(
.await?;
}

database::models::project_item::GalleryItem {
let gallery_item = vec![database::models::project_item::GalleryItem {
image_url: file_url,
featured: item.featured,
title: item.title,
description: item.description,
created: Utc::now(),
ordering: item.ordering.unwrap_or(0),
}
.insert(project_item.inner.id, &mut transaction)
.await?;
}];
GalleryItem::insert_many(gallery_item, project_item.inner.id, &mut transaction).await?;

database::models::Project::clear_cache(
project_item.inner.id,
Expand Down

0 comments on commit 2d01a5f

Please sign in to comment.