[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [amarok] /: Refactoring: Move MySqlServerTester functionality to storage
From:       Ralf Engels <ralf-engels () gmx ! de>
Date:       2015-01-17 18:12:20
Message-ID: E1YCXrA-000431-No () scm ! kde ! org
[Download RAW message or body]

Git commit 3aaaf720f7039be446ad99f859efd5b229b26273 by Ralf Engels.
Committed on 03/12/2014 at 21:32.
Pushed by rengels into branch 'master'.

Refactoring: Move MySqlServerTester functionality to storage

Logic of checking for available database has now changed.

- StorageFactories will report errors to StorageManager
- StorageManager will report errors
- App will display errors from storage manager

M  +8    -24   src/App.cpp
M  +0    -13   src/CMakeLists.txt
D  +0    -51   src/MySqlServerTester.cpp
D  +0    -31   src/MySqlServerTester.h
M  +0    -20   src/core-impl/collections/db/sql/SqlCollection.cpp
M  +38   -1    src/core-impl/storage/StorageManager.cpp
M  +19   -0    src/core-impl/storage/StorageManager.h
M  +1    -10   src/core-impl/storage/sql/mysql-shared/MySqlStorage.cpp
M  +16   -5    src/core-impl/storage/sql/mysql-shared/MySqlStorage.h
M  +32   -20   src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.cpp
M  +5    -4    src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h
M  +14   -1    src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorageFactory.cpp
 M  +62   -24   src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.cpp
M  +8    -3    src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.h
M  +14   -1    src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorageFactory.cpp
 M  +0    -2    src/core/collections/Collection.h
M  +0    -3    src/core/storage/SqlStorage.h
M  +8    -2    src/core/storage/StorageFactory.h
M  +4    -3    src/core/support/PluginFactory.h
M  +1    -0    tests/core-impl/collections/db/sql/TestDatabaseUpdater.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestDatabaseUpdater.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlAlbum.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlAlbum.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlArtist.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlArtist.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlCollection.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlCollection.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlCollectionLocation.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlQueryMaker.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlQueryMaker.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlScanManager.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlScanManager.h
M  +1    -0    tests/core-impl/collections/db/sql/TestSqlTrack.cpp
M  +2    -2    tests/core-impl/collections/db/sql/TestSqlTrack.h

http://commits.kde.org/amarok/3aaaf720f7039be446ad99f859efd5b229b26273

diff --git a/src/App.cpp b/src/App.cpp
index 4930354..88d597a 100644
--- a/src/App.cpp
+++ b/src/App.cpp
@@ -60,11 +60,6 @@
 #include "statsyncing/Controller.h"
 #include "widgets/Osd.h"
 
-
-#ifdef NO_MYSQL_EMBEDDED
-#include "MySqlServerTester.h"
-#endif
-
 #include <iostream>
 
 #include <KAction>
@@ -501,29 +496,18 @@ App::continueInit()
 
     PERF_LOG( "App init done" )
 
-#ifdef NO_MYSQL_EMBEDDED
-    bool useServer = true;
-    if( !AmarokConfig::useServer() )
+    // check that the amarok sql configuration is valid.
+    if( !StorageManager::instance()->getLastErrors().isEmpty() )
     {
-        useServer = false;
-        AmarokConfig::setUseServer( true );
-    }
-    if( !MySqlServerTester::testSettings(
-             AmarokConfig::host(),
-             AmarokConfig::user(),
-             AmarokConfig::password(),
-             AmarokConfig::port()
-         )
-    )
-    {
-        KMessageBox::messageBox( 0, KMessageBox::Information,
-                ( !useServer ? i18n( "The embedded database was not found; you must \
                set up a database server connection.\nYou must restart Amarok after \
                doing this." ) :
-                              i18n( "The connection details for the database server \
were invalid.\nYou must enter correct settings and restart Amarok after doing this." \
                ) ),
-                i18n( "Database Error" ) );
+        KMessageBox::error( The::mainWindow(), i18n( "The amarok database reported "
+                 "the following errors:\n%1\nIn most cases you will need to resolve \
" +                 "these errors before Amarok will run properly." ).
+                 arg( StorageManager::instance()->getLastErrors().join( "\n" ) ),
+                 i18n( "Database Error" ));
+        StorageManager::instance()->clearLastErrors();
         slotConfigAmarok( "DatabaseConfig" );
     }
     else
-#endif
     {
         handleFirstRun();
     }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7b7369f..327ec10 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -752,15 +752,6 @@ set(amaroklib_LIB_SRCS
     moodbar/MoodbarManager.cpp
 )
 
-if( NOT BUILD_MYSQLE_COLLECTION )
-    set(amaroklib_LIB_SRCS
-        ${amaroklib_LIB_SRCS}
-        MySqlServerTester.cpp
-    )
-    add_definitions(${MYSQL_CFLAGS})
-    include_directories(${MYSQL_INCLUDE_DIR})
-endif( NOT BUILD_MYSQLE_COLLECTION )
-
 if( LIBMYGPO_QT_FOUND )
     set( EXTRA_LIBS ${LIBMYGPO_QT_LIBRARIES} )
     include_directories(     ${LIBMYGPO_QT_INCLUDE_DIRS} \
${LIBMYGPO_QT_INCLUDE_DIRS}/../ ) @@ -920,10 +911,6 @@ if(KDE4_BUILD_TESTS)
     target_link_libraries(amaroklib ${QT_QTTEST_LIBRARY})
 endif()
 
-if( NOT BUILD_MYSQLE_COLLECTION )
-    target_link_libraries(amaroklib ${MYSQL_LIBRARIES} ${ZLIB_LIBRARIES})
-endif( NOT BUILD_MYSQLE_COLLECTION )
-
 if(WIN32)
     target_link_libraries(amaroklib ${QT_QTWEBKIT_LIBRARY})
 endif(WIN32)
diff --git a/src/MySqlServerTester.cpp b/src/MySqlServerTester.cpp
deleted file mode 100644
index 5d49c10..0000000
--- a/src/MySqlServerTester.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************************
                
- * Copyright (c) 2009 Jeff Mitchell <mitchell@kde.org>                               \
                *
- *                                                                                   \
                *
- * This program is free software; you can redistribute it and/or modify it under     \
                *
- * the terms of the GNU General Public License as published by the Free Software     \
                *
- * Foundation; either version 2 of the License, or (at your option) any later        \
                *
- * version.                                                                          \
                *
- *                                                                                   \
                *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY   \
                *
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   \
                *
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.          \
                *
- *                                                                                   \
                *
- * You should have received a copy of the GNU General Public License along with      \
                *
- * this program.  If not, see <http://www.gnu.org/licenses/>.                        \
                *
- ****************************************************************************************/
                
-
-#include "MySqlServerTester.h"
-
-#include "core/support/Debug.h"
-#include <mysql.h>
-
-bool MySqlServerTester::testSettings( const QString &host, const QString &user, \
                const QString &password, int port )
-{
-    DEBUG_BLOCK
-    if( mysql_library_init( 0, NULL, NULL ) )
-    {
-        error() << "MySQL library initialization failed!";
-        return false;
-    }
-
-    MYSQL* db = mysql_init( NULL );
-
-    if( !db )
-    {
-        error() << "MySQL initialization failed";
-        return false;
-    }
-
-    if( !mysql_real_connect( db, host.toUtf8(), user.toUtf8(), password.toUtf8(), \
                NULL, port, NULL, CLIENT_COMPRESS ) )
-    {
-        mysql_close( db );
-        db = 0;
-        return false;
-    }
-    
-    mysql_close( db );
-    db = 0;
-    return true;
-}
-
-
diff --git a/src/MySqlServerTester.h b/src/MySqlServerTester.h
deleted file mode 100644
index d72f669..0000000
--- a/src/MySqlServerTester.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************************************
                
- * Copyright (c) 2009 Jeff Mitchell <mitchell@kde.org>                               \
                *
- *                                                                                   \
                *
- * This program is free software; you can redistribute it and/or modify it under     \
                *
- * the terms of the GNU General Public License as published by the Free Software     \
                *
- * Foundation; either version 2 of the License, or (at your option) any later        \
                *
- * version.                                                                          \
                *
- *                                                                                   \
                *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY   \
                *
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   \
                *
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.          \
                *
- *                                                                                   \
                *
- * You should have received a copy of the GNU General Public License along with      \
                *
- * this program.  If not, see <http://www.gnu.org/licenses/>.                        \
                *
- ****************************************************************************************/
                
-
-#ifndef AMAROK_MYSQLSERVERTESTER_H
-#define AMAROK_MYSQLSERVERTESTER_H
-
-#include <QString>
-
-class MySqlServerTester
-{
-    public:
-        MySqlServerTester() { ; }
-        virtual ~MySqlServerTester();
-        
-        static bool testSettings( const QString &host, const QString &user, const \
                QString &password, int port );
-};
-
-#endif
diff --git a/src/core-impl/collections/db/sql/SqlCollection.cpp \
b/src/core-impl/collections/db/sql/SqlCollection.cpp index 4f20b85..bba0b9c 100644
--- a/src/core-impl/collections/db/sql/SqlCollection.cpp
+++ b/src/core-impl/collections/db/sql/SqlCollection.cpp
@@ -41,7 +41,6 @@
 
 #include <KStandardDirs>
 #include <KApplication>
-#include <KMessageBox>
 #include <threadweaver/ThreadWeaver.h>
 
 #include <QApplication>
@@ -275,25 +274,6 @@ SqlCollection::SqlCollection( SqlStorage* storage )
              m_scanManager,      \
SLOT(requestScan(QList<KUrl>,GenericScanManager::ScanType)) );  \
ThreadWeaver::Weaver::instance()->enqueue( m_directoryWatcher );  
-
-    // we need a UI-dialog service, but for now just output the messages
-    if( !storage->getLastErrors().isEmpty() )
-    {
-        if( QApplication::type() != QApplication::Tty )
-        {
-            KMessageBox::error( The::mainWindow(), i18n( "The amarok database \
                reported "
-                    "the following errors:\n%1\nIn most cases you will need to \
                resolve "
-                    "these errors before Amarok will run properly.",
-                    storage->getLastErrors().join( "\n" ) ) );
-        }
-        else
-        {
-            warning() << QString( "The amarok database reported the following \
                errors:\n"
-                                  "%1\n"
-                                  "In most cases you will need to resolve these \
                errors before Amarok will run properly.").
-                arg(storage->getLastErrors().join( "\n" ) );
-        }
-    }
 }
 
 SqlCollection::~SqlCollection()
