Refactored db directory
This commit is contained in:
@@ -29,6 +29,7 @@ jsonwebtoken = "9.0.0"
|
|||||||
redis = { version = "0.23.3", features = ["tokio-comp", "connection-manager", "r2d2"] }
|
redis = { version = "0.23.3", features = ["tokio-comp", "connection-manager", "r2d2"] }
|
||||||
base64 = "0.21.4"
|
base64 = "0.21.4"
|
||||||
rust-s3 = "0.33.0"
|
rust-s3 = "0.33.0"
|
||||||
|
minio = "0.1.0"
|
||||||
|
|
||||||
[dependencies.tokio]
|
[dependencies.tokio]
|
||||||
version = "1.32.0"
|
version = "1.32.0"
|
||||||
@@ -46,7 +47,7 @@ features = ["json", "rustls-tls"]
|
|||||||
[dependencies.diesel]
|
[dependencies.diesel]
|
||||||
version = "2.1.2"
|
version = "2.1.2"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["postgres", "32-column-tables", "serde_json", "r2d2", "with-deprecated"]
|
features = ["postgres", "chrono", "32-column-tables", "serde_json", "r2d2", "with-deprecated"]
|
||||||
|
|
||||||
[dependencies.serenity]
|
[dependencies.serenity]
|
||||||
version = "0.11.6"
|
version = "0.11.6"
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
role TEXT NOT NULL,
|
role TEXT NOT NULL,
|
||||||
first_name TEXT NOT NULL,
|
first_name TEXT NOT NULL,
|
||||||
last_name TEXT NOT NULL,
|
last_name TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
verified BOOLEAN NOT NULL DEFAULT FALSE
|
verified BOOLEAN NOT NULL DEFAULT FALSE
|
||||||
);
|
);
|
||||||
@@ -15,7 +15,8 @@ use siren::ServiceError;
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct TokenClaims {
|
struct TokenClaims {
|
||||||
sub: String, // Subject
|
sub: String, // Subject
|
||||||
token_uuid: String, // Issuer
|
token_uuid: String, // Token UUID
|
||||||
|
iss: String, // Issuer
|
||||||
exp: i64, // Expiration time
|
exp: i64, // Expiration time
|
||||||
iat: i64, // Issued At
|
iat: i64, // Issued At
|
||||||
nbf: i64 // Not Before
|
nbf: i64 // Not Before
|
||||||
@@ -73,6 +74,7 @@ pub fn generate_token(email: &str, ttl: i64, private_key: &str) -> Result<TokenD
|
|||||||
};
|
};
|
||||||
let claims = TokenClaims {
|
let claims = TokenClaims {
|
||||||
sub: token_details.email.clone(),
|
sub: token_details.email.clone(),
|
||||||
|
iss: "siren".to_string(),
|
||||||
token_uuid: token_details.token_uuid.to_string(),
|
token_uuid: token_details.token_uuid.to_string(),
|
||||||
exp: token_details.expires_in.unwrap(),
|
exp: token_details.expires_in.unwrap(),
|
||||||
iat: now.timestamp(),
|
iat: now.timestamp(),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use redis::Commands;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::db::schema::users;
|
use crate::storage::{schema::users, connection};
|
||||||
|
|
||||||
use super::{hash_password, verify_token};
|
use super::{hash_password, verify_token};
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ impl RegisterUser {
|
|||||||
role: "user".to_string(),
|
role: "user".to_string(),
|
||||||
first_name: self.first_name,
|
first_name: self.first_name,
|
||||||
last_name: self.last_name,
|
last_name: self.last_name,
|
||||||
|
updated_at: chrono::Utc::now().naive_utc(),
|
||||||
|
created_at: chrono::Utc::now().naive_utc(),
|
||||||
verified: false,
|
verified: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -46,12 +48,14 @@ pub struct QueryUser {
|
|||||||
pub role: String,
|
pub role: String,
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
pub last_name: String,
|
pub last_name: String,
|
||||||
|
pub updated_at: chrono::NaiveDateTime,
|
||||||
|
pub created_at: chrono::NaiveDateTime,
|
||||||
pub verified: bool,
|
pub verified: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueryUser {
|
impl QueryUser {
|
||||||
pub fn get_by_email(email: &str) -> Result<QueryUser, ServiceError> {
|
pub fn get_by_email(email: &str) -> Result<QueryUser, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
// Check if the user exists by email, case insensitive
|
// Check if the user exists by email, case insensitive
|
||||||
|
|
||||||
let user = users::table
|
let user = users::table
|
||||||
@@ -69,12 +73,14 @@ pub struct InsertUser {
|
|||||||
pub role: String,
|
pub role: String,
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
pub last_name: String,
|
pub last_name: String,
|
||||||
|
pub updated_at: chrono::NaiveDateTime,
|
||||||
|
pub created_at: chrono::NaiveDateTime,
|
||||||
pub verified: bool,
|
pub verified: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InsertUser {
|
impl InsertUser {
|
||||||
pub fn insert(user: Self) -> Result<QueryUser, ServiceError> {
|
pub fn insert(user: Self) -> Result<QueryUser, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let user = diesel::insert_into(users::table)
|
let user = diesel::insert_into(users::table)
|
||||||
.values(user)
|
.values(user)
|
||||||
.get_result(&mut conn)?;
|
.get_result(&mut conn)?;
|
||||||
@@ -141,7 +147,7 @@ impl FromRequest for JwtAuth {
|
|||||||
|
|
||||||
let access_token_uuid = uuid::Uuid::parse_str(&access_token_details.token_uuid.to_string()).unwrap();
|
let access_token_uuid = uuid::Uuid::parse_str(&access_token_details.token_uuid.to_string()).unwrap();
|
||||||
|
|
||||||
let mut conn = match crate::db::redis_connection() {
|
let mut conn = match crate::storage::redis_connection() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to get redis connection: {}", err);
|
error!("Failed to get redis connection: {}", err);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use redis::AsyncCommands;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::{auth::{LoginRequest, RegisterUser, InsertUser, QueryUser, verify_password, JwtAuth, verify_token, generate_access_token, generate_refresh_token}, db};
|
use crate::{auth::{LoginRequest, RegisterUser, InsertUser, QueryUser, verify_password, JwtAuth, verify_token, generate_access_token, generate_refresh_token}, storage};
|
||||||
|
|
||||||
#[post("/register")]
|
#[post("/register")]
|
||||||
async fn register(user: web::Json<RegisterUser>) -> HttpResponse {
|
async fn register(user: web::Json<RegisterUser>) -> HttpResponse {
|
||||||
@@ -58,7 +58,7 @@ async fn login(request: web::Json<LoginRequest>) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conn = match db::redis_async_connection().await {
|
let mut conn = match storage::redis_async_connection().await {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to get redis connection: {}", err);
|
error!("Failed to get redis connection: {}", err);
|
||||||
@@ -169,7 +169,7 @@ async fn refresh(req: HttpRequest) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conn = match db::redis_async_connection().await {
|
let mut conn = match storage::redis_async_connection().await {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to get redis connection: {}", err);
|
error!("Failed to get redis connection: {}", err);
|
||||||
@@ -292,7 +292,7 @@ async fn logout(req: HttpRequest, auth: JwtAuth) -> HttpResponse {
|
|||||||
Err(err) => return ResponseError::error_response(&err)
|
Err(err) => return ResponseError::error_response(&err)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conn = match db::redis_async_connection().await {
|
let mut conn = match storage::redis_async_connection().await {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to get redis connection: {}", err);
|
error!("Failed to get redis connection: {}", err);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use serde::{Serialize, Deserialize};
|
|||||||
use serenity::model::prelude::{GuildChannel, ChannelType};
|
use serenity::model::prelude::{GuildChannel, ChannelType};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::{AppState, bot::commands::audio::{play::play_track, join}, db::guilds::QueryGuild, auth::{JwtAuth, verify_role}};
|
use crate::{AppState, bot::commands::audio::{play::play_track, join}, storage::guilds::QueryGuild, auth::{JwtAuth, verify_role}};
|
||||||
|
|
||||||
#[get("/guilds")]
|
#[get("/guilds")]
|
||||||
async fn get_guilds(data: web::Data<Arc<AppState>>, auth: JwtAuth) -> HttpResponse {
|
async fn get_guilds(data: web::Data<Arc<AppState>>, auth: JwtAuth) -> HttpResponse {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use siren::ServiceError;
|
|||||||
use songbird::{EventHandler, Songbird};
|
use songbird::{EventHandler, Songbird};
|
||||||
|
|
||||||
use crate::bot::commands::audio::{leave, add_song, get_songbird};
|
use crate::bot::commands::audio::{leave, add_song, get_songbird};
|
||||||
use crate::db::guilds::QueryGuild;
|
use crate::storage::guilds::QueryGuild;
|
||||||
|
|
||||||
use super::{create_response, edit_response, join_by_user};
|
use super::{create_response, edit_response, join_by_user};
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use serenity::builder::CreateApplicationCommand;
|
|||||||
use serenity::model::application::interaction::application_command::ApplicationCommandInteraction;
|
use serenity::model::application::interaction::application_command::ApplicationCommandInteraction;
|
||||||
use songbird::Songbird;
|
use songbird::Songbird;
|
||||||
|
|
||||||
use crate::db::guilds::InsertGuild;
|
use crate::storage::guilds::InsertGuild;
|
||||||
|
|
||||||
use super::{get_songbird, create_response, edit_response};
|
use super::{get_songbird, create_response, edit_response};
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use serenity::model::gateway::Ready;
|
|||||||
use serenity::model::channel::Message;
|
use serenity::model::channel::Message;
|
||||||
use serenity::prelude::*;
|
use serenity::prelude::*;
|
||||||
|
|
||||||
use crate::db::guilds::InsertGuild;
|
use crate::storage::guilds::InsertGuild;
|
||||||
|
|
||||||
use super::commands;
|
use super::commands;
|
||||||
use super::commands::audio::create_response;
|
use super::commands::audio::create_response;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
pub mod backgrounds;
|
||||||
|
pub mod bestiary;
|
||||||
|
pub mod classes;
|
||||||
|
pub mod conditions;
|
||||||
|
pub mod feats;
|
||||||
|
pub mod items;
|
||||||
|
pub mod options;
|
||||||
|
pub mod races;
|
||||||
|
pub mod spells;
|
||||||
|
|
||||||
|
pub fn load_data(data_dir_path: &str) {
|
||||||
|
spells::load_data(data_dir_path);
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ use diesel::prelude::*;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::db::{schema::spells::{self}, classes::AbilityType, conditions::ConditionType};
|
use crate::storage::connection;
|
||||||
|
use crate::storage::schema::spells::{self};
|
||||||
|
use crate::dnd::{classes::AbilityType, conditions::ConditionType};
|
||||||
|
|
||||||
use super::{SchoolType, CastingTime, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType, Effect};
|
use super::{SchoolType, CastingTime, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType, Effect};
|
||||||
|
|
||||||
@@ -61,7 +63,7 @@ impl Default for QueryFilters {
|
|||||||
|
|
||||||
impl QuerySpell {
|
impl QuerySpell {
|
||||||
pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result<Vec<Self>, ServiceError> {
|
pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result<Vec<Self>, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let mut query = spells::table.limit(limit as i64).into_boxed();
|
let mut query = spells::table.limit(limit as i64).into_boxed();
|
||||||
// Limit query to page and limit
|
// Limit query to page and limit
|
||||||
let offset = (page - 1) * limit;
|
let offset = (page - 1) * limit;
|
||||||
@@ -108,7 +110,7 @@ impl QuerySpell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_count(filters: &QueryFilters) -> Result<i64, ServiceError> {
|
pub fn get_count(filters: &QueryFilters) -> Result<i64, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let mut query = spells::table.count().into_boxed();
|
let mut query = spells::table.count().into_boxed();
|
||||||
if let Some(name) = &filters.by_name {
|
if let Some(name) = &filters.by_name {
|
||||||
query = query.filter(spells::name.ilike(format!("%{}%", name)));
|
query = query.filter(spells::name.ilike(format!("%{}%", name)));
|
||||||
@@ -149,7 +151,7 @@ impl QuerySpell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_by_id(id: i32) -> Result<Self, ServiceError> {
|
pub fn get_by_id(id: i32) -> Result<Self, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let spell = spells::table
|
let spell = spells::table
|
||||||
.filter(spells::id.eq(id))
|
.filter(spells::id.eq(id))
|
||||||
.first::<QuerySpell>(&mut conn)?;
|
.first::<QuerySpell>(&mut conn)?;
|
||||||
@@ -157,7 +159,7 @@ impl QuerySpell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(id: i32) -> Result<Self, ServiceError> {
|
pub fn delete(id: i32) -> Result<Self, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?;
|
let spell = diesel::delete(spells::table.filter(spells::id.eq(id))).get_result(&mut conn)?;
|
||||||
Ok(spell)
|
Ok(spell)
|
||||||
}
|
}
|
||||||
@@ -182,13 +184,13 @@ pub struct InsertSpell {
|
|||||||
|
|
||||||
impl InsertSpell {
|
impl InsertSpell {
|
||||||
pub fn insert(spell: Self) -> Result<QuerySpell, ServiceError> {
|
pub fn insert(spell: Self) -> Result<QuerySpell, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let spell = diesel::insert_into(spells::table).values(spell).get_result(&mut conn)?;
|
let spell = diesel::insert_into(spells::table).values(spell).get_result(&mut conn)?;
|
||||||
Ok(spell)
|
Ok(spell)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(id: i32, spell: Self) -> Result<QuerySpell, ServiceError> {
|
pub fn update(id: i32, spell: Self) -> Result<QuerySpell, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let spell = diesel::update(spells::table.filter(spells::id.eq(id))).set(spell).get_result(&mut conn)?;
|
let spell = diesel::update(spells::table.filter(spells::id.eq(id))).set(spell).get_result(&mut conn)?;
|
||||||
Ok(spell)
|
Ok(spell)
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ use log::error;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use siren::{GetResponse, Metadata, ServiceError};
|
use siren::{GetResponse, Metadata, ServiceError};
|
||||||
|
|
||||||
use crate::{db::spells::{QuerySpell, QueryFilters}, auth::{JwtAuth, verify_role}};
|
use crate::{dnd::spells::{QuerySpell, QueryFilters}, auth::{JwtAuth, verify_role}};
|
||||||
|
|
||||||
use super::{Spell, InsertSpell};
|
use super::{Spell, InsertSpell};
|
||||||
|
|
||||||
@@ -112,6 +112,24 @@ impl From<redis::RedisError> for ServiceError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<s3::error::S3Error> for ServiceError {
|
||||||
|
fn from(error: s3::error::S3Error) -> ServiceError {
|
||||||
|
ServiceError::new(500, format!("Unknown s3 error: {}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<s3::creds::error::CredentialsError> for ServiceError {
|
||||||
|
fn from(error: s3::creds::error::CredentialsError) -> ServiceError {
|
||||||
|
ServiceError::new(500, format!("Unknown credentials error: {}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<minio::s3::error::Error> for ServiceError {
|
||||||
|
fn from(error: minio::s3::error::Error) -> ServiceError {
|
||||||
|
ServiceError::new(500, format!("Unknown minio error: {}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ResponseError for ServiceError {
|
impl ResponseError for ServiceError {
|
||||||
fn error_response(&self) -> HttpResponse {
|
fn error_response(&self) -> HttpResponse {
|
||||||
let status_code = match StatusCode::from_u16(self.status) {
|
let status_code = match StatusCode::from_u16(self.status) {
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ use dotenv::dotenv;
|
|||||||
mod auth;
|
mod auth;
|
||||||
mod dnd;
|
mod dnd;
|
||||||
mod bot;
|
mod bot;
|
||||||
mod db;
|
mod storage;
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info"));
|
env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "warn,siren=info"));
|
||||||
db::init();
|
storage::init();
|
||||||
match env::var("DATA_DIR_PATH") {
|
match env::var("DATA_DIR_PATH") {
|
||||||
Ok(data_dir_path) => db::load_data(&data_dir_path),
|
Ok(data_dir_path) => dnd::load_data(&data_dir_path),
|
||||||
Err(err) => warn!("Unable to load initial database data: {}", err)
|
Err(err) => warn!("Unable to load initial database data: {}", err)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,6 +111,11 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let host = env::var("SERVICE_HOST").unwrap_or("localhost".to_string());
|
let host = env::var("SERVICE_HOST").unwrap_or("localhost".to_string());
|
||||||
let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string());
|
let port = env::var("SERVICE_PORT").unwrap_or("5000".to_string());
|
||||||
|
|
||||||
|
match crate::storage::create_bucket("siren").await {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(err) => {}
|
||||||
|
};
|
||||||
|
|
||||||
let server = match HttpServer::new(move || {
|
let server = match HttpServer::new(move || {
|
||||||
let cors = Cors::default()
|
let cors = Cors::default()
|
||||||
.allow_any_origin()
|
.allow_any_origin()
|
||||||
@@ -121,8 +126,8 @@ async fn main() -> std::io::Result<()> {
|
|||||||
App::new()
|
App::new()
|
||||||
.wrap(cors)
|
.wrap(cors)
|
||||||
.app_data(web::Data::new(Arc::clone(&app_data)))
|
.app_data(web::Data::new(Arc::clone(&app_data)))
|
||||||
.configure(crate::db::messages::init_routes)
|
.configure(crate::storage::messages::init_routes)
|
||||||
.configure(crate::db::spells::init_routes)
|
.configure(crate::dnd::spells::init_routes)
|
||||||
.configure(crate::auth::init_routes)
|
.configure(crate::auth::init_routes)
|
||||||
.configure(crate::bot::api::init_routes)
|
.configure(crate::bot::api::init_routes)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use diesel::prelude::*;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::db::{schema::guilds, connection};
|
use crate::storage::{schema::guilds, connection};
|
||||||
|
|
||||||
#[derive(Queryable, QueryableByName, Serialize, Deserialize)]
|
#[derive(Queryable, QueryableByName, Serialize, Deserialize)]
|
||||||
#[diesel(table_name = guilds)]
|
#[diesel(table_name = guilds)]
|
||||||
@@ -2,7 +2,7 @@ use diesel::prelude::*;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
|
|
||||||
use crate::db::schema::messages::{self};
|
use crate::storage::{schema::messages::{self}, connection};
|
||||||
|
|
||||||
#[derive(Queryable, Selectable, Serialize, Deserialize)]
|
#[derive(Queryable, Selectable, Serialize, Deserialize)]
|
||||||
#[diesel(table_name = messages)]
|
#[diesel(table_name = messages)]
|
||||||
@@ -49,7 +49,7 @@ impl Default for QueryFilters {
|
|||||||
|
|
||||||
impl QueryMessage {
|
impl QueryMessage {
|
||||||
pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result<Vec<Self>, ServiceError> {
|
pub fn get_all(filters: &QueryFilters, limit: i32, page: i32) -> Result<Vec<Self>, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let mut query = messages::table.limit(limit as i64).order(messages::created.asc()).into_boxed();
|
let mut query = messages::table.limit(limit as i64).order(messages::created.asc()).into_boxed();
|
||||||
// Limit query to page and limit
|
// Limit query to page and limit
|
||||||
let offset = (page - 1) * limit;
|
let offset = (page - 1) * limit;
|
||||||
@@ -88,7 +88,7 @@ impl QueryMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_count(fitlers: &QueryFilters) -> Result<i64, ServiceError> {
|
pub fn get_count(fitlers: &QueryFilters) -> Result<i64, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let mut query = messages::table.into_boxed();
|
let mut query = messages::table.into_boxed();
|
||||||
// Apply filters
|
// Apply filters
|
||||||
if let Some(id) = &fitlers.by_id {
|
if let Some(id) = &fitlers.by_id {
|
||||||
@@ -141,7 +141,7 @@ pub struct InsertMessage {
|
|||||||
|
|
||||||
impl InsertMessage {
|
impl InsertMessage {
|
||||||
pub fn insert(message: Self) -> Result<QueryMessage, ServiceError> {
|
pub fn insert(message: Self) -> Result<QueryMessage, ServiceError> {
|
||||||
let mut conn = crate::db::connection()?;
|
let mut conn = connection()?;
|
||||||
let message = diesel::insert_into(messages::table)
|
let message = diesel::insert_into(messages::table)
|
||||||
.values(message)
|
.values(message)
|
||||||
.get_result(&mut conn)?;
|
.get_result(&mut conn)?;
|
||||||
@@ -3,7 +3,7 @@ use log::error;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use siren::{GetResponse, Metadata, ServiceError};
|
use siren::{GetResponse, Metadata, ServiceError};
|
||||||
|
|
||||||
use crate::{db::messages::{QueryMessage, QueryFilters, InsertMessage}, auth::{JwtAuth, verify_role}};
|
use crate::{storage::messages::{QueryMessage, QueryFilters, InsertMessage}, auth::{JwtAuth, verify_role}};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct GetAllParams {
|
struct GetAllParams {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use diesel::{r2d2::ConnectionManager as DieselConnectionManager, PgConnection};
|
use diesel::{r2d2::ConnectionManager as DieselConnectionManager, PgConnection};
|
||||||
// use redis::{aio::{Connection as RedisConnection, ConnectionManager as RedisConnectionManager}, AsyncCommands};
|
use minio::s3::{client::Client as MinioClient, http::BaseUrl, creds::StaticProvider, args::{MakeBucketArgs, BucketExistsArgs}};
|
||||||
use redis::aio::Connection as RedisConnection;
|
use redis::{Client as RedisClient, aio::Connection as RedisConnection};
|
||||||
use siren::ServiceError;
|
use siren::ServiceError;
|
||||||
use crate::diesel_migrations::MigrationHarness;
|
use crate::diesel_migrations::MigrationHarness;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
@@ -8,22 +8,12 @@ use log::{error, info};
|
|||||||
use r2d2;
|
use r2d2;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub mod backgrounds;
|
|
||||||
pub mod bestiary;
|
|
||||||
pub mod classes;
|
|
||||||
pub mod conditions;
|
|
||||||
pub mod feats;
|
|
||||||
pub mod guilds;
|
pub mod guilds;
|
||||||
pub mod items;
|
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
pub mod options;
|
|
||||||
pub mod races;
|
|
||||||
pub mod spells;
|
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
||||||
type DbPool = r2d2::Pool<DieselConnectionManager<PgConnection>>;
|
type DbPool = r2d2::Pool<DieselConnectionManager<PgConnection>>;
|
||||||
pub type DbConnection = r2d2::PooledConnection<DieselConnectionManager<PgConnection>>;
|
pub type DbConnection = r2d2::PooledConnection<DieselConnectionManager<PgConnection>>;
|
||||||
// type RedisPool = r2d2::Pool<redis::ConnectionManager>;
|
|
||||||
|
|
||||||
pub const MIGRATIONS: diesel_migrations::EmbeddedMigrations = embed_migrations!();
|
pub const MIGRATIONS: diesel_migrations::EmbeddedMigrations = embed_migrations!();
|
||||||
|
|
||||||
@@ -38,18 +28,39 @@ lazy_static! {
|
|||||||
let manager = DieselConnectionManager::<PgConnection>::new(url);
|
let manager = DieselConnectionManager::<PgConnection>::new(url);
|
||||||
DbPool::builder().test_on_check_out(true).build(manager).expect("Failed to create db pool")
|
DbPool::builder().test_on_check_out(true).build(manager).expect("Failed to create db pool")
|
||||||
};
|
};
|
||||||
// static ref REDIS_POOL: RedisPool = {
|
static ref REDIS: RedisClient = {
|
||||||
// let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
||||||
// let port = env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
let port = env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
||||||
// let url = format!("redis://{}:{}", host, port);
|
let url = format!("redis://{}:{}", host, port);
|
||||||
// let client = redis::Client::open(url).expect("Failed to create redis client");
|
RedisClient::open(url).expect("Failed to create redis client")
|
||||||
// let manager = RedisConnectionManager::new(client);
|
};
|
||||||
// "".to_string()
|
static ref MINIO: MinioClient = {
|
||||||
// };
|
let url = env::var("MINIO_URL").unwrap_or("localhost".to_string());
|
||||||
|
let port = env::var("MINIO_PORT").unwrap_or("9000".to_string());
|
||||||
|
let base_url = format!("http://{}:{}", url, port).parse::<BaseUrl>().unwrap();
|
||||||
|
|
||||||
|
let user = env::var("MINIO_ROOT_USER").expect("MINIO_ROOT_USER is not set");
|
||||||
|
let password = env::var("MINIO_ROOT_PASSWORD").expect("MINIO_ROOT_PASSWORD is not set");
|
||||||
|
|
||||||
|
let static_provider = StaticProvider::new(
|
||||||
|
&user,
|
||||||
|
&password,
|
||||||
|
None
|
||||||
|
);
|
||||||
|
|
||||||
|
MinioClient::new(
|
||||||
|
base_url,
|
||||||
|
Some(Box::new(static_provider)),
|
||||||
|
None,
|
||||||
|
None
|
||||||
|
).expect("Failed to create minio client")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
lazy_static::initialize(&POOL);
|
lazy_static::initialize(&POOL);
|
||||||
|
lazy_static::initialize(&REDIS);
|
||||||
|
lazy_static::initialize(&MINIO);
|
||||||
let mut pool: DbConnection = connection().expect("Failed to get db connection");
|
let mut pool: DbConnection = connection().expect("Failed to get db connection");
|
||||||
match pool.run_pending_migrations(MIGRATIONS) {
|
match pool.run_pending_migrations(MIGRATIONS) {
|
||||||
Ok(_) => info!("Database initialized"),
|
Ok(_) => info!("Database initialized"),
|
||||||
@@ -62,26 +73,21 @@ pub fn connection() -> Result<DbConnection, ServiceError> {
|
|||||||
.map_err(|e| ServiceError::new(500, format!("Failed getting db connection: {}", e)))
|
.map_err(|e| ServiceError::new(500, format!("Failed getting db connection: {}", e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redis_client() -> Result<redis::Client, ServiceError> {
|
|
||||||
let host = env::var("REDIS_HOST").unwrap_or("localhost".to_string());
|
|
||||||
let port = env::var("REDIS_PORT").unwrap_or("6379".to_string());
|
|
||||||
let url = format!("redis://{}:{}", host, port);
|
|
||||||
let client = redis::Client::open(url)?;
|
|
||||||
Ok(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn redis_connection() -> Result<redis::Connection, ServiceError> {
|
pub fn redis_connection() -> Result<redis::Connection, ServiceError> {
|
||||||
let client = redis_client()?;
|
let conn = REDIS.get_connection()?;
|
||||||
let conn = client.get_connection()?;
|
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn redis_async_connection() -> Result<RedisConnection, ServiceError> {
|
pub async fn redis_async_connection() -> Result<RedisConnection, ServiceError> {
|
||||||
let client = redis_client()?;
|
let conn = REDIS.get_async_connection().await?;
|
||||||
let conn = client.get_async_connection().await?;
|
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_data(data_dir_path: &str) {
|
pub async fn create_bucket(bucket_name: &str) -> Result<(), ServiceError> {
|
||||||
spells::load_data(data_dir_path);
|
let exists = MINIO.bucket_exists(&BucketExistsArgs::new(&bucket_name).unwrap()).await?;
|
||||||
|
if !exists {
|
||||||
|
MINIO.make_bucket(&MakeBucketArgs::new(&bucket_name).unwrap()).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -46,6 +46,8 @@ diesel::table! {
|
|||||||
role -> Text,
|
role -> Text,
|
||||||
first_name -> Text,
|
first_name -> Text,
|
||||||
last_name -> Text,
|
last_name -> Text,
|
||||||
|
updated_at -> Timestamp,
|
||||||
|
created_at -> Timestamp,
|
||||||
verified -> Bool,
|
verified -> Bool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user