File indexing completed on 2025-01-05 04:47:05

0001 /*
0002  * SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  *
0006  */
0007 
0008 #pragma once
0009 
0010 #include <QDateTime>
0011 #include <QTimeZone>
0012 #include <QVariant>
0013 
0014 #include "storage/datastore.h"
0015 #include "storage/dbtype.h"
0016 
0017 namespace Akonadi
0018 {
0019 namespace Server
0020 {
0021 namespace Utils
0022 {
0023 /**
0024  * Converts a QVariant to a QString depending on its internal type.
0025  */
0026 static inline QString variantToString(const QVariant &variant)
0027 {
0028     if (variant.typeId() == QMetaType::QString) {
0029         return variant.toString();
0030     } else if (variant.typeId() == QMetaType::QByteArray) {
0031         return QString::fromUtf8(variant.toByteArray());
0032     } else {
0033         qWarning("Unable to convert variant of type %s to QString", variant.typeName());
0034         Q_ASSERT(false);
0035         return QString();
0036     }
0037 }
0038 
0039 /**
0040  * Converts a QVariant to a QByteArray depending on its internal type.
0041  */
0042 static inline QByteArray variantToByteArray(const QVariant &variant)
0043 {
0044     if (variant.typeId() == QMetaType::QString) {
0045         return variant.toString().toUtf8();
0046     } else if (variant.typeId() == QMetaType::QByteArray) {
0047         return variant.toByteArray();
0048     } else {
0049         qWarning("Unable to convert variant of type %s to QByteArray", variant.typeName());
0050         Q_ASSERT(false);
0051         return QByteArray();
0052     }
0053 }
0054 
0055 static inline QDateTime variantToDateTime(const QVariant &variant, DataStore *dataStore = DataStore::self())
0056 {
0057     if (variant.canConvert<QDateTime>()) {
0058         // MySQL and SQLite backends read the datetime from the database and
0059         // assume it's local time. We stored it as UTC though, so we just need
0060         // to change the interpretation in QDateTime.
0061         // PostgreSQL on the other hand reads the datetime and assumes it's
0062         // UTC(?) and converts it to local time via QDateTime::toLocalTime(),
0063         // so we need to convert it back to UTC manually.
0064         switch (DbType::type(dataStore->database())) {
0065         case DbType::MySQL:
0066         case DbType::Sqlite: {
0067             QDateTime dt = variant.toDateTime();
0068             dt.setTimeZone(QTimeZone::UTC);
0069             return dt;
0070         }
0071         case DbType::PostgreSQL:
0072             return variant.toDateTime().toUTC();
0073         default:
0074             Q_UNREACHABLE();
0075         }
0076     } else {
0077         qWarning("Unable to convert variant of type %s to QDateTime", variant.typeName());
0078         Q_ASSERT(false);
0079         return QDateTime();
0080     }
0081 }
0082 
0083 /**
0084  * Returns the socket @p directory that is passed to this method or the one
0085  * the user has overwritten via the config file.
0086  * The passed @p fnLengthHint will also ensure the absolute file path length of the
0087  * directory + separator + hint would not overflow the system limitation.
0088  */
0089 QString preferredSocketDirectory(const QString &directory, int fnLengthHint = -1);
0090 
0091 /**
0092  * Returns name of filesystem that @p directory is stored on. This
0093  * only works on Linux and returns empty string on other platforms or when it's
0094  * unable to detect the filesystem.
0095  */
0096 QString getDirectoryFileSystem(const QString &directory);
0097 
0098 /**
0099  * Disables filesystem copy-on-write feature on given file or directory.
0100  * Only works on Linux and does nothing on other platforms.
0101  *
0102  * It was tested only with Btrfs but in theory can be called on any FS that
0103  * supports NOCOW.
0104  */
0105 void disableCoW(const QString &path);
0106 
0107 } // namespace Utils
0108 } // namespace Server
0109 } // namespace Akonadi