v1.8.56: Database Tree Explorer + thread-safe SQL operations

- Add HeidiSQL-style database tree panel (Databases → Tables → Columns)
- Lazy loading with ttk.Treeview, context menus, double-click SELECT TOP 1000
- Fix pymysql thread safety: serialize all DB ops with threading.Lock
- Use lock.acquire(timeout=10) to prevent deadlocks between tree and query threads
- Always reset _executing flag in finally block to prevent stuck queries
- Add _ensure_connected() auto-reconnect on broken connections
- Add sql_client check_connection() null safety
- Add 12 tree-related i18n keys (EN/RU/ZH)
- Clean up old releases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chrome-storm-c442
2026-02-25 04:18:45 -05:00
parent ac7e174e41
commit 6f0bfe39f1
7 changed files with 528 additions and 119 deletions

View File

@@ -327,6 +327,19 @@ _EN = {
"query_connected": "Connected to {alias} ({db})",
"query_connecting": "Connecting...",
"query_disconnected": "Not connected",
# Database tree
"tree_databases": "Databases",
"tree_refresh": "Refresh",
"tree_use_db": "Use database",
"tree_select_top": "SELECT TOP 1000",
"tree_describe": "Describe table",
"tree_copy_name": "Copy name",
"tree_select_column": "Insert column",
"tree_loading": "Loading...",
"tree_no_tables": "(no tables)",
"tree_no_columns": "(no columns)",
"tree_connected": "Connected",
"query_exported": "Exported to {path}",
# Redis tab
@@ -741,6 +754,19 @@ _RU = {
"query_disconnected": "Не подключено",
"query_exported": "Экспортировано в {path}",
# Database tree
"tree_databases": "Базы данных",
"tree_refresh": "Обновить",
"tree_use_db": "Выбрать базу",
"tree_select_top": "SELECT TOP 1000",
"tree_describe": "Описание таблицы",
"tree_copy_name": "Копировать имя",
"tree_select_column": "Вставить колонку",
"tree_loading": "Загрузка...",
"tree_no_tables": "(нет таблиц)",
"tree_no_columns": "(нет колонок)",
"tree_connected": "Подключено",
# Redis tab
"redis_clear": "Очистить",
"redis_execute": "Выполнить",
@@ -1153,6 +1179,19 @@ _ZH = {
"query_disconnected": "未连接",
"query_exported": "已导出到 {path}",
# Database tree
"tree_databases": "数据库",
"tree_refresh": "刷新",
"tree_use_db": "选择数据库",
"tree_select_top": "SELECT TOP 1000",
"tree_describe": "表描述",
"tree_copy_name": "复制名称",
"tree_select_column": "插入列",
"tree_loading": "加载中...",
"tree_no_tables": "(无表)",
"tree_no_columns": "(无列)",
"tree_connected": "已连接",
# Redis tab
"redis_clear": "清除",
"redis_execute": "执行",

View File

@@ -70,6 +70,8 @@ class SQLClient:
log.info("sql_client: disconnected")
def check_connection(self) -> bool:
if self._conn is None:
return False
try:
cur = self._conn.cursor()
cur.execute("SELECT 1")