on xenial help sign in
Init AsyncQuery asynchronously
41c6cd1Dalton Durst
plugins/Utils/windowstatestorage.cpp+34−26
@@ -48,17 +48,23 @@ public:
48
48
49 Q_INVOKABLE const QString getDbName()
49 Q_INVOKABLE const QString getDbName()
50 {
50 {
51+ if (!m_ok) {
52+ return "ERROR";
53+ }
51 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
54 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
52 return connection.databaseName();
55 return connection.databaseName();
53 }
56 }
54
57
55 Q_INVOKABLE bool initdb()
58 Q_INVOKABLE bool initdb()
56 {
59 {
60+ if (m_ok) {
61+ return true;
62+ }
57 QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
63 QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
58 connection.setDatabaseName(m_dbName);
64 connection.setDatabaseName(m_dbName);
59 connection.setConnectOptions(QStringLiteral("QSQLITE_BUSY_TIMEOUT=1000"));
65 connection.setConnectOptions(QStringLiteral("QSQLITE_BUSY_TIMEOUT=1000"));
60 if (!connection.open()) {
66 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();
62 return false;
68 return false;
63 }
69 }
64 QSqlQuery query(connection);
70 QSqlQuery query(connection);
@@ -86,11 +92,15 @@ public:
86 return false;
92 return false;
87 }
93 }
88 }
94 }
95+ m_ok = true;
89 return true;
96 return true;
90 }
97 }
91
98
92 Q_INVOKABLE int getState(const QString &windowId) const
99 Q_INVOKABLE int getState(const QString &windowId) const
93 {
100 {
101+ if (!m_ok) {
102+ return -1;
103+ }
94 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
104 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
95 QSqlQuery query(connection);
105 QSqlQuery query(connection);
96 query.prepare(m_getStateQuery);
106 query.prepare(m_getStateQuery);
@@ -116,6 +126,9 @@ public:
116
126
117 Q_INVOKABLE QRect getGeometry(const QString &windowId) const
127 Q_INVOKABLE QRect getGeometry(const QString &windowId) const
118 {
128 {
129+ if (!m_ok) {
130+ return QRect();
131+ }
119 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
132 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
120 QSqlQuery query(connection);
133 QSqlQuery query(connection);
121 query.prepare(m_getGeometryQuery);
134 query.prepare(m_getGeometryQuery);
@@ -154,6 +167,9 @@ public:
154
167
155 Q_INVOKABLE int getStage(const QString &appId) const
168 Q_INVOKABLE int getStage(const QString &appId) const
156 {
169 {
170+ if (!m_ok) {
171+ return -1;
172+ }
157 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
173 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
158 QSqlQuery query(connection);
174 QSqlQuery query(connection);
159 query.prepare(m_getStageQuery);
175 query.prepare(m_getStageQuery);
@@ -181,6 +197,9 @@ public Q_SLOTS:
181
197
182 void saveState(const QString &windowId, WindowStateStorage::WindowState state)
198 void saveState(const QString &windowId, WindowStateStorage::WindowState state)
183 {
199 {
200+ if (!m_ok) {
201+ return;
202+ }
184 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
203 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
185 QSqlQuery query(connection);
204 QSqlQuery query(connection);
186 query.prepare(m_saveStateQuery);
205 query.prepare(m_saveStateQuery);
@@ -193,6 +212,9 @@ public Q_SLOTS:
193
212
194 void saveGeometry(const QString &windowId, const QRect &rect)
213 void saveGeometry(const QString &windowId, const QRect &rect)
195 {
214 {
215+ if (!m_ok) {
216+ return;
217+ }
196 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
218 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
197 QSqlQuery query(connection);
219 QSqlQuery query(connection);
198 query.prepare(m_saveGeometryQuery);
220 query.prepare(m_saveGeometryQuery);
@@ -208,6 +230,9 @@ public Q_SLOTS:
208
230
209 void saveStage(const QString &appId, int stage)
231 void saveStage(const QString &appId, int stage)
210 {
232 {
233+ if (!m_ok) {
234+ return;
235+ }
211 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
236 QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
212 QSqlQuery query(connection);
237 QSqlQuery query(connection);
213 query.prepare(m_saveStageQuery);
238 query.prepare(m_saveStageQuery);
@@ -227,6 +252,7 @@ private:
227 const QString m_getStageQuery = QStringLiteral("SELECT stage FROM stage WHERE appId = :appId");
252 const QString m_getStageQuery = QStringLiteral("SELECT stage FROM stage WHERE appId = :appId");
228 const QString m_saveStageQuery = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values (:appId, :stage)");
253 const QString m_saveStageQuery = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values (:appId, :stage)");
229 QString m_dbName;
254 QString m_dbName;
255+ bool m_ok = false;
230
256
231 void logSqlError(const QSqlQuery query) const
257 void logSqlError(const QSqlQuery query) const
232 {
258 {
@@ -254,20 +280,14 @@ WindowStateStorage::WindowStateStorage(const QString& dbName, QObject *parent):
254 m_asyncQuery->moveToThread(&m_thread);
280 m_asyncQuery->moveToThread(&m_thread);
255 connect(&m_thread, &QThread::finished, m_asyncQuery, &QObject::deleteLater);
281 connect(&m_thread, &QThread::finished, m_asyncQuery, &QObject::deleteLater);
256 m_thread.start();
282 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.
258 QMetaObject::invokeMethod(m_asyncQuery, "initdb",
286 QMetaObject::invokeMethod(m_asyncQuery, "initdb",
259− Qt::BlockingQueuedConnection,
287+ Qt::QueuedConnection);
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);
288+ connect(this, &WindowStateStorage::saveState, m_asyncQuery, &AsyncQuery::saveState);
267− connect(this, &WindowStateStorage::saveGeometry, m_asyncQuery, &AsyncQuery::saveGeometry);
289+ connect(this, &WindowStateStorage::saveGeometry, m_asyncQuery, &AsyncQuery::saveGeometry);
268− connect(this, &WindowStateStorage::saveStage, m_asyncQuery, &AsyncQuery::saveStage);
290+ connect(this, &WindowStateStorage::saveStage, m_asyncQuery, &AsyncQuery::saveStage);
269− m_asyncOk = true;
270− }
271}
291}
272
292
273WindowStateStorage::~WindowStateStorage()
293WindowStateStorage::~WindowStateStorage()
@@ -278,9 +298,6 @@ WindowStateStorage::~WindowStateStorage()
278
298
279WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
299WindowStateStorage::WindowState WindowStateStorage::getState(const QString &windowId, WindowStateStorage::WindowState defaultValue) const
280{
300{
281− if (!m_asyncOk) {
282− return defaultValue;
283− }
284 int state;
301 int state;
285
302
286 QMetaObject::invokeMethod(m_asyncQuery, "getState", Qt::BlockingQueuedConnection,
303 QMetaObject::invokeMethod(m_asyncQuery, "getState", Qt::BlockingQueuedConnection,
@@ -297,9 +314,6 @@ WindowStateStorage::WindowState WindowStateStorage::getState(const QString &wind
297
314
298int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
315int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
299{
316{
300− if (!m_asyncOk) {
301− return defaultValue;
302− }
303 int stage;
317 int stage;
304
318
305 QMetaObject::invokeMethod(m_asyncQuery, "getStage", Qt::BlockingQueuedConnection,
319 QMetaObject::invokeMethod(m_asyncQuery, "getStage", Qt::BlockingQueuedConnection,
@@ -316,9 +330,6 @@ int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
316
330
317QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
331QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
318{
332{
319− if (!m_asyncOk) {
320− return defaultValue;
321− }
322 QRect geometry;
333 QRect geometry;
323 QMetaObject::invokeMethod(m_asyncQuery, "getGeometry", Qt::BlockingQueuedConnection,
334 QMetaObject::invokeMethod(m_asyncQuery, "getGeometry", Qt::BlockingQueuedConnection,
324 Q_RETURN_ARG(QRect, geometry),
335 Q_RETURN_ARG(QRect, geometry),
@@ -332,9 +343,6 @@ QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defa
332
343
333const QString WindowStateStorage::getDbName()
344const QString WindowStateStorage::getDbName()
334{
345{
335− if (!m_asyncOk) {
336− return QStringLiteral("ERROR");
337− }
338 QString dbName;
346 QString dbName;
339 QMetaObject::invokeMethod(m_asyncQuery, "getDbName", Qt::BlockingQueuedConnection,
347 QMetaObject::invokeMethod(m_asyncQuery, "getDbName", Qt::BlockingQueuedConnection,
340 Q_RETURN_ARG(QString, dbName)
348 Q_RETURN_ARG(QString, dbName)
plugins/Utils/windowstatestorage.h−1
@@ -73,5 +73,4 @@ Q_SIGNALS:
73private:
73private:
74 QThread m_thread;
74 QThread m_thread;
75 AsyncQuery *m_asyncQuery;
75 AsyncQuery *m_asyncQuery;
76− bool m_asyncOk;
77};
76};
tests/plugins/Utils/WindowStateStorageTest.cpp+1−2
@@ -59,8 +59,7 @@ private Q_SLOTS:
59 WindowStateStorage::WindowState defaultState{WindowStateStorage::WindowState::WindowStateMaximizedBottomRight};
59 WindowStateStorage::WindowState defaultState{WindowStateStorage::WindowState::WindowStateMaximizedBottomRight};
60
60
61 delete storage;
61 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\"");
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\"");
63− QTest::ignoreMessage(QtWarningMsg, "WindowStateStorage Failed to initialize AsyncQuery! Windows will not be restored to their previous location.");
64 storage = new WindowStateStorage(QStringLiteral("/nonexistent/there/is/no/way/this/exists/"), this);
63 storage = new WindowStateStorage(QStringLiteral("/nonexistent/there/is/no/way/this/exists/"), this);
65 QCOMPARE(storage->getDbName(), QStringLiteral("ERROR"));
64 QCOMPARE(storage->getDbName(), QStringLiteral("ERROR"));
66
65