Add a CompletionHistory instead of HistoryVisits table
This commit is contained in:
parent
c64b7d00e6
commit
57d96a4512
@ -72,13 +72,13 @@ class Entry:
|
||||
return self.url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
|
||||
|
||||
|
||||
class HistoryVisits(sql.SqlTable):
|
||||
class CompletionHistory(sql.SqlTable):
|
||||
|
||||
"""Secondary table with visited URLs and timestamps."""
|
||||
"""History which only has the newest entry for each URL."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__("Visits", ['url', 'atime'],
|
||||
fkeys={'url': 'History(url)'})
|
||||
super().__init__("CompletionHistory", ['url', 'title', 'last_atime'],
|
||||
constraints={'url': 'PRIMARY KEY'}, parent=parent)
|
||||
|
||||
|
||||
class WebHistory(sql.SqlTable):
|
||||
@ -86,14 +86,11 @@ class WebHistory(sql.SqlTable):
|
||||
"""The global history of visited pages."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__("History",
|
||||
['url', 'title', 'last_atime', 'redirect'],
|
||||
constraints={'url': 'PRIMARY KEY'},
|
||||
super().__init__("History", ['url', 'title', 'atime', 'redirect'],
|
||||
parent=parent)
|
||||
self.visits = HistoryVisits(parent=self)
|
||||
self.completion = CompletionHistory(parent=self)
|
||||
self.create_index('HistoryIndex', 'url')
|
||||
self._contains_query = self.contains_query('url')
|
||||
# FIXME
|
||||
self._between_query = sql.Query('SELECT * FROM History '
|
||||
'where not redirect '
|
||||
'and not url like "qute://%" '
|
||||
@ -117,8 +114,10 @@ class WebHistory(sql.SqlTable):
|
||||
def _add_entry(self, entry):
|
||||
"""Add an entry to the in-memory database."""
|
||||
self.insert([entry.url_str(), entry.title, int(entry.atime),
|
||||
entry.redirect], replace=True)
|
||||
self.visits.insert([entry.url_str(), int(entry.atime)])
|
||||
entry.redirect])
|
||||
if not entry.redirect:
|
||||
self.completion.insert([entry.url_str(), entry.title,
|
||||
int(entry.atime)], replace=True)
|
||||
|
||||
def get_recent(self):
|
||||
"""Get the most recent history entries."""
|
||||
@ -229,9 +228,10 @@ class WebHistory(sql.SqlTable):
|
||||
raise ValueError("Invalid flags {!r}".format(flags))
|
||||
|
||||
redirect = 'r' in flags
|
||||
row = (url, title, float(atime), redirect)
|
||||
completion_row = None if redirect else (url, title, float(atime))
|
||||
|
||||
return ((url, float(atime)),
|
||||
(url, title, float(atime), bool(redirect)))
|
||||
return (row, completion_row)
|
||||
|
||||
def import_txt(self):
|
||||
"""Import a history text file into sqlite if it exists.
|
||||
@ -258,20 +258,21 @@ class WebHistory(sql.SqlTable):
|
||||
"""Import a text file into the sql database."""
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
rows = []
|
||||
visit_rows = []
|
||||
completion_rows = []
|
||||
for (i, line) in enumerate(f):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
visit_row, row = self._parse_entry(line.strip())
|
||||
row, completion_row = self._parse_entry(line.strip())
|
||||
rows.append(row)
|
||||
visit_rows.append(visit_row)
|
||||
if completion_row is not None:
|
||||
completion_rows.append(completion_row)
|
||||
except ValueError:
|
||||
raise Exception('Failed to parse line #{} of {}: "{}"'
|
||||
.format(i, path, line))
|
||||
self.insert_batch(rows, replace=True)
|
||||
self.visits.insert_batch(visit_rows)
|
||||
self.insert_batch(rows)
|
||||
self.completion.insert_batch(completion_rows, replace=True)
|
||||
|
||||
@cmdutils.register(instance='web-history', debug=True)
|
||||
def debug_dump_history(self, dest):
|
||||
@ -280,7 +281,6 @@ class WebHistory(sql.SqlTable):
|
||||
Args:
|
||||
dest: Where to write the file to.
|
||||
"""
|
||||
# FIXME
|
||||
dest = os.path.expanduser(dest)
|
||||
|
||||
lines = ('{}{} {} {}'
|
||||
|
@ -30,7 +30,7 @@ class SqlCategory(QSqlQueryModel):
|
||||
"""Wraps a SqlQuery for use as a completion category."""
|
||||
|
||||
def __init__(self, name, *, filter_fields, sort_by=None, sort_order=None,
|
||||
select='*', where=None, group_by=None, suffix=None, parent=None):
|
||||
select='*', where=None, group_by=None, parent=None):
|
||||
"""Create a new completion category backed by a sql table.
|
||||
|
||||
Args:
|
||||
|
@ -77,8 +77,8 @@ def url():
|
||||
timefmt = config.get('completion', 'timestamp-format')
|
||||
select_time = "strftime('{}', last_atime, 'unixepoch')".format(timefmt)
|
||||
hist_cat = sqlcategory.SqlCategory(
|
||||
'History', sort_order='desc', sort_by='last_atime',
|
||||
'CompletionHistory', sort_order='desc', sort_by='last_atime',
|
||||
filter_fields=['url', 'title'],
|
||||
select='url, title, {}'.format(select_time), where='not redirect')
|
||||
select='url, title, {}'.format(select_time))
|
||||
model.add_category(hist_cat)
|
||||
return model
|
||||
|
@ -106,8 +106,7 @@ class SqlTable(QObject):
|
||||
|
||||
changed = pyqtSignal()
|
||||
|
||||
def __init__(self, name, fields, constraints=None, fkeys=None,
|
||||
parent=None):
|
||||
def __init__(self, name, fields, constraints=None, parent=None):
|
||||
"""Create a new table in the sql database.
|
||||
|
||||
Raises SqlException if the table already exists.
|
||||
@ -116,22 +115,16 @@ class SqlTable(QObject):
|
||||
name: Name of the table.
|
||||
fields: A list of field names.
|
||||
constraints: A dict mapping field names to constraint strings.
|
||||
fkeys: A dict mapping field names to foreign keys.
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self._name = name
|
||||
|
||||
constraints = constraints or {}
|
||||
fkeys = fkeys or {}
|
||||
|
||||
column_defs = ['{} {}'.format(field, constraints.get(field, ''))
|
||||
for field in fields]
|
||||
for field, fkey in sorted(fkeys.items()):
|
||||
column_defs.append('FOREIGN KEY({}) REFERENCES {}'.format(
|
||||
field, fkey))
|
||||
|
||||
q = Query("CREATE TABLE IF NOT EXISTS {} ({})"
|
||||
.format(name, ','.join(column_defs)))
|
||||
|
||||
q.run()
|
||||
# pylint: disable=invalid-name
|
||||
self.Entry = collections.namedtuple(name + '_Entry', fields)
|
||||
|
@ -155,24 +155,22 @@ def bookmarks(bookmark_manager_stub):
|
||||
|
||||
@pytest.fixture
|
||||
def web_history_stub(stubs, init_sql):
|
||||
return sql.SqlTable("History", ['url', 'title', 'atime', 'redirect'])
|
||||
return sql.SqlTable("CompletionHistory", ['url', 'title', 'last_atime'])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def web_history(web_history_stub, init_sql):
|
||||
"""Pre-populate the web-history database."""
|
||||
web_history_stub.insert(['http://some-redirect.example.com', 'redirect',
|
||||
datetime(2016, 9, 5).timestamp(), True])
|
||||
web_history_stub.insert(['http://qutebrowser.org', 'qutebrowser',
|
||||
datetime(2015, 9, 5).timestamp(), False])
|
||||
datetime(2015, 9, 5).timestamp()])
|
||||
web_history_stub.insert(['https://python.org', 'Welcome to Python.org',
|
||||
datetime(2016, 2, 8).timestamp(), False])
|
||||
datetime(2016, 2, 8).timestamp()])
|
||||
web_history_stub.insert(['https://python.org', 'Welcome to Python.org',
|
||||
datetime(2016, 3, 8).timestamp(), False])
|
||||
datetime(2016, 3, 8).timestamp()])
|
||||
web_history_stub.insert(['https://python.org', 'Welcome to Python.org',
|
||||
datetime(2014, 3, 8).timestamp(), False])
|
||||
datetime(2014, 3, 8).timestamp()])
|
||||
web_history_stub.insert(['https://github.com', 'https://github.com',
|
||||
datetime(2016, 5, 1).timestamp(), False])
|
||||
datetime(2016, 5, 1).timestamp()])
|
||||
return web_history_stub
|
||||
|
||||
|
||||
@ -336,7 +334,7 @@ def test_url_completion_pattern(config_stub, web_history_stub,
|
||||
url, title, pattern, rowcount):
|
||||
"""Test that url completion filters by url and title."""
|
||||
config_stub.data['completion'] = {'timestamp-format': '%Y-%m-%d'}
|
||||
web_history_stub.insert([url, title, 0, False])
|
||||
web_history_stub.insert([url, title, 0])
|
||||
model = urlmodel.url()
|
||||
model.set_pattern(pattern)
|
||||
# 2, 0 is History
|
||||
@ -582,10 +580,9 @@ def test_url_completion_benchmark(benchmark, config_stub,
|
||||
'web-history-max-items': 1000}
|
||||
|
||||
entries = [web_history_stub.Entry(
|
||||
atime=i,
|
||||
last_atime=i,
|
||||
url='http://example.com/{}'.format(i),
|
||||
title='title{}'.format(i),
|
||||
redirect=False)
|
||||
title='title{}'.format(i))
|
||||
for i in range(100000)]
|
||||
|
||||
web_history_stub.insert_batch(entries)
|
||||
|
Loading…
Reference in New Issue
Block a user