Coverage for src / local_deep_research / metrics / database.py: 100%
33 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
1"""Database utilities for metrics module with SQLAlchemy."""
3from contextlib import contextmanager
4from typing import Generator, Optional
6from sqlalchemy.orm import Session
8from ..database.session_context import get_user_db_session
11class MetricsDatabase:
12 """Database manager for metrics using SQLAlchemy."""
14 def __init__(
15 self, username: Optional[str] = None, password: Optional[str] = None
16 ):
17 # Store credentials if provided (for testing/background tasks)
18 self.username = username
19 self.password = password
21 @contextmanager
22 def get_session(
23 self, username: Optional[str] = None, password: Optional[str] = None
24 ) -> Generator[Session, None, None]:
25 """Get a database session with automatic cleanup.
27 Args:
28 username: Override username for this session
29 password: Override password for this session (if needed for thread access)
30 """
31 # Use provided username or fall back to stored/session username
32 user = username or self.username
33 pwd = password or self.password
35 # Try to get username from Flask session if still not available
36 if not user:
37 try:
38 from flask import session as flask_session
40 user = flask_session.get("username")
41 except:
42 pass
44 if not user:
45 # No username available - can't access user database
46 yield None
47 return
49 # If we have password, use thread-safe access
50 if pwd:
51 from ..database.thread_metrics import metrics_writer
53 metrics_writer.set_user_password(user, pwd)
54 with metrics_writer.get_session(user) as session:
55 yield session
56 else:
57 # Use the per-user database session with proper context management
58 with get_user_db_session(user) as session:
59 yield session
62# Singleton instance
63_metrics_db = None
66def get_metrics_db() -> MetricsDatabase:
67 """Get the singleton metrics database instance."""
68 global _metrics_db
69 if _metrics_db is None:
70 _metrics_db = MetricsDatabase()
71 return _metrics_db