mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
generic over executor types
This commit is contained in:
Generated
+11
@@ -2101,6 +2101,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"sqlx_mysql_helpers",
|
||||
"tokens",
|
||||
"toml",
|
||||
]
|
||||
@@ -6322,6 +6323,14 @@ dependencies = [
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sqlx_mysql_helpers"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"errors",
|
||||
"sqlx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
@@ -7750,6 +7759,7 @@ dependencies = [
|
||||
"database_queries",
|
||||
"dotenv",
|
||||
"enums",
|
||||
"errors",
|
||||
"hmac 0.10.1",
|
||||
"http_server_common",
|
||||
"jwt",
|
||||
@@ -7767,6 +7777,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha2 0.9.5",
|
||||
"sqlx",
|
||||
"sqlx_mysql_helpers",
|
||||
"time 0.2.26",
|
||||
"tokens",
|
||||
"toml",
|
||||
|
||||
@@ -36,6 +36,7 @@ members = [
|
||||
"crates/lib/media",
|
||||
"crates/lib/redis_common",
|
||||
"crates/lib/sqlite_queries",
|
||||
"crates/lib/sqlx_mysql_helpers",
|
||||
"crates/lib/subprocess_common",
|
||||
"crates/lib/tts_common",
|
||||
"crates/lib/url_config",
|
||||
|
||||
@@ -21,6 +21,7 @@ container_common = { path = "../container_common" }
|
||||
enums = { path = "../../_types/enums" }
|
||||
errors = { path = "../errors" }
|
||||
reusable_types = { path = "../../_types/reusable_types" }
|
||||
sqlx_mysql_helpers = { path = "../sqlx_mysql_helpers" }
|
||||
tokens = { path = "../../_types/tokens" }
|
||||
|
||||
# External
|
||||
|
||||
+7
-8
@@ -5,8 +5,7 @@
|
||||
use anyhow::anyhow;
|
||||
use errors::AnyhowResult;
|
||||
use log::warn;
|
||||
use sqlx::MySql;
|
||||
use sqlx::pool::PoolConnection;
|
||||
use sqlx::{Executor, MySql};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct SessionRecord {
|
||||
@@ -14,12 +13,12 @@ pub struct SessionRecord {
|
||||
pub user_token: String,
|
||||
}
|
||||
|
||||
pub async fn get_user_session_by_token_light(
|
||||
mysql_connection: &mut PoolConnection<MySql>,
|
||||
pub async fn get_user_session_by_token_light<'e, 'c : 'e, E>(
|
||||
mysql_executor: E,
|
||||
session_token: &str,
|
||||
) -> AnyhowResult<Option<SessionRecord>> {
|
||||
|
||||
// NB: Lookup failure is Err(RowNotFound).
|
||||
) -> AnyhowResult<Option<SessionRecord>>
|
||||
where E: 'e + Executor<'c, Database = MySql>
|
||||
{
|
||||
let maybe_session_record = sqlx::query_as!(
|
||||
SessionRecord,
|
||||
r#"
|
||||
@@ -32,7 +31,7 @@ AND deleted_at IS NULL
|
||||
"#,
|
||||
session_token,
|
||||
)
|
||||
.fetch_one(mysql_connection)
|
||||
.fetch_one(mysql_executor)
|
||||
.await;
|
||||
|
||||
match maybe_session_record {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "sqlx_mysql_helpers"
|
||||
edition = "2018"
|
||||
version = "0.0.1"
|
||||
authors = [
|
||||
"Brandon Thomas <bt@brand.io>",
|
||||
"Brandon Thomas <echelon@gmail.com>",
|
||||
]
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "sqlx_mysql_helpers"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
# Internal
|
||||
errors = { path = "../errors" }
|
||||
|
||||
# MySql Database
|
||||
# "offline" supports typesafe builds without a live database
|
||||
# "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" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
# None yet
|
||||
@@ -0,0 +1,78 @@
|
||||
use sqlx::{MySql, MySqlPool};
|
||||
use sqlx::pool::PoolConnection;
|
||||
use errors::AnyhowResult;
|
||||
|
||||
/// Pass a handle to MySql without caring about the type.
|
||||
pub enum MySqlHandle {
|
||||
ConnectionPool(MySqlPool),
|
||||
Connection(PoolConnection<MySql>),
|
||||
}
|
||||
|
||||
/// Pass a handle to MySql without caring about the type.
|
||||
/// NB: The connection is typically owned, whereas the connection pool is not.
|
||||
pub enum MySqlHandleMixedRef<'a> {
|
||||
ConnectionPool(&'a MySqlPool),
|
||||
Connection(PoolConnection<MySql>),
|
||||
}
|
||||
|
||||
/// Pass a handle to MySql without caring about the type.
|
||||
pub enum MySqlHandleRef<'a> {
|
||||
ConnectionPool(&'a MySqlPool),
|
||||
Connection(&'a mut PoolConnection<MySql>),
|
||||
}
|
||||
|
||||
//impl MySqlHandle {
|
||||
// pub fn as_ref(&mut self) -> MySqlHandleRef {
|
||||
// match self {
|
||||
// Self::ConnectionPool(inner) => MySqlHandleRef::ConnectionPool(inner),
|
||||
// Self::Connection(inner) => MySqlHandleRef::Connection(inner),
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
impl <'a> MySqlHandleMixedRef<'a> {
|
||||
/// Consume the handle and return a connection.
|
||||
pub async fn to_discrete_connection(self) -> AnyhowResult<PoolConnection<MySql>> {
|
||||
match self {
|
||||
Self::Connection(connection) => Ok(connection),
|
||||
Self::ConnectionPool(pool) => Ok(pool.acquire().await?),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//impl <'a> MySqlHandleRef<'a> {
|
||||
// /// Consume the handle and return a connection.
|
||||
// pub async fn to_discrete_connection(self) -> AnyhowResult<()> {
|
||||
// let _r = match self {
|
||||
// Self::Connection(connection) => Ok(connection),
|
||||
// Self::ConnectionPool(pool) => {
|
||||
// let connection = pool.acquire().await?;
|
||||
// Ok(connection)
|
||||
// },
|
||||
// };
|
||||
//
|
||||
// Ok(())
|
||||
// }
|
||||
//}
|
||||
//
|
||||
///// Exists to hold ownership (if necessary)
|
||||
//pub struct MySqlConnectionWrapper<'a> {
|
||||
// maybe_owned: Option<PoolConnection<MySql>>,
|
||||
// reference: &'a mut PoolConnection<MySql>,
|
||||
//}
|
||||
|
||||
|
||||
|
||||
// TODO:
|
||||
//impl <'a> MySqlConnectionRef<'a> {
|
||||
// pub async fn get_pool_connection(&'a mut self) -> AnyhowResult<&'a PoolConnection<MySql>> {
|
||||
// match self {
|
||||
// MySqlConnectionRef::ConnectionPool(pool) => {
|
||||
// let connection = pool.acquire().await?;
|
||||
// Ok(connection)
|
||||
// }
|
||||
// MySqlConnectionRef::Connection(inner) => Ok(inner),
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,20 @@
|
||||
//! sqlx_mysql_helpers
|
||||
//!
|
||||
//! Collect reusable Sqlx functions and patterns, particularly for MySQL databases.
|
||||
//!
|
||||
|
||||
// Never allow these
|
||||
#![forbid(private_in_public)]
|
||||
#![forbid(unused_must_use)] // NB: It's unsafe to not close/check some things
|
||||
|
||||
// Okay to toggle
|
||||
#![forbid(unreachable_patterns)]
|
||||
#![forbid(unused_imports)]
|
||||
#![forbid(unused_mut)]
|
||||
#![forbid(unused_variables)]
|
||||
|
||||
// Always allow
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
pub mod any_connection;
|
||||
@@ -18,10 +18,12 @@ path = "src/lib.rs"
|
||||
container_common = { path = "../../../lib/container_common" }
|
||||
database_queries = { path = "../../../lib/database_queries" }
|
||||
enums = { path = "../../../_types/enums" }
|
||||
errors = { path = "../../../lib/errors" }
|
||||
http_server_common = { path = "../../../lib/http_server_common" }
|
||||
redis_caching = { path = "../../../lib/caching/redis_caching" }
|
||||
redis_common = { path = "../../../lib/redis_common" }
|
||||
reusable_types = { path = "../../../_types/reusable_types" }
|
||||
sqlx_mysql_helpers = { path = "../../../lib/sqlx_mysql_helpers" }
|
||||
tokens = { path = "../../../_types/tokens" }
|
||||
user_input_common = { path = "../../../lib/user_input_common" }
|
||||
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
// NB: Incrementally getting rid of build warnings...
|
||||
#![forbid(unused_imports)]
|
||||
#![forbid(unused_mut)]
|
||||
#![forbid(unused_variables)]
|
||||
//#![forbid(unused_imports)]
|
||||
//#![forbid(unused_mut)]
|
||||
//#![forbid(unused_variables)]
|
||||
|
||||
use actix_web::HttpRequest;
|
||||
use log::warn;
|
||||
use container_common::anyhow_result::AnyhowResult;
|
||||
use crate::utils::session_cookie_manager::SessionCookieManager;
|
||||
use crate::utils::user_session_extended::{UserSessionExtended, UserSessionPreferences, UserSessionPremiumPlanInfo, UserSessionRoleAndPermissions, UserSessionSubscriptionPlan, UserSessionUserDetails};
|
||||
use database_queries::queries::users::user_sessions::get_user_session_by_token::{get_user_session_by_token, SessionUserRecord};
|
||||
use database_queries::queries::users::user_sessions::get_user_session_by_token_light::{get_user_session_by_token_light, SessionRecord};
|
||||
use database_queries::queries::users::user_subscriptions::list_active_user_subscriptions::list_active_user_subscriptions;
|
||||
use log::warn;
|
||||
use redis_caching::redis_ttl_cache::{RedisTtlCache, RedisTtlCacheConnection};
|
||||
use sqlx::pool::PoolConnection;
|
||||
use sqlx::{MySqlPool, MySql};
|
||||
use redis_common::redis_cache_keys::RedisCacheKeys;
|
||||
use sqlx::pool::PoolConnection;
|
||||
use sqlx::{MySqlPool, MySql, Acquire, Executor};
|
||||
use sqlx_mysql_helpers::any_connection::MySqlHandleMixedRef;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SessionChecker {
|
||||
@@ -48,8 +49,8 @@ impl SessionChecker {
|
||||
pool: &MySqlPool
|
||||
) -> AnyhowResult<Option<SessionRecord>>
|
||||
{
|
||||
let mut connection = pool.acquire().await?;
|
||||
self.maybe_get_session_light_from_connection(request, &mut connection).await
|
||||
//let mysql_handle = MySqlHandleMixedRef::ConnectionPool(pool);
|
||||
self.do_session_light_lookup_and_cookie_decode(request, pool).await
|
||||
}
|
||||
|
||||
pub async fn maybe_get_session_light_from_connection(
|
||||
@@ -58,42 +59,42 @@ impl SessionChecker {
|
||||
mysql_connection: &mut PoolConnection<MySql>,
|
||||
) -> AnyhowResult<Option<SessionRecord>>
|
||||
{
|
||||
let session_token = match self.cookie_manager.decode_session_token_from_request(request)? {
|
||||
None => return Ok(None),
|
||||
Some(session_token) => session_token,
|
||||
};
|
||||
|
||||
get_user_session_by_token_light(mysql_connection, &session_token).await
|
||||
//let mysql_handle = MySqlHandleMixedRef::Connection(mysql_connection);
|
||||
self.do_session_light_lookup_and_cookie_decode(request, mysql_connection).await
|
||||
}
|
||||
|
||||
async fn maybe_get_session_light_from_connection_cached(
|
||||
async fn do_session_light_lookup_and_cookie_decode<'e, 'c : 'e, E>(
|
||||
&self,
|
||||
request: &HttpRequest,
|
||||
mysql_connection: &mut PoolConnection<MySql>,
|
||||
//mysql_handle: MySqlHandleMixedRef<'_>,
|
||||
mysql_executor: E,
|
||||
) -> AnyhowResult<Option<SessionRecord>>
|
||||
where E: 'e + Executor<'c, Database = MySql>
|
||||
{
|
||||
let session_token = match self.cookie_manager.decode_session_token_from_request(request)? {
|
||||
None => return Ok(None),
|
||||
Some(session_token) => session_token,
|
||||
};
|
||||
|
||||
self.do_session_light_lookup(mysql_connection, &session_token).await
|
||||
self.do_session_light_lookup(mysql_executor, &session_token).await
|
||||
}
|
||||
|
||||
async fn do_session_light_lookup(
|
||||
async fn do_session_light_lookup<'e, 'c : 'e, E>(
|
||||
&self,
|
||||
mysql_connection: &mut PoolConnection<MySql>,
|
||||
//mysql_handle: MySqlHandleMixedRef<'_>,
|
||||
mysql_executor: E,
|
||||
session_token: &str,
|
||||
) -> AnyhowResult<Option<SessionRecord>>
|
||||
where E: 'e + Executor<'c, Database = MySql>
|
||||
{
|
||||
match self.maybe_get_redis_cache_connection() {
|
||||
None => {
|
||||
get_user_session_by_token_light(mysql_connection, session_token).await
|
||||
get_user_session_by_token_light(mysql_executor, session_token).await
|
||||
}
|
||||
Some(mut redis_ttl_cache) => {
|
||||
let cache_key = RedisCacheKeys::session_record_light(session_token);
|
||||
redis_ttl_cache.lazy_load_if_not_cached(&cache_key, move || {
|
||||
get_user_session_by_token_light(mysql_connection, session_token)
|
||||
get_user_session_by_token_light(mysql_executor, session_token)
|
||||
}).await
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user