diff --git a/src/core-impl/storage/StorageManager.cpp \
b/src/core-impl/storage/StorageManager.cpp index 3e485f5..ca96afb 100644
--- a/src/core-impl/storage/StorageManager.cpp
+++ b/src/core-impl/storage/StorageManager.cpp
@@ -61,7 +61,7 @@ public:
     virtual QString longTextColumnType() const { return QString(); }
     virtual QString randomFunc() const { return QString(); }
 
-    virtual QStringList getLastErrors() const  { return QStringList(); }
+    virtual QStringList getLastErrors() const { return QStringList(); }
 
     /** Clears the list of the last errors. */
     virtual void clearLastErrors() { }
@@ -74,6 +74,15 @@ static EmptySqlStorage emptyStorage;
 struct StorageManager::Private
 {
     SqlStorage* sqlDatabase;
+
+    /** A list that collects errors from database plugins
+     *
+     *  StoragePlugin factories can report errors that
+     *  prevent the storage from even being created.
+     *
+     *  This list collects them.
+     */
+    QStringList errorList;
 };
 
 StorageManager *StorageManager::s_instance = 0;
@@ -142,9 +151,31 @@ StorageManager::setFactories( const \
QList<Plugins::PluginFactory*> &factories )  
         connect( factory, SIGNAL(newStorage(SqlStorage*)),
                  this, SLOT(slotNewStorage(SqlStorage*)) );
