149 lines
5.8 KiB
Python
149 lines
5.8 KiB
Python
import psycopg2
|
|
from psycopg2 import sql
|
|
from psycopg2.extras import execute_values
|
|
from psycopg2.extras import RealDictCursor
|
|
|
|
|
|
class DBForma:
|
|
def __init__(self, db_obj: dict):
|
|
"""
|
|
Inicializa la conexión a la base de datos.
|
|
|
|
:param db_obj: Diccionario con las credenciales de la base de datos.
|
|
Debe contener: host, port, database, user, password
|
|
"""
|
|
self.db_obj = db_obj
|
|
|
|
def _get_connection(self):
|
|
"""
|
|
Crea y retorna una nueva conexión a la base de datos.
|
|
"""
|
|
return psycopg2.connect(
|
|
host=self.db_obj['host'],
|
|
port=self.db_obj['port'],
|
|
database=self.db_obj['database'],
|
|
user=self.db_obj['user'],
|
|
password=self.db_obj['password']
|
|
)
|
|
|
|
def login(self, email: str):
|
|
"""
|
|
Verifica las credenciales de un usuario.
|
|
|
|
:param email: Email del usuario a verificar
|
|
:return: Tupla con la contraseña si el usuario existe, None si no existe
|
|
:raises: RuntimeError si hay algún error en la consulta
|
|
"""
|
|
# Corrección 1: Usar parámetros correctamente para evitar SQL injection
|
|
query = "SELECT pswd FROM users WHERE email = %s;"
|
|
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
# Corrección 2: Pasar parámetros como tupla (aunque sea uno solo)
|
|
cursor.execute(query, (email,))
|
|
return cursor.fetchone()
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error al verificar credenciales: {e}")
|
|
|
|
def reset_pswd(self, email: str):
|
|
query = "SELECT email FROM users WHERE email = %s;"
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, (email,))
|
|
return cursor.fetchone()
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error al verificar credenciales: {e}")
|
|
|
|
|
|
def get_id(self, email: str):
|
|
query = "SELECT id FROM users WHERE email = %s;"
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, (email,))
|
|
return cursor.fetchone()
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error al verificar credenciales: {e}")
|
|
|
|
def get_data(self, query: str, data_tuple: tuple):
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, data_tuple)
|
|
result = cursor.fetchone()
|
|
return result
|
|
except psycopg2.DatabaseError as e:
|
|
conn.rollback() # Asegura que la conexión no quede en un estado erróneo
|
|
raise RuntimeError(f"Error al ejecutar la consulta: {e}")
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error inesperado: {e}")
|
|
|
|
def get_all_data(self, query: str, data_tuple: tuple = ()):
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, data_tuple)
|
|
result = cursor.fetchall()
|
|
return result
|
|
except psycopg2.DatabaseError as e:
|
|
conn.rollback() # Asegura que la conexión no quede en un estado erróneo
|
|
raise RuntimeError(f"Error al ejecutar la consulta: {e}")
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error inesperado: {e}")
|
|
|
|
def get_all_data_dict(self, query):
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor(cursor_factory=RealDictCursor) as cursor:
|
|
cursor.execute(query)
|
|
return cursor.fetchall()
|
|
except psycopg2.DatabaseError as e:
|
|
raise RuntimeError(f"Error al ejecutar la consulta: {e}")
|
|
except Exception as e:
|
|
raise RuntimeError(f"Error inesperado: {e}")
|
|
|
|
def update_data(self, query: str, data_tuple: tuple) -> bool:
|
|
"""
|
|
"""
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, data_tuple)
|
|
if cursor.rowcount == 0:
|
|
return False
|
|
conn.commit() # Confirmar explícitamente la transacción
|
|
return True
|
|
except Exception as e:
|
|
conn.rollback() # Revertir en caso de error
|
|
raise RuntimeError(f"Error al actualizar la contraseña: {e}")
|
|
|
|
|
|
def update_pswd(self, pswd: str, email: str) -> bool:
|
|
"""
|
|
Actualiza la contraseña de un usuario en la base de datos.
|
|
|
|
Args:
|
|
pswd: Nueva contraseña (debería estar hasheada)
|
|
email: Email del usuario a actualizar
|
|
|
|
Returns:
|
|
bool: True si la actualización fue exitosa, False si no se actualizó ningún registro
|
|
|
|
Raises:
|
|
RuntimeError: Si ocurre un error durante la operación
|
|
"""
|
|
query = "UPDATE users SET pswd = %s, is_pswd_reseted = true WHERE email = %s;"
|
|
try:
|
|
with self._get_connection() as conn:
|
|
with conn.cursor() as cursor:
|
|
cursor.execute(query, (pswd, email))
|
|
# Verificar si realmente se actualizó algún registro
|
|
if cursor.rowcount == 0:
|
|
return False
|
|
conn.commit() # Confirmar explícitamente la transacción
|
|
return True
|
|
except Exception as e:
|
|
conn.rollback() # Revertir en caso de error
|
|
raise RuntimeError(f"Error al actualizar la contraseña: {e}") |