summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <dvratil@kde.org>2016-09-08 10:33:25 (GMT)
committerDaniel Vrátil <dvratil@kde.org>2016-09-08 10:33:27 (GMT)
commita290219c516eb2d2de955a7f1951e9a874608c82 (patch)
tree7d770587c90d7907d1ad1cf8ed709ee39fc5c252
parentf918dafea123a82d9000b5292bb1f697b970247b (diff)
Fix MTIME handling accross multiple backends
MySQL and PSQL don't support milliseconds in datetime columns, so we need to strip milliseconds in STORE response before sending it back, otherwise the MTIME send by STORE does not match MTIME of a separately fetched from the database. Secondly, MySQL and SQLite QtSql drivers assume that the datetime stored in DB is local time (even though we stored as UTC), while PSQL driver assumes it's UTC and converts to local time, so we need to handle this separetly for each backend.
-rw-r--r--src/server/handler/store.cpp9
-rw-r--r--src/server/utils.h26
2 files changed, 29 insertions, 6 deletions
diff --git a/src/server/handler/store.cpp b/src/server/handler/store.cpp
index 0e79de5..fccd697 100644
--- a/src/server/handler/store.cpp
+++ b/src/server/handler/store.cpp
@@ -141,7 +141,14 @@ bool Store::parseStream()
Transaction transaction(store);
ExternalPartStorageTransaction storageTrx;
// Set the same modification time for each item.
- const QDateTime modificationtime = QDateTime::currentDateTimeUtc();
+ QDateTime modificationtime = QDateTime::currentDateTimeUtc();
+ if (DbType::type(store->database()) != DbType::Sqlite) {
+ // Remove milliseconds from the modificationtime. PSQL and MySQL don't
+ // support milliseconds in DATETIME column, so FETCHed Items will report
+ // time without milliseconds, while this command would return answer
+ // with milliseconds
+ modificationtime = modificationtime.addMSecs(-modificationtime.time().msec());
+ }
// retrieve selected items
SelectQueryBuilder<PimItem> qb;
diff --git a/src/server/utils.h b/src/server/utils.h
index 73b7dd3..ccec4d5 100644
--- a/src/server/utils.h
+++ b/src/server/utils.h
@@ -26,6 +26,9 @@
#include <QtCore/QDateTime>
#include <QtCore/QSet>
+#include "storage/datastore.h"
+#include "storage/dbtype.h"
+
namespace Akonadi {
namespace Server {
namespace Utils {
@@ -65,11 +68,24 @@ static inline QByteArray variantToByteArray(const QVariant &variant)
static inline QDateTime variantToDateTime(const QVariant &variant)
{
if (variant.canConvert(QVariant::DateTime)) {
- // the dt is stored as QString, which is serialized to Qt::LocalTime,
- // even though it's UTC (but the information about TZ is not stored in DB)
- QDateTime dt = variant.toDateTime();
- dt.setTimeSpec(Qt::UTC);
- return dt;
+ // MySQL and SQLite backends read the datetime from the database and
+ // assume it's local time. We stored it as UTC though, so we just need
+ // to change the interpretation in QDateTime.
+ // PostgreSQL on the other hand reads the datetime and assumes it's
+ // UTC(?) and converts it to local time via QDateTime::toLocalTime(),
+ // so we need to convert it back to UTC manually.
+ switch (DbType::type(DataStore::self()->database())) {
+ case DbType::MySQL:
+ case DbType::Sqlite: {
+ QDateTime dt = variant.toDateTime();
+ dt.setTimeSpec(Qt::UTC);
+ return dt;
+ }
+ case DbType::PostgreSQL:
+ return variant.toDateTime().toUTC();
+ default:
+ Q_UNREACHABLE();
+ }
} else {
qWarning("Unable to convert variant of type %s to QDateTime", variant.typeName());
Q_ASSERT(false);