Unsolved QtMessageHandler with SQLite Database
-
Hi,
i thinking about to install a message handler with a connection to a SQlite database. I haven't tested this at all!I want to do something like that:
main.cpp:
#include <QtWidgets/QApplication> #include <QSqlDatabase> bool createEventsDatabase() { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "events"); db.setDatabaseName("events.db"); if (!db.open()) return false; QStringList tables = db.tables(); if (!tables.contains(...)) // check if the database contains the necessary tables { // create tables } db.close(); } void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QSqlDatabase db = QSqlDatabase::database("events"); db.open(); QSqlQuery query(db); // insert msg type, context values and msg into the database query.prepare("insert into events( ... ) values(:...)"); query.bindValue(":...", msg.toLocal8Bit()); query.exec(); db.close(); } int main(int argc, char *argv[]) { if(createEventsDatabase()) return 1; qInstallMessageHandler(myMessageOutput); QApplication app(argc, argv); // all Qt message should be handled by my own handler and stored in the db qInfo() << "Test Info"; qDebug() << "Test Debug"; qWarning() << "Test Warning"; ... return app.exec(); }
Is this a good idea?
Thanks
-
I would not store messages in a SQL db.
If you do want to do it you should not open and close the db each time you want to store a message. Open the db once and close it if your application is closed.You could even use a thread to write to db: in your message handler you would just put the message in a queue and that second thread would take it from the queue and write it into db. This way you will not slow down your main thread.
-
@jsulm
I supposed that the performance will slow down.Can I use a global QSqlDatabase connection outside the main function? And close the connection when the main event loop has return its value?
main.cpp
QSqlDatabase db; bool createEventsDatabase() { db = QSqlDatabase::addDatabase("QSQLITE", "events"); db.setDatabaseName("events.db"); if (db.open()) return false; // error! QStringList tables = db.tables(); if (!tables.contains(QLatin1String("events"), Qt::CaseInsensitive)) { ... } } void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QSqlQuery query(db); query.prepare("insert into events( ... ) values(:...)"); // add msg type, context values and msg query.bindValue(":...", msg.toLocal8Bit()); query.exec(); } int main(int argc, char *argv[]) { if(createEventsDatabase()) return 1; qInstallMessageHandler(myMessageOutput); QApplication app(argc, argv); qInfo() << "Test Info"; qDebug() << "Test Debug"; qWarning() << "Test Warning"; ... int ret = app.exec(); db.close(); return ret ; }
In your secound way i have no idea how to send the request from myMessageOutput function to the thread that writes the data into the database.
-
You can use the default database connection if you do not have any other.
You can get the default connection everywhere like this:QSqlDatabase db = QSqlDatabase::database();
You already close the connection in main.
Regarding multi-threading: you could use a signal which is emitted in your message handler. Your second thread then has a slot connected to this signal. The data you want to log can be passed as signal parameter.
-
Now i have tested my idea and .. yeah it was really not a good idea.
My applications was to slow to handle my events correctly!I haven't tested writing into the database in another thread!