+        connect( factory, SIGNAL(newError(QStringList)),
+                 this, SLOT(slotNewError(QStringList)) );
     }
 }
 
+QStringList
+StorageManager::getLastErrors() const
+{
+    if( !d->errorList.isEmpty() )
+        return d->errorList;
+    if( d->sqlDatabase == &emptyStorage )
+    {
+        QStringList list;
+        list << i18n( "The configured database plugin could be loaded." );
+        return list;
+    }
+    return d->errorList;
+}
+
+void
+StorageManager::clearLastErrors()
+{
+    d->errorList.clear();
+}
+
 void
 StorageManager::slotNewStorage( SqlStorage* newStorage )
 {
@@ -168,4 +199,10 @@ StorageManager::slotNewStorage( SqlStorage* newStorage )
     d->sqlDatabase = newStorage;
 }
 
+void
+StorageManager::slotNewError( QStringList errorMessageList )
+{
+    d->errorList << errorMessageList;
+}
+
 
diff --git a/src/core-impl/storage/StorageManager.h \
b/src/core-impl/storage/StorageManager.h index 6fa5a86..1532ccf 100644
--- a/src/core-impl/storage/StorageManager.h
+++ b/src/core-impl/storage/StorageManager.h
@@ -21,6 +21,7 @@
 
 #include <QObject>
 #include <QList>
+#include <QStringList>
 
 namespace Plugins {
     class PluginFactory;
@@ -73,6 +74,15 @@ class AMAROK_EXPORT StorageManager : public QObject
          */
         void setFactories( const QList<Plugins::PluginFactory*> &factories );
 
+        /** Returns a list of the last sql errors.
+          The list might not include every one error if the number
+          is beyond a sensible limit.
+          */
+        QStringList getLastErrors() const;
+
+        /** Clears the list of the last errors. */
+        void clearLastErrors();
+
     private slots:
 
         /** Will be called whenever a factory emits a newStorage signal.
@@ -85,6 +95,15 @@ class AMAROK_EXPORT StorageManager : public QObject
          */
         void slotNewStorage( SqlStorage* newStorage );
 
+        /** Will be called whenever a factory emits a newError signal.
+         *
+         *  The factories will not emit the newStorage signal in case
+         *  of initialization problems.
+         *  In order to report their issues they will instead emit
+         *  newError with the list of errors.
+         */
+        void slotNewError( QStringList errorMessageList );
+
     private:
         static StorageManager* s_instance;
         StorageManager();
diff --git a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.cpp \
b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.cpp index 1031c15..3f2f98c \
                100644
--- a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.cpp
+++ b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.cpp
@@ -95,16 +95,7 @@ MySqlStorage::MySqlStorage()
 }
 
 MySqlStorage::~MySqlStorage()
