File size: 4,951 Bytes
634b5dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# db_manager.py
import sqlite3
from config import STUDENT_DB_PATH
import streamlit as st
import os
import time

MAX_RETRIES = 3
RETRY_DELAY = 2 # seconds

def get_db_connection():
    # Ensure the directory for the SQLite DB exists
    db_dir = os.path.dirname(STUDENT_DB_PATH)
    if db_dir and not os.path.exists(db_dir):
        try:
            os.makedirs(db_dir, exist_ok=True)
            print(f"Created directory for SQLite DB: {db_dir}")
        except Exception as e:
            st.error(f"无法创建SQLite数据库目录 {db_dir}: {e}")
            print(f"Could not create SQLite DB directory {db_dir}: {e}")
            return None # Cannot proceed if directory creation fails

    conn = None
    for attempt in range(MAX_RETRIES):
        try:
            conn = sqlite3.connect(STUDENT_DB_PATH, timeout=10) # Added timeout
            return conn
        except sqlite3.OperationalError as e:
            if "database is locked" in str(e):
                print(f"SQLite DB is locked (Attempt {attempt + 1}/{MAX_RETRIES}). Retrying in {RETRY_DELAY}s...")
                if attempt < MAX_RETRIES - 1:
                    time.sleep(RETRY_DELAY)
                else:
                    st.error("SQLite数据库持续锁定,请稍后再试。")
                    print("SQLite DB remains locked after multiple retries.")
                    return None
            else:
                st.error(f"连接SQLite数据库时出错: {e}")
                print(f"Error connecting to SQLite DB: {e}")
                return None
        except Exception as e: # Catch other potential errors
            st.error(f"连接SQLite数据库时发生未知错误: {e}")
            print(f"Unknown error connecting to SQLite DB: {e}")
            return None
    return None


def init_student_db():
    conn = get_db_connection()
    if conn is None:
        return
    try:
        cursor = conn.cursor()
        cursor.execute('''

        CREATE TABLE IF NOT EXISTS students (

            id INTEGER PRIMARY KEY AUTOINCREMENT,

            name TEXT UNIQUE NOT NULL,

            characteristics_summary TEXT,

            last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP

        )

        ''')
        conn.commit()
    except Exception as e:
        st.error(f"初始化学生数据库表时出错: {e}")
        print(f"Error initializing student DB table: {e}")
    finally:
        if conn:
            conn.close()

def add_or_update_student(name: str, characteristics_summary: str = None):
    conn = get_db_connection()
    if conn is None:
        return False
    try:
        cursor = conn.cursor()
        # Upsert logic: Insert if name doesn't exist, or update if it does.
        # Using INSERT OR IGNORE then UPDATE is a common pattern.
        cursor.execute("INSERT OR IGNORE INTO students (name) VALUES (?)", (name,))
        if characteristics_summary is not None: # Allow updating only name or also characteristics
            cursor.execute("""

            UPDATE students

            SET characteristics_summary = ?, last_updated = CURRENT_TIMESTAMP

            WHERE name = ?

            """, (characteristics_summary, name))
        else: # Only ensure the student exists, update last_updated if already present
             cursor.execute("""

            UPDATE students

            SET last_updated = CURRENT_TIMESTAMP

            WHERE name = ? AND EXISTS (SELECT 1 FROM students WHERE name = ?)

            """, (name,name))

        conn.commit()
        return True
    except Exception as e:
        st.error(f"添加或更新学生 '{name}' 时出错: {e}")
        print(f"Error adding/updating student '{name}': {e}")
        return False
    finally:
        if conn:
            conn.close()

def get_student_characteristics(name: str):
    conn = get_db_connection()
    if conn is None:
        return None
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT characteristics_summary FROM students WHERE name = ?", (name,))
        result = cursor.fetchone()
        return result[0] if result else None
    except Exception as e:
        st.error(f"获取学生 '{name}' 特点时出错: {e}")
        print(f"Error getting characteristics for student '{name}': {e}")
        return None
    finally:
        if conn:
            conn.close()

def get_all_student_names():
    conn = get_db_connection()
    if conn is None:
        return []
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT name FROM students ORDER BY name ASC")
        results = [row[0] for row in cursor.fetchall()]
        return results
    except Exception as e:
        st.error(f"获取所有学生姓名时出错: {e}")
        print(f"Error getting all student names: {e}")
        return []
    finally:
        if conn:
            conn.close()