mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 14:22:04 +00:00
init
This commit is contained in:
99
api/database.py
Normal file
99
api/database.py
Normal file
@@ -0,0 +1,99 @@
|
||||
"""
|
||||
Database Models and Connection
|
||||
==============================
|
||||
|
||||
SQLite database schema for feature storage using SQLAlchemy.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import Boolean, Column, Integer, String, Text, create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker, Session
|
||||
from sqlalchemy.types import JSON
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Feature(Base):
|
||||
"""Feature model representing a test case/feature to implement."""
|
||||
|
||||
__tablename__ = "features"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
priority = Column(Integer, nullable=False, default=999, index=True)
|
||||
category = Column(String(100), nullable=False)
|
||||
name = Column(String(255), nullable=False)
|
||||
description = Column(Text, nullable=False)
|
||||
steps = Column(JSON, nullable=False) # Stored as JSON array
|
||||
passes = Column(Boolean, default=False, index=True)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Convert feature to dictionary for JSON serialization."""
|
||||
return {
|
||||
"id": self.id,
|
||||
"priority": self.priority,
|
||||
"category": self.category,
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"steps": self.steps,
|
||||
"passes": self.passes,
|
||||
}
|
||||
|
||||
|
||||
def get_database_path(project_dir: Path) -> Path:
|
||||
"""Return the path to the SQLite database for a project."""
|
||||
return project_dir / "features.db"
|
||||
|
||||
|
||||
def get_database_url(project_dir: Path) -> str:
|
||||
"""Return the SQLAlchemy database URL for a project.
|
||||
|
||||
Uses POSIX-style paths (forward slashes) for cross-platform compatibility.
|
||||
"""
|
||||
db_path = get_database_path(project_dir)
|
||||
return f"sqlite:///{db_path.as_posix()}"
|
||||
|
||||
|
||||
def create_database(project_dir: Path) -> tuple:
|
||||
"""
|
||||
Create database and return engine + session maker.
|
||||
|
||||
Args:
|
||||
project_dir: Directory containing the project
|
||||
|
||||
Returns:
|
||||
Tuple of (engine, SessionLocal)
|
||||
"""
|
||||
db_url = get_database_url(project_dir)
|
||||
engine = create_engine(db_url, connect_args={"check_same_thread": False})
|
||||
Base.metadata.create_all(bind=engine)
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
return engine, SessionLocal
|
||||
|
||||
|
||||
# Global session maker - will be set when server starts
|
||||
_session_maker: Optional[sessionmaker] = None
|
||||
|
||||
|
||||
def set_session_maker(session_maker: sessionmaker) -> None:
|
||||
"""Set the global session maker."""
|
||||
global _session_maker
|
||||
_session_maker = session_maker
|
||||
|
||||
|
||||
def get_db() -> Session:
|
||||
"""
|
||||
Dependency for FastAPI to get database session.
|
||||
|
||||
Yields a database session and ensures it's closed after use.
|
||||
"""
|
||||
if _session_maker is None:
|
||||
raise RuntimeError("Database not initialized. Call set_session_maker first.")
|
||||
|
||||
db = _session_maker()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user