Spaces:
Running
Running
| # src/database/db_operations.py | |
| import os | |
| import sqlite3 | |
| class MindGuardDatabase: | |
| """ | |
| This class handles the Long-Term Memory of MindGuard. | |
| It connects to a local SQLite database to save chat logs, track emotions, | |
| and pull historical context for the LLM. | |
| """ | |
| def __init__(self): | |
| print("πΎ Initializing MindGuard SQLite Memory Bank...") | |
| # --- STRICT ARCHITECTURE PATHING --- | |
| self.script_dir = os.path.dirname(os.path.abspath(__file__)) | |
| self.project_root = os.path.abspath(os.path.join(self.script_dir, "../../")) | |
| # 1. Define the exact path for the local SQLite file | |
| # We will save it right next to our ChromaDB in the artifacts folder | |
| self.db_dir = os.path.join(self.project_root, "artifacts", "database") | |
| os.makedirs(self.db_dir, exist_ok=True) | |
| self.db_path = os.path.join(self.db_dir, "mindguard_memory.sqlite3") | |
| try: | |
| # 2. Establish connection to the local SQLite file | |
| # check_same_thread=False allows Streamlit/FastAPI to talk to it later without crashing | |
| self.conn = sqlite3.connect(self.db_path, check_same_thread=False) | |
| # This forces SQLite to return rows as dictionaries, exactly like PostgreSQL did! | |
| self.conn.row_factory = sqlite3.Row | |
| self.cursor = self.conn.cursor() | |
| print(f"β Successfully connected to SQLite at: {self.db_path}") | |
| # 3. Ensure our tables exist | |
| self._create_tables() | |
| except sqlite3.Error as e: | |
| print(f"β DATABASE ERROR: Could not connect to SQLite.") | |
| print(f"Details: {e}") | |
| def _create_tables(self): | |
| """Creates the database schema if it doesn't already exist.""" | |
| # --- THE FIX: SQLite Syntax --- | |
| # PostgreSQL uses 'SERIAL' for auto-counting IDs. SQLite uses 'INTEGER PRIMARY KEY AUTOINCREMENT' | |
| create_table_query = """ | |
| CREATE TABLE IF NOT EXISTS chat_history ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| session_id TEXT NOT NULL, | |
| user_message TEXT NOT NULL, | |
| bot_response TEXT NOT NULL, | |
| diagnosed_emotion TEXT, | |
| risk_level TEXT, | |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| """ | |
| self.cursor.execute(create_table_query) | |
| self.conn.commit() # SQLite requires us to manually commit structural changes | |
| print("β Database schema validated.") | |
| def save_interaction(self, session_id, user_message, bot_response, emotion, risk_level): | |
| """Saves a single conversation turn into the database.""" | |
| # --- THE FIX: SQLite Parameters --- | |
| # PostgreSQL uses %s for security. SQLite uses ? | |
| insert_query = """ | |
| INSERT INTO chat_history (session_id, user_message, bot_response, diagnosed_emotion, risk_level) | |
| VALUES (?, ?, ?, ?, ?); | |
| """ | |
| self.cursor.execute(insert_query, (session_id, user_message, bot_response, emotion, risk_level)) | |
| self.conn.commit() # SQLite requires us to manually commit inserted data | |
| print("πΎ Interaction saved to Long-Term Memory.") | |
| def get_recent_history(self, session_id, limit=3): | |
| """ | |
| Pulls the last few messages from a specific user session. | |
| We will feed this to the Groq LLM so it remembers what it just said. | |
| """ | |
| select_query = """ | |
| SELECT user_message, bot_response | |
| FROM chat_history | |
| WHERE session_id = ? | |
| ORDER BY timestamp DESC | |
| LIMIT ?; | |
| """ | |
| self.cursor.execute(select_query, (session_id, limit)) | |
| results = self.cursor.fetchall() | |
| # SQLite returns Row objects. We convert them to standard dicts and reverse them. | |
| return list(reversed([dict(row) for row in results])) | |
| def close(self): | |
| """Safely shuts down the database connection.""" | |
| self.cursor.close() | |
| self.conn.close() | |
| print("π Database connection closed.") | |
| # --- EXECUTION BLOCK --- | |
| if __name__ == "__main__": | |
| db = MindGuardDatabase() | |
| # Simulate a user session | |
| test_session = "user_mohit_001" | |
| print("\n--- Testing Database Save ---") | |
| db.save_interaction( | |
| session_id=test_session, | |
| user_message="I have a massive presentation tomorrow and my chest is tight.", | |
| bot_response="I can sense the tension... start humming a low note.", | |
| emotion="Nervousness", | |
| risk_level="Medium" | |
| ) | |
| print("\n--- Testing Database Retrieval ---") | |
| history = db.get_recent_history(session_id=test_session) | |
| for row in history: | |
| print(f"User said: {row['user_message']}") | |
| print(f"Bot said: {row['bot_response'][:50]}...") # Truncated for readability | |
| db.close() |