139_spanish-voice-trainer/database.py

152 lines
4.5 KiB
Python
Raw Normal View History

2026-06-24 05:37:22 +00:00
# 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()