on xenial help sign in
Init AsyncQuery asynchronously

Given review comments to the effect of this being desirable[1], initialize AsyncQuery using a QueuedConnection instead of a BlockingQueuedConnection. This makes us move the short-circuit handling into AsyncQuery. [1] https://github.com/ubports/unity8/pull/356#discussion_r559277288

commit41c6cd174b6e105470d1dfc2e3ba307036f13bb8 authorDalton Durst <dalton@ubports.com> dateMon 18 Jan 2021, 14:16 (6 years ago) parentb096586
3 files changed+35−29
plugins/Utils/windowstatestorage.cpp+34−26 plugins/Utils/windowstatestorage.h−1 tests/plugins/Utils/WindowStateStorageTest.cpp+1−2
plugins/Utils/windowstatestorage.cpp+34−26
@@ -48,17 +48,23 @@ public:
4848
4949 Q_INVOKABLE const QString getDbName()
5050 {
51+ if (!m_ok) {
52+ return "ERROR";
53+ }
5154 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
5255 return connection.databaseName();
5356 }
5457
5558 Q_INVOKABLE bool initdb()
5659 {
60+ if (m_ok) {
61+ return true;
62+ }
5763 QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
5864 connection.setDatabaseName(m_dbName);
5965 connection.setConnectOptions(QStringLiteral("QSQLITE_BUSY_TIMEOUT=1000"));
6066 if (!connection.open()) {
61− qWarning() << "AsyncQuery::initdb: Error opening state database " << m_dbName << connection.lastError().driverText() << connection.lastError().databaseText();
67+ qWarning() << "AsyncQuery::initdb: Error opening state database. Window positions will not be saved or restored." << m_dbName << connection.lastError().driverText() << connection.lastError().databaseText();
6268 return false;
6369 }
6470 QSqlQuery query(connection);
@@ -86,11 +92,15 @@ public:
8692 return false;
8793 }
8894 }
95+ m_ok = true;
8996 return true;
9097 }
9198
9299 Q_INVOKABLE int getState(const QString &windowId) const
93100 {
101+ if (!m_ok) {
102+ return -1;
103+ }
94104 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
95105 QSqlQuery query(connection);
96106 query.prepare(m_getStateQuery);
@@ -116,6 +126,9 @@ public:
116126
117127 Q_INVOKABLE QRect getGeometry(const QString &windowId) const
118128 {
129+ if (!m_ok) {
130+ return QRect();
131+ }
119132 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
120133 QSqlQuery query(connection);
121134 query.prepare(m_getGeometryQuery);
@@ -154,6 +167,9 @@ public:
154167
155168 Q_INVOKABLE int getStage(const QString &appId) const
156169 {
170+ if (!m_ok) {
171+ return -1;
172+ }
157173 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
158174 QSqlQuery query(connection);
159175 query.prepare(m_getStageQuery);
@@ -181,6 +197,9 @@ public Q_SLOTS:
181197
182198 void saveState(const QString &windowId, WindowStateStorage::WindowState state)
183199 {
200+ if (!m_ok) {
201+ return;
202+ }
184203 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
185204 QSqlQuery query(connection);
186205 query.prepare(m_saveStateQuery);
@@ -193,6 +212,9 @@ public Q_SLOTS:
193212
194213 void saveGeometry(const QString &windowId, const QRect &rect)
195214 {
215+ if (!m_ok) {
216+ return;
217+ }
196218 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
197219 QSqlQuery query(connection);
198220 query.prepare(m_saveGeometryQuery);
@@ -208,6 +230,9 @@ public Q_SLOTS:
208230
209231 void saveStage(const QString &appId, int stage)
210232 {
233+ if (!m_ok) {
234+ return;
235+ }
211236 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
212237 QSqlQuery query(connection);
213238 query.prepare(m_saveStageQuery);
@@ -227,6 +252,7 @@ private:
227252 const QString m_getStageQuery = QStringLiteral("SELECT stage FROM stage WHERE appId = :appId");
228253 const QString m_saveStageQuery = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values (:appId, :stage)");
229254 QString m_dbName;
255+ bool m_ok = false;
230256
231257 void logSqlError(const QSqlQuery query) const
232258 {
@@ -254,20 +280,14 @@ WindowStateStorage::WindowStateStorage(const QString& dbName, QObject *parent):
254280 m_asyncQuery->moveToThread(&m_thread);
255281 connect(&m_thread, &QThread::finished, m_asyncQuery, &QObject::deleteLater);
256282 m_thread.start();
257− bool queryInitSuccessful;
283+ // Note that we're relying on initdb being called before any other methods
284+ // on AsyncQuery. Given the current behavior of QueuedConnection (slots
285+ // invoked in the order they are received), this is fine.
258286 QMetaObject::invokeMethod(m_asyncQuery, "initdb",
259− Qt::BlockingQueuedConnection,
260− Q_RETURN_ARG(bool, queryInitSuccessful));
261− if (!queryInitSuccessful) {
262− qWarning() << "WindowStateStorage Failed to initialize AsyncQuery! Windows will not be restored to their previous location.";
263− m_asyncOk = false;
264− m_thread.quit();
265− } else {
266− connect(this, &WindowStateStorage::saveState, m_asyncQuery, &AsyncQuery::saveState);
267− connect(this, &WindowStateStorage::saveGeometry, m_asyncQuery, &AsyncQuery::saveGeometry);
268− connect(this, &WindowStateStorage::saveStage, m_asyncQuery, &AsyncQuery::saveStage);
269− m_asyncOk = true;
270− }
287+ Qt::QueuedConnection);
288+ connect(this, &WindowStateStorage::saveState, m_asyncQuery, &AsyncQuery::saveState);
289+ connect(this, &WindowStateStorage::saveGeometry, m_asyncQuery, &AsyncQuery::saveGeometry);
290+ connect(this, &WindowStateStorage::saveStage, m_asyncQuery, &AsyncQuery::saveStage);
271291}
272292
273293WindowStateStorage::~WindowStateStorage()
@@ -278,9 +298,6 @@ WindowStateStorage::~WindowStateStorage()
278298
279299WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
280300{
281− if (!m_asyncOk) {
282− return defaultValue;
283− }
284301 int state;
285302
286303 QMetaObject::invokeMethod(m_asyncQuery, "getState", Qt::BlockingQueuedConnection,
@@ -297,9 +314,6 @@ WindowStateStorage::WindowState WindowStateStorage::getState(const QString &wind
297314
298315int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
299316{
300− if (!m_asyncOk) {
301− return defaultValue;
302− }
303317 int stage;
304318
305319 QMetaObject::invokeMethod(m_asyncQuery, "getStage", Qt::BlockingQueuedConnection,
@@ -316,9 +330,6 @@ int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
316330
317331QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
318332{
319− if (!m_asyncOk) {
320− return defaultValue;
321− }
322333 QRect geometry;
323334 QMetaObject::invokeMethod(m_asyncQuery, "getGeometry", Qt::BlockingQueuedConnection,
324335 Q_RETURN_ARG(QRect, geometry),
@@ -332,9 +343,6 @@ QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defa
332343
333344const QString WindowStateStorage::getDbName()
334345{
335− if (!m_asyncOk) {
336− return QStringLiteral("ERROR");
337− }
338346 QString dbName;
339347 QMetaObject::invokeMethod(m_asyncQuery, "getDbName", Qt::BlockingQueuedConnection,
340348 Q_RETURN_ARG(QString, dbName)
plugins/Utils/windowstatestorage.h−1
@@ -73,5 +73,4 @@ Q_SIGNALS:
7373private:
7474 QThread m_thread;
7575 AsyncQuery *m_asyncQuery;
76− bool m_asyncOk;
7776};
tests/plugins/Utils/WindowStateStorageTest.cpp+1−2
@@ -59,8 +59,7 @@ private Q_SLOTS:
5959 WindowStateStorage::WindowState defaultState{WindowStateStorage::WindowState::WindowStateMaximizedBottomRight};
6060
6161 delete storage;
62− QTest::ignoreMessage(QtWarningMsg, "AsyncQuery::initdb: Error opening state database \"/nonexistent/there/is/no/way/this/exists/\" \"Error opening database\" \"unable to open database file\"");
63− QTest::ignoreMessage(QtWarningMsg, "WindowStateStorage Failed to initialize AsyncQuery! Windows will not be restored to their previous location.");
62+ QTest::ignoreMessage(QtWarningMsg, "AsyncQuery::initdb: Error opening state database. Window positions will not be saved or restored. \"/nonexistent/there/is/no/way/this/exists/\" \"Error opening database\" \"unable to open database file\"");
6463 storage = new WindowStateStorage(QStringLiteral("/nonexistent/there/is/no/way/this/exists/"), this);
6564 QCOMPARE(storage->getDbName(), QStringLiteral("ERROR"));
6665