diff --git a/crates/lib/database_queries/src/queries/model_categories/list_categories_query_builder.rs b/crates/lib/database_queries/src/queries/model_categories/list_categories_query_builder.rs index 9c2235d402..b5d119e3d7 100644 --- a/crates/lib/database_queries/src/queries/model_categories/list_categories_query_builder.rs +++ b/crates/lib/database_queries/src/queries/model_categories/list_categories_query_builder.rs @@ -3,7 +3,8 @@ use chrono::{DateTime, Utc}; use container_common::anyhow_result::AnyhowResult; use crate::helpers::boolean_converters::{i8_to_bool, nullable_i8_to_optional_bool}; use log::{warn, info}; -use sqlx::MySqlPool; +use sqlx::{MySql, MySqlPool}; +use sqlx::pool::PoolConnection; /// List of categories /// This is *NOT* paginated, as that defeats the purpose of having a category system. @@ -118,12 +119,21 @@ impl ListCategoriesQueryBuilder { } /// Perform the query based on the set predicates. + #[deprecated = "Use the PoolConnection method instead of the MySqlPool one."] pub async fn perform_query( &self, - mysql_pool: &MySqlPool + mysql_pool: &MySqlPool, ) -> AnyhowResult { + let mut mysql_connection = mysql_pool.acquire().await?; + self.perform_query_using_connection(&mut mysql_connection).await + } - let internal_results = self.perform_internal_query(mysql_pool).await?; + /// Perform the query based on the set predicates. + pub async fn perform_query_using_connection( + &self, + mysql_connection: &mut PoolConnection, + ) -> AnyhowResult { + let internal_results = self.perform_internal_query(mysql_connection).await?; let categories = internal_results .into_iter() @@ -158,7 +168,7 @@ impl ListCategoriesQueryBuilder { /// Perform the query based on the set predicates. async fn perform_internal_query( &self, - mysql_pool: &MySqlPool + mysql_connection: &mut PoolConnection ) -> AnyhowResult> { let query = self.build_query_string(); @@ -174,7 +184,7 @@ impl ListCategoriesQueryBuilder { query = query.bind(model_type); } - let mut results = query.fetch_all(mysql_pool) + let mut results = query.fetch_all(mysql_connection) .await?; Ok(results) diff --git a/crates/lib/database_queries/src/queries/tts/stats/calculate_tts_model_leaderboard.rs b/crates/lib/database_queries/src/queries/tts/stats/calculate_tts_model_leaderboard.rs index 0f5b4a5e86..74876af238 100644 --- a/crates/lib/database_queries/src/queries/tts/stats/calculate_tts_model_leaderboard.rs +++ b/crates/lib/database_queries/src/queries/tts/stats/calculate_tts_model_leaderboard.rs @@ -1,7 +1,8 @@ use anyhow::anyhow; use container_common::anyhow_result::AnyhowResult; use log::warn; -use sqlx::MySqlPool; +use sqlx::{MySql, MySqlPool}; +use sqlx::pool::PoolConnection; #[derive(Serialize)] pub struct TtsLeaderboardRecordForList { @@ -23,7 +24,7 @@ struct TtsLeaderboardRecordForListRaw { // NB: This may need to become an offline query if it is expensive. pub async fn calculate_tts_model_leaderboard( - mysql_pool: &MySqlPool + mysql_pool: &mut PoolConnection ) -> AnyhowResult> { // NB: We're not requiring "is_public_listing_approved IS TRUE" for TTS models diff --git a/crates/lib/database_queries/src/queries/tts/tts_category_assignments/list_assigned_tts_categories_query_builder.rs b/crates/lib/database_queries/src/queries/tts/tts_category_assignments/list_assigned_tts_categories_query_builder.rs index eb3e225169..38c753adf6 100644 --- a/crates/lib/database_queries/src/queries/tts/tts_category_assignments/list_assigned_tts_categories_query_builder.rs +++ b/crates/lib/database_queries/src/queries/tts/tts_category_assignments/list_assigned_tts_categories_query_builder.rs @@ -3,7 +3,8 @@ use chrono::{DateTime, Utc}; use container_common::anyhow_result::AnyhowResult; use crate::helpers::boolean_converters::{i8_to_bool, nullable_i8_to_optional_bool}; use log::{warn, info}; -use sqlx::MySqlPool; +use sqlx::{MySql, MySqlPool}; +use sqlx::pool::PoolConnection; /// List of assigned categories for a TTS model /// This is *NOT* paginated, as that defeats the purpose of having a category system. @@ -94,12 +95,22 @@ impl ListAssignedTtsCategoriesQueryBuilder { } /// Perform the query based on the set predicates. + #[deprecated = "Use the PoolConnection method instead of the MySqlPool one."] pub async fn perform_query( &self, mysql_pool: &MySqlPool ) -> AnyhowResult { + let mut mysql_connection = mysql_pool.acquire().await?; + self.perform_query_by_connection(&mut mysql_connection).await + } - let internal_results = self.perform_internal_query(mysql_pool).await?; + /// Perform the query based on the set predicates. + pub async fn perform_query_by_connection( + &self, + mysql_connection: &mut PoolConnection + ) -> AnyhowResult { + + let internal_results = self.perform_internal_query(mysql_connection).await?; let categories = internal_results .into_iter() @@ -137,7 +148,7 @@ impl ListAssignedTtsCategoriesQueryBuilder { /// Perform the query based on the set predicates. async fn perform_internal_query( &self, - mysql_pool: &MySqlPool + mysql_connection: &mut PoolConnection ) -> AnyhowResult> { let query = self.build_query_string(); @@ -148,7 +159,7 @@ impl ListAssignedTtsCategoriesQueryBuilder { // NB: Model token is always used for scoping. query = query.bind(&self.scope_tts_model_token); - let mut results = query.fetch_all(mysql_pool) + let mut results = query.fetch_all(mysql_connection) .await?; Ok(results) diff --git a/crates/lib/database_queries/src/queries/tts/tts_models/get_tts_model.rs b/crates/lib/database_queries/src/queries/tts/tts_models/get_tts_model.rs index 70933e4478..cae563b19c 100644 --- a/crates/lib/database_queries/src/queries/tts/tts_models/get_tts_model.rs +++ b/crates/lib/database_queries/src/queries/tts/tts_models/get_tts_model.rs @@ -10,7 +10,8 @@ use crate::column_types::record_visibility::RecordVisibility; use crate::column_types::vocoder_type::VocoderType; use crate::helpers::boolean_converters::i8_to_bool; use log::warn; -use sqlx::MySqlPool; +use sqlx::pool::PoolConnection; +use sqlx::{MySql, MySqlPool}; // FIXME: This is the old style of query scoping and shouldn't be copied. // The moderator-only fields are good practice, though. @@ -76,16 +77,26 @@ pub struct TtsModelModeratorFields { // FIXME: This is the old style of query scoping and shouldn't be copied. // The moderator-only fields are good practice, though. + pub async fn get_tts_model_by_token( tts_model_token: &str, can_see_deleted: bool, mysql_pool: &MySqlPool ) -> AnyhowResult> { + let mut connection = mysql_pool.acquire().await?; + get_tts_model_by_token_using_connection(tts_model_token, can_see_deleted, &mut connection).await +} + +pub async fn get_tts_model_by_token_using_connection( + tts_model_token: &str, + can_see_deleted: bool, + mysql_connection: &mut PoolConnection +) -> AnyhowResult> { let maybe_record = if can_see_deleted { - select_including_deleted(tts_model_token, mysql_pool).await + select_including_deleted(tts_model_token, mysql_connection).await } else { - select_without_deleted(tts_model_token, mysql_pool).await + select_without_deleted(tts_model_token, mysql_connection).await }; let model : InternalTtsModelRecordRaw = match maybe_record { @@ -161,7 +172,7 @@ pub async fn get_tts_model_by_token( async fn select_including_deleted( tts_model_token: &str, - mysql_pool: &MySqlPool + mysql_connection: &mut PoolConnection ) -> Result { sqlx::query_as!( InternalTtsModelRecordRaw, @@ -224,13 +235,13 @@ WHERE tts.token = ? "#, tts_model_token ) - .fetch_one(mysql_pool) + .fetch_one(mysql_connection) .await // TODO: This will return error if it doesn't exist } async fn select_without_deleted( tts_model_token: &str, - mysql_pool: &MySqlPool + mysql_connection: &mut PoolConnection ) -> Result { sqlx::query_as!( InternalTtsModelRecordRaw, @@ -296,7 +307,7 @@ WHERE "#, tts_model_token ) - .fetch_one(mysql_pool) + .fetch_one(mysql_connection) .await // TODO: This will return error if it doesn't exist } diff --git a/crates/lib/database_queries/src/queries/w2l/stats/calculate_w2l_template_leaderboard.rs b/crates/lib/database_queries/src/queries/w2l/stats/calculate_w2l_template_leaderboard.rs index 52ed9d5979..4966960274 100644 --- a/crates/lib/database_queries/src/queries/w2l/stats/calculate_w2l_template_leaderboard.rs +++ b/crates/lib/database_queries/src/queries/w2l/stats/calculate_w2l_template_leaderboard.rs @@ -1,7 +1,8 @@ use anyhow::anyhow; use container_common::anyhow_result::AnyhowResult; use log::warn; -use sqlx::MySqlPool; +use sqlx::{MySql, MySqlPool}; +use sqlx::pool::PoolConnection; #[derive(Serialize)] pub struct W2lLeaderboardRecordForList { @@ -23,7 +24,7 @@ struct W2lLeaderboardRecordForListRaw { // NB: This may need to become an offline query if it is expensive. pub async fn calculate_w2l_template_leaderboard( - mysql_pool: &MySqlPool + mysql_pool: &mut PoolConnection ) -> AnyhowResult> { // NB: We're requiring "is_public_listing_approved IS TRUE" for W2L templates! diff --git a/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_categories.rs b/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_categories.rs index 5ccf74d83f..c7968cc39c 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_categories.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_categories.rs @@ -1,27 +1,17 @@ -use actix_http::Error; -use actix_http::http::header; -use actix_web::HttpResponseBuilder; -use actix_web::cookie::Cookie; +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + use actix_web::error::ResponseError; use actix_web::http::StatusCode; -use actix_web::web::{Path, Json}; -use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use actix_web::{web, HttpResponse, HttpRequest}; use chrono::{DateTime, Utc}; -use crate::http_server::web_utils::ip_address::get_request_ip; -use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; -use crate::http_server::web_utils::response_success_helpers::simple_json_success; use crate::server_state::ServerState; -use crate::util::email_to_gravatar::email_to_gravatar; -use crate::util::markdown_to_html::markdown_to_html; use database_queries::queries::model_categories::list_categories_query_builder::ListCategoriesQueryBuilder; use http_server_common::response::serialize_as_json_error::serialize_as_json_error; use lexical_sort::natural_lexical_cmp; -use log::{info, warn, log, error}; -use regex::Regex; -use sqlx::MySqlPool; -use sqlx::error::DatabaseError; -use sqlx::error::Error::Database; -use sqlx::mysql::MySqlDatabaseError; +use log::{info, warn, error}; use std::fmt; use std::sync::Arc; @@ -96,7 +86,7 @@ impl fmt::Display for ListTtsCategoriesError { // =============== Handler =============== pub async fn list_tts_categories_handler( - http_request: HttpRequest, + _http_request: HttpRequest, server_state: web::Data>) -> Result { let maybe_categories = server_state.caches.category_list.copy_without_bump_if_unexpired() @@ -111,13 +101,20 @@ pub async fn list_tts_categories_handler( categories }, None => { + let mut mysql_connection = server_state.mysql_pool.acquire() + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + ListTtsCategoriesError::ServerError + })?; + let query_builder = ListCategoriesQueryBuilder::new() .show_deleted(false) .show_unapproved(false) .scope_model_type(Some("tts")); let query_result = - query_builder.perform_query(&server_state.mysql_pool).await; + query_builder.perform_query_using_connection(&mut mysql_connection).await; let results = match query_result { Ok(results) => results, @@ -163,14 +160,13 @@ pub async fn list_tts_categories_handler( }, }; - // TODO: Cache results in Redis w/ TTL. let response = ListTtsCategoriesResponse { success: true, categories, }; let body = serde_json::to_string(&response) - .map_err(|e| ListTtsCategoriesError::ServerError)?; + .map_err(|_e| ListTtsCategoriesError::ServerError)?; Ok(HttpResponse::Ok() .content_type("application/json") diff --git a/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_model_assigned_categories.rs b/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_model_assigned_categories.rs index 3daff48f93..249c6ead70 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_model_assigned_categories.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/categories/list_tts_model_assigned_categories.rs @@ -1,23 +1,17 @@ -use actix_http::Error; -use actix_http::http::header; -use actix_web::HttpResponseBuilder; -use actix_web::cookie::Cookie; +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + use actix_web::error::ResponseError; use actix_web::http::StatusCode; -use actix_web::web::{Path, Json}; -use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use actix_web::web::Path; +use actix_web::{web, HttpResponse, HttpRequest}; use chrono::{DateTime, Utc}; -use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; -use crate::http_server::web_utils::response_success_helpers::simple_json_success; use crate::server_state::ServerState; use database_queries::queries::tts::tts_category_assignments::list_assigned_tts_categories_query_builder::ListAssignedTtsCategoriesQueryBuilder; use http_server_common::response::serialize_as_json_error::serialize_as_json_error; -use log::{info, warn, log}; -use regex::Regex; -use sqlx::MySqlPool; -use sqlx::error::DatabaseError; -use sqlx::error::Error::Database; -use sqlx::mysql::MySqlDatabaseError; +use log::warn; use std::fmt; use std::sync::Arc; @@ -100,9 +94,16 @@ pub async fn list_tts_model_assigned_categories_handler( path: Path, server_state: web::Data>) -> Result { + let mut mysql_connection = server_state.mysql_pool.acquire() + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + ListTtsModelAssignedCategoriesError::ServerError + })?; + let maybe_user_session = server_state .session_checker - .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .maybe_get_user_session_from_connection(&http_request, &mut mysql_connection) .await .map_err(|e| { warn!("Session checker error: {:?}", e); @@ -120,7 +121,7 @@ pub async fn list_tts_model_assigned_categories_handler( .show_unapproved(is_mod); let query_result = - query_builder.perform_query(&server_state.mysql_pool).await; + query_builder.perform_query_by_connection(&mut mysql_connection).await; let results = match query_result { Ok(results) => results, @@ -130,21 +131,21 @@ pub async fn list_tts_model_assigned_categories_handler( } }; - let mut categories = results.categories.iter() + let mut categories = results.categories.into_iter() .map(|c| { DisplayCategory { - category_token: c.category_token.clone(), - model_type: c.model_type.clone(), - maybe_super_category_token: c.maybe_super_category_token.clone(), + category_token: c.category_token, + model_type: c.model_type, + maybe_super_category_token: c.maybe_super_category_token, can_directly_have_models: c.can_directly_have_models, can_have_subcategories: c.can_have_subcategories, can_only_mods_apply: c.can_only_mods_apply, name: c.name.clone(), - maybe_dropdown_name:c.maybe_dropdown_name.clone(), - is_mod_approved: c.is_mod_approved.clone(), - category_created_at: c.category_created_at.clone(), - category_updated_at: c.category_updated_at.clone(), - category_deleted_at: c.category_deleted_at.clone(), + maybe_dropdown_name:c.maybe_dropdown_name, + is_mod_approved: c.is_mod_approved, + category_created_at: c.category_created_at, + category_updated_at: c.category_updated_at, + category_deleted_at: c.category_deleted_at, } }) .collect::>(); @@ -158,7 +159,7 @@ pub async fn list_tts_model_assigned_categories_handler( }; let body = serde_json::to_string(&response) - .map_err(|e| ListTtsModelAssignedCategoriesError::ServerError)?; + .map_err(|_e| ListTtsModelAssignedCategoriesError::ServerError)?; Ok(HttpResponse::Ok() .content_type("application/json") diff --git a/crates/service/storyteller_web/src/http_server/endpoints/leaderboard/get_leaderboard.rs b/crates/service/storyteller_web/src/http_server/endpoints/leaderboard/get_leaderboard.rs index de65564b56..e01c5135f1 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/leaderboard/get_leaderboard.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/leaderboard/get_leaderboard.rs @@ -1,24 +1,18 @@ -use actix_http::Error; -use actix_http::http::header; -use actix_web::HttpResponseBuilder; -use actix_web::cookie::Cookie; +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + use actix_web::error::ResponseError; use actix_web::http::StatusCode; -use actix_web::{Responder, web, HttpResponse, error, HttpRequest, HttpMessage}; -use chrono::{DateTime, Utc}; -use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use actix_web::{web, HttpResponse, HttpRequest}; use crate::http_server::web_utils::serialize_as_json_error::serialize_as_json_error; use crate::server_state::ServerState; use database_queries::queries::tts::stats::calculate_tts_model_leaderboard::TtsLeaderboardRecordForList; use database_queries::queries::tts::stats::calculate_tts_model_leaderboard::calculate_tts_model_leaderboard; use database_queries::queries::w2l::stats::calculate_w2l_template_leaderboard::W2lLeaderboardRecordForList; use database_queries::queries::w2l::stats::calculate_w2l_template_leaderboard::calculate_w2l_template_leaderboard; -use log::{info, warn, log}; -use regex::Regex; -use sqlx::MySqlPool; -use sqlx::error::DatabaseError; -use sqlx::error::Error::Database; -use sqlx::mysql::MySqlDatabaseError; +use log::warn; use std::fmt; use std::sync::Arc; @@ -71,15 +65,34 @@ impl fmt::Display for LeaderboardErrorResponse { } pub async fn leaderboard_handler( - http_request: HttpRequest, + _http_request: HttpRequest, server_state: web::Data> ) -> Result { + // TODO: There has to be a better way of doing this in parallel. + // Some more intelligent DB connection pool. (What did jOOQ in Java do? Surely not this insanity!) + let mysql_connection_1 = server_state.mysql_pool.acquire(); + let mysql_connection_2 = server_state.mysql_pool.acquire(); + + let mut mysql_connection_1 = mysql_connection_1 + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + LeaderboardErrorResponse::server_error() + })?; + + let mut mysql_connection_2 = mysql_connection_2 + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + LeaderboardErrorResponse::server_error() + })?; + let maybe_tts_results = - calculate_tts_model_leaderboard(&server_state.mysql_pool); + calculate_tts_model_leaderboard(&mut mysql_connection_1); let maybe_w2l_results = - calculate_w2l_template_leaderboard(&server_state.mysql_pool); + calculate_w2l_template_leaderboard(&mut mysql_connection_2); let tts_results = match maybe_tts_results.await { Ok(results) => results, @@ -104,7 +117,7 @@ pub async fn leaderboard_handler( }; let body = serde_json::to_string(&response) - .map_err(|e| LeaderboardErrorResponse::server_error())?; + .map_err(|_e| LeaderboardErrorResponse::server_error())?; Ok(HttpResponse::Ok() .content_type("application/json") diff --git a/crates/service/storyteller_web/src/http_server/endpoints/tts/get_tts_model.rs b/crates/service/storyteller_web/src/http_server/endpoints/tts/get_tts_model.rs index 31e6272a3b..89019199df 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/tts/get_tts_model.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/tts/get_tts_model.rs @@ -8,11 +8,11 @@ use actix_web::http::StatusCode; use actix_web::web::Path; use actix_web::{web, HttpResponse, HttpRequest}; use chrono::{DateTime, Utc}; -use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; use crate::server_state::ServerState; use database_queries::column_types::record_visibility::RecordVisibility; use database_queries::column_types::vocoder_type::VocoderType; -use database_queries::queries::tts::tts_models::get_tts_model::get_tts_model_by_token; +use database_queries::queries::tts::tts_models::get_tts_model::get_tts_model_by_token_using_connection; +use http_server_common::response::serialize_as_json_error::serialize_as_json_error; use log::warn; use std::fmt; use std::sync::Arc; @@ -116,7 +116,7 @@ pub struct TtsModelModeratorFieldInfo { // =============== Error Response =============== -#[derive(Debug)] +#[derive(Debug, Serialize)] pub enum GetTtsModelError { ServerError, NotFound, @@ -125,18 +125,13 @@ pub enum GetTtsModelError { impl ResponseError for GetTtsModelError { fn status_code(&self) -> StatusCode { match *self { - GetTtsModelError::ServerError=> StatusCode::INTERNAL_SERVER_ERROR, + GetTtsModelError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, GetTtsModelError::NotFound => StatusCode::NOT_FOUND, } } fn error_response(&self) -> HttpResponse { - let error_reason = match self { - GetTtsModelError::ServerError => "server error".to_string(), - GetTtsModelError::NotFound => "not found".to_string(), - }; - - to_simple_json_error(&error_reason, self.status_code()) + serialize_as_json_error(self) } } @@ -154,9 +149,16 @@ pub async fn get_tts_model_handler( path: Path, server_state: web::Data>) -> Result { + let mut mysql_connection = server_state.mysql_pool.acquire() + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + GetTtsModelError::ServerError + })?; + let maybe_user_session = server_state .session_checker - .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .maybe_get_user_session_from_connection(&http_request, &mut mysql_connection) .await .map_err(|e| { warn!("Session checker error: {:?}", e); @@ -176,10 +178,10 @@ pub async fn get_tts_model_handler( || user_session.can_edit_other_users_tts_models; } - let model_query_result = get_tts_model_by_token( + let model_query_result = get_tts_model_by_token_using_connection( &path.token, show_deleted_models, - &server_state.mysql_pool + &mut mysql_connection, ).await; let mut model = match model_query_result { diff --git a/crates/service/storyteller_web/src/http_server/endpoints/users/session_info.rs b/crates/service/storyteller_web/src/http_server/endpoints/users/session_info.rs index f25deca3e4..9fb1e4792d 100644 --- a/crates/service/storyteller_web/src/http_server/endpoints/users/session_info.rs +++ b/crates/service/storyteller_web/src/http_server/endpoints/users/session_info.rs @@ -1,20 +1,15 @@ -use actix_http::Error; -use actix_http::http::header; -use actix_web::cookie::Cookie; -use actix_web::HttpResponseBuilder; +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + use actix_web::error::ResponseError; use actix_web::http::StatusCode; -use actix_web::{Responder, web, HttpResponse, error, HttpRequest, HttpMessage}; -use crate::AnyhowResult; +use actix_web::{web, HttpResponse, HttpRequest}; use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; use crate::server_state::ServerState; -use derive_more::{Display, Error}; -use log::{info, warn, log}; -use regex::Regex; -use sqlx::MySqlPool; -use sqlx::error::DatabaseError; -use sqlx::error::Error::Database; -use sqlx::mysql::MySqlDatabaseError; +use log::warn; +use std::fmt; use std::sync::Arc; #[derive(Serialize, Copy, Clone)] @@ -79,7 +74,7 @@ pub struct SessionInfoSuccessResponse { pub user: Option, } -#[derive(Debug, Display)] +#[derive(Debug)] pub enum SessionInfoError { ServerError, } @@ -100,13 +95,27 @@ impl ResponseError for SessionInfoError { } } +// NB: Not using derive_more::Display since Clion doesn't understand it. +impl fmt::Display for SessionInfoError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + pub async fn session_info_handler( http_request: HttpRequest, server_state: web::Data>) -> Result { + let mut mysql_connection = server_state.mysql_pool.acquire() + .await + .map_err(|e| { + warn!("Could not acquire DB pool: {:?}", e); + SessionInfoError::ServerError + })?; + let maybe_user_session = server_state .session_checker - .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .maybe_get_user_session_from_connection(&http_request, &mut mysql_connection) .await .map_err(|e| { warn!("Session checker error: {:?}", e); @@ -168,7 +177,7 @@ pub async fn session_info_handler( }; let body = serde_json::to_string(&response) - .map_err(|e| SessionInfoError::ServerError)?; + .map_err(|_e| SessionInfoError::ServerError)?; Ok(HttpResponse::Ok() .content_type("application/json") diff --git a/crates/service/storyteller_web/src/http_server/web_utils/session_checker.rs b/crates/service/storyteller_web/src/http_server/web_utils/session_checker.rs index c49e3cfbb6..aa4e2aa247 100644 --- a/crates/service/storyteller_web/src/http_server/web_utils/session_checker.rs +++ b/crates/service/storyteller_web/src/http_server/web_utils/session_checker.rs @@ -1,13 +1,18 @@ +// NB: Incrementally getting rid of build warnings... +#![forbid(unused_imports)] +#![forbid(unused_mut)] +#![forbid(unused_variables)] + use actix_web::HttpRequest; use anyhow::anyhow; use crate::AnyhowResult; use crate::http_server::web_utils::cookie_manager::CookieManager; use database_queries::column_types::record_visibility::RecordVisibility; use database_queries::helpers::boolean_converters::{nullable_i8_to_optional_bool, i8_to_bool}; -use log::{info, warn}; -use sqlx::{MySqlPool, MySql}; +use log::warn; use sqlx::error::Error::RowNotFound; use sqlx::pool::PoolConnection; +use sqlx::{MySqlPool, MySql}; #[derive(Clone)] pub struct SessionChecker { @@ -165,18 +170,22 @@ AND deleted_at IS NULL } } - //#[deprecated = "Use the PoolConnection method"] + #[deprecated = "Use the PoolConnection method instead of the MySqlPool one."] pub async fn maybe_get_user_session( &self, request: &HttpRequest, - pool: &MySqlPool) -> AnyhowResult> + pool: &MySqlPool, + ) -> AnyhowResult> { let mut connection = pool.acquire().await?; self.maybe_get_user_session_from_connection(request, &mut connection).await } - pub async fn maybe_get_user_session_from_connection(&self, request: &HttpRequest, pool: &mut PoolConnection) - -> AnyhowResult> + pub async fn maybe_get_user_session_from_connection( + &self, + request: &HttpRequest, + mysql_connection: &mut PoolConnection, + ) -> AnyhowResult> { let session_token = match self.cookie_manager.decode_session_token_from_request(request)? { @@ -240,7 +249,7 @@ WHERE user_sessions.token = ? "#, session_token.to_string(), ) - .fetch_one(pool) + .fetch_one(mysql_connection) .await; // TODO: This will return error if it doesn't exist match maybe_user_record {