Implement custom where clause in SQL.
Allow categories to specify a WHERE clause that applies in addition to the pattern filter. This allows the url completion model to filter out redirect entries. This also fixed the usage of ESCAPE so it applies to all the LIKE statements.
This commit is contained in:
parent
9f27a9a5d7
commit
fe80878788
@ -29,7 +29,7 @@ from qutebrowser.misc import sql
|
||||
|
||||
|
||||
class SqlCompletionCategory(QSqlQueryModel):
|
||||
def __init__(self, name, sort_by, sort_order, limit, select,
|
||||
def __init__(self, name, sort_by, sort_order, limit, select, where,
|
||||
columns_to_filter, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.tablename = name
|
||||
@ -37,9 +37,12 @@ class SqlCompletionCategory(QSqlQueryModel):
|
||||
query = sql.run_query('select * from {} limit 1'.format(name))
|
||||
self._fields = [query.record().fieldName(i) for i in columns_to_filter]
|
||||
|
||||
querystr = 'select {} from {} where '.format(select, name)
|
||||
querystr += ' or '.join('{} like ?'.format(f) for f in self._fields)
|
||||
querystr += " escape '\\'"
|
||||
querystr = 'select {} from {} where ('.format(select, name)
|
||||
querystr += ' or '.join("{} like ? escape '\\'".format(f)
|
||||
for f in self._fields)
|
||||
querystr += ')'
|
||||
if where:
|
||||
querystr += ' and ' + where
|
||||
|
||||
if sort_by:
|
||||
sortstr = 'asc' if sort_order == Qt.AscendingOrder else 'desc'
|
||||
@ -87,13 +90,14 @@ class SqlCompletionModel(QAbstractItemModel):
|
||||
self.srcmodel = self # TODO: dummy for compat with old API
|
||||
self.pattern = ''
|
||||
|
||||
def new_category(self, name, select='*', sort_by=None,
|
||||
def new_category(self, name, select='*', where=None, sort_by=None,
|
||||
sort_order=None, limit=None):
|
||||
"""Create a new completion category and add it to this model.
|
||||
|
||||
Args:
|
||||
name: Name of category, and the table in the database.
|
||||
select: A custom result column expression for the select statement.
|
||||
where: An optional clause to filter out some rows.
|
||||
sort_by: The name of the field to sort by, or None for no sorting.
|
||||
sort_order: Sorting order, if sort_by is non-None.
|
||||
limit: Maximum row count to return on a query.
|
||||
@ -102,7 +106,7 @@ class SqlCompletionModel(QAbstractItemModel):
|
||||
"""
|
||||
cat = SqlCompletionCategory(name, parent=self, sort_by=sort_by,
|
||||
sort_order=sort_order, limit=limit,
|
||||
select=select,
|
||||
select=select, where=where,
|
||||
columns_to_filter=self.columns_to_filter)
|
||||
self._categories.append(cat)
|
||||
|
||||
|
@ -38,7 +38,8 @@ def url():
|
||||
select_time = "strftime('{}', atime, 'unixepoch')".format(timefmt)
|
||||
model.new_category('History',
|
||||
limit=limit,
|
||||
select='url, title, {}'.format(select_time))
|
||||
select='url, title, {}'.format(select_time),
|
||||
where='not redirect')
|
||||
model.new_category('Quickmarks', select='url, name')
|
||||
model.new_category('Bookmarks')
|
||||
return model
|
||||
|
@ -154,6 +154,8 @@ def web_history(stubs, init_sql):
|
||||
"""Pre-populate the web-history database."""
|
||||
table = sql.SqlTable("History", ['url', 'title', 'atime', 'redirect'],
|
||||
primary_key='url')
|
||||
table.insert(['http://some-redirect.example.com', 'redirect',
|
||||
datetime(2016, 9, 5).timestamp(), True])
|
||||
table.insert(['http://qutebrowser.org', 'qutebrowser',
|
||||
datetime(2015, 9, 5).timestamp(), False])
|
||||
table.insert(['https://python.org', 'Welcome to Python.org',
|
||||
@ -266,6 +268,7 @@ def test_url_completion(qtmodeltester, config_stub, web_history, quickmarks,
|
||||
- quickmarks, bookmarks, and urls are included
|
||||
- no more than 'web-history-max-items' items are included (TODO)
|
||||
- the most recent entries are included
|
||||
- redirect entries are not included
|
||||
"""
|
||||
# TODO: time formatting and item limiting
|
||||
config_stub.data['completion'] = {'timestamp-format': '%Y-%m-%d',
|
||||
|
@ -156,6 +156,10 @@ def test_sorting(sort_by, sort_order, data, expected):
|
||||
[('A', [('a_b', '', ''), ('__a', '', ''), ('abc', '', '')])],
|
||||
[('A', [('a_b', '', ''), ('__a', '', '')])]),
|
||||
|
||||
('%', [0, 1],
|
||||
[('A', [('\\foo', '\\bar', '')])],
|
||||
[('A', [])]),
|
||||
|
||||
("can't", [0],
|
||||
[('A', [("can't touch this", '', ''), ('a', '', '')])],
|
||||
[('A', [("can't touch this", '', '')])]),
|
||||
@ -218,3 +222,12 @@ def test_select():
|
||||
model = sqlmodel.SqlCompletionModel()
|
||||
model.new_category('test_select', select='b, c, a')
|
||||
_check_model(model, [('test_select', [('bar', 'baz', 'foo')])])
|
||||
|
||||
|
||||
def test_where():
|
||||
table = sql.SqlTable('test_where', ['a', 'b', 'c'], primary_key='a')
|
||||
table.insert(['foo', 'bar', False])
|
||||
table.insert(['baz', 'biz', True])
|
||||
model = sqlmodel.SqlCompletionModel()
|
||||
model.new_category('test_where', where='not c')
|
||||
_check_model(model, [('test_where', [('foo', 'bar', False)])])
|
||||
|
Loading…
Reference in New Issue
Block a user