File indexing completed on 2025-01-05 04:46:56
0001 /* 0002 SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "dbconfig.h" 0008 0009 #include "akonadiserver_debug.h" 0010 #include "dbconfigmysql.h" 0011 #include "dbconfigpostgresql.h" 0012 #include "dbconfigsqlite.h" 0013 0014 #include <config-akonadi.h> 0015 0016 #include "private/instance_p.h" 0017 #include "private/standarddirs_p.h" 0018 0019 #include <QProcess> 0020 #include <memory> 0021 0022 using namespace Akonadi; 0023 using namespace Akonadi::Server; 0024 0025 // TODO: make me Q_GLOBAL_STATIC 0026 static DbConfig *s_DbConfigInstance = nullptr; 0027 0028 DbConfig::DbConfig() 0029 : DbConfig(StandardDirs::serverConfigFile(StandardDirs::ReadWrite)) 0030 { 0031 } 0032 0033 DbConfig::DbConfig(const QString &configFile) 0034 { 0035 QSettings settings(configFile, QSettings::IniFormat); 0036 0037 mSizeThreshold = 4096; 0038 const QVariant value = settings.value(QStringLiteral("General/SizeThreshold"), mSizeThreshold); 0039 if (value.canConvert<qint64>()) { 0040 mSizeThreshold = value.value<qint64>(); 0041 if (mSizeThreshold < 0) { 0042 mSizeThreshold = 0; 0043 } 0044 } else { 0045 mSizeThreshold = 0; 0046 } 0047 } 0048 0049 DbConfig::~DbConfig() 0050 { 0051 } 0052 0053 bool DbConfig::isConfigured() 0054 { 0055 return s_DbConfigInstance; 0056 } 0057 0058 QString DbConfig::defaultAvailableDatabaseBackend(QSettings &settings) 0059 { 0060 QString driverName = QStringLiteral(AKONADI_DATABASE_BACKEND); 0061 0062 std::unique_ptr<DbConfig> dbConfigFallbackTest; 0063 if (driverName == QLatin1StringView("QMYSQL")) { 0064 dbConfigFallbackTest = std::make_unique<DbConfigMysql>(); 0065 } else if (driverName == QLatin1StringView("QPSQL")) { 0066 dbConfigFallbackTest = std::make_unique<DbConfigPostgresql>(); 0067 } 0068 0069 if (dbConfigFallbackTest && !dbConfigFallbackTest->isAvailable(settings) && DbConfigSqlite().isAvailable(settings)) { 0070 qCWarning(AKONADISERVER_LOG) << driverName << " requirements not available. Falling back to using QSQLITE."; 0071 driverName = QStringLiteral("QSQLITE"); 0072 } 0073 0074 return driverName; 0075 } 0076 0077 DbConfig *DbConfig::configuredDatabase() 0078 { 0079 if (!s_DbConfigInstance) { 0080 const QString serverConfigFile = StandardDirs::serverConfigFile(StandardDirs::ReadWrite); 0081 QSettings settings(serverConfigFile, QSettings::IniFormat); 0082 0083 // determine driver to use 0084 QString driverName = settings.value(QStringLiteral("General/Driver")).toString(); 0085 if (driverName.isEmpty()) { 0086 driverName = defaultAvailableDatabaseBackend(settings); 0087 0088 // when using the default, write it explicitly, in case the default changes later 0089 settings.setValue(QStringLiteral("General/Driver"), driverName); 0090 settings.sync(); 0091 } 0092 0093 if (driverName == QLatin1StringView("QMYSQL")) { 0094 s_DbConfigInstance = new DbConfigMysql; 0095 } else if (driverName == QLatin1StringView("QSQLITE") || driverName == QLatin1StringView("QSQLITE3")) { 0096 // QSQLITE3 is legacy name for the Akonadi fork of the upstream QSQLITE driver. 0097 // It is kept here for backwards compatibility with old server config files. 0098 s_DbConfigInstance = new DbConfigSqlite(); 0099 } else if (driverName == QLatin1StringView("QPSQL")) { 0100 s_DbConfigInstance = new DbConfigPostgresql; 0101 } else { 0102 qCCritical(AKONADISERVER_LOG) << "Unknown database driver: " << driverName; 0103 qCCritical(AKONADISERVER_LOG) << "Available drivers are: " << QSqlDatabase::drivers(); 0104 return nullptr; 0105 } 0106 0107 if (!s_DbConfigInstance->init(settings)) { 0108 delete s_DbConfigInstance; 0109 s_DbConfigInstance = nullptr; 0110 } 0111 } 0112 0113 return s_DbConfigInstance; 0114 } 0115 0116 void DbConfig::destroy() 0117 { 0118 delete s_DbConfigInstance; 0119 s_DbConfigInstance = nullptr; 0120 } 0121 0122 bool DbConfig::startInternalServer() 0123 { 0124 // do nothing 0125 return true; 0126 } 0127 0128 void DbConfig::stopInternalServer() 0129 { 0130 // do nothing 0131 } 0132 0133 void DbConfig::setup() 0134 { 0135 // do nothing 0136 } 0137 0138 qint64 DbConfig::sizeThreshold() const 0139 { 0140 return mSizeThreshold; 0141 } 0142 0143 QString DbConfig::defaultDatabaseName() 0144 { 0145 if (!Instance::hasIdentifier()) { 0146 return QStringLiteral("akonadi"); 0147 } 0148 // dash is not allowed in PSQL 0149 return QLatin1StringView("akonadi_") % Instance::identifier().replace(QLatin1Char('-'), QLatin1Char('_')); 0150 } 0151 0152 void DbConfig::initSession(const QSqlDatabase &database) 0153 { 0154 Q_UNUSED(database) 0155 } 0156 0157 int DbConfig::execute(const QString &cmd, const QStringList &args) const 0158 { 0159 qCDebug(AKONADISERVER_LOG) << "Executing: " << cmd << args.join(QLatin1Char(' ')); 0160 return QProcess::execute(cmd, args); 0161 }