@@ -28,191 +28,212 @@
28#include <QRect>
28#include <QRect>
29#include <unity/shell/application/ApplicationInfoInterface.h>
29#include <unity/shell/application/ApplicationInfoInterface.h>
31−AsyncQuery::AsyncQuery(const QString& dbName):
36−AsyncQuery::~AsyncQuery()
32+class AsyncQuery: public QObject
38− QSqlDatabase::removeDatabase(m_connectionName);
34+ Q_OBJECT
41−bool AsyncQuery::initdb()
37+ AsyncQuery(const QString& dbName):
43− QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
39+ {
44− connection.setDatabaseName(m_dbName);
45− if (!connection.open()) {
46− qWarning() << "Error opening state database " << m_dbName << connection.lastError().driverText() << connection.lastError().databaseText();
49− QSqlQuery query(connection);
51− if (!connection.tables().contains(QStringLiteral("geometry"))) {
42+ ~AsyncQuery()
52− QString geometryQuery = QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);");
43+ {
53− if (!query.exec(geometryQuery)) {
44+ QSqlDatabase::removeDatabase(m_connectionName);
54− logSqlError(query);
45+ }
47+ Q_PROPERTY (const QString dbName READ getDbName)
49+ Q_INVOKABLE const QString getDbName()
51+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
52+ return connection.databaseName();
55+ Q_INVOKABLE bool initdb()
57+ QSqlDatabase connection = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), m_connectionName);
58+ connection.setDatabaseName(m_dbName);
59+ if (!connection.open()) {
60+ qWarning() << "Error opening state database " << m_dbName << connection.lastError().driverText() << connection.lastError().databaseText();
55 return false;
61 return false;
63+ QSqlQuery query(connection);
65+ if (!connection.tables().contains(QStringLiteral("geometry"))) {
66+ QString geometryQuery = QStringLiteral("CREATE TABLE geometry(windowId TEXT UNIQUE, x INTEGER, y INTEGER, width INTEGER, height INTEGER);");
67+ if (!query.exec(geometryQuery)) {
73+ if (!connection.tables().contains(QStringLiteral("state"))) {
74+ QString stateQuery = QStringLiteral("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);");
75+ if (!query.exec(stateQuery)) {
81+ if (!connection.tables().contains(QStringLiteral("stage"))) {
82+ QString stageQuery = QStringLiteral("CREATE TABLE stage(appId TEXT UNIQUE, stage INTEGER);");
83+ if (!query.exec(stageQuery)) {
59− if (!connection.tables().contains(QStringLiteral("state"))) {
91+ Q_INVOKABLE int getState(const QString &windowId) const
60− QString stateQuery = QStringLiteral("CREATE TABLE state(windowId TEXT UNIQUE, state INTEGER);");
92+ {
93+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
94+ QSqlQuery query(connection);
95+ query.prepare(m_getStateQuery);
96+ query.bindValue(":windowId", windowId);
61− if (!query.exec(stateQuery)) {
97+ query.exec();
98+ if (!query.isActive() || !query.isSelect()) {
62 logSqlError(query);
99 logSqlError(query);
63− return false;
100+ return -1;
102+ if (!query.first()) {
105+ bool converted = false;
106+ QVariant resultStr = query.value(0);
107+ int result = resultStr.toInt(&converted);
111+ qWarning() << "getState result expected integer, got " << resultStr;
67− if (!connection.tables().contains(QStringLiteral("stage"))) {
116+ Q_INVOKABLE QRect getGeometry(const QString &windowId) const
68− QString stageQuery = QStringLiteral("CREATE TABLE stage(appId TEXT UNIQUE, stage INTEGER);");
117+ {
118+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
119+ QSqlQuery query(connection);
120+ query.prepare(m_getGeometryQuery);
121+ query.bindValue(":windowId", windowId);
69− if (!query.exec(stageQuery)) {
122+ query.exec();
123+ if (!query.isActive() || !query.isSelect()) {
70 logSqlError(query);
124 logSqlError(query);
71− return false;
125+ return QRect();
77−void AsyncQuery::saveState(const QString &windowId, int state)
79− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
80− QSqlQuery query(connection);
81− query.prepare(m_saveStateQuery);
82− query.bindValue(":windowId", windowId);
83− query.bindValue(":state", state);
84− if (!query.exec()) {
128+ if (!query.first()) {
85− logSqlError(query);
129+ return QRect();
89−int AsyncQuery::getState(const QString &windowId) const
132+ bool xConverted, yConverted, widthConverted, heightConverted = false;
90−{
133+ int x, y, width, height;
91− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
134+ QVariant xResultStr = query.value(QStringLiteral("x"));
92− QSqlQuery query(connection);
135+ QVariant yResultStr = query.value(QStringLiteral("y"));
93− query.prepare(m_getStateQuery);
94− query.bindValue(":windowId", windowId);
96− if (!query.isActive() || !query.isSelect()) {
100− if (!query.first()) {
103− bool converted = false;
104− QVariant resultStr = query.value(0);
136+ QVariant widthResultStr = query.value(QStringLiteral("width"));
105− int result = resultStr.toInt(&converted);
137+ QVariant heightResultStr = query.value(QStringLiteral("height"));
106− if (converted) {
138+ x = xResultStr.toInt(&xConverted);
107− return result;
139+ y = yResultStr.toInt(&yConverted);
140+ width = widthResultStr.toInt(&widthConverted);
141+ height = heightResultStr.toInt(&heightConverted);
143+ if (xConverted && yConverted && widthConverted && heightConverted) {
144+ return QRect(x, y, width, height);
108− } else {
145+ } else {
109− qWarning() << "getState result expected integer, got " << resultStr;
146+ qWarning() << "getGeometry result expected integers, got x:"
147+ << xResultStr << "y:" << yResultStr << "width" << widthResultStr
148+ << "height:" << heightResultStr;
110− return -1;
149+ return QRect();
114−void AsyncQuery::saveGeometry(const QString &windowId, const QRect &rect)
116− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
117− QSqlQuery query(connection);
118− query.prepare(m_saveGeometryQuery);
119− query.bindValue(":windowId", windowId);
120− query.bindValue(":x", rect.x());
121− query.bindValue(":y", rect.y());
122− query.bindValue(":width", rect.width());
123− query.bindValue(":height", rect.height());
124− if (!query.exec()) {
129−QRect AsyncQuery::getGeometry(const QString &windowId) const
154+ Q_INVOKABLE int getStage(const QString &appId) const
131− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
156+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
132− QSqlQuery query(connection);
157+ QSqlQuery query(connection);
133− query.prepare(m_getGeometryQuery);
158+ query.prepare(m_getStageQuery);
134− query.bindValue(":windowId", windowId);
159+ query.bindValue(":appId", appId);
135− query.exec();
160+ query.exec();
136− if (!query.isActive() || !query.isSelect()) {
161+ if (!query.isActive() || !query.isSelect()) {
137− logSqlError(query);
162+ logSqlError(query);
165+ if (!query.first()) {
138− return QRect();
166+ return -1;
168+ bool converted = false;
169+ QVariant resultStr = query.value(0);
170+ int result = resultStr.toInt(&converted);
174+ qWarning() << "getStage result expected integer, got " << resultStr;
141− if (!query.first()) {
179+public Q_SLOTS:
145− bool xConverted, yConverted, widthConverted, heightConverted = false;
181+ void saveState(const QString &windowId, int state)
146− int x, y, width, height;
182+ {
147− QVariant xResultStr = query.value(QStringLiteral("x"));
183+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
148− QVariant yResultStr = query.value(QStringLiteral("y"));
184+ QSqlQuery query(connection);
149− QVariant widthResultStr = query.value(QStringLiteral("width"));
185+ query.prepare(m_saveStateQuery);
150− QVariant heightResultStr = query.value(QStringLiteral("height"));
186+ query.bindValue(":windowId", windowId);
151− x = xResultStr.toInt(&xConverted);
187+ query.bindValue(":state", state);
152− y = yResultStr.toInt(&yConverted);
188+ if (!query.exec()) {
153− width = widthResultStr.toInt(&widthConverted);
189+ logSqlError(query);
154− height = heightResultStr.toInt(&heightConverted);
190+ }
156− if (xConverted && yConverted && widthConverted && heightConverted) {
157− return QRect(x, y, width, height);
159− qWarning() << "getGeometry result expected integers, got x:"
160− << xResultStr << "y:" << yResultStr << "width" << widthResultStr
161− << "height:" << heightResultStr;
165−}
193+ void saveGeometry(const QString &windowId, const QRect &rect)
167−void AsyncQuery::saveStage(const QString &appId, int stage)
169− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
195+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
170− QSqlQuery query(connection);
196+ QSqlQuery query(connection);
171− query.prepare(m_saveStageQuery);
197+ query.prepare(m_saveGeometryQuery);
172− query.bindValue(":appId", appId);
198+ query.bindValue(":windowId", windowId);
173− query.bindValue(":stage", stage);
199+ query.bindValue(":x", rect.x());
200+ query.bindValue(":y", rect.y());
201+ query.bindValue(":width", rect.width());
202+ query.bindValue(":height", rect.height());
174− if (!query.exec()) {
203+ if (!query.exec()) {
175− logSqlError(query);
204+ logSqlError(query);
179−int AsyncQuery::getStage(const QString &appId) const
208+ void saveStage(const QString &appId, int stage)
181− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
210+ QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
182− QSqlQuery query(connection);
211+ QSqlQuery query(connection);
183− query.prepare(m_getStageQuery);
212+ query.prepare(m_saveStageQuery);
184− query.bindValue(":appId", appId);
213+ query.bindValue(":appId", appId);
214+ query.bindValue(":stage", stage);
185− query.exec();
215+ if (!query.exec()) {
186− if (!query.isActive() || !query.isSelect()) {
187− logSqlError(query);
216+ logSqlError(query);
190− if (!query.first()) {
193− bool converted = false;
194− QVariant resultStr = query.value(0);
195− int result = resultStr.toInt(&converted);
199− qWarning() << "getStage result expected integer, got " << resultStr;
204−void AsyncQuery::logSqlError(const QSqlQuery query) const
206− qWarning() << "Error executing query" << query.lastQuery()
207− << "Driver error:" << query.lastError().driverText()
208− << "Database error:" << query.lastError().databaseText();
211−const QString AsyncQuery::getDbName()
220+private:
221+ const QString m_connectionName = QStringLiteral("WindowStateStorage");
222+ const QString m_getStateQuery = QStringLiteral("SELECT state FROM state WHERE windowId = :windowId");
223+ const QString m_saveStateQuery = QStringLiteral("INSERT OR REPLACE INTO state (windowId, state) values (:windowId, :state)");
224+ const QString m_getGeometryQuery = QStringLiteral("SELECT * FROM geometry WHERE windowId = :windowId");
225+ const QString m_saveGeometryQuery = QStringLiteral("INSERT OR REPLACE INTO geometry (windowId, x, y, width, height) values (:windowId, :x, :y, :width, :height)");
226+ const QString m_getStageQuery = QStringLiteral("SELECT stage FROM stage WHERE appId = :appId");
227+ const QString m_saveStageQuery = QStringLiteral("INSERT OR REPLACE INTO stage (appId, stage) values (:appId, :stage)");
230+ void logSqlError(const QSqlQuery query) const
213− QSqlDatabase connection = QSqlDatabase::database(m_connectionName);
232+ qWarning() << "Error executing query" << query.lastQuery()
214− return connection.databaseName();
233+ << "Driver error:" << query.lastError().driverText()
234+ << "Database error:" << query.lastError().databaseText();
217WindowStateStorage::WindowStateStorage(const QString& dbName, QObject *parent):
238WindowStateStorage::WindowStateStorage(const QString& dbName, QObject *parent):
218 QObject(parent),
239 QObject(parent),