-{
-    DEBUG_BLOCK
-
-    QMutexLocker locker( &m_mutex );
-    if( m_db )
-    {
-        mysql_close( m_db );
-        m_db = 0;
-    }
-}
+{ }
 
 QStringList MySqlStorage::query( const QString& statement )
 {
diff --git a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h \
b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h index 1a6e798..f09ee30 100644
--- a/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h
+++ b/src/core-impl/storage/sql/mysql-shared/MySqlStorage.h
@@ -40,6 +40,12 @@ class MySqlStorage: public SqlStorage
         MySqlStorage();
         virtual ~MySqlStorage();
 
+        /** Initializes the sql storage.
+         *
+         *  @returns true if the initialization was successfull.
+         */
+        virtual bool init() = 0;
+
         virtual QStringList query( const QString &query );
         virtual int insert( const QString &statement, const QString &table = \
QString() );  
@@ -49,14 +55,12 @@ class MySqlStorage: public SqlStorage
         virtual QString boolTrue() const;
         virtual QString boolFalse() const;
         virtual QString idType() const;
-        virtual QString textColumnType( int length ) const;
-        virtual QString exactTextColumnType( int length ) const;
+        virtual QString textColumnType( int length = 255 ) const;
+        virtual QString exactTextColumnType( int length = 1000 ) const;
         //the below value may have to be decreased even more for different indexes; \
                only time will tell
-        virtual QString exactIndexableTextColumnType( int length ) const;
+        virtual QString exactIndexableTextColumnType( int length = 324 ) const;
         virtual QString longTextColumnType() const;
 
-        virtual QString type() const = 0;
-
         /** Returns a list of the last sql errors.
             The list might not include every one error if the number
             is beyond a sensible limit.
@@ -67,6 +71,12 @@ class MySqlStorage: public SqlStorage
         void clearLastErrors();
 
     protected:
+        /** Adds an error message to the m_lastErrors.
+         *
+         *  Adds a message including the mysql error number and mesage
+         *  to the last error messages.
+         *  @param message Usually the query statement being executed.
+         */
         void reportError( const QString &message );
 
         void initThreadInitializer();
@@ -74,6 +84,7 @@ class MySqlStorage: public SqlStorage
 
         MYSQL* m_db;
 
+        /** Mutex protecting the m_lastErrors list */
         mutable QMutex m_mutex;
 
         QString m_debugIdent;
diff --git a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.cpp \
b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.cpp index \
                d07085a..3db04e2 100644
--- a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.cpp
+++ b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.cpp
@@ -19,9 +19,9 @@
 
 #include "MySqlEmbeddedStorage.h"
 
-#include "core/support/Amarok.h"
-#include "core/support/Debug.h"
-#include "amarokconfig.h"
+#include <amarokconfig.h>
+#include <core/support/Amarok.h>
+#include <core/support/Debug.h>
 
 #include <QDir>
 #include <QString>
@@ -34,19 +34,26 @@
 
 MySqlEmbeddedStorage::MySqlEmbeddedStorage( const QString &storageLocation )
     : MySqlStorage()
+    , m_storageLocation( storageLocation )
 {
     m_debugIdent = "MySQLe";
+}
+
+bool
+MySqlEmbeddedStorage::init()
+{
 
-    QString storagePath = storageLocation;
+    // -- figuring out and setting the database path.
+    QString storagePath = m_storageLocation;
     QString databaseDir;
-    if( storageLocation.isEmpty() )
+    if( storagePath.isEmpty() )
     {
         storagePath = Amarok::saveLocation();
         databaseDir = Amarok::config( "MySQLe" ).readEntry( "data", \
QString(storagePath + "mysqle") );  }
     else
     {
-        QDir dir( storageLocation );
+        QDir dir( storagePath );
         dir.mkpath( "." );  //ensure directory exists
         databaseDir = dir.absolutePath() + QDir::separator() + "mysqle";
     }
@@ -72,6 +79,7 @@ MySqlEmbeddedStorage::MySqlEmbeddedStorage( const QString \
&storageLocation )  dir.mkpath( "." );
     }
 
+    // -- initializing the library
     int ret = mysql_library_init( mysql_args.size(), \
const_cast<char**>(mysql_args.data()), 0 );  if( ret != 0 )
     {
@@ -82,7 +90,7 @@ MySqlEmbeddedStorage::MySqlEmbeddedStorage( const QString \
&storageLocation )  m_lastErrors.append( errorMessage );
         error() << errorMessage.toLocal8Bit().constData();
         error() << "mysqle arguments were:" << mysql_args;
-        return;
+        return false;
     }
 
     m_db = mysql_init( NULL );
@@ -90,7 +98,8 @@ MySqlEmbeddedStorage::MySqlEmbeddedStorage( const QString \
&storageLocation )  if( !m_db )
     {
         error() << "MySQLe initialization failed";
-        return;
+        mysql_library_end();
+        return false;
     }
 
     if( mysql_options( m_db, MYSQL_READ_DEFAULT_GROUP, "amarokclient" ) )
@@ -100,25 +109,28 @@ MySqlEmbeddedStorage::MySqlEmbeddedStorage( const QString \
&storageLocation )  
     if( !mysql_real_connect( m_db, NULL,NULL,NULL, 0, 0,NULL, 0 ) )
     {
-        error() << "Could not connect to mysql!";
-        reportError( "na" );
+        error() << "Could not connect to mysql embedded!";
+        reportError( "call to mysql_real_connect" );
         mysql_close( m_db );
+        mysql_library_end();
         m_db = 0;
+        return false;
     }
-    else
-    {
-        sharedInit( "amarok" );
-        debug() << "Connected to MySQL server" << mysql_get_server_info( m_db );
-    }
+
+    sharedInit( "amarok" );
+    debug() << "Connected to MySQL server" << mysql_get_server_info( m_db );
 
     MySqlStorage::initThreadInitializer();
+
+    return true;
 }
 
 MySqlEmbeddedStorage::~MySqlEmbeddedStorage()
-{}
-
-QString
-MySqlEmbeddedStorage::type() const
 {
-    return "MySQLe";
+    if( m_db )
+    {
+        mysql_close( m_db );
+        mysql_library_end();
+    }
 }
