File indexing completed on 2024-05-19 04:49:26

0001 /****************************************************************************************
0002  * Copyright (c) 2014 Ralf Engels <ralf-engels@gmx.de>                                  *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #define DEBUG_PREFIX "StorageManager"
0018 
0019 #include "StorageManager.h"
0020 
0021 #include <core/storage/SqlStorage.h>
0022 #include <core/storage/StorageFactory.h>
0023 
0024 #include <core/support/Amarok.h>
0025 #include <core/support/Debug.h>
0026 
0027 #include <KConfigGroup>
0028 #include <KLocalizedString>
0029 
0030 /** A SqlStorage that doesn't do anything.
0031  *
0032  *  An object of this type is used whenever we couldn't
0033  *  load a better SqlStorage.
0034  *
0035  *  The reason is that plugins don't have to check for
0036  *  a null pointer as SqlStorage every time.
0037  */
0038 class EmptySqlStorage : public SqlStorage
0039 {
0040 public:
0041     EmptySqlStorage() {}
0042     ~EmptySqlStorage() override {}
0043 
0044     virtual int sqlDatabasePriority() const
0045     { return 10; }
0046 
0047     virtual QString type() const { return QStringLiteral("Empty"); }
0048 
0049     QString escape( const QString &text) const override { return text; }
0050 
0051     QStringList query( const QString &) override { return QStringList(); }
0052     int insert( const QString &, const QString &) override { return 0; }
0053 
0054     QString boolTrue() const override { return QString(); }
0055     QString boolFalse() const override { return QString(); }
0056 
0057     QString idType() const override { return QString(); }
0058     QString textColumnType( int ) const override { return QString(); }
0059     QString exactTextColumnType( int ) const override { return QString(); }
0060 
0061     QString exactIndexableTextColumnType( int ) const override { return QString(); }
0062     QString longTextColumnType() const override { return QString(); }
0063     QString randomFunc() const override { return QString(); }
0064 
0065     QStringList getLastErrors() const override { return QStringList(); }
0066 
0067     /** Clears the list of the last errors. */
0068     void clearLastErrors() override { }
0069 };
0070 
0071 
0072 struct StorageManager::Private
0073 {
0074     QSharedPointer<SqlStorage> sqlDatabase;
0075 
0076     /** A list that collects errors from database plugins
0077      *
0078      *  StoragePlugin factories can report errors that
0079      *  prevent the storage from even being created.
0080      *
0081      *  This list collects them.
0082      */
0083     QStringList errorList;
0084 };
0085 
0086 StorageManager *StorageManager::s_instance = nullptr;
0087 
0088 
0089 StorageManager *
0090 StorageManager::instance()
0091 {
0092     if( !s_instance ) {
0093         s_instance = new StorageManager();
0094         s_instance->init();
0095     }
0096 
0097     return s_instance;
0098 }
0099 
0100 void
0101 StorageManager::destroy()
0102 {
0103     if( s_instance ) {
0104         delete s_instance;
0105         s_instance = nullptr;
0106     }
0107 }
0108 
0109 StorageManager::StorageManager()
0110     : QObject()
0111     , d( new Private )
0112 {
0113     DEBUG_BLOCK
0114 
0115     setObjectName( QStringLiteral("StorageManager") );
0116     qRegisterMetaType<SqlStorage *>( "SqlStorage*" );
0117     d->sqlDatabase = QSharedPointer<SqlStorage>( new EmptySqlStorage );
0118 }
0119 
0120 StorageManager::~StorageManager()
0121 {
0122     DEBUG_BLOCK
0123 
0124     delete d;
0125 }
0126 
0127 QSharedPointer<SqlStorage>
0128 StorageManager::sqlStorage() const
0129 {
0130     return d->sqlDatabase;
0131 }
0132 
0133 void
0134 StorageManager::init()
0135 {
0136 }
0137 
0138 void
0139 StorageManager::setFactories( const QList<QSharedPointer<Plugins::PluginFactory> > &factories )
0140 {
0141     for( const auto &pFactory : factories )
0142     {
0143         auto factory = qobject_cast<StorageFactory*>( pFactory );
0144         if( !factory )
0145             continue;
0146 
0147         connect( factory.data(), &StorageFactory::newStorage,
0148                  this, &StorageManager::slotNewStorage );
0149         connect( factory.data(), &StorageFactory::newError,
0150                  this, &StorageManager::slotNewError );
0151     }
0152 }
0153 
0154 QStringList
0155 StorageManager::getLastErrors() const
0156 {
0157     if( !d->errorList.isEmpty() )
0158         return d->errorList;
0159     if( d->sqlDatabase.dynamicCast<EmptySqlStorage>() )
0160     {
0161         QStringList list;
0162         list << i18n( "The configured database plugin could not be loaded." );
0163         return list;
0164     }
0165     return d->errorList;
0166 }
0167 
0168 void
0169 StorageManager::clearLastErrors()
0170 {
0171     d->errorList.clear();
0172 }
0173 
0174 void
0175 StorageManager::slotNewStorage( QSharedPointer<SqlStorage> newStorage )
0176 {
0177     DEBUG_BLOCK
0178 
0179     if( !newStorage )
0180     {
0181         warning() << "Warning, newStorage in slotNewStorage is 0";
0182         return;
0183     }
0184 
0185     if( d->sqlDatabase && !d->sqlDatabase.dynamicCast<EmptySqlStorage>() )
0186     {
0187         warning() << "Warning, newStorage when we already have a storage";
0188         return; // once we have the database set we can't change it since
0189         // plugins might have already created their tables in the old database
0190         // or caching data from it.
0191     }
0192 
0193     d->sqlDatabase = newStorage;
0194 }
0195 
0196 void
0197 StorageManager::slotNewError( const QStringList &errorMessageList )
0198 {
0199     d->errorList << errorMessageList;
0200 }
0201 
0202