""" SQLite database ORM using SQLAlchemy. """ from sqlalchemy import create_engine, Column, String, Integer, Float, DateTime, Text, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, Session from datetime import datetime import uuid from pathlib import Path Base = declarative_base() class VoiceProfile(Base): """Voice profile database model.""" __tablename__ = "profiles" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String, unique=True, nullable=False) description = Column(Text) language = Column(String, default="en") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class ProfileSample(Base): """Voice profile sample database model.""" __tablename__ = "profile_samples" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) profile_id = Column(String, ForeignKey("profiles.id"), nullable=False) audio_path = Column(String, nullable=False) reference_text = Column(Text, nullable=False) class Generation(Base): """Generation history database model.""" __tablename__ = "generations" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) profile_id = Column(String, ForeignKey("profiles.id"), nullable=False) text = Column(Text, nullable=False) language = Column(String, default="en") audio_path = Column(String, nullable=False) duration = Column(Float, nullable=False) seed = Column(Integer) created_at = Column(DateTime, default=datetime.utcnow) class Project(Base): """Audio studio project database model.""" __tablename__ = "projects" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String, nullable=False) data = Column(Text) # JSON string created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Database setup _db_path = Path("data/voicebox.db") _db_path.parent.mkdir(parents=True, exist_ok=True) engine = create_engine( f"sqlite:///{_db_path}", connect_args={"check_same_thread": False}, ) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) def init_db(): """Initialize database tables.""" Base.metadata.create_all(bind=engine) def get_db(): """Get database session (generator for dependency injection).""" db = SessionLocal() try: yield db finally: db.close()