Initial Codes
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
QThread-based async worker for all database operations.
|
||||
Emits results/errors via Qt signals so the UI stays responsive.
|
||||
"""
|
||||
import time
|
||||
from PyQt6.QtCore import QThread, pyqtSignal
|
||||
|
||||
from app.utils.logger import get_logger
|
||||
|
||||
_log = get_logger(__name__)
|
||||
|
||||
|
||||
class QueryWorker(QThread):
|
||||
"""Execute a SQL query in a background thread."""
|
||||
|
||||
finished = pyqtSignal(list, list, int, float) # cols, rows, rowcount, elapsed_sec
|
||||
error = pyqtSignal(str)
|
||||
script_done = pyqtSignal(list) # list of (cols, rows, cnt, msg)
|
||||
|
||||
def __init__(self, driver, sql: str, is_script: bool = False, parent=None):
|
||||
super().__init__(parent)
|
||||
self._driver = driver
|
||||
self._sql = sql
|
||||
self._script = is_script
|
||||
|
||||
def run(self):
|
||||
t0 = time.perf_counter()
|
||||
try:
|
||||
if self._script:
|
||||
results = self._driver.execute_script(self._sql)
|
||||
self.script_done.emit(results)
|
||||
else:
|
||||
cols, rows, cnt = self._driver.execute_query(self._sql)
|
||||
elapsed = time.perf_counter() - t0
|
||||
_log.debug("Query OK (%.3f s, %d row(s)) SQL: %.200s",
|
||||
elapsed, cnt, self._sql.replace("\n", " "))
|
||||
self.finished.emit(cols, list(rows), cnt, elapsed)
|
||||
except Exception as e:
|
||||
_log.error("Query failed SQL: %.300s", self._sql.replace("\n", " "),
|
||||
exc_info=True)
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class SchemaWorker(QThread):
|
||||
"""Generic async loader for schema introspection calls."""
|
||||
|
||||
result = pyqtSignal(object)
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, fn, *args, parent=None):
|
||||
super().__init__(parent)
|
||||
self._fn = fn
|
||||
self._args = args
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
data = self._fn(*self._args)
|
||||
self.result.emit(data)
|
||||
except Exception as e:
|
||||
_log.error("SchemaWorker error fn=%s args=%s",
|
||||
getattr(self._fn, "__name__", "?"), self._args,
|
||||
exc_info=True)
|
||||
self.error.emit(str(e))
|
||||
|
||||
|
||||
class TableDataWorker(QThread):
|
||||
"""Load paginated table data in background."""
|
||||
|
||||
finished = pyqtSignal(list, list, int) # cols, rows, total_count
|
||||
error = pyqtSignal(str)
|
||||
|
||||
def __init__(self, driver, database, table,
|
||||
where="", order_by="", limit=1000, offset=0, parent=None):
|
||||
super().__init__(parent)
|
||||
self._driver = driver
|
||||
self._database = database
|
||||
self._table = table
|
||||
self._where = where
|
||||
self._order_by = order_by
|
||||
self._limit = limit
|
||||
self._offset = offset
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
cols, rows, cnt = self._driver.get_table_data(
|
||||
self._database, self._table,
|
||||
self._where, self._order_by, self._limit, self._offset
|
||||
)
|
||||
total = self._driver.get_table_row_count(
|
||||
self._database, self._table, self._where
|
||||
)
|
||||
self.finished.emit(cols, list(rows), total)
|
||||
except Exception as e:
|
||||
_log.error("TableDataWorker error table=%s.%s where=%r",
|
||||
self._database, self._table, self._where,
|
||||
exc_info=True)
|
||||
self.error.emit(str(e))
|
||||
|
||||
Reference in New Issue
Block a user