Handle query errors

This commit is contained in:
Kovid Goyal 2022-06-09 08:32:45 +05:30
parent d057f8e238
commit eba1b4f05e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -15,7 +15,8 @@ from qt.core import (
) )
from threading import Event, Thread from threading import Event, Thread
from calibre.gui2 import gprefs from calibre.db import FTSQueryError
from calibre.gui2 import gprefs, error_dialog
from calibre.gui2.fts.utils import get_db from calibre.gui2.fts.utils import get_db
from calibre.gui2.library.annotations import BusyCursor from calibre.gui2.library.annotations import BusyCursor
from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.progress_indicator import ProgressIndicator
@ -88,6 +89,7 @@ class ResultsModel(QAbstractItemModel):
search_started = pyqtSignal() search_started = pyqtSignal()
matches_found = pyqtSignal(int) matches_found = pyqtSignal(int)
search_complete = pyqtSignal() search_complete = pyqtSignal()
query_failed = pyqtSignal(str, str)
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@ -104,18 +106,22 @@ class ResultsModel(QAbstractItemModel):
def search(self, fts_engine_query, use_stemming=True, restrict_to_book_ids=None): def search(self, fts_engine_query, use_stemming=True, restrict_to_book_ids=None):
db = get_db() db = get_db()
failure = []
def construct(all_matches): def construct(all_matches):
self.result_map = r = {} self.result_map = r = {}
sr = self.results = [] sr = self.results = []
for x in all_matches: try:
book_id = x['book_id'] for x in all_matches:
results = r.get(book_id) book_id = x['book_id']
if results is None: results = r.get(book_id)
results = Results(book_id) if results is None:
r[book_id] = len(sr) results = Results(book_id)
sr.append(results) r[book_id] = len(sr)
sr.append(results)
except FTSQueryError as e:
failure.append(e)
sk = fts_engine_query, use_stemming, restrict_to_book_ids, id(db) sk = fts_engine_query, use_stemming, restrict_to_book_ids, id(db)
if sk == self.current_search_key: if sk == self.current_search_key:
@ -130,15 +136,22 @@ class ResultsModel(QAbstractItemModel):
restrict_to_book_ids=restrict_to_book_ids, result_type=construct, return_text=False restrict_to_book_ids=restrict_to_book_ids, result_type=construct, return_text=False
) )
self.endResetModel() self.endResetModel()
self.matches_found.emit(len(self.results)) if not failure:
self.matches_found.emit(len(self.results))
self.current_query_id = next(self.query_id_counter) self.current_query_id = next(self.query_id_counter)
self.current_thread_abort = Event() self.current_thread_abort = Event()
self.current_thread = Thread( if failure:
name='FTSQuery', daemon=True, target=self.search_text_in_thread, args=( self.current_thread = Thread(target=lambda *a: None)
self.current_query_id, self.current_thread_abort, fts_engine_query,), kwargs=dict( self.all_results_found.emit(self.current_query_id)
use_stemming=use_stemming, highlight_start='\x1d', highlight_end='\x1d', snippet_size=64, if fts_engine_query.strip():
restrict_to_book_ids=restrict_to_book_ids, return_text=True) self.query_failed.emit(fts_engine_query, str(failure[0]))
) else:
self.current_thread = Thread(
name='FTSQuery', daemon=True, target=self.search_text_in_thread, args=(
self.current_query_id, self.current_thread_abort, fts_engine_query,), kwargs=dict(
use_stemming=use_stemming, highlight_start='\x1d', highlight_end='\x1d', snippet_size=64,
restrict_to_book_ids=restrict_to_book_ids, return_text=True)
)
self.current_thread.start() self.current_thread.start()
return True return True
@ -252,11 +265,18 @@ class ResultsView(QTreeView):
self.m = ResultsModel(self) self.m = ResultsModel(self)
self.m.search_complete.connect(self.search_complete) self.m.search_complete.connect(self.search_complete)
self.m.search_started.connect(self.search_started) self.m.search_started.connect(self.search_started)
self.m.query_failed.connect(self.query_failed, type=Qt.ConnectionType.QueuedConnection)
self.m.matches_found.connect(self.matches_found) self.m.matches_found.connect(self.matches_found)
self.setModel(self.m) self.setModel(self.m)
self.delegate = SearchDelegate(self) self.delegate = SearchDelegate(self)
self.setItemDelegate(self.delegate) self.setItemDelegate(self.delegate)
def query_failed(self, query, err_msg):
error_dialog(self, _('Invalid search query'), _(
'The search query: {query} was not understood. See <a href="{fts_url}">here</a> for details on the'
' supported query syntax.').format(
query=query, fts_url='https://www.sqlite.org/fts5.html#full_text_query_syntax'), det_msg=err_msg, show=True)
def search(self, *a): def search(self, *a):
gui = get_gui() gui = get_gui()
restrict = None restrict = None