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