Spaces:
Running
Running
| from __future__ import annotations | |
| import time | |
| from typing import Any | |
| from app.core.database import ConnectionConfig, pool_manager | |
| from app.core.database.base import StatementResult | |
| from app.core.logger import get_logger | |
| from app.models.schemas import ( | |
| DatabaseQueryError, | |
| DatabaseQueryRequest, | |
| DatabaseQueryResponse, | |
| StatementResultSchema, | |
| ) | |
| _logger = get_logger(__name__) | |
| def _root_cause(exc: Exception) -> str: | |
| cause = exc.__cause__ or exc.__context__ | |
| if cause: | |
| return f"{exc} [{cause}]" | |
| return str(exc) | |
| class DatabaseService: | |
| async def execute_query(self, request: DatabaseQueryRequest) -> DatabaseQueryResponse: | |
| start_time = time.monotonic() | |
| config = ConnectionConfig(**request.to_connection_config()) | |
| try: | |
| executor = await pool_manager.get_executor(config) | |
| except Exception as exc: | |
| elapsed = (time.monotonic() - start_time) * 1000 | |
| _logger.error( | |
| "Failed to acquire executor for %s: %s", | |
| config.safe_repr, exc, | |
| ) | |
| return DatabaseQueryResponse( | |
| success=False, | |
| execution_time_ms=round(elapsed, 2), | |
| error=DatabaseQueryError( | |
| message=f"Connection failed: {_root_cause(exc)}", | |
| code=type(exc).__name__, | |
| ), | |
| ) | |
| try: | |
| results = await executor.execute( | |
| request.query, | |
| use_transaction=request.use_transaction, | |
| ) | |
| except Exception as exc: | |
| elapsed = (time.monotonic() - start_time) * 1000 | |
| _logger.error( | |
| "Query execution failed for %s: %s", | |
| config.safe_repr, exc, | |
| ) | |
| return DatabaseQueryResponse( | |
| success=False, | |
| execution_time_ms=round(elapsed, 2), | |
| error=DatabaseQueryError( | |
| message=f"Execution failed: {_root_cause(exc)}", | |
| code=type(exc).__name__, | |
| ), | |
| ) | |
| elapsed = (time.monotonic() - start_time) * 1000 | |
| statement_results = [ | |
| StatementResultSchema( | |
| success=r.success, | |
| rows=r.rows, | |
| data=r.data, | |
| error=r.error, | |
| error_code=r.error_code, | |
| ) | |
| for r in results | |
| ] | |
| overall_success = all(r.success for r in results) | |
| if overall_success: | |
| _logger.info( | |
| "Query success for %s (%d stmts, %.2fms)", | |
| config.safe_repr, len(results), elapsed, | |
| ) | |
| return DatabaseQueryResponse( | |
| success=True, | |
| execution_time_ms=round(elapsed, 2), | |
| results=statement_results, | |
| ) | |
| _logger.warning( | |
| "Query partial/full failure for %s (%d stmts, %.2fms)", | |
| config.safe_repr, len(results), elapsed, | |
| ) | |
| return DatabaseQueryResponse( | |
| success=False, | |
| execution_time_ms=round(elapsed, 2), | |
| results=statement_results, | |
| ) | |