From 9f27a9a5d77a5bdd63d9c6a1d1f52e8429d87a97 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 14 Feb 2017 20:32:44 -0500 Subject: [PATCH] Implement column selectors for sql completion. A SQL completion category can now provide a customized column expression for the select statement. This enables the url model to format timestamps, as well as rearrange the name and url in the quickmark section. --- qutebrowser/completion/models/sqlmodel.py | 12 +++++++---- qutebrowser/completion/models/urlmodel.py | 8 ++++++-- tests/unit/completion/test_models.py | 25 +++++------------------ tests/unit/completion/test_sqlmodel.py | 8 ++++++++ 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/qutebrowser/completion/models/sqlmodel.py b/qutebrowser/completion/models/sqlmodel.py index b45990e6d..8a0abda2b 100644 --- a/qutebrowser/completion/models/sqlmodel.py +++ b/qutebrowser/completion/models/sqlmodel.py @@ -29,15 +29,15 @@ from qutebrowser.misc import sql class SqlCompletionCategory(QSqlQueryModel): - def __init__(self, name, sort_by, sort_order, limit, columns_to_filter, - parent=None): + def __init__(self, name, sort_by, sort_order, limit, select, + columns_to_filter, parent=None): super().__init__(parent=parent) self.tablename = name 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(self.tablename) + querystr = 'select {} from {} where '.format(select, name) querystr += ' or '.join('{} like ?'.format(f) for f in self._fields) querystr += " escape '\\'" @@ -87,18 +87,22 @@ class SqlCompletionModel(QAbstractItemModel): self.srcmodel = self # TODO: dummy for compat with old API self.pattern = '' - def new_category(self, name, sort_by=None, sort_order=None, limit=None): + def new_category(self, name, select='*', 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. 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. Return: A new CompletionCategory. """ cat = SqlCompletionCategory(name, parent=self, sort_by=sort_by, sort_order=sort_order, limit=limit, + select=select, columns_to_filter=self.columns_to_filter) self._categories.append(cat) diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py index b844fa93e..164a5da15 100644 --- a/qutebrowser/completion/models/urlmodel.py +++ b/qutebrowser/completion/models/urlmodel.py @@ -33,8 +33,12 @@ def url(): model = sqlmodel.SqlCompletionModel(column_widths=(40, 50, 10), columns_to_filter=[urlcol, textcol]) + limit = config.get('completion', 'web-history-max-items') + timefmt = config.get('completion', 'timestamp-format') + select_time = "strftime('{}', atime, 'unixepoch')".format(timefmt) model.new_category('History', - limit=config.get('completion', 'web-history-max-items')) - model.new_category('Quickmarks') + limit=limit, + select='url, title, {}'.format(select_time)) + model.new_category('Quickmarks', select='url, name') model.new_category('Bookmarks') return model diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py index 91ac8286f..21b65e092 100644 --- a/tests/unit/completion/test_models.py +++ b/tests/unit/completion/test_models.py @@ -275,34 +275,19 @@ def test_url_completion(qtmodeltester, config_stub, web_history, quickmarks, qtmodeltester.check(model) _check_completions(model, { - # TODO: rearrange columns so address comes first - #"Quickmarks": [ - # ('https://wiki.archlinux.org', 'aw', None), - # ('https://duckduckgo.com', 'ddg', None), - # ('https://wikipedia.org', 'wiki', None), - #], "Quickmarks": [ - ('aw', 'https://wiki.archlinux.org', None), - ('ddg', 'https://duckduckgo.com', None), - ('wiki', 'https://wikipedia.org', None), + ('https://wiki.archlinux.org', 'aw', None), + ('https://duckduckgo.com', 'ddg', None), + ('https://wikipedia.org', 'wiki', None), ], "Bookmarks": [ ('https://github.com', 'GitHub', None), ('https://python.org', 'Welcome to Python.org', None), ('http://qutebrowser.org', 'qutebrowser | qutebrowser', None), ], - # TODO: time formatting and item limiting - #"History": [ - # ('https://python.org', 'Welcome to Python.org', '2016-03-08'), - # ('https://github.com', 'GitHub', '2016-05-01'), - # ('http://qutebrowser.org', 'qutebrowser | qutebrowser', - # '2015-09-05', False) - #], "History": [ - ('http://qutebrowser.org', 'qutebrowser', - datetime(2015, 9, 5).timestamp()), - ('https://python.org', 'Welcome to Python.org', - datetime(2016, 3, 8).timestamp()), + ('http://qutebrowser.org', 'qutebrowser', '2015-09-05'), + ('https://python.org', 'Welcome to Python.org', '2016-03-08'), ], }) diff --git a/tests/unit/completion/test_sqlmodel.py b/tests/unit/completion/test_sqlmodel.py index 1044a831f..a0dbbe7b3 100644 --- a/tests/unit/completion/test_sqlmodel.py +++ b/tests/unit/completion/test_sqlmodel.py @@ -210,3 +210,11 @@ def test_limit(): model = sqlmodel.SqlCompletionModel() model.new_category('test_limit', limit=3) assert model.count() == 3 + + +def test_select(): + table = sql.SqlTable('test_select', ['a', 'b', 'c'], primary_key='a') + table.insert(['foo', 'bar', 'baz']) + model = sqlmodel.SqlCompletionModel() + model.new_category('test_select', select='b, c, a') + _check_model(model, [('test_select', [('bar', 'baz', 'foo')])])