# database.py import sqlite3 import os DB_NAME = "spanish_trainer.db" def get_connection(): """Returns a connection to the SQLite database with row factory enabled.""" conn = sqlite3.connect(DB_NAME) conn.row_factory = sqlite3.Row return conn def ensure_database_populated(): """ Creates empty tables using the unified schema if running in a fresh environment without a database file. """ conn = get_connection() cursor = conn.cursor() try: # 1. Simplified unified translations table cursor.execute(""" CREATE TABLE IF NOT EXISTS translations ( translation_id INTEGER PRIMARY KEY AUTOINCREMENT, es_text TEXT NOT NULL, en_text TEXT NOT NULL, source_context TEXT, tags TEXT, notes TEXT ); """) # 2. Key-value configuration table cursor.execute(""" CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT ); """) conn.commit() finally: conn.close() # ========================================== # SETTINGS CRUD FUNCTIONS # ========================================== def load_all_settings(): """Fetches all system configuration properties into a flat Python dictionary.""" conn = get_connection() cursor = conn.cursor() settings_dict = {} try: cursor.execute("SELECT settings.key, settings.value FROM settings;") for row in cursor.fetchall(): settings_dict[row["key"]] = row["value"] finally: conn.close() return settings_dict def save_setting_to_db(key, value): """Inserts or replaces an application configuration entry.""" conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?); """, (key, value)) conn.commit() finally: conn.close() # ========================================== # TRANSLATIONS CRUD FUNCTIONS # ========================================== def get_all_translations_explicit(): """ Retrieves all 784+ records using completely explicit, table-qualified column declarations for the engines. """ conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" SELECT translations.translation_id, translations.es_text, translations.en_text, translations.source_context, translations.tags, translations.notes FROM translations ORDER BY translations.translation_id ASC; """) return [dict(row) for row in cursor.fetchall()] finally: conn.close() def get_translation_by_id(translation_id): """Loads a single unified record row for specific inspection or editing.""" conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" SELECT translations.translation_id, translations.es_text, translations.en_text, translations.source_context, translations.tags, translations.notes FROM translations WHERE translations.translation_id = ?; """, (translation_id,)) row = cursor.fetchone() return dict(row) if row else None finally: conn.close() def update_translation_record(translation_id, es_text, en_text, source_context, tags, notes): """Saves sandbox interface edits directly back down into the table.""" conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" UPDATE translations SET es_text = ?, en_text = ?, source_context = ?, tags = ?, notes = ? WHERE translation_id = ?; """, (es_text, en_text, source_context, tags, notes, translation_id)) conn.commit() finally: conn.close() def delete_translation_record(translation_id): """Permanently drops a phrase card row from the data index.""" conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" DELETE FROM translations WHERE translations.translation_id = ?; """, (translation_id,)) conn.commit() finally: conn.close() def insert_translation_record(es_text, en_text, source_context, tags, notes): """Inserts a completely fresh record into the translations table.""" conn = get_connection() cursor = conn.cursor() try: cursor.execute(""" INSERT INTO translations (es_text, en_text, source_context, tags, notes) VALUES (?, ?, ?, ?, ?); """, (es_text, en_text, source_context, tags, notes)) conn.commit() finally: conn.close()