diff --git a/autotests/KDbTestUtils.h b/autotests/KDbTestUtils.h --- a/autotests/KDbTestUtils.h +++ b/autotests/KDbTestUtils.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2015-2018 Jarosław Staniek + Copyright (C) 2015-2019 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -75,6 +75,10 @@ KDBTESTUTILS_EXPORT bool qCompare(const QString &val1, const KDbEscapedString &val2, const char *actual, const char *expected, const char *file, int line); + +KDBTESTUTILS_EXPORT bool qCompare(const QStringList &val1, const QStringList &val2, + const char *actual, const char *expected, const char *file, + int line); } //! Calls @a call and verifies status of @a resultable @@ -191,7 +195,8 @@ protected: void testDisconnectPrivate(); - void testDriver(const QString &driverId, bool fileBased, const QStringList &mimeTypes); + void testDriver(const QString &driverId, bool fileBased, const QStringList &expectedMimeTypes, + const QStringList &possiblyInvalidMimeTypes); void testDriverManagerInternal(bool forceEmpty); private: diff --git a/autotests/KDbTestUtils.cpp b/autotests/KDbTestUtils.cpp --- a/autotests/KDbTestUtils.cpp +++ b/autotests/KDbTestUtils.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2015-2018 Jarosław Staniek + Copyright (C) 2015-2019 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -95,6 +95,21 @@ toString(val1), toString(qPrintable(val2.toString())), actual, expected, file, line); } + +static char *toString(const QStringList &list) +{ + return toString(qPrintable(QStringLiteral("QStringList(%1)").arg(list.join(", ")))); +} + +KDBTESTUTILS_EXPORT bool qCompare(const QStringList &val1, const QStringList &val2, + const char *actual, const char *expected, const char *file, + int line) +{ + return val1 == val2 ? compare_helper(true, "COMPARE()", toString(val1), toString(val2), actual, + expected, file, line) + : compare_helper(false, "Compared values are not the same", toString(val1), + toString(val2), actual, expected, file, line); +} } class KDbTestUtils::Private { @@ -197,38 +212,56 @@ testDriverManagerInternal(false); } -void KDbTestUtils::testDriver(const QString &driverId, bool fileBased, const QStringList &mimeTypes) +void KDbTestUtils::testDriver(const QString &driverId, bool fileBased, + const QStringList &expectedMimeTypes, + const QStringList &possiblyInvalidMimeTypes) { // find the metadata const KDbDriverMetaData* driverMetaData; - KDB_VERIFY(manager.resultable(), driverMetaData = manager.driverMetaData(driverId), "Driver metadata not found"); + KDB_VERIFY(manager.resultable(), driverMetaData = manager.driverMetaData(driverId), + qPrintable(QStringLiteral("Driver metadata not found for id=%1").arg(driverId))); QCOMPARE(driverMetaData->id(), driverId); QCOMPARE(driverMetaData->isFileBased(), fileBased); // test the mimetypes - QStringList foundMimeTypes(driverMetaData->mimeTypes()); - foundMimeTypes.sort(); - QStringList expectedMimeTypes(mimeTypes); - expectedMimeTypes.sort(); - //qDebug() << "mimeTypes:" << mimeTypes; - QCOMPARE(foundMimeTypes, expectedMimeTypes); - QVERIFY(!KDb::defaultFileBasedDriverMimeType().isEmpty()); + const QStringList foundMimeTypes(driverMetaData->mimeTypes()); + QVERIFY2(!KDb::defaultFileBasedDriverMimeType().isEmpty(), + qPrintable(QStringLiteral("id=%1").arg(driverId))); QMimeDatabase mimeDb; - foreach(const QString &mimeName, expectedMimeTypes) { - QVERIFY2(mimeDb.mimeTypeForName(mimeName).isValid(), - qPrintable(QString("%1 MIME type not found in the MIME database").arg(mimeName))); + for (const QString &mimeName : expectedMimeTypes) { + if (!mimeDb.mimeTypeForName(mimeName).isValid()) { + const QString msg = QStringLiteral("MIME type %1 not found in the MIME database").arg(mimeName); + if (possiblyInvalidMimeTypes.contains(mimeName)) { + qInfo() << qPrintable(msg); + continue; // ignore + } else { + QVERIFY2(mimeDb.mimeTypeForName(mimeName).isValid(), qPrintable(msg)); + } + } + const QStringList ids = manager.driverIdsForMimeType(mimeName); + QVERIFY2(!ids.isEmpty(), + qPrintable(QStringLiteral("No drivers found for MIME type=%1").arg(mimeName))); + QVERIFY2(ids.contains(driverId), + qPrintable(QStringLiteral("No driver with id=%1 found for MIME type=%2") + .arg(driverId, mimeName))); + } + // each found mime type expected? + for (const QString &mimeName : foundMimeTypes) { + QVERIFY2(expectedMimeTypes.contains(mimeName), + qPrintable(QStringLiteral("Unexpected MIME type=%1 found for driver with id=%2") + .arg(mimeName, driverId))); } // find driver for the metadata KDB_VERIFY(manager.resultable(), driver = manager.driver(driverId), "Driver not found"); } void KDbTestUtils::testSqliteDriverInternal() { - QStringList mimeTypes; - mimeTypes << "application/x-kexiproject-sqlite3" << "application/x-sqlite3"; - testDriver("org.kde.kdb.sqlite", - true, // file-based - mimeTypes); - QVERIFY2(mimeTypes.contains(KDb::defaultFileBasedDriverMimeType()), "SQLite's MIME types should include the default file based one"); + const QStringList mimeTypes { "application/x-kexiproject-sqlite3", "application/x-sqlite3", + "application/x-vnd.kde.kexi", "application/vnd.sqlite3" }; + const QStringList possiblyInvalidMimeTypes { "application/vnd.sqlite3" }; + testDriver("org.kde.kdb.sqlite", true /* file-based */, mimeTypes, possiblyInvalidMimeTypes); + QVERIFY2(mimeTypes.contains(KDb::defaultFileBasedDriverMimeType()), + "SQLite's MIME types should include the default file based one"); } void KDbTestUtils::testConnectInternal(const KDbConnectionData &cdata, diff --git a/src/KDbDriverManager.h b/src/KDbDriverManager.h --- a/src/KDbDriverManager.h +++ b/src/KDbDriverManager.h @@ -76,10 +76,18 @@ That drivers can be loaded by first use of driver() method. */ QStringList driverIds(); - /*! @return list of driver IDs for @a mimeType mime type. - Empty list is returned if no driver has been found. - Works only with drivers of file-based databases such as SQLite. - The lookup is case insensitive. */ + /** + * Returns list of driver IDs for @a mimeType MIME type + * + * IDs of drivers for file-based databases are only returned. + * Empty list is returned if no driver has been found for the type or if the type is invalid. + * Driver supports the supplied MIME type if it is specified as supported in the driver's + * metadata. If a MIME type alias is supplied, proper type for this alias is resolved and driver + * IDs for that type are returned. Similarly, if proper MIME type is supplied, IDs are returned + * for drivers that support any alias for this type. + * + * The lookup is case insensitive. + */ QStringList driverIdsForMimeType(const QString& mimeType); /*! @return HTML-formatted message about possible problems encountered. diff --git a/src/KDbDriverManager.cpp b/src/KDbDriverManager.cpp --- a/src/KDbDriverManager.cpp +++ b/src/KDbDriverManager.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -102,6 +103,7 @@ = KDbJsonTrader::self()->query(QLatin1String("KDb/Driver")); const QString expectedVersion = QString::fromLatin1("%1.%2") .arg(KDB_STABLE_VERSION_MAJOR).arg(KDB_STABLE_VERSION_MINOR); + QMimeDatabase mimedb; foreach(const QPluginLoader *loader, offers) { //QJsonObject json = loader->metaData(); //drivermanagerDebug() << json; @@ -123,7 +125,18 @@ } continue; } - foreach (const QString& mimeType, metaData->mimeTypes()) { + QSet resolvedMimeTypes; + for (const QString &mimeType : metaData->mimeTypes()) { + const QMimeType mime = mimedb.mimeTypeForName(mimeType); + if (!mime.isValid()) { + kdbWarning() << "Driver with ID" << metaData->id() + << "specifies the unknown MIME type" + << mimeType; + continue; + } + resolvedMimeTypes.insert(mime.name()); + } + for (const QString &mimeType : resolvedMimeTypes) { m_metadata_by_mimetype.insertMulti(mimeType, metaData.data()); } m_driversMetaData.insert(metaData->id(), metaData.data()); @@ -162,7 +175,12 @@ if (!lookupDrivers()) { return QStringList(); } - const QList metaDatas(m_metadata_by_mimetype.values(mimeType.toLower())); + QMimeDatabase mimedb; + const QMimeType mime = mimedb.mimeTypeForName(mimeType.toLower()); + if (!mime.isValid()) { + return QStringList(); + } + const QList metaDatas(m_metadata_by_mimetype.values(mime.name())); QStringList result; foreach (const KDbDriverMetaData* metaData, metaDatas) { result.append(metaData->id());