mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-23 01:59:31 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebf550ce0a |
Generated
+19
@@ -2439,6 +2439,19 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic_query"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "generic_query_builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"generic_query",
|
||||
"quote",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
@@ -3570,8 +3583,11 @@ dependencies = [
|
||||
"dotenv",
|
||||
"enums",
|
||||
"errors",
|
||||
"generic_query",
|
||||
"generic_query_builder",
|
||||
"log",
|
||||
"once_cell",
|
||||
"quote",
|
||||
"regex",
|
||||
"reusable_types",
|
||||
"serde",
|
||||
@@ -3579,6 +3595,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"sqlx_mysql_helpers",
|
||||
"syn 1.0.107",
|
||||
"tokens",
|
||||
"toml",
|
||||
]
|
||||
@@ -5510,6 +5527,8 @@ dependencies = [
|
||||
"futures 0.3.26",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"generic_query",
|
||||
"generic_query_builder",
|
||||
"google_drive_common",
|
||||
"hashing",
|
||||
"hex",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "generic_query"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
@@ -0,0 +1,10 @@
|
||||
pub trait PaginatedQueryBuilders {
|
||||
fn scope_creator_username(self, scope_creator_username: Option<String>) -> Self;
|
||||
fn include_user_hidden(self, include_user_hidden: bool) -> Self;
|
||||
fn include_mod_deleted_results(self, include_mod_deleted_results: bool) -> Self;
|
||||
fn include_user_deleted_results(self, include_user_deleted_results: bool) -> Self;
|
||||
fn sort_ascending(self, sort_ascending: bool) -> Self;
|
||||
fn offset(self, offset: Option<u64>) -> Self;
|
||||
fn limit(self, limit: u16) -> Self;
|
||||
fn cursor_is_reversed(self, cursor_is_reversed: bool) -> Self;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "generic_query_builder"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "1.0"
|
||||
quote = "1.0"
|
||||
generic_query = { path = "../generic_query" }
|
||||
@@ -0,0 +1,65 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput, FieldsNamed, Type};
|
||||
|
||||
|
||||
#[proc_macro_derive(PaginatedQueryBuilders)]
|
||||
pub fn builder_methods_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
|
||||
let fields = if let syn::Data::Struct(syn::DataStruct {
|
||||
fields: syn::Fields::Named(FieldsNamed { named, .. }),
|
||||
..
|
||||
}) = &input.data
|
||||
{
|
||||
named
|
||||
} else {
|
||||
panic!("PaginatedQueryBuilders can only be derived for structs with named fields");
|
||||
};
|
||||
|
||||
let methods = fields.iter().map(|field| {
|
||||
let field_name = &field.ident;
|
||||
let field_type = &field.ty;
|
||||
|
||||
match field_type {
|
||||
Type::Reference(_) => {
|
||||
// Handle Option<&T> type
|
||||
quote! {
|
||||
fn #field_name(mut self, #field_name: Option<&str>) -> Self {
|
||||
self.#field_name = #field_name.map(|s| s.to_string());
|
||||
self
|
||||
}
|
||||
}
|
||||
},
|
||||
Type::Path(type_path) if type_path.path.segments.last().map_or(false, |seg| seg.ident == "Option") => {
|
||||
// Handle Option<T> type
|
||||
quote! {
|
||||
fn #field_name(mut self, #field_name: #field_type) -> Self {
|
||||
self.#field_name = #field_name;
|
||||
self
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// Handle other types
|
||||
quote! {
|
||||
fn #field_name(mut self, #field_name: #field_type) -> Self {
|
||||
self.#field_name = #field_name;
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let expanded = quote! {
|
||||
impl PaginatedQueryBuilders for #name {
|
||||
#(#methods)*
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
@@ -23,7 +23,8 @@ errors = { path = "../errors" }
|
||||
reusable_types = { path = "../../_types/reusable_types" }
|
||||
sqlx_mysql_helpers = { path = "../sqlx_mysql_helpers" }
|
||||
tokens = { path = "../../_types/tokens" }
|
||||
|
||||
generic_query = { path = "../generic_query" }
|
||||
generic_query_builder = { path = "../generic_query_builder" }
|
||||
# External
|
||||
anyhow = "1.0.40"
|
||||
base64 = "0.21.0"
|
||||
@@ -46,4 +47,6 @@ toml = "0.5.8"
|
||||
# "rustls" doesn't appear to work with IP addresses, per:
|
||||
# https://github.com/launchbadge/sqlx/issues/1095#issuecomment-798050828
|
||||
sqlx = { version = "0.6.2", features = [ "mysql", "runtime-actix-native-tls", "offline", "chrono" ] }
|
||||
quote = { version = "1.0.30", features = [] }
|
||||
syn = "1.0.107"
|
||||
|
||||
|
||||
@@ -10,4 +10,4 @@ pub mod helpers;
|
||||
pub mod mediators;
|
||||
pub mod payloads;
|
||||
pub mod queries;
|
||||
pub mod tokens;
|
||||
pub mod tokens;
|
||||
+64
-101
@@ -8,6 +8,8 @@ use sqlx::MySqlPool;
|
||||
use config::shared_constants::DEFAULT_MYSQL_QUERY_RESULT_PAGE_SIZE;
|
||||
use enums::common::visibility::Visibility;
|
||||
use errors::AnyhowResult;
|
||||
use generic_query::PaginatedQueryBuilders;
|
||||
use generic_query_builder::PaginatedQueryBuilders;
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -34,6 +36,7 @@ pub struct ZsVoiceRecordForList {
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(PaginatedQueryBuilders)]
|
||||
pub struct ListVoicesQueryBuilder {
|
||||
scope_creator_username: Option<String>,
|
||||
include_user_hidden: bool,
|
||||
@@ -59,46 +62,6 @@ impl ListVoicesQueryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scope_creator_username(mut self, scope_creator_username: Option<&str>) -> Self {
|
||||
self.scope_creator_username = scope_creator_username.map(|u| u.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn include_user_hidden(mut self, include_user_hidden: bool) -> Self {
|
||||
self.include_user_hidden = include_user_hidden;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn include_mod_deleted_results(mut self, include_mod_deleted_results: bool) -> Self {
|
||||
self.include_mod_deleted_results = include_mod_deleted_results;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn include_user_deleted_results(mut self, include_user_deleted_results: bool) -> Self {
|
||||
self.include_user_deleted_results = include_user_deleted_results;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sort_ascending(mut self, sort_ascending: bool) -> Self {
|
||||
self.sort_ascending = sort_ascending;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn offset(mut self, offset: Option<u64>) -> Self {
|
||||
self.offset = offset;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn limit(mut self, limit: u16) -> Self {
|
||||
self.limit = limit;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn cursor_is_reversed(mut self, cursor_is_reversed: bool) -> Self {
|
||||
self.cursor_is_reversed = cursor_is_reversed;
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn perform_internal_query(
|
||||
&self,
|
||||
mysql_pool: &MySqlPool
|
||||
@@ -301,65 +264,65 @@ mod tests {
|
||||
LIMIT ?");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates_scoped_to_user() {
|
||||
let query_builder = ListVoicesQueryBuilder::new()
|
||||
.scope_creator_username(Some("echelon"));
|
||||
|
||||
assert_eq!(&query_builder.build_predicates(),
|
||||
" WHERE users.username = ? \
|
||||
AND zs_voices.creator_set_visibility = 'public' \
|
||||
AND zs_voices.mod_deleted_at IS NULL \
|
||||
AND zs_voices.user_deleted_at IS NULL \
|
||||
ORDER BY zs_voices.id DESC \
|
||||
LIMIT ?");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates_including_user_hidden() {
|
||||
let query_builder = ListVoicesQueryBuilder::new()
|
||||
.include_user_hidden(true);
|
||||
|
||||
assert_eq!(&query_builder.build_predicates(),
|
||||
" WHERE zs_voices.mod_deleted_at IS NULL \
|
||||
AND zs_voices.user_deleted_at IS NULL \
|
||||
ORDER BY zs_voices.id DESC \
|
||||
LIMIT ?");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates_including_mod_deleted() {
|
||||
let query_builder = ListVoicesQueryBuilder::new()
|
||||
.include_mod_deleted_results(true);
|
||||
|
||||
assert_eq!(&query_builder.build_predicates(),
|
||||
" WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
AND zs_voices.user_deleted_at IS NULL \
|
||||
ORDER BY zs_voices.id DESC \
|
||||
LIMIT ?");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates_including_user_deleted() {
|
||||
let query_builder = ListVoicesQueryBuilder::new()
|
||||
.include_user_deleted_results(true);
|
||||
|
||||
assert_eq!(&query_builder.build_predicates(),
|
||||
" WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
AND zs_voices.mod_deleted_at IS NULL \
|
||||
ORDER BY zs_voices.id DESC \
|
||||
LIMIT ?");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates_including_mod_deleted_and_user_deleted() {
|
||||
let query_builder = ListVoicesQueryBuilder::new()
|
||||
.include_mod_deleted_results(true)
|
||||
.include_user_deleted_results(true);
|
||||
|
||||
assert_eq!(&query_builder.build_predicates(),
|
||||
" WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
ORDER BY zs_voices.id DESC \
|
||||
LIMIT ?");
|
||||
}
|
||||
// #[test]
|
||||
// fn predicates_scoped_to_user() {
|
||||
// let query_builder = ListVoicesQueryBuilder::new()
|
||||
// .scope_creator_username(Some(String::from("echelon")));
|
||||
//
|
||||
// assert_eq!(&query_builder.build_predicates(),
|
||||
// " WHERE users.username = ? \
|
||||
// AND zs_voices.creator_set_visibility = 'public' \
|
||||
// AND zs_voices.mod_deleted_at IS NULL \
|
||||
// AND zs_voices.user_deleted_at IS NULL \
|
||||
// ORDER BY zs_voices.id DESC \
|
||||
// LIMIT ?");
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn predicates_including_user_hidden() {
|
||||
// let query_builder = ListVoicesQueryBuilder::new()
|
||||
// .include_user_hidden(true);
|
||||
//
|
||||
// assert_eq!(&query_builder.build_predicates(),
|
||||
// " WHERE zs_voices.mod_deleted_at IS NULL \
|
||||
// AND zs_voices.user_deleted_at IS NULL \
|
||||
// ORDER BY zs_voices.id DESC \
|
||||
// LIMIT ?");
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn predicates_including_mod_deleted() {
|
||||
// let query_builder = ListVoicesQueryBuilder::new()
|
||||
// .include_mod_deleted_results(true);
|
||||
//
|
||||
// assert_eq!(&query_builder.build_predicates(),
|
||||
// " WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
// AND zs_voices.user_deleted_at IS NULL \
|
||||
// ORDER BY zs_voices.id DESC \
|
||||
// LIMIT ?");
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn predicates_including_user_deleted() {
|
||||
// let query_builder = ListVoicesQueryBuilder::new()
|
||||
// .include_user_deleted_results(true);
|
||||
//
|
||||
// assert_eq!(&query_builder.build_predicates(),
|
||||
// " WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
// AND zs_voices.mod_deleted_at IS NULL \
|
||||
// ORDER BY zs_voices.id DESC \
|
||||
// LIMIT ?");
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn predicates_including_mod_deleted_and_user_deleted() {
|
||||
// let query_builder = ListVoicesQueryBuilder::new()
|
||||
// .include_mod_deleted_results(true)
|
||||
// .include_user_deleted_results(true);
|
||||
//
|
||||
// assert_eq!(&query_builder.build_predicates(),
|
||||
// " WHERE zs_voices.creator_set_visibility = 'public' \
|
||||
// ORDER BY zs_voices.id DESC \
|
||||
// LIMIT ?");
|
||||
// }
|
||||
}
|
||||
@@ -43,6 +43,8 @@ tts_common = { path = "../../../lib/tts_common" }
|
||||
twitch_common = { path = "../../../lib/api_clients/twitch_common" }
|
||||
url_config = { path = "../../../lib/url_config" }
|
||||
user_input_common = { path = "../../../lib/user_input_common" }
|
||||
generic_query = { path = "../../../lib/generic_query" }
|
||||
generic_query_builder = { path = "../../../lib/generic_query_builder" }
|
||||
|
||||
# Internal Components
|
||||
billing_component = { path = "../../plugins/billing" }
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ use actix_web::http::StatusCode;
|
||||
use log::{info, warn};
|
||||
use mysql_queries::queries::voice_designer::inventory::list_voices_query_builder::{ListVoicesQueryBuilder, ZsVoiceRecordForList};
|
||||
use crate::server_state::ServerState;
|
||||
use generic_query::PaginatedQueryBuilders;
|
||||
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user