File 0002-Check-availability-of-Postgresql-backend-and-clean-a.patch of Package akonadi-server

From 4b30cf44d36543c809658f83feac2284ec4db11a Mon Sep 17 00:00:00 2001
From: Antonio Larrosa <antonio.larrosa@gmail.com>
Date: Mon, 27 Jul 2020 14:44:52 +0200
Subject: [PATCH 2/6] Check availability of Postgresql backend and clean a bit
 the code

Rename `areRequirementsAvailable` method to `isAvailable` and implement the
method for DbConfigPostgresql too.
Extract the code from `DbConfig::configuredDatabase` that selects the fallback
to use to a new separate static method, `defaultAvailableDatabaseBackend`
to be more clear about what that code does and simplify `configuredDatabase`.

Now if Postgresql is expected to be used (because akonadi was built like that)
but QPSQL is not available or the initdb/pg_ctl binaries don't exist, then we
fallback to trying to use QSQLITE3.

As with the `DbConfigMysql` change, if QSQLITE3 can't be used either, then
the code will continue trying to use postgresql and fail as expected.
---
 src/server/storage/dbconfig.cpp           | 35 ++++++++++++++++-------
 src/server/storage/dbconfig.h             | 13 +++++++++
 src/server/storage/dbconfigmysql.cpp      |  2 +-
 src/server/storage/dbconfigmysql.h        |  2 +-
 src/server/storage/dbconfigpostgresql.cpp | 19 ++++++++++++
 src/server/storage/dbconfigpostgresql.h   |  7 +++++
 src/server/storage/dbconfigsqlite.cpp     |  2 +-
 src/server/storage/dbconfigsqlite.h       |  2 +-
 8 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/src/server/storage/dbconfig.cpp b/src/server/storage/dbconfig.cpp
index 21ef708d0..e102ddad8 100644
--- a/src/server/storage/dbconfig.cpp
+++ b/src/server/storage/dbconfig.cpp
@@ -49,6 +49,28 @@ bool DbConfig::isConfigured()
     return s_DbConfigInstance;
 }
 
