llm-ready-data / app /services /database_service.py
Soumik-404's picture
feat: add db apis
89157f5
Raw
History Blame
3.19 kB
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,
)