""" Database connection management for MongoDB Infrastructure Layer - handles low-level database connectivity """ import os from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase from pymongo import IndexModel, ASCENDING, DESCENDING from typing import Optional import logging logger = logging.getLogger(__name__) class DatabaseConnection: """Manages MongoDB connection and database operations""" def __init__(self): self.client: Optional[AsyncIOMotorClient] = None self.database: Optional[AsyncIOMotorDatabase] = None self._mongodb_url = os.getenv("MONGODB_URL", "mongodb://localhost:27017") self._database_name = os.getenv("DATABASE_NAME", "energy_monitoring") async def connect(self) -> None: """Establish connection to MongoDB""" try: logger.info(f"Connecting to MongoDB at: {self._mongodb_url}") self.client = AsyncIOMotorClient(self._mongodb_url) await self.client.admin.command('ping') self.database = self.client[self._database_name] await self._create_indexes() logger.info("Successfully connected to MongoDB") except Exception as e: logger.error(f"Error connecting to MongoDB: {e}") raise async def disconnect(self) -> None: """Close MongoDB connection""" if self.client: self.client.close() logger.info("Disconnected from MongoDB") async def get_database(self) -> AsyncIOMotorDatabase: """Get database instance""" if not self.database: await self.connect() return self.database async def _create_indexes(self) -> None: """Create database indexes for optimal performance""" try: # Sensor readings collection indexes sensor_readings_indexes = [ IndexModel([("sensor_id", ASCENDING), ("timestamp", DESCENDING)]), IndexModel([("timestamp", DESCENDING)]), IndexModel([("room", ASCENDING), ("timestamp", DESCENDING)]), IndexModel([("sensor_type", ASCENDING), ("timestamp", DESCENDING)]), IndexModel([("created_at", DESCENDING)]), ] await self.database.sensor_readings.create_indexes(sensor_readings_indexes) # Room metrics collection indexes room_metrics_indexes = [ IndexModel([("room", ASCENDING), ("timestamp", DESCENDING)]), IndexModel([("timestamp", DESCENDING)]), IndexModel([("created_at", DESCENDING)]), ] await self.database.room_metrics.create_indexes(room_metrics_indexes) # Sensor metadata collection indexes sensor_metadata_indexes = [ IndexModel([("sensor_id", ASCENDING)], unique=True), IndexModel([("room", ASCENDING)]), IndexModel([("sensor_type", ASCENDING)]), IndexModel([("status", ASCENDING)]), ] await self.database.sensor_metadata.create_indexes(sensor_metadata_indexes) # System events collection indexes system_events_indexes = [ IndexModel([("timestamp", DESCENDING)]), IndexModel([("event_type", ASCENDING), ("timestamp", DESCENDING)]), IndexModel([("severity", ASCENDING), ("timestamp", DESCENDING)]), ] await self.database.system_events.create_indexes(system_events_indexes) logger.info("Database indexes created successfully") except Exception as e: logger.error(f"Error creating indexes: {e}") # Global database connection instance database_connection = DatabaseConnection()