diff --git a/crates/schema/database/mysql_queries/src/queries/mod.rs b/crates/schema/database/mysql_queries/src/queries/mod.rs index bc4474b920..8968b34858 100644 --- a/crates/schema/database/mysql_queries/src/queries/mod.rs +++ b/crates/schema/database/mysql_queries/src/queries/mod.rs @@ -37,6 +37,8 @@ pub mod trending_model_analytics; pub mod tts; pub mod twitch; pub mod unsubscribe_reason; +pub mod uploaded_video_notes; +pub mod uploaded_videos; pub mod user_impersonation_requests; pub mod user_referral_codes; pub mod user_referrals; diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/insert_uploaded_video_note.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/insert_uploaded_video_note.rs new file mode 100644 index 0000000000..94f9bdaecf --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/insert_uploaded_video_note.rs @@ -0,0 +1,69 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_model_type::UploadedVideoNoteReportedModelType; +use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_website::UploadedVideoNoteReportedWebsite; +use tokens::tokens::uploaded_video_notes::UploadVideoNoteToken; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +pub struct InsertUploadedVideoNoteArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub uploaded_video_token: &'e UploadedVideoToken, + + pub maybe_filename: Option<&'e str>, + pub maybe_reported_model_type: Option, + pub maybe_reported_model_name: Option<&'e str>, + pub maybe_website: Option, + pub maybe_other_website: Option<&'e str>, + pub maybe_comments: Option<&'e str>, + + pub comment_create_ip_address: &'e str, + + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Insert a new `uploaded_video_notes` record. The `UploadVideoNoteToken` is +/// minted here (in the data-access layer, not the handler) and returned. +/// `created_at` is set to `NOW()`. +pub async fn insert_uploaded_video_note<'e, 'c: 'e, E>( + args: InsertUploadedVideoNoteArgs<'e, 'c, E>, +) -> Result +where + E: 'e + Executor<'c, Database = MySql>, +{ + let token = UploadVideoNoteToken::generate(); + + sqlx::query!( + r#" +INSERT INTO uploaded_video_notes +SET + token = ?, + uploaded_video_token = ?, + maybe_filename = ?, + maybe_reported_model_type = ?, + maybe_reported_model_name = ?, + maybe_website = ?, + maybe_other_website = ?, + maybe_comments = ?, + comment_create_ip_address = ?, + created_at = NOW() + "#, + token.as_str(), + args.uploaded_video_token.as_str(), + args.maybe_filename, + args.maybe_reported_model_type.map(|model_type| model_type.to_str()), + args.maybe_reported_model_name, + args.maybe_website.map(|website| website.to_str()), + args.maybe_other_website, + args.maybe_comments, + args.comment_create_ip_address, + ) + .execute(args.mysql_executor) + .await?; + + Ok(token) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/mod.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/mod.rs new file mode 100644 index 0000000000..42575f4dbb --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/mod.rs @@ -0,0 +1,2 @@ +pub mod insert_uploaded_video_note; +pub mod update_uploaded_video_note; diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/update_uploaded_video_note.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/update_uploaded_video_note.rs new file mode 100644 index 0000000000..31cfbbdbab --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_video_notes/update_uploaded_video_note.rs @@ -0,0 +1,65 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_model_type::UploadedVideoNoteReportedModelType; +use enums::by_table::uploaded_video_notes::uploaded_video_note_reported_website::UploadedVideoNoteReportedWebsite; +use tokens::tokens::uploaded_video_notes::UploadVideoNoteToken; + +pub struct UpdateUploadedVideoNoteArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub token: &'e UploadVideoNoteToken, + + pub maybe_filename: Option<&'e str>, + pub maybe_reported_model_type: Option, + pub maybe_reported_model_name: Option<&'e str>, + pub maybe_website: Option, + pub maybe_other_website: Option<&'e str>, + pub maybe_comments: Option<&'e str>, + + /// IP address of the request making the update; stamped on `maybe_comment_update_ip_address`. + pub maybe_comment_update_ip_address: Option<&'e str>, + + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Update the mutable fields of an `uploaded_video_notes` record by `token`. +/// `updated_at` is refreshed via the column's `ON UPDATE` clause. Returns the +/// number of rows affected (0 if no row matched). +pub async fn update_uploaded_video_note<'e, 'c: 'e, E>( + args: UpdateUploadedVideoNoteArgs<'e, 'c, E>, +) -> Result +where + E: 'e + Executor<'c, Database = MySql>, +{ + let result = sqlx::query!( + r#" +UPDATE uploaded_video_notes +SET + maybe_filename = ?, + maybe_reported_model_type = ?, + maybe_reported_model_name = ?, + maybe_website = ?, + maybe_other_website = ?, + maybe_comments = ?, + maybe_comment_update_ip_address = ? +WHERE token = ? +LIMIT 1 + "#, + args.maybe_filename, + args.maybe_reported_model_type.map(|model_type| model_type.to_str()), + args.maybe_reported_model_name, + args.maybe_website.map(|website| website.to_str()), + args.maybe_other_website, + args.maybe_comments, + args.maybe_comment_update_ip_address, + args.token.as_str(), + ) + .execute(args.mysql_executor) + .await?; + + Ok(result.rows_affected()) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_sha1_checksum.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_sha1_checksum.rs new file mode 100644 index 0000000000..e21f5a1cf8 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_sha1_checksum.rs @@ -0,0 +1,68 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_videos::uploaded_video_detected_model_family::UploadedVideoDetectedModelFamily; +use enums::by_table::uploaded_videos::uploaded_video_detected_model_type::UploadedVideoDetectedModelType; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +use crate::queries::uploaded_videos::uploaded_video_row::UploadedVideoRow; + +pub struct GetUploadedVideoBySha1ChecksumArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub sha1_checksum: &'e str, + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Look up an `uploaded_videos` record by its `sha1_checksum`. `Ok(None)` if no +/// row matches. Useful for de-duplicating re-uploads of the same bytes. +pub async fn get_uploaded_video_by_sha1_checksum<'e, 'c: 'e, E>( + args: GetUploadedVideoBySha1ChecksumArgs<'e, 'c, E>, +) -> Result, sqlx::Error> +where + E: 'e + Executor<'c, Database = MySql>, +{ + let result = sqlx::query!( + r#" +SELECT + token as `token: UploadedVideoToken`, + sha1_checksum, + filesize_bytes as `filesize_bytes: u32`, + maybe_width as `maybe_width: u32`, + maybe_height as `maybe_height: u32`, + maybe_resolution, + maybe_detected_model_family as `maybe_detected_model_family: UploadedVideoDetectedModelFamily`, + maybe_detected_model_type as `maybe_detected_model_type: UploadedVideoDetectedModelType`, + maybe_report, + upload_ip_address, + maybe_updated_ip_address, + created_at, + updated_at +FROM uploaded_videos +WHERE sha1_checksum = ? +LIMIT 1 + "#, + args.sha1_checksum, + ) + .fetch_optional(args.mysql_executor) + .await?; + + Ok(result.map(|r| UploadedVideoRow { + token: r.token, + sha1_checksum: r.sha1_checksum, + filesize_bytes: r.filesize_bytes, + maybe_width: r.maybe_width, + maybe_height: r.maybe_height, + maybe_resolution: r.maybe_resolution, + maybe_detected_model_family: r.maybe_detected_model_family, + maybe_detected_model_type: r.maybe_detected_model_type, + maybe_report: r.maybe_report, + upload_ip_address: r.upload_ip_address, + maybe_updated_ip_address: r.maybe_updated_ip_address, + created_at: r.created_at, + updated_at: r.updated_at, + })) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_token.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_token.rs new file mode 100644 index 0000000000..a07162f9e4 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/get_uploaded_video_by_token.rs @@ -0,0 +1,67 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_videos::uploaded_video_detected_model_family::UploadedVideoDetectedModelFamily; +use enums::by_table::uploaded_videos::uploaded_video_detected_model_type::UploadedVideoDetectedModelType; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +use crate::queries::uploaded_videos::uploaded_video_row::UploadedVideoRow; + +pub struct GetUploadedVideoByTokenArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub token: &'e UploadedVideoToken, + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Look up an `uploaded_videos` record by its `token`. `Ok(None)` if no row matches. +pub async fn get_uploaded_video_by_token<'e, 'c: 'e, E>( + args: GetUploadedVideoByTokenArgs<'e, 'c, E>, +) -> Result, sqlx::Error> +where + E: 'e + Executor<'c, Database = MySql>, +{ + let result = sqlx::query!( + r#" +SELECT + token as `token: UploadedVideoToken`, + sha1_checksum, + filesize_bytes as `filesize_bytes: u32`, + maybe_width as `maybe_width: u32`, + maybe_height as `maybe_height: u32`, + maybe_resolution, + maybe_detected_model_family as `maybe_detected_model_family: UploadedVideoDetectedModelFamily`, + maybe_detected_model_type as `maybe_detected_model_type: UploadedVideoDetectedModelType`, + maybe_report, + upload_ip_address, + maybe_updated_ip_address, + created_at, + updated_at +FROM uploaded_videos +WHERE token = ? +LIMIT 1 + "#, + args.token.as_str(), + ) + .fetch_optional(args.mysql_executor) + .await?; + + Ok(result.map(|r| UploadedVideoRow { + token: r.token, + sha1_checksum: r.sha1_checksum, + filesize_bytes: r.filesize_bytes, + maybe_width: r.maybe_width, + maybe_height: r.maybe_height, + maybe_resolution: r.maybe_resolution, + maybe_detected_model_family: r.maybe_detected_model_family, + maybe_detected_model_type: r.maybe_detected_model_type, + maybe_report: r.maybe_report, + upload_ip_address: r.upload_ip_address, + maybe_updated_ip_address: r.maybe_updated_ip_address, + created_at: r.created_at, + updated_at: r.updated_at, + })) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/insert_uploaded_video.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/insert_uploaded_video.rs new file mode 100644 index 0000000000..44caaf85a6 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/insert_uploaded_video.rs @@ -0,0 +1,72 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_videos::uploaded_video_detected_model_family::UploadedVideoDetectedModelFamily; +use enums::by_table::uploaded_videos::uploaded_video_detected_model_type::UploadedVideoDetectedModelType; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +pub struct InsertUploadedVideoArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub sha1_checksum: &'e str, + pub filesize_bytes: u32, + + pub maybe_width: Option, + pub maybe_height: Option, + pub maybe_resolution: Option<&'e str>, + + pub maybe_detected_model_family: Option, + pub maybe_detected_model_type: Option, + pub maybe_report: Option<&'e str>, + + pub upload_ip_address: &'e str, + + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Insert a new `uploaded_videos` record. The `UploadedVideoToken` is minted +/// here (in the data-access layer, not the handler) and returned. `created_at` +/// is set to `NOW()`. +pub async fn insert_uploaded_video<'e, 'c: 'e, E>( + args: InsertUploadedVideoArgs<'e, 'c, E>, +) -> Result +where + E: 'e + Executor<'c, Database = MySql>, +{ + let token = UploadedVideoToken::generate(); + + sqlx::query!( + r#" +INSERT INTO uploaded_videos +SET + token = ?, + sha1_checksum = ?, + filesize_bytes = ?, + maybe_width = ?, + maybe_height = ?, + maybe_resolution = ?, + maybe_detected_model_family = ?, + maybe_detected_model_type = ?, + maybe_report = ?, + upload_ip_address = ?, + created_at = NOW() + "#, + token.as_str(), + args.sha1_checksum, + args.filesize_bytes, + args.maybe_width, + args.maybe_height, + args.maybe_resolution, + args.maybe_detected_model_family.map(|family| family.to_str()), + args.maybe_detected_model_type.map(|model_type| model_type.to_str()), + args.maybe_report, + args.upload_ip_address, + ) + .execute(args.mysql_executor) + .await?; + + Ok(token) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/mod.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/mod.rs new file mode 100644 index 0000000000..be54484288 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/mod.rs @@ -0,0 +1,5 @@ +pub mod get_uploaded_video_by_sha1_checksum; +pub mod get_uploaded_video_by_token; +pub mod insert_uploaded_video; +pub mod update_uploaded_video; +pub mod uploaded_video_row; diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/update_uploaded_video.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/update_uploaded_video.rs new file mode 100644 index 0000000000..aa0ef1c885 --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/update_uploaded_video.rs @@ -0,0 +1,67 @@ +use std::marker::PhantomData; + +use sqlx::{Executor, MySql}; + +use enums::by_table::uploaded_videos::uploaded_video_detected_model_family::UploadedVideoDetectedModelFamily; +use enums::by_table::uploaded_videos::uploaded_video_detected_model_type::UploadedVideoDetectedModelType; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +pub struct UpdateUploadedVideoArgs<'e, 'c, E> +where + E: 'e + Executor<'c, Database = MySql>, +{ + pub token: &'e UploadedVideoToken, + + pub maybe_width: Option, + pub maybe_height: Option, + pub maybe_resolution: Option<&'e str>, + + pub maybe_detected_model_family: Option, + pub maybe_detected_model_type: Option, + pub maybe_report: Option<&'e str>, + + /// IP address of the request making the update; stamped on `maybe_updated_ip_address`. + pub maybe_updated_ip_address: Option<&'e str>, + + pub mysql_executor: E, + pub phantom: PhantomData<&'c E>, +} + +/// Update the mutable fields of an `uploaded_videos` record by `token` +/// (dimensions, detection, report, updater IP). `updated_at` is refreshed via +/// the column's `ON UPDATE` clause. Returns the number of rows affected (0 if no +/// row matched). +pub async fn update_uploaded_video<'e, 'c: 'e, E>( + args: UpdateUploadedVideoArgs<'e, 'c, E>, +) -> Result +where + E: 'e + Executor<'c, Database = MySql>, +{ + let result = sqlx::query!( + r#" +UPDATE uploaded_videos +SET + maybe_width = ?, + maybe_height = ?, + maybe_resolution = ?, + maybe_detected_model_family = ?, + maybe_detected_model_type = ?, + maybe_report = ?, + maybe_updated_ip_address = ? +WHERE token = ? +LIMIT 1 + "#, + args.maybe_width, + args.maybe_height, + args.maybe_resolution, + args.maybe_detected_model_family.map(|family| family.to_str()), + args.maybe_detected_model_type.map(|model_type| model_type.to_str()), + args.maybe_report, + args.maybe_updated_ip_address, + args.token.as_str(), + ) + .execute(args.mysql_executor) + .await?; + + Ok(result.rows_affected()) +} diff --git a/crates/schema/database/mysql_queries/src/queries/uploaded_videos/uploaded_video_row.rs b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/uploaded_video_row.rs new file mode 100644 index 0000000000..64d27b87cb --- /dev/null +++ b/crates/schema/database/mysql_queries/src/queries/uploaded_videos/uploaded_video_row.rs @@ -0,0 +1,28 @@ +use chrono::{DateTime, Utc}; + +use enums::by_table::uploaded_videos::uploaded_video_detected_model_family::UploadedVideoDetectedModelFamily; +use enums::by_table::uploaded_videos::uploaded_video_detected_model_type::UploadedVideoDetectedModelType; +use tokens::tokens::uploaded_videos::UploadedVideoToken; + +/// A materialized `uploaded_videos` row (minus the internal `id`). +#[derive(Debug, Clone)] +pub struct UploadedVideoRow { + pub token: UploadedVideoToken, + + pub sha1_checksum: String, + pub filesize_bytes: u32, + + pub maybe_width: Option, + pub maybe_height: Option, + pub maybe_resolution: Option, + + pub maybe_detected_model_family: Option, + pub maybe_detected_model_type: Option, + pub maybe_report: Option, + + pub upload_ip_address: String, + pub maybe_updated_ip_address: Option, + + pub created_at: DateTime, + pub updated_at: DateTime, +}