# Copyright (c) 2025 Patrick Motsch # All rights reserved. """ Dynamic database registry — each interface self-registers its DB on import. Usage in any interfaceDb*.py / interfaceFeature*.py: from modules.shared.dbRegistry import registerDatabase registerDatabase("poweron_xyz") """ import logging import threading from typing import Dict, Optional from modules.connectors.connectorDbPostgre import DatabaseConnector from modules.shared.configuration import APP_CONFIG logger = logging.getLogger(__name__) _lock = threading.Lock() _registry: Dict[str, str] = {} def registerDatabase(dbName: str, configPrefix: str = "DB") -> None: """Register a database for health monitoring. Called at module-level by each interface so that the registry is populated automatically as interfaces are imported. Args: dbName: PostgreSQL database name (e.g. "poweron_app"). configPrefix: Config key prefix for host/port/user/password. Default "DB" reads DB_HOST, DB_PORT, etc. """ with _lock: if dbName in _registry: return _registry[dbName] = configPrefix logger.debug(f"Database registered: {dbName} (configPrefix={configPrefix})") def getRegisteredDatabases() -> Dict[str, str]: """Return snapshot of all registered databases {dbName: configPrefix}.""" with _lock: return dict(_registry) def _getConnectorForDb(dbName: str) -> DatabaseConnector: """Create a lightweight DatabaseConnector for the given registered DB. Intended for read-only health queries (pg_stat, orphan scans). Uses the same APP_CONFIG credentials as the application connectors. """ with _lock: configPrefix = _registry.get(dbName) if configPrefix is None: raise ValueError(f"Database '{dbName}' is not registered.") hostKey = f"{configPrefix}_HOST" if configPrefix != "DB" else "DB_HOST" portKey = f"{configPrefix}_PORT" if configPrefix != "DB" else "DB_PORT" userKey = f"{configPrefix}_USER" if configPrefix != "DB" else "DB_USER" passwordKey = f"{configPrefix}_PASSWORD_SECRET" if configPrefix != "DB" else "DB_PASSWORD_SECRET" return DatabaseConnector( dbHost=APP_CONFIG.get(hostKey, "localhost"), dbDatabase=dbName, dbUser=APP_CONFIG.get(userKey), dbPassword=APP_CONFIG.get(passwordKey), dbPort=int(APP_CONFIG.get(portKey, 5432)), )