Use a prepared query for historyContains.

This is called often, hopefully a prepared query will speed it up.
This also modifies Query.run to return self for easier chaining, so you
can use `query.run.value()` instead of `query.run` ; query.value()`.
This commit is contained in:
Ryan Roden-Corrent 2017-06-06 21:48:58 -04:00
parent 5b827cf86a
commit 478a719f77
3 changed files with 21 additions and 17 deletions

View File

@ -79,6 +79,7 @@ class WebHistory(sql.SqlTable):
super().__init__("History", ['url', 'title', 'atime', 'redirect'],
parent=parent)
self.create_index('HistoryIndex', 'url', where='not redirect')
self._contains_query = self.contains_query('url')
self._between_query = sql.Query('SELECT * FROM History '
'where not redirect '
'and not url like "qute://%" '
@ -97,7 +98,7 @@ class WebHistory(sql.SqlTable):
return utils.get_repr(self, length=len(self))
def __contains__(self, url):
return self.contains('url', url)
return self._contains_query.run([url]).value()
def _add_entry(self, entry):
"""Add an entry to the in-memory database."""

View File

@ -83,6 +83,7 @@ class Query(QSqlQuery):
if not self.exec_():
raise SqlException('Failed to exec query "{}": "{}"'.format(
self.lastQuery(), self.lastError().text()))
return self
def value(self):
"""Return the result of a single-value query (e.g. an EXISTS)."""
@ -140,17 +141,14 @@ class SqlTable(QObject):
q.run()
return iter(q)
def contains(self, field, value):
"""Return whether the table contains the matching item.
def contains_query(self, field):
"""Return a prepared query that checks for the existence of an item.
Args:
field: Field to match.
value: Value to check for the given field.
"""
q = Query("Select EXISTS(SELECT * FROM {} where {} = ?)"
.format(self._name, field))
q.run([value])
return q.value()
return Query("Select EXISTS(SELECT * FROM {} where {} = ?)"
.format(self._name, field))
def __len__(self):
"""Return the count of rows in the table."""

View File

@ -94,15 +94,20 @@ def test_contains():
table.insert(['one', 1, False])
table.insert(['nine', 9, False])
table.insert(['thirteen', 13, True])
assert table.contains('name', 'one')
assert table.contains('name', 'thirteen')
assert table.contains('val', 9)
assert table.contains('lucky', False)
assert table.contains('lucky', True)
assert not table.contains('name', 'oone')
assert not table.contains('name', 1)
assert not table.contains('name', '*')
assert not table.contains('val', 10)
name_query = table.contains_query('name')
val_query = table.contains_query('val')
lucky_query = table.contains_query('lucky')
assert name_query.run(['one']).value()
assert name_query.run(['thirteen']).value()
assert val_query.run([9]).value()
assert lucky_query.run([False]).value()
assert lucky_query.run([True]).value()
assert not name_query.run(['oone']).value()
assert not name_query.run([1]).value()
assert not name_query.run(['*']).value()
assert not val_query.run([10]).value()
def test_delete_all(qtbot):