+QString DbConfig::defaultAvailableDatabaseBackend(QSettings &settings)
+{
+    QString driverName = QStringLiteral(AKONADI_DATABASE_BACKEND);
+
+    DbConfig *dbConfigFallbackTest = 0L;
+    if (driverName == QLatin1String("QMYSQL")) {
+        dbConfigFallbackTest = new DbConfigMysql;
+    } else if (driverName == QLatin1String("QPSQL")) {
+        dbConfigFallbackTest = new DbConfigPostgresql;
+    }
+
+    if (dbConfigFallbackTest && !dbConfigFallbackTest->isAvailable(settings)
+        && DbConfigSqlite(DbConfigSqlite::Custom).isAvailable(settings)) {
+        qCWarning(AKONADISERVER_LOG) << driverName << " requirements not available. Falling back to using QSQLITE3.";
+        driverName = QStringLiteral("QSQLITE3");
+    }
+    delete dbConfigFallbackTest;
+
+    return driverName;
+}
+
+
 DbConfig *DbConfig::configuredDatabase()
 {
     if (!s_DbConfigInstance) {
@@ -58,17 +80,8 @@ DbConfig *DbConfig::configuredDatabase()
         // determine driver to use
         QString driverName = settings.value(QStringLiteral("General/Driver")).toString();
         if (driverName.isEmpty()) {
-            driverName = QStringLiteral(AKONADI_DATABASE_BACKEND);
-
-            // If we fallback to use QMYSQL by default, let's check that it's really available.
-            if (driverName == QLatin1String("QMYSQL")) {
-                DbConfigMysql dbConfigMysql;
-                if (!dbConfigMysql.areRequirementsAvailable(settings)
-                    && DbConfigSqlite(DbConfigSqlite::Custom).areRequirementsAvailable(settings)) {
-                    qCWarning(AKONADISERVER_LOG) << "QMYSQL requirements not available. Falling back to using QSQLITE3.";
-                    driverName = QStringLiteral("QSQLITE3");
-                }
-            }
+            driverName = defaultAvailableDatabaseBackend(settings);
+
             // when using the default, write it explicitly, in case the default changes later
             settings.setValue(QStringLiteral("General/Driver"), driverName);
             settings.sync();
diff --git a/src/server/storage/dbconfig.h b/src/server/storage/dbconfig.h
index 79cea3a2c..33ec28672 100644
--- a/src/server/storage/dbconfig.h
+++ b/src/server/storage/dbconfig.h
@@ -55,6 +55,12 @@ public:
      */
     virtual bool init(QSettings &settings, bool storeSettings=true) = 0;
 
+    /**
+     * This method checks if the requirements for this database connection are met
+     * in the system (i.e. QMYSQL driver is available, mysqld binary is found, etc.).
+     */
+    virtual bool isAvailable(QSettings &settings) = 0;
+
     /**
      * This method applies the configured settings to the QtSql @p database
      * instance.
@@ -105,6 +111,13 @@ protected:
      */
     static QString defaultDatabaseName();
 
+    /*
+     * Returns the Database backend we should use by default. Usually it should be the same value
+     * configured as AKONADI_DATABASE_BACKEND at build time, but this method checks if that
+     * backend is really available and if it's not, it falls back to returning "QSQLITE3".
+     */
+    static QString defaultAvailableDatabaseBackend(QSettings &settings);
+
     /**
      * Calls QProcess::execute() and also prints the command and arguments via qCDebug()
      */
diff --git a/src/server/storage/dbconfigmysql.cpp b/src/server/storage/dbconfigmysql.cpp
index c8673e02f..f21facd39 100644
--- a/src/server/storage/dbconfigmysql.cpp
+++ b/src/server/storage/dbconfigmysql.cpp
@@ -158,7 +158,7 @@ bool DbConfigMysql::init(QSettings &settings, bool storeSettings)
     return true;
 }
 
-bool DbConfigMysql::areRequirementsAvailable(QSettings &settings)
+bool DbConfigMysql::isAvailable(QSettings &settings)
 {
     if (!QSqlDatabase::drivers().contains(driverName()))
         return false;
diff --git a/src/server/storage/dbconfigmysql.h b/src/server/storage/dbconfigmysql.h
index a2a03bbbb..6454e0f9d 100644
--- a/src/server/storage/dbconfigmysql.h
+++ b/src/server/storage/dbconfigmysql.h
@@ -46,7 +46,7 @@ public:
      * This method checks if the requirements for this database connection are met
      * in the system (QMYSQL driver is available, mysqld binary is found, etc.).
      */
-    bool areRequirementsAvailable(QSettings &settings);
+    bool isAvailable(QSettings &settings) override;
 
     /**
      * This method applies the configured settings to the QtSql @p database
diff --git a/src/server/storage/dbconfigpostgresql.cpp b/src/server/storage/dbconfigpostgresql.cpp
index 35358b029..3043af807 100644
--- a/src/server/storage/dbconfigpostgresql.cpp
+++ b/src/server/storage/dbconfigpostgresql.cpp
@@ -205,6 +205,25 @@ bool DbConfigPostgresql::init(QSettings &settings, bool storeSettings)
     return true;
 }
 
+bool DbConfigPostgresql::isAvailable(QSettings &settings)
+{
+    if (!QSqlDatabase::drivers().contains(driverName()))
+        return false;
+
+    if (!init(settings, false))
+        return false;
+
+    if (mInternalServer) {
+        if (mInitDbPath.isEmpty() || !QFile::exists(mInitDbPath))
+            return false;
+
+        if (mServerPath.isEmpty() || !QFile::exists(mServerPath))
+            return false;
+    }
+
+    return true;
+}
+
 void DbConfigPostgresql::apply(QSqlDatabase &database)
 {
     if (!mDatabaseName.isEmpty()) {
diff --git a/src/server/storage/dbconfigpostgresql.h b/src/server/storage/dbconfigpostgresql.h
index ab39665d4..bbfced139 100644
--- a/src/server/storage/dbconfigpostgresql.h
+++ b/src/server/storage/dbconfigpostgresql.h
@@ -40,6 +40,13 @@ public:
      */
     bool init(QSettings &settings, bool storeSettings=true) override;
 
+    /**
+     * This method checks if the requirements for this database connection are
+     * met in the system (QPOSTGRESQL driver is available, postgresql binary is
+     * found, etc.).
+     */
+    bool isAvailable(QSettings &settings) override;
+
     /**
      * This method applies the configured settings to the QtSql @p database
      * instance.
diff --git a/src/server/storage/dbconfigsqlite.cpp b/src/server/storage/dbconfigsqlite.cpp
index 349ec048d..50eb2fcb4 100644
--- a/src/server/storage/dbconfigsqlite.cpp
+++ b/src/server/storage/dbconfigsqlite.cpp
@@ -100,7 +100,7 @@ bool DbConfigSqlite::init(QSettings &settings, bool storeSettings)
     return true;
 }
 
-bool DbConfigSqlite::areRequirementsAvailable(QSettings &settings)
+bool DbConfigSqlite::isAvailable(QSettings &settings)
 {
     if (!QSqlDatabase::drivers().contains(driverName()))
         return false;
diff --git a/src/server/storage/dbconfigsqlite.h b/src/server/storage/dbconfigsqlite.h
index 4410bd85b..e0158366b 100644
--- a/src/server/storage/dbconfigsqlite.h
+++ b/src/server/storage/dbconfigsqlite.h
@@ -48,7 +48,7 @@ public:
      * This method checks if the requirements for this database connection are met
      * in the system (QSQLITE/QSQLITE3 driver is available, object can be initialized, etc.).
      */
-    bool areRequirementsAvailable(QSettings &settings);
+    bool isAvailable(QSettings &settings) override;
 
     /**
      * This method applies the configured settings to the QtSql @p database
-- 
2.28.0

openSUSE Build Service is sponsored by