+
diff --git a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h \
b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h index \
                d4a9a82..308121f 100644
--- a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h
+++ b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorage.h
@@ -19,13 +19,11 @@
 #define MYSQLEMBEDDEDSTORAGE_H
 
 #include "../amarok_sqlstorage_export.h"
-#include <core/storage/SqlStorage.h>
-#include <core-impl/storage/sql/mysql-shared/MySqlStorage.h>
+#include "../mysql-shared/MySqlStorage.h"
 
 /**
  * Implements a MySqlStorage using a MySQL Embedded Server
  */
-
 class AMAROK_SQLSTORAGE_MYSQLE_EXPORT MySqlEmbeddedStorage : public MySqlStorage
 {
     public:
@@ -38,7 +36,10 @@ class AMAROK_SQLSTORAGE_MYSQLE_EXPORT MySqlEmbeddedStorage : \
                public MySqlStorage
         MySqlEmbeddedStorage( const QString &storageLocation = QString() );
         virtual ~MySqlEmbeddedStorage();
 
-        virtual QString type() const;
+        virtual bool init();
+
+    private:
+        QString m_storageLocation;
 };
 
 #endif // MYSQLEMBEDDEDSTORAGE_H
diff --git a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorageFactory.cpp \
b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorageFactory.cpp index \
                abfda86..6d25923 100644
--- a/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorageFactory.cpp
+++ b/src/core-impl/storage/sql/mysqlestorage/MySqlEmbeddedStorageFactory.cpp
@@ -40,7 +40,20 @@ MySqleStorageFactory::init()
     m_initialized = true;
 
     if( ! Amarok::config( "MySQL" ).readEntry( "UseServer", false ) )
-        emit newStorage( new MySqlEmbeddedStorage() );
+    {
+        MySqlEmbeddedStorage* storage = new MySqlEmbeddedStorage();
+        bool initResult = storage->init();
+
+        // handle errors during creation
+        if( !storage->getLastErrors().isEmpty() )
+            emit newError( storage->getLastErrors() );
+        storage->clearLastErrors();
+
+        if( initResult )
+            emit newStorage( storage );
+        else
+            delete storage;
+    }
 }
 
 #include "MySqlEmbeddedStorageFactory.moc"
diff --git a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.cpp \
b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.cpp index \
                c630490..f427b2e 100644
--- a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.cpp
+++ b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.cpp
@@ -31,14 +31,22 @@
 MySqlServerStorage::MySqlServerStorage()
     : MySqlStorage()
 {
+    m_debugIdent = "MySQL-server";
+}
+
+bool
+MySqlServerStorage::init()
+{
     DEBUG_BLOCK
 
-    m_debugIdent = "MySQL-server";
 
-    if( mysql_library_init( 0, NULL, NULL ) )
+    // -- initializing the library
+    int ret = mysql_library_init( 0, NULL, NULL );
+    if( ret != 0 )
     {
+        // it has no sense to call reportError here because m_db is not yet \
initialized  error() << "MySQL library initialization failed!";
-        return;
+        return false;
     }
 
     m_db = mysql_init( NULL );
@@ -47,11 +55,10 @@ MySqlServerStorage::MySqlServerStorage()
     {
         error() << "MySQL initialization failed";
         mysql_library_end();
-        return;
+        return false;
     }
 
     //first here, the right way for >= 5.1.6
-
     my_bool reconnect = true;
     if( mysql_options( m_db, MYSQL_OPT_RECONNECT, &reconnect ) )
         reportError( "Asking for automatic reconnect did not succeed!" );
@@ -68,39 +75,38 @@ MySqlServerStorage::MySqlServerStorage()
                 CLIENT_COMPRESS )
         )
     {
-        debug() << "connection to mysql failed";
-        error() << "Could not connect to mysql!";
-        reportError( "na" );
+        error() << "Could not connect to mysql server!";
+        reportError( "call to mysql_real_connect" );
         mysql_close( m_db );
         mysql_library_end();
         m_db = 0;
+        return false;
     }
+
+    //but in versions prior to 5.1.6, have to call it after every real_connect
+    reconnect = true;
+    if( mysql_options( m_db, MYSQL_OPT_RECONNECT, &reconnect ) )
+        reportError( "Asking for automatic reconnect did not succeed!" );
     else
-    {
-        //but in versions prior to 5.1.6, have to call it after every real_connect
-        my_bool reconnect = true;
-        if( mysql_options( m_db, MYSQL_OPT_RECONNECT, &reconnect ) )
-            reportError( "Asking for automatic reconnect did not succeed!" );
-        else
-            debug() << "Automatic reconnect successfully activated";
+        debug() << "Automatic reconnect successfully activated";
 
-        QString databaseName = Amarok::config( "MySQL" ).readEntry( "Database", \
                "amarokdb" );
-        sharedInit( databaseName );
-        debug() << "Connected to MySQL server" << mysql_get_server_info( m_db );
-    }
+    QString databaseName = Amarok::config( "MySQL" ).readEntry( "Database", \
"amarokdb" ); +    sharedInit( databaseName );
+    debug() << "Connected to MySQL server" << mysql_get_server_info( m_db );
 
     MySqlServerStorage::initThreadInitializer();
+    return true;
 }
 
 MySqlServerStorage::~MySqlServerStorage()
 {
     DEBUG_BLOCK
-}
 
-QString
-MySqlServerStorage::type() const
-{
-    return "MySQL";
+    if( m_db )
+    {
+        mysql_close( m_db );
+        mysql_library_end();
+    }
 }
 
 QStringList
@@ -138,3 +144,35 @@ MySqlServerStorage::query( const QString &query )
 }
 
 
+bool
+MySqlServerStorage::testSettings( const QString &host, const QString &user, const \
QString &password, int port ) +{
+    DEBUG_BLOCK
+    if( mysql_library_init( 0, NULL, NULL ) )
+    {
+        error() << "MySQL library initialization failed!";
+        return false;
+    }
+
+    MYSQL* db = mysql_init( NULL );
+
+    if( !db )
+    {
+        error() << "MySQL initialization failed";
+        return false;
+    }
+
+    if( !mysql_real_connect( db, host.toUtf8(), user.toUtf8(), password.toUtf8(), \
NULL, port, NULL, CLIENT_COMPRESS ) ) +    {
+        mysql_close( db );
+        db = 0;
+        return false;
+    }
+
+    mysql_close( db );
+    db = 0;
+    return true;
+}
+
+
+
diff --git a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.h \
b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.h index \
                027b1f5..f63cee7 100644
--- a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.h
+++ b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorage.h
@@ -18,20 +18,25 @@
 #ifndef AMAROK_STORAGE_MYSQLSERVERSTORAGE_H
 #define AMAROK_STORAGE_MYSQLSERVERSTORAGE_H
 
-#include "amarok_export.h"
+#include "../amarok_sqlstorage_export.h"
 #include "../mysql-shared/MySqlStorage.h"
 
 /**
  * Implements a MySqlStorage using a MySQL Server
  */
-class AMAROK_EXPORT MySqlServerStorage: public MySqlStorage
+class AMAROK_SQLSTORAGE_MYSQLE_EXPORT MySqlServerStorage: public MySqlStorage
 {
     public:
+        /** Connect to the server defined by the configuration options. */
         MySqlServerStorage();
         virtual ~MySqlServerStorage();
 
-        virtual QString type() const;
+        virtual bool init();
+
         virtual QStringList query( const QString &query );
+
+        /** Returns true if the given settings allow to connect to a sql server. */
+        static bool testSettings( const QString &host, const QString &user, const \
QString &password, int port );  };
 
 #endif
diff --git a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorageFactory.cpp \
b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorageFactory.cpp index \
                86802fe..676821a 100644
--- a/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorageFactory.cpp
+++ b/src/core-impl/storage/sql/mysqlserverstorage/MySqlServerStorageFactory.cpp
@@ -40,7 +40,20 @@ MySqlServerStorageFactory::init()
     m_initialized = true;
 
     if( Amarok::config( "MySQL" ).readEntry( "UseServer", false ) )
-        emit newStorage( new MySqlServerStorage() );
+    {
+        MySqlServerStorage* storage = new MySqlServerStorage();
+        bool initResult = storage->init();
+
+        // handle errors during creation
+        if( !storage->getLastErrors().isEmpty() )
+            emit newError( storage->getLastErrors() );
+        storage->clearLastErrors();
+
+        if( initResult )
+            emit newStorage( storage );
+        else
+            delete storage;
+    }
 }
 
 #include "MySqlServerStorageFactory.moc"
diff --git a/src/core/collections/Collection.h b/src/core/collections/Collection.h
index 79e85a8..bfa6e32 100644
--- a/src/core/collections/Collection.h
+++ b/src/core/collections/Collection.h
@@ -51,8 +51,6 @@ namespace Collections
             CollectionFactory( QObject *parent, const QVariantList &args );
             virtual ~CollectionFactory();
 
-            virtual void init() = 0;
-
         signals:
             void newCollection( Collections::Collection *newCollection );
     };
diff --git a/src/core/storage/SqlStorage.h b/src/core/storage/SqlStorage.h
index 02e538b..1bcf433 100644
--- a/src/core/storage/SqlStorage.h
+++ b/src/core/storage/SqlStorage.h
@@ -32,9 +32,6 @@ public:
     SqlStorage() {}
     virtual ~SqlStorage() {}
 
-    /** Returns e.g. MySQLe */
-    virtual QString type() const = 0;
-
     virtual QString escape( const QString &text ) const = 0;
 
     virtual QStringList query( const QString &query ) = 0;
diff --git a/src/core/storage/StorageFactory.h b/src/core/storage/StorageFactory.h
index 7bcf0ce..0dfda33 100644
--- a/src/core/storage/StorageFactory.h
+++ b/src/core/storage/StorageFactory.h
@@ -39,13 +39,19 @@ public:
     StorageFactory( QObject *parent, const QVariantList &args );
     virtual ~StorageFactory();
 
-    virtual void init() = 0;
-
 signals:
     /** Emitted whenever the factory produces a new storage.
      *
      */
     void newStorage( SqlStorage *newStorage );
+
+    /**
+     *  The factories will not emit the newStorage signal in case
+     *  of initialization problems.
+     *  In order to report their issues they will instead emit
+     *  newError with the list of errors.
+     */
+    void newError( QStringList errorMessageList );
 };
 
 
diff --git a/src/core/support/PluginFactory.h b/src/core/support/PluginFactory.h
index 59f6c1a..beec8d0 100644
--- a/src/core/support/PluginFactory.h
+++ b/src/core/support/PluginFactory.h
@@ -31,6 +31,7 @@ namespace Plugins {
  *  - CollectionFactory
  *  - ServiceFactory
  *  - ImportFactory
+ *  - StorageFactory
  *
  *  Plugins need to set the m_info variables.
  *  Plugins also need to set a valid category in their Desktop file.
@@ -44,8 +45,8 @@ public:
     PluginFactory( QObject *parent, const QVariantList &args );
     virtual ~PluginFactory() = 0;
 
-    /**
-     * Initialize the service plugin of this type.
+    /** Initialize the service plugin of this type.
+     *
      * Reimplemented by subclasses, which must set
      * m_initialized = true when the function has finished.
      *
@@ -58,7 +59,7 @@ public:
 
 protected:
     bool m_initialized; ///< set after init was called
-    KPluginInfo m_info;
+    KPluginInfo m_info; ///< contains the KPluginInfo returned by info(). Should be \
set in the constructor  };
 
 } // namespace Plugins
diff --git a/tests/core-impl/collections/db/sql/TestDatabaseUpdater.cpp \
b/tests/core-impl/collections/db/sql/TestDatabaseUpdater.cpp index 0d0928c..7c2d904 \
                100644
--- a/tests/core-impl/collections/db/sql/TestDatabaseUpdater.cpp
+++ b/tests/core-impl/collections/db/sql/TestDatabaseUpdater.cpp
@@ -40,6 +40,7 @@ DatabaseUpdaterTest::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
 }
 
diff --git a/tests/core-impl/collections/db/sql/TestDatabaseUpdater.h \
b/tests/core-impl/collections/db/sql/TestDatabaseUpdater.h index f4ca356..b29d818 \
                100644
--- a/tests/core-impl/collections/db/sql/TestDatabaseUpdater.h
+++ b/tests/core-impl/collections/db/sql/TestDatabaseUpdater.h
@@ -21,7 +21,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 
 namespace Collections {
     class SqlCollection;
@@ -47,7 +47,7 @@ private slots:
 
 private:
     Collections::SqlCollection *m_collection;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 
diff --git a/tests/core-impl/collections/db/sql/TestSqlAlbum.cpp \
b/tests/core-impl/collections/db/sql/TestSqlAlbum.cpp index d12d2b9..6386b7c 100644
--- a/tests/core-impl/collections/db/sql/TestSqlAlbum.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlAlbum.cpp
@@ -48,6 +48,7 @@ TestSqlAlbum::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
     m_collection->setMountPointManager( new SqlMountPointManagerMock( this, \
m_storage ) );  }
diff --git a/tests/core-impl/collections/db/sql/TestSqlAlbum.h \
b/tests/core-impl/collections/db/sql/TestSqlAlbum.h index 595c574..e105e4a 100644
--- a/tests/core-impl/collections/db/sql/TestSqlAlbum.h
+++ b/tests/core-impl/collections/db/sql/TestSqlAlbum.h
@@ -21,7 +21,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 class SqlRegistry;
 
 namespace Collections {
@@ -60,7 +60,7 @@ private slots:
 
 private:
     Collections::SqlCollection *m_collection;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 
diff --git a/tests/core-impl/collections/db/sql/TestSqlArtist.cpp \
b/tests/core-impl/collections/db/sql/TestSqlArtist.cpp index 2571187..074cefc 100644
--- a/tests/core-impl/collections/db/sql/TestSqlArtist.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlArtist.cpp
@@ -39,6 +39,7 @@ TestSqlArtist::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
     m_collection->setMountPointManager( new SqlMountPointManagerMock( this, \
m_storage ) );  }
diff --git a/tests/core-impl/collections/db/sql/TestSqlArtist.h \
b/tests/core-impl/collections/db/sql/TestSqlArtist.h index 14a28c3..f8aed9d 100644
--- a/tests/core-impl/collections/db/sql/TestSqlArtist.h
+++ b/tests/core-impl/collections/db/sql/TestSqlArtist.h
@@ -20,7 +20,7 @@
 #include <QtTest/QtTest>
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 
 namespace Collections {
     class SqlCollection;
@@ -43,7 +43,7 @@ private slots:
 
 private:
     Collections::SqlCollection *m_collection;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 
     public:
diff --git a/tests/core-impl/collections/db/sql/TestSqlCollection.cpp \
b/tests/core-impl/collections/db/sql/TestSqlCollection.cpp index 9039875..aca0973 \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlCollection.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlCollection.cpp
@@ -38,6 +38,7 @@ TestSqlCollection::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
     m_mpmMock = new SqlMountPointManagerMock( this, m_storage );
     m_collection->setMountPointManager( m_mpmMock );
diff --git a/tests/core-impl/collections/db/sql/TestSqlCollection.h \
b/tests/core-impl/collections/db/sql/TestSqlCollection.h index f1da34a..6a30fde \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlCollection.h
+++ b/tests/core-impl/collections/db/sql/TestSqlCollection.h
@@ -22,7 +22,7 @@
 #include <KTempDir>
 
 class SqlMountPointManagerMock;
-class SqlStorage;
+class MySqlStorage;
 
 namespace Collections {
     class SqlCollection;
@@ -47,7 +47,7 @@ private slots:
 private:
     Collections::SqlCollection *m_collection;
     SqlMountPointManagerMock *m_mpmMock;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 
diff --git a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp \
b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp index \
                a21deaa..e83724f 100644
--- a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.cpp
@@ -116,6 +116,7 @@ TestSqlCollectionLocation::initTestCase()
     Amarok::Components::setLogger( new ProxyLogger() );
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
     SqlMountPointManagerMock *mock = new SqlMountPointManagerMock( this, m_storage \
                );
     mock->setCollectionFolders( QStringList() << m_tmpDir->name() ); // the target \
                folder needs to have enough space and be writable
diff --git a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.h \
b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.h index \
                3855ec3..3331b6a 100644
--- a/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.h
+++ b/tests/core-impl/collections/db/sql/TestSqlCollectionLocation.h
@@ -21,7 +21,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 namespace Collections
 {
     class SqlCollection;
@@ -50,7 +50,7 @@ private:
 
 private:
     Collections::SqlCollection *m_collection;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 
diff --git a/tests/core-impl/collections/db/sql/TestSqlQueryMaker.cpp \
b/tests/core-impl/collections/db/sql/TestSqlQueryMaker.cpp index b0f69b9..5c83fc5 \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlQueryMaker.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlQueryMaker.cpp
@@ -69,6 +69,7 @@ TestSqlQueryMaker::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
 
     QMap<int,QString> mountPoints;
diff --git a/tests/core-impl/collections/db/sql/TestSqlQueryMaker.h \
b/tests/core-impl/collections/db/sql/TestSqlQueryMaker.h index 2d3bc85..5c6e10b \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlQueryMaker.h
+++ b/tests/core-impl/collections/db/sql/TestSqlQueryMaker.h
@@ -22,7 +22,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 class SqlMountPointManagerMock;
 
 namespace Collections {
@@ -95,7 +95,7 @@ private:
 
     Collections::SqlCollection *m_collection;
     SqlMountPointManagerMock *m_mpm;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 
diff --git a/tests/core-impl/collections/db/sql/TestSqlScanManager.cpp \
b/tests/core-impl/collections/db/sql/TestSqlScanManager.cpp index d0e4437..2c942dd \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlScanManager.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlScanManager.cpp
@@ -60,6 +60,7 @@ TestSqlScanManager::initTestCase()
     m_tmpDatabaseDir = new KTempDir();
     QVERIFY( m_tmpDatabaseDir->exists() );
     m_storage = new MySqlEmbeddedStorage( m_tmpDatabaseDir->name() );
+    QVERIFY( m_storage->init() );
 
     m_collection = new Collections::SqlCollection( m_storage );
     connect( m_collection, SIGNAL(updated()), this, SLOT(slotCollectionUpdated()) );
diff --git a/tests/core-impl/collections/db/sql/TestSqlScanManager.h \
b/tests/core-impl/collections/db/sql/TestSqlScanManager.h index 24b439a..e408f78 \
                100644
--- a/tests/core-impl/collections/db/sql/TestSqlScanManager.h
+++ b/tests/core-impl/collections/db/sql/TestSqlScanManager.h
@@ -24,7 +24,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 class GenericScanManager;
 
 class QIODevice;
@@ -169,7 +169,7 @@ private:
 
     int m_collectionUpdatedCount;
 
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDatabaseDir;
     KTempDir *m_tmpCollectionDir;
     QString m_sourcePath; // the path to the template .mp3 file
diff --git a/tests/core-impl/collections/db/sql/TestSqlTrack.cpp \
b/tests/core-impl/collections/db/sql/TestSqlTrack.cpp index d94af9e..d3bdf81 100644
--- a/tests/core-impl/collections/db/sql/TestSqlTrack.cpp
+++ b/tests/core-impl/collections/db/sql/TestSqlTrack.cpp
@@ -47,6 +47,7 @@ TestSqlTrack::initTestCase()
 {
     m_tmpDir = new KTempDir();
     m_storage = new MySqlEmbeddedStorage( m_tmpDir->name() );
+    QVERIFY( m_storage->init() );
     m_collection = new Collections::SqlCollection( m_storage );
     m_collection->setMountPointManager( new SqlMountPointManagerMock( this, \
m_storage ) );  
diff --git a/tests/core-impl/collections/db/sql/TestSqlTrack.h \
b/tests/core-impl/collections/db/sql/TestSqlTrack.h index 0cce0df..2ba4929 100644
--- a/tests/core-impl/collections/db/sql/TestSqlTrack.h
+++ b/tests/core-impl/collections/db/sql/TestSqlTrack.h
@@ -21,7 +21,7 @@
 
 #include <KTempDir>
 
-class SqlStorage;
+class MySqlStorage;
 class SqlRegistry;
 
 namespace Collections {
@@ -65,7 +65,7 @@ private:
     void getAllValues( Meta::SqlTrack *track );
 
     Collections::SqlCollection *m_collection;
-    SqlStorage *m_storage;
+    MySqlStorage *m_storage;
     KTempDir *m_tmpDir;
 };
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic