From de2c642a7e5cd52e83af5d2b9726f6b02058dff4 Mon Sep 17 00:00:00 2001 From: silverqx Date: Fri, 24 Jun 2022 15:01:16 +0200 Subject: [PATCH] tests enhanced connections handling If DB driver for any connection is not available then skip all tests for this connection. - also added DB::drivers()/isDriverAvailable()/... --- include/orm/databasemanager.hpp | 10 +++++++-- include/orm/db.hpp | 10 +++++++-- include/orm/tiny/model.hpp | 1 - src/orm/databasemanager.cpp | 36 +++++++++++++++++++++++++------ src/orm/db.cpp | 25 ++++++++++++++++----- tests/TinyUtils/src/databases.cpp | 34 ++++++++++++++--------------- tests/TinyUtils/src/databases.hpp | 4 ---- 7 files changed, 81 insertions(+), 39 deletions(-) diff --git a/include/orm/databasemanager.hpp b/include/orm/databasemanager.hpp index 860e8a14d..a547dd308 100644 --- a/include/orm/databasemanager.hpp +++ b/include/orm/databasemanager.hpp @@ -159,14 +159,20 @@ namespace Query to be called before querying a database. */ QSqlDatabase connectEagerly(const QString &name = ""); - /*! Get all of the support drivers. */ - QStringList supportedDrivers() const; /*! Returns a list containing the names of all connections. */ QStringList connectionNames() const; /*! Returns a list containing the names of opened connections. */ QStringList openedConnectionNames() const; /*! Get the number of registered connections. */ std::size_t connectionsSize() const; + /*! Get all of the support drivers. */ + QStringList supportedDrivers() const; + /*! Get all of the available drivers (loadable). */ + QStringList drivers() const; + /*! Is the given driver name available? */ + bool isDriverAvailable(const QString &driverName) const; + /*! Is a driver for the given connection available? */ + bool isConnectionDriverAvailable(const QString &connectionName); /*! Get the default connection name. */ const QString &getDefaultConnection() const final; diff --git a/include/orm/db.hpp b/include/orm/db.hpp index 170bfa8cd..34226261c 100644 --- a/include/orm/db.hpp +++ b/include/orm/db.hpp @@ -73,14 +73,20 @@ namespace Orm to be called before querying a database. */ static QSqlDatabase connectEagerly(const QString &name = ""); - /*! Get all of the support drivers. */ - static QStringList supportedDrivers(); /*! Returns a list containing the names of all connections. */ static QStringList connectionNames(); /*! Returns a list containing the names of opened connections. */ static QStringList openedConnectionNames(); /*! Get the number of registered connections. */ static std::size_t connectionsSize(); + /*! Get all of the support drivers. */ + static QStringList supportedDrivers(); + /*! Get all of the available drivers (loadable). */ + static QStringList drivers(); + /*! Is the given driver name available? */ + static bool isDriverAvailable(const QString &driverName); + /*! Is a driver for the given connection available? */ + static bool isConnectionDriverAvailable(const QString &connectionName); /*! Get the default connection name. */ static const QString &getDefaultConnection(); diff --git a/include/orm/tiny/model.hpp b/include/orm/tiny/model.hpp index fbba5878a..759ab36f9 100644 --- a/include/orm/tiny/model.hpp +++ b/include/orm/tiny/model.hpp @@ -1317,7 +1317,6 @@ TINYORM_END_COMMON_NAMESPACE // CUR study how to use acquire/release memory order for m_queryLogId atomic silverqx // FUTURE divide Query Builder and TinyOrm to own packages (dlls)? think about it 🤔 silverqx // BUG clang on mingw inline static initialization with another static in the same class defined line before, all other compilers (on linux too) works silverqx -// CUR cmake when MYSQL_PING is on and QMYSQL driver is not build ctest fails, fail configure? I don't knwo how I will solve this for now, also fix qmake silverqx // BUG docs many-to-many examples contain queries with created_at in pivot table, but pivot doesn't contain timestamp columns silverqx // CUR docs mdx syntax highlight prism Treeview https://prismjs.com/plugins/treeview/ silverqx // CUR docs IdealImage silverqx diff --git a/src/orm/databasemanager.cpp b/src/orm/databasemanager.cpp index ca677fac8..553d63940 100644 --- a/src/orm/databasemanager.cpp +++ b/src/orm/databasemanager.cpp @@ -362,13 +362,6 @@ QSqlDatabase DatabaseManager::connectEagerly(const QString &name) return connection(name).connectEagerly(); } -QStringList DatabaseManager::supportedDrivers() const -{ - // FUTURE add method to not only supported drivers, but also check if driver is available/loadable by qsqldatabase silverqx - // aaaaaaaaaaaaaachjo 🤔😁 -- 4 months later, looks much better, right? - return {QMYSQL, QPSQL, QSQLITE}; -} - QStringList DatabaseManager::connectionNames() const { return (*m_configuration).keys(); @@ -391,6 +384,35 @@ std::size_t DatabaseManager::connectionsSize() const return (*m_connections).size(); } +QStringList DatabaseManager::supportedDrivers() const +{ + // aaaaaaaaaaaaaachjo 🤔😁 -- 4 months later, looks much better, right? + return {QMYSQL, QPSQL, QSQLITE}; +} + +QStringList DatabaseManager::drivers() const +{ + return QSqlDatabase::drivers(); +} + +bool DatabaseManager::isDriverAvailable(const QString &driverName) const +{ + return QSqlDatabase::isDriverAvailable(driverName); +} + +bool DatabaseManager::isConnectionDriverAvailable(const QString &connectionName) +{ + const auto driverName = configuration(connectionName)[driver_].value(); + + if (!supportedDrivers().contains(driverName)) + throw Exceptions::LogicError( + QStringLiteral("An unsupported driver name '%1' has been defined for " + "the '%2' connection.") + .arg(driverName, connectionName)); + + return QSqlDatabase::isDriverAvailable(driverName); +} + const QString & DatabaseManager::getDefaultConnection() const { diff --git a/src/orm/db.cpp b/src/orm/db.cpp index da946b4d9..ca9af2128 100644 --- a/src/orm/db.cpp +++ b/src/orm/db.cpp @@ -82,11 +82,6 @@ QSqlDatabase DB::connectEagerly(const QString &name) return manager().connectEagerly(name); } -QStringList DB::supportedDrivers() -{ - return manager().supportedDrivers(); -} - QStringList DB::connectionNames() { return manager().connectionNames(); @@ -102,6 +97,26 @@ std::size_t DB::connectionsSize() return manager().connectionsSize(); } +QStringList DB::supportedDrivers() +{ + return manager().supportedDrivers(); +} + +QStringList DB::drivers() +{ + return manager().drivers(); +} + +bool Orm::DB::isDriverAvailable(const QString &driverName) +{ + return manager().isDriverAvailable(driverName); +} + +bool DB::isConnectionDriverAvailable(const QString &connectionName) +{ + return manager().isConnectionDriverAvailable(connectionName); +} + const QString &DB::getDefaultConnection() { return manager().getDefaultConnection(); diff --git a/tests/TinyUtils/src/databases.cpp b/tests/TinyUtils/src/databases.cpp index 4a4f31095..b6b4b4c4a 100644 --- a/tests/TinyUtils/src/databases.cpp +++ b/tests/TinyUtils/src/databases.cpp @@ -71,10 +71,12 @@ const QStringList &Databases::createConnections(const QStringList &connections) throwIfConnectionsInitialized(); // Ownership of a shared_ptr() + static const auto manager = *db = DB::create(); + /* The default connection is empty for tests, there is no default connection because it can produce hard to find bugs, I have to be explicit about the connection which will be used. */ - static const auto manager = *db = DB::create(getConfigurations(connections), EMPTY); + manager->addConnections(createConfigurationsHash(connections), EMPTY); static const auto cachedConnectionNames = manager->connectionNames(); @@ -117,37 +119,33 @@ const std::shared_ptr &Databases::manager() /* private */ -const Databases::ConfigurationsType & -Databases::getConfigurations(const QStringList &connections) -{ - static auto configurations = createConfigurationsHash(connections); - - // When connections variable is empty, then return all configurations - if (connections.isEmpty()) - return configurations; - - return configurations; -} - const Databases::ConfigurationsType & Databases::createConfigurationsHash(const QStringList &connections) { static ConfigurationsType configurations; - const auto shouldCreateConnection = [&connections](const auto &connection) + const auto shouldCreateConnection = [&connections] + (const auto &connection, auto &&driver) { - return connections.isEmpty() || connections.contains(connection); + const auto isAvailable = DB::isDriverAvailable(driver); + + if (!isAvailable) + qWarning("%s driver not available, all tests for this database will be " + "skipped.", driver.toLatin1().constData()); + + return isAvailable && + (connections.isEmpty() || connections.contains(connection)); }; - if (shouldCreateConnection(MYSQL)) + if (shouldCreateConnection(MYSQL, QMYSQL)) if (auto [config, envDefined] = mysqlConfiguration(); envDefined) configurations[MYSQL] = std::move(config); - if (shouldCreateConnection(SQLITE)) + if (shouldCreateConnection(SQLITE, QSQLITE)) if (auto [config, envDefined] = sqliteConfiguration(); envDefined) configurations[SQLITE] = std::move(config); - if (shouldCreateConnection(POSTGRESQL)) + if (shouldCreateConnection(POSTGRESQL, QPSQL)) if (auto [config, envDefined] = postgresConfiguration(); envDefined) configurations[POSTGRESQL] = std::move(config); diff --git a/tests/TinyUtils/src/databases.hpp b/tests/TinyUtils/src/databases.hpp index 3ea54d12a..c8e4de2f0 100644 --- a/tests/TinyUtils/src/databases.hpp +++ b/tests/TinyUtils/src/databases.hpp @@ -45,10 +45,6 @@ namespace TestUtils static const std::shared_ptr &manager(); private: - /*! Obtain configurations for the given connection names. */ - static const ConfigurationsType & - getConfigurations(const QStringList &connections = {}); - /*! Create database configurations hash. */ static const ConfigurationsType & createConfigurationsHash(const QStringList &connections);