>
> If anyone has other ideas how to show progress of a database
> function, then you are welcome to share. I have considered
> using notice processing, but this requires access to libpq
> objects such as PGconn, which can be tricky with Qt (altough
> possible, as Qt uses libpq internally). And to be able to
> cancel requests I still need asynchronous query API, which is
> missing in Qt.
>
I took a time to try this out and and it works quite well. The idea is
to raise specially formatted notices from plpgsql function. For example
"set_progress_steps: 1000" sets total steps and resets progress dialog.
Another message "set_progress: 15" sets current progress counter and
advances the progress bar on screen. The messages are caught with libpq
notice handler, see
http://www.postgresql.org/docs/7.4/interactive/libpq-notice-processing.h
tml.
The tricky part was how to get access to underlying libpq structures
through Qt-s SQL layer. Fortunately Qt programmers had left hook for
that, I only had to do one ugly cast from QSqlDriver to QPSQLDriver and
add src/sql/drivers/psql to include path. These are not standard things
to do, but seem quite harmless.
After that I was quite happy with my solution, but it would be still
nice to get canceling to work. I felt lucky again, when I found from
libpq documentation, that PQrequestCancel can be used to cancel queries
issued through PQexec. This allows me to cancel queries, issued by Qt,
from notice handler. The original code that executed the query can stay
unchanged, because canceled query just returns error and as I use
standard error handling, I can ignore this error in standard handler or
display reasonable message.
Finally I managed to put together quite general framework, which is very
easy to include in existing Qt applications. What you have to do:
1. Create 3 functions in database: set_progress_steps,
set_progress_text, set_progress. These are included in progress.sql.
2. Add noticeProcessor function to your codebase and call
PQsetNoticeProcessor after you have set up database connection, see
progress.cpp.
3. Add $QTDIR/src/sql/drivers/psql to your include path and libpq to
your list of libraries. See progress.pro for example how to do it under
Windows (sorry, I didn't have Linux with Qt sources handy).
4. Use functions set_progress_steps, set_progress_text and set_progress
in your database functions and it should work automagically, without any
change in the code that is calling those functions!
You can find those 4 files attached to this mail, hopefully 3KB is not
too much.
Tambet