"""Repositorio para gestionar nodos.""" from typing import Optional, List from datetime import datetime from dataclasses import dataclass from .database import db @dataclass class Node: """Modelo de Node.""" node_name: str db_name: str active: bool notes: Optional[str] updated_at: str class NodeRepository: """Repositorio para operaciones con nodos.""" @staticmethod def create(node_name: str, db_name: str, notes: Optional[str] = None): """ Crea o actualiza un nodo. Args: node_name: Nombre del nodo (case-insensitive) db_name: Nombre de la base de datos notes: Notas opcionales """ now = datetime.utcnow().isoformat() node_name_upper = node_name.upper() db.execute(""" INSERT OR REPLACE INTO nodes (node_name, db_name, active, notes, updated_at) VALUES (?, ?, 1, ?, ?) """, (node_name_upper, db_name, notes, now)) @staticmethod def get(node_name: str) -> Optional[Node]: """Obtiene un nodo por nombre (case-insensitive).""" node_name_upper = node_name.upper() row = db.fetchone("SELECT * FROM nodes WHERE node_name = ?", (node_name_upper,)) if not row: return None return Node( node_name=row["node_name"], db_name=row["db_name"], active=bool(row["active"]), notes=row["notes"], updated_at=row["updated_at"] ) @staticmethod def get_all(active_only: bool = False) -> List[Node]: """ Obtiene todos los nodos. Args: active_only: Si True, solo devuelve nodos activos Returns: Lista de nodos """ query = "SELECT * FROM nodes" if active_only: query += " WHERE active = 1" query += " ORDER BY node_name" rows = db.fetchall(query) return [Node( node_name=row["node_name"], db_name=row["db_name"], active=bool(row["active"]), notes=row["notes"], updated_at=row["updated_at"] ) for row in rows] @staticmethod def update( node_name: str, db_name: Optional[str] = None, active: Optional[bool] = None, notes: Optional[str] = None ): """Actualiza un nodo.""" node_name_upper = node_name.upper() updates = [] params = [] if db_name is not None: updates.append("db_name = ?") params.append(db_name) if active is not None: updates.append("active = ?") params.append(1 if active else 0) if notes is not None: updates.append("notes = ?") params.append(notes) if updates: now = datetime.utcnow().isoformat() updates.append("updated_at = ?") params.append(now) params.append(node_name_upper) db.execute( f"UPDATE nodes SET {', '.join(updates)} WHERE node_name = ?", tuple(params) ) @staticmethod def delete(node_name: str): """Elimina un nodo.""" node_name_upper = node_name.upper() db.execute("DELETE FROM nodes WHERE node_name = ?", (node_name_upper,)) @staticmethod def get_db_for_node(node_name: str) -> Optional[str]: """ Obtiene el nombre de DB para un nodo (si está activo). Args: node_name: Nombre del nodo Returns: Nombre de la DB o None si no existe o está inactivo """ node = NodeRepository.get(node_name) if node and node.active: return node.db_name return None