Taking the completion widget as an argument was overly complex.
The process now looks like:
1. CompletionView gets deletion request
2. CompletionView passes selected index to CompletionModel
3. CompletionModel passes the row data to the owning category
4. The category runs its custom completion function.
This also fixes a bug. With the switch to the hybrid (list/sql)
completion model, the view was no longer updating when items were
deleted. This fixes that by ensuring the correct signals are emitted.
The SQL model must be refreshed by running the query. We could try using
a SqlTableModel so we can call removeRows instead.
The test for deleting a url fails because qmodeltester claims the length
of the query model is still 3.
For QSqlQueryModel, the argument should always be an invalid index:
http://doc.qt.io/qt-5/qsqlquerymodel.html#canFetchMore
For a QStandardItemModel, it doesn't matter. Either way, passing the
top-level parent index was wrong.
_insert_query gets called with a query and dict of values such as:
{'val': 1, 'lucky': False, 'name': 'one'}
Via bindValues(), we only assign a placeholder in the query string to a value,
so we get a query with bindings like:
INSERT INTO Foo values(:lucky,:val,:name)
{':name': 'one', ':val': 1, ':lucky': False}
So what we're executing is something like:
INSERT INTO Foo values(false,1,"one")
However, if the column order in the database doesn't happen to be the order
we're passing the values in, we get the wrong values in the wrong columns.
Instead, we now do:
INSERT INTO Foo (lucky, val, name) values(false,1,"one")
Which inserts the values in the order we intended.
With Python 3.6, this just happened to work before because we always passed the
keyword arguments in the table column order, and in 3.6 dicts
(and thus **kwargs) happen to be ordered:
https://mail.python.org/pipermail/python-dev/2016-September/146327.html
On Travis CI we are sometimes seeing:
```
CompletionView.selection_changed[str].emit():
argument 1 has unexpected type 'int'
```
Cast the data to a string before emitting it just to be safe.
This allows replace to be a named parameter and allows consolidating
some duplicate code between various insert methods.
This also fixes some tests that broke because batch insert was broken.
No longer needed with sql backend. Query results build their own
namedtuple from the returned columns, and inserting new entries is just
done with named parameters.