Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| from sqlmodel import SQLModel, create_engine | |
| from sqlalchemy import inspect, text | |
| from env.env_loader import load_env_file | |
| def get_default_db_path() -> Path: | |
| project_root = Path(__file__).resolve().parents[1] | |
| return project_root / "code_review_env.db" | |
| def get_engine(db_path: str | Path | None = None, echo: bool = False): | |
| load_env_file() | |
| env_url = os.getenv("GRAPHREVIEW_DATABASE_URL", "").strip() | |
| if env_url: | |
| connect_args: dict[str, object] = {} | |
| if env_url.startswith("sqlite://"): | |
| connect_args["check_same_thread"] = False | |
| return create_engine(env_url, echo=echo, connect_args=connect_args) | |
| # Turso remote URL path (libSQL over SQLAlchemy dialect). | |
| turso_url = ( | |
| os.getenv("GRAPHREVIEW_REMOTE_SQLITE_URL", "").strip() | |
| or os.getenv("TURSO_DATABASE_URL", "").strip() | |
| ) | |
| turso_token = ( | |
| os.getenv("GRAPHREVIEW_REMOTE_SQLITE_AUTH_TOKEN", "").strip() | |
| or os.getenv("TURSO_AUTH_TOKEN", "").strip() | |
| ) | |
| if turso_url: | |
| # Example TURSO_DATABASE_URL: libsql://my-db.turso.io | |
| engine_url = f"sqlite+{turso_url}?secure=true" | |
| connect_args: dict[str, object] = {} | |
| if turso_token: | |
| connect_args["auth_token"] = turso_token | |
| return create_engine(engine_url, echo=echo, connect_args=connect_args) | |
| path = Path(db_path) if db_path else get_default_db_path() | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| return create_engine(f"sqlite:///{path}", echo=echo, connect_args={"check_same_thread": False}) | |
| def init_db(db_path: str | Path | None = None, echo: bool = False) -> None: | |
| load_env_file() | |
| from db import schema # noqa: F401 | |
| engine = get_engine(db_path=db_path, echo=echo) | |
| SQLModel.metadata.create_all(engine) | |
| _apply_lightweight_migrations(engine) | |
| def _apply_lightweight_migrations(engine) -> None: | |
| inspector = inspect(engine) | |
| if "trainingannotation" not in inspector.get_table_names(): | |
| from db.schema import TrainingAnnotation # local import to avoid circular startup order | |
| TrainingAnnotation.__table__.create(bind=engine, checkfirst=True) | |
| inspector = inspect(engine) | |
| if "reviewannotation" not in inspector.get_table_names(): | |
| return | |
| existing_columns = {col["name"] for col in inspector.get_columns("reviewannotation")} | |
| add_statements: list[str] = [] | |
| if "task_id" not in existing_columns: | |
| add_statements.append("ALTER TABLE reviewannotation ADD COLUMN task_id TEXT") | |
| if "reward_given" not in existing_columns: | |
| add_statements.append("ALTER TABLE reviewannotation ADD COLUMN reward_given FLOAT DEFAULT 0.0") | |
| if "attributed_to" not in existing_columns: | |
| add_statements.append("ALTER TABLE reviewannotation ADD COLUMN attributed_to TEXT") | |
| if "is_amendment" not in existing_columns: | |
| add_statements.append("ALTER TABLE reviewannotation ADD COLUMN is_amendment BOOLEAN DEFAULT 0") | |
| if not add_statements: | |
| add_statements = [] | |
| if "moduleedge" in inspector.get_table_names(): | |
| edge_columns = {col["name"] for col in inspector.get_columns("moduleedge")} | |
| if "connection_summary" not in edge_columns: | |
| add_statements.append("ALTER TABLE moduleedge ADD COLUMN connection_summary TEXT DEFAULT ''") | |
| if "analyzerrun" in inspector.get_table_names(): | |
| analyzer_columns = {col["name"] for col in inspector.get_columns("analyzerrun")} | |
| if "analyzer_version" not in analyzer_columns: | |
| add_statements.append("ALTER TABLE analyzerrun ADD COLUMN analyzer_version TEXT DEFAULT ''") | |
| if "command_hash" not in analyzer_columns: | |
| add_statements.append("ALTER TABLE analyzerrun ADD COLUMN command_hash TEXT DEFAULT ''") | |
| if not add_statements: | |
| return | |
| with engine.begin() as conn: | |
| for stmt in add_statements: | |
| conn.execute(text(stmt)) | |
| if __name__ == "__main__": | |
| init_db() | |
| print("Database initialized") | |