Add cached table example
Needs ReviewPublic

Authored by jfita on Apr 24 2020, 10:09 PM.

Details

Reviewers
staniek
piggz
Summary

It is a reimplementation of the same example from Qt: an application
that demonstrates how to use a table view to show an edit a table with
KDb, caching any changes to the data until the user explicitly submits
them. See https://doc.qt.io/qt-5/qtsql-cachedtable-example.html.

According to Jarosław, the only currently available QTableView-like
widget that has support for KDb is part of KEXI and can not be easily
reused. Moreover, KDb does not provide models based on
QAbstractItemModel. Therefore the example either had to create a table
widget or a proxy QAbstractItemModel to KDb’s cursor. I did the latter.

Qt’s example creates a SQLite database on memory (i.e., ":memory:" as
database path), but KDb does not allow that: for file-based drivers, it
checks that the driver actually created the file. Therefore i had to
create a temporary database on disk that gets deleted at exit.

The table’s sample data is the same that is being used as an example
data source for KReport.

As for the QAbstactTableModel implementation, at first i tried to use an
instance of KDbTableViewData and, like KEXI does, preload all its
records at the begining. This worked as expected.

However, i believe that i can not make use of KDbTableViewData’s edit
buffer to hold the cached data because, as i understood it, that buffer
can only hold the data for a single record —a row— while the example
wants to cache all changes to all records. I guess that
KDbTableViewData’s user case is for KEXI’s commit-on-row-change
behavior.

I made it work by keeping a map of row→KDbRecordEditBuffer inside the
model proxy, but at that point KDbTableViewData was of little benefit
and i dropped it in favor of using the cursor instead.

Finally, i had a bit of trouble with cleaning up of cursor instances.
The example’s TableModel is responsible for the cursor it creates and
therefore must delete it in its destructor. At first i deleted the
instance of TableModel inside the main window’s destructor, called when
the application exits, but it seems that KDbDriverManager registers a
slot against Qt’s aboutToQuit, a signal emitted *before* the main window
is deleted. At that point TableModel was holding a dangling cursor and
received a SIGSEGV.

Being an example i could, maybe, just ignore the deletion of that
cursor, but then i was worried that it would seem like there is no need
to close or delete cursors. That is why i now delete the table model
when the main window is closed, before the aboutToQuit signal is
emitted.

Diff Detail

Repository
R15 KDb
Branch
cachedtable-example
Lint
No Linters Available
Unit
No Unit Test Coverage
Build Status
Buildable 25865
Build 25883: arc lint + arc unit
jfita created this revision.Apr 24 2020, 10:09 PM
Restricted Application added a project: KDb. · View Herald TranscriptApr 24 2020, 10:09 PM
Restricted Application added a subscriber: Kexi-Devel-list. · View Herald Transcript
jfita requested review of this revision.Apr 24 2020, 10:09 PM

My plan is to include the example as a tutorial in the documentation, but first i wanted for you to review the code alone and see all i did wrong.

This is what the example looks like:

Thank you Jordi, I will review it. This looks like a wonderful example app!