improve postgresql performance

This commit is contained in:
DioCrafts
2025-04-09 00:21:20 +02:00
parent 7473ee438f
commit 8f1d213526
36 changed files with 2191 additions and 233 deletions
+22 -65
View File
@@ -1,4 +1,4 @@
use sqlx::{postgres::PgPoolOptions, PgPool};
use sqlx::{postgres::PgPoolOptions, PgPool, Row};
use anyhow::Result;
use std::time::Duration;
use crate::common::config::AppConfig;
@@ -29,74 +29,31 @@ pub async fn create_database_pool(config: &AppConfig) -> Result<PgPool> {
match sqlx::query("SELECT 1").execute(&pool).await {
Ok(_) => {
tracing::info!("Conexión a PostgreSQL establecida correctamente");
// Verify if migrations have been applied
let migration_check = sqlx::query("SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'auth' AND tablename = 'users')")
.fetch_one(&pool)
.await;
match migration_check {
Ok(row) => {
let tables_exist: bool = row.get(0);
if !tables_exist {
tracing::warn!("Las tablas de la base de datos no existen. Por favor, ejecuta las migraciones con: cargo run --bin migrate --features migrations");
}
},
Err(_) => {
tracing::warn!("No se pudo verificar el estado de las migraciones. Por favor, ejecuta las migraciones con: cargo run --bin migrate --features migrations");
}
}
return Ok(pool);
},
Err(e) => {
tracing::error!("Error al verificar conexión: {}", e);
// Try creating the tables in this case - might be missing schema
tracing::info!("Intentando crear las tablas necesarias...");
// Simple schema creation - this handles fresh installations
let create_tables_result = sqlx::query(r#"
-- Create the auth schema if not exists
CREATE SCHEMA IF NOT EXISTS auth;
-- Create UserRole enum type if not exists
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'userrole') THEN
CREATE TYPE auth.userrole AS ENUM ('admin', 'user');
END IF;
END $$;
-- Create the auth.users table
CREATE TABLE IF NOT EXISTS auth.users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(32) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
role auth.userrole NOT NULL,
storage_quota_bytes BIGINT NOT NULL,
storage_used_bytes BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL,
last_login_at TIMESTAMPTZ,
active BOOLEAN NOT NULL DEFAULT TRUE
);
-- Create an index on username and email for fast lookups
CREATE INDEX IF NOT EXISTS idx_users_username ON auth.users(username);
CREATE INDEX IF NOT EXISTS idx_users_email ON auth.users(email);
-- Create the sessions table
CREATE TABLE IF NOT EXISTS auth.sessions (
id VARCHAR(36) PRIMARY KEY,
user_id VARCHAR(36) NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
refresh_token VARCHAR(255) NOT NULL UNIQUE,
expires_at TIMESTAMPTZ NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
created_at TIMESTAMPTZ NOT NULL,
revoked BOOLEAN NOT NULL DEFAULT FALSE
);
-- Create indexes on user_id and refresh_token for fast lookups
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON auth.sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_sessions_refresh_token ON auth.sessions(refresh_token);
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON auth.sessions(expires_at);
"#).execute(&pool).await;
match create_tables_result {
Ok(_) => {
tracing::info!("Tablas creadas correctamente");
return Ok(pool);
},
Err(table_err) => {
tracing::error!("Error al crear tablas: {}", table_err);
if attempt >= MAX_ATTEMPTS {
return Err(anyhow::anyhow!("Error en la conexión a PostgreSQL: {}", table_err));
}
}
tracing::warn!("La base de datos parece no estar configurada. Por favor, ejecuta las migraciones con: cargo run --bin migrate --features migrations");
if attempt >= MAX_ATTEMPTS {
return Err(anyhow::anyhow!("Error al verificar la conexión a PostgreSQL: {}", e));
}
}
}
+16
View File
@@ -311,6 +311,7 @@ pub struct AppState {
pub share_service: Option<Arc<dyn crate::application::ports::share_ports::ShareUseCase>>,
pub favorites_service: Option<Arc<dyn FavoritesUseCase>>,
pub recent_service: Option<Arc<dyn RecentItemsUseCase>>,
pub storage_usage_service: Option<Arc<dyn crate::application::ports::storage_ports::StorageUsagePort>>,
}
impl Default for AppState {
@@ -439,6 +440,14 @@ impl Default for AppState {
async fn delete_file(&self, _id: &str) -> Result<(), crate::common::errors::DomainError> {
Ok(())
}
async fn get_folder_details(&self, _folder_id: &str) -> Result<crate::domain::entities::file::File, crate::common::errors::DomainError> {
Ok(crate::domain::entities::file::File::default())
}
async fn get_folder_path_str(&self, _folder_id: &str) -> Result<String, crate::common::errors::DomainError> {
Ok("/Mi Carpeta - dummy".to_string())
}
}
struct DummyFileStoragePort;
@@ -815,6 +824,7 @@ impl Default for AppState {
share_service: None,
favorites_service: None,
recent_service: None,
storage_usage_service: None,
}
}
}
@@ -835,6 +845,7 @@ impl AppState {
share_service: None,
favorites_service: None,
recent_service: None,
storage_usage_service: None,
}
}
@@ -867,4 +878,9 @@ impl AppState {
self.recent_service = Some(recent_service);
self
}
pub fn with_storage_usage_service(mut self, storage_usage_service: Arc<dyn crate::application::ports::storage_ports::StorageUsagePort>) -> Self {
self.storage_usage_service = Some(storage_usage_service);
self
}
}