from typing import List, Dict, Any
from sqlalchemy.orm import Session
from sqlalchemy.exc import SQLAlchemyError
from app.core.vector_store.faiss_store import FaissVectorStore
from app.core.vector_store.embedder.mock import MockEmbedder
from app.db import models
class DocumentService:
"""
Service class for managing document lifecycle, including
adding, retrieving, and deleting documents and their vector metadata.
"""
def __init__(self, vector_store: FaissVectorStore):
self.vector_store = vector_store
self.embedder = self.vector_store.embedder
def add_document(self, db: Session, doc_data: Dict[str, Any]) -> int:
"""
Adds a new document and its vector metadata.
"""
try:
document_db = models.Document(**doc_data)
db.add(document_db)
db.commit()
db.refresh(document_db)
# Determine embedding model name if needed
embedding_model_name = "mock_embedder" if isinstance(self.embedder, MockEmbedder) else "GenAIEmbedder"
# Pass db_session explicitly as positional argument, and document_id
faiss_index_id = self.vector_store.add_document(
text= document_db.text,
document_id=document_db.id,
db_session=db,
embedding_model=embedding_model_name
)
return document_db.id
except SQLAlchemyError:
db.rollback()
raise
def get_all_documents(self, db: Session) -> List[models.Document]:
"""
Retrieves all documents from the database.
"""
return db.query(models.Document).order_by(models.Document.created_at.desc()).all()
def delete_document(self, db: Session, document_id: int) -> int:
"""
Deletes a document and its associated vector metadata from the database.
"""
try:
doc_to_delete = db.query(models.Document).filter(models.Document.id == document_id).first()
if not doc_to_delete:
return None
# Assuming you also need to delete the vector metadata associated with the document
# for a full cleanup.
# db.query(models.VectorMetadata).filter(models.VectorMetadata.document_id == document_id).delete()
db.delete(doc_to_delete)
db.commit()
return document_id
except SQLAlchemyError as e:
db.rollback()
raise