extragear/multimedia/amarok/src/collection/sqlcollection

Jeff Mitchell kde-dev at emailgoeshere.com
Sat Aug 2 00:16:26 CEST 2008


SVN commit 840827 by mitchell:

Port the fileadded/filedeleted features of AFT over.  One question: how best to notify clients (like the playlist) of changed file status?  In 1.4 
it used a combination of path/UID -- both were necessary (and both still are, since either value can change).  But with Meta, can I avoid emits 
and signals/slots, and simply make a Meta pointer to the appropriate track, modify the UID and/or the URL inside that pointer, and be done with 
it?  If I can do this, then I still have to somehow notify clients that they need to check their Meta pointers and see if the files are still 
valid.

If someone more familiar with Meta and shared pointers could help enlighten me, I'd appreciate it.

Note: this required another schema change...

CCMAIL:amarok-devel at kde.org


 M  +22 -8     DatabaseUpdater.cpp  
 M  +2 -1      DatabaseUpdater.h  
 M  +38 -1     ScanManager.cpp  
 M  +11 -0     ScanManager.h  
 M  +9 -1      ScanResultProcessor.cpp  
 M  +3 -0      ScanResultProcessor.h  
 M  +24 -0     SqlCollection.cpp  
 M  +4 -0      SqlCollection.h  


--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/DatabaseUpdater.cpp #840826:840827
@@ -19,6 +19,7 @@
 #include "DatabaseUpdater.h"
 
 #include "Debug.h"
+#include "mountpointmanager.h"
 #include "SqlCollection.h"
 
 static const int DB_VERSION = 1;
@@ -165,7 +166,6 @@
                     "(url " + m_collection->exactTextColumnType() +
                     ",deviceid INTEGER"
                     ",uniqueid " + m_collection->exactTextColumnType(128) + " UNIQUE"
-                    ",dir " + m_collection->exactTextColumnType() + 
                     ");";
         m_collection->query( create );
         m_collection->query( "CREATE INDEX uniqueid_temp_uniqueid ON uniqueid_temp(uniqueid);" );
@@ -505,7 +505,6 @@
                     "(url " + m_collection->exactTextColumnType() +
                     ",deviceid INTEGER"
                     ",uniqueid " + m_collection->exactTextColumnType(128) + " UNIQUE"
-                    ",dir " + m_collection->exactTextColumnType() +
                     ");";
         m_collection->query( create );
         m_collection->query( "CREATE INDEX uniqueid_uniqueid ON uniqueid(uniqueid);" );
@@ -531,27 +530,42 @@
 }
 
 void
-DatabaseUpdater::removeFilesInDir( int deviceid, const QString &rdir )
+DatabaseUpdater::removeFilesInDir( int deviceid, const QString &rdir, QHash<QString, QString> *filesRemoved )
 {
-    QString select = QString( "SELECT urls.id FROM urls LEFT JOIN directories ON urls.directory = directories.id "
+    QString select = QString( "SELECT urls.id, urls.rpath, uniqueid.uniqueid LEFT JOIN directories ON urls.directory = directories.id "
+                              "LEFT JOIN uniqueid ON uniqueid.url = urls.rpath AND uniqueid.deviceid = urls.deviceid "
                               "WHERE directories.deviceid = %1 AND directories.dir = '%2';" )
                                 .arg( QString::number( deviceid ), m_collection->escape( rdir ) );
     QStringList idResult = m_collection->query( select );
     if( !idResult.isEmpty() )
     {
+        QString id;
         QString ids;
-        foreach( const QString &id, idResult )
+        QString url;
+        QString uniqueid;
+        QString uniqueids;
+        QStringList::ConstIterator it = idResult.begin(), end = idResult.end();
+        while( it != end )
         {
+            id = (*(it++));
+            url = (*(it++));
+            uniqueid = (*(it++));
             if( !ids.isEmpty() )
                 ids += ',';
             ids += id;
+            if( !uniqueid.isEmpty() )
+            {
+                (*filesRemoved)[uniqueid] = MountPointManager::instance()->getAbsolutePath( deviceid, url );
+                if( !uniqueids.isEmpty() )
+                    uniqueids += ',';
+                uniqueids += uniqueid;
+            }
         }
         QString drop = QString( "DELETE FROM tracks WHERE id IN (%1);" ).arg( ids );
         m_collection->query( drop );
+        drop = QString( "DELETE FROM uniqueid WHERE uniqueid IN (%1);" ).arg( uniqueids );
+        m_collection->query( drop );
     }
-    QString query = QString( "DELETE FROM uniqueid WHERE uniqueid.deviceid = '%1' AND uniqueid.dir = '%2';" )
-                                .arg( deviceid )
-                                .arg( m_collection->escape( rdir ) );
 }
 
 void
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/DatabaseUpdater.h #840826:840827
@@ -19,6 +19,7 @@
 #ifndef AMAROK_DATABASEUPDATER_H
 #define AMAROK_DATABASEUPDATER_H
 
+#include <QHash>
 #include <QString>
 
 class SqlCollection;
@@ -40,7 +41,7 @@
 
     void deleteAllRedundant( const QString &type ); //type is artist,album,genre,composer or year
 
-    void removeFilesInDir( int deviceid, const QString &rdir );
+    void removeFilesInDir( int deviceid, const QString &rdir, QHash<QString, QString> *filesDeleted );
     void removeFilesInDirFromTemporaryTables( int deviceid, const QString &rdir );
 
 private:
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/ScanManager.cpp #840826:840827
@@ -338,6 +338,8 @@
         m_scanner->start();
         m_parser = new XmlParseJob( this, m_collection );
         m_parser->setIsIncremental( m_isIncremental );
+        m_parser->setFilesAddedHash( &m_filesAdded );
+        m_parser->setFilesDeletedHash( &m_filesDeleted );
         connect( m_parser, SIGNAL( done( ThreadWeaver::Job* ) ), SLOT( slotJobDone() ) );
         ThreadWeaver::Weaver::instance()->enqueue( m_parser );
     }
@@ -360,6 +362,8 @@
     : ThreadWeaver::Job( parent )
     , m_collection( collection )
     , m_isIncremental( false )
+    , m_filesAdded( 0 )
+    , m_filesDeleted( 0 )
 {
     The::statusBar()->newProgressOperation( this )
             .setDescription( i18n( "Scanning music" ) );
@@ -378,6 +382,18 @@
 }
 
 void
+XmlParseJob::setFilesAddedHash( QHash<QString, QString>* hash )
+{
+    m_filesAdded = hash;
+}
+
+void
+XmlParseJob::setFilesDeletedHash( QHash<QString, QString>* hash )
+{
+    m_filesDeleted = hash;
+}
+
+void
 XmlParseJob::run()
 {
     DEBUG_BLOCK
@@ -386,6 +402,7 @@
     QString currentDir;
 
     ScanResultProcessor processor( m_collection );
+    processor.setFilesDeletedHash( m_filesDeleted );
     if( m_isIncremental )
     {
         processor.setScanType( ScanResultProcessor::IncrementalScan );
@@ -437,7 +454,6 @@
                     data.insert( Meta::Field::TRACKNUMBER, attrs.value( "track" ).toString() );
                     data.insert( Meta::Field::DISCNUMBER, attrs.value( "discnumber" ).toString() );
                     data.insert( Meta::Field::BPM, attrs.value( "bpm" ).toString() );
-                    data.insert( Meta::Field::UNIQUEID, attrs.value( "uniqueid" ).toString() );
                     //filetype and uniqueid are missing in the fields, compilation is not used here
                     if( attrs.value( "audioproperties" ) == "true" )
                     {
@@ -448,6 +464,9 @@
                     if( !attrs.value( "filesize" ).isEmpty() )
                         data.insert( Meta::Field::FILESIZE, attrs.value( "filesize" ).toString() );
 
+                    data.insert( Meta::Field::UNIQUEID, attrs.value( "uniqueid" ).toString() );
+                    (*m_filesAdded)[attrs.value( "uniqueid ").toString()] = attrs.value( "path" ).toString();
+
                     KUrl url( data.value( Meta::Field::URL ).toString() );
                     if( firstTrack )
                     {
@@ -522,6 +541,24 @@
         }
         processor.commit();
     }
+    if( !m_isIncremental )
+    {
+        m_collection->emitFilesDeleted( *m_filesDeleted );
+        m_collection->emitFilesAdded( *m_filesAdded );
+    }
+    else
+    {
+        QHash<QString, QString>::Iterator it;
+        for( it = m_filesAdded->begin(); it != m_filesAdded->end(); ++it )
+        {
+            if( m_filesDeleted->contains( it.key() ) )
+                m_filesDeleted->remove( it.key() );
+        }
+        for( it = m_filesAdded->begin(); it != m_filesAdded->end(); ++it )
+            m_collection->emitFileAdded( it.value(), it.key() );
+        for( it = m_filesDeleted->begin(); it != m_filesDeleted->end(); ++it )
+            m_collection->emitFileDeleted( it.value(), it.key() );
+    } 
 }
 
 void
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/ScanManager.h #840826:840827
@@ -23,6 +23,7 @@
 
 #include "AmarokProcess.h"
 
+#include <QHash>
 #include <QMutex>
 #include <QObject>
 #include <QWaitCondition>
@@ -36,6 +37,7 @@
 class ScanManager : public QObject
 {
     Q_OBJECT
+
     public:
         ScanManager( SqlCollection *parent );
 
@@ -63,8 +65,12 @@
         SqlCollection *m_collection;
 
         AmarokProcess *m_scanner;
+
         XmlParseJob *m_parser;
 
+        QHash<QString, QString> m_filesAdded;
+        QHash<QString, QString> m_filesDeleted;
+
         int m_restartCount;
         bool m_isIncremental;
         bool m_blockScan;
@@ -82,13 +88,18 @@
         void addNewXmlData( const QString &data );
 
         void setIsIncremental( bool incremental );
+        void setFilesAddedHash( QHash<QString, QString>* hash );
+        void setFilesDeletedHash( QHash<QString, QString>* hash );
 
     signals:
         void incrementProgress();
 
     private:
+        ScanManager *m_scanManager;
         SqlCollection *m_collection;
         bool m_isIncremental;
+        QHash<QString, QString> *m_filesAdded;
+        QHash<QString, QString> *m_filesDeleted;
         QXmlStreamReader m_reader;
         QString m_nextData;
         QWaitCondition m_wait;
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/ScanResultProcessor.cpp #840826:840827
@@ -36,6 +36,7 @@
 ScanResultProcessor::ScanResultProcessor( SqlCollection *collection )
     : m_collection( collection )
     , m_setupComplete( false )
+    , m_filesDeleted( 0 )
     , m_type( FullScan )
 {
     DEBUG_BLOCK
@@ -53,6 +54,12 @@
 }
 
 void
+ScanResultProcessor::setFilesDeletedHash( QHash<QString, QString>* hash )
+{
+    m_filesDeleted = hash;
+}
+
+void
 ScanResultProcessor::addDirectory( const QString &dir, uint mtime )
 {
     setupDatabase();
@@ -110,7 +117,7 @@
             debug() << "removing " << dir << " from database";
             int deviceid = MountPointManager::instance()->getIdForUrl( dir );
             const QString rpath = MountPointManager::instance()->getRelativePath( deviceid, dir );
-            m_collection->dbUpdater()->removeFilesInDir( deviceid, rpath );
+            m_collection->dbUpdater()->removeFilesInDir( deviceid, rpath, m_filesDeleted );
         }
     }
     else
@@ -309,6 +316,7 @@
 
     m_collection->insert( insert, "tracks_temp" );
 
+    qDebug() << "AFT ID: " << trackData.value( Field::UNIQUEID ).toString();
     //Do AFT stuff here?
 
 }
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/ScanResultProcessor.h #840826:840827
@@ -44,6 +44,7 @@
         void addDirectory( const QString &dir, uint mtime );
         void addImage( const QString &path, const QList< QPair<QString, QString> > );
         void setScanType( ScanType type );
+        void setFilesDeletedHash( QHash<QString, QString>* hash );
         void processDirectory( const QList<QVariantMap > &data );
         void commit();
         void rollback();
@@ -79,6 +80,8 @@
 
         QHash<QString, uint> m_filesInDirs;
 
+        QHash<QString, QString>* m_filesDeleted;
+
         ScanType m_type;
 };
 
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/SqlCollection.cpp #840826:840827
@@ -207,6 +207,30 @@
     emit updated();
 }
 
+void
+SqlCollection::emitFilesAdded( const QHash<QString, QString> &files )
+{
+
+}
+
+void
+SqlCollection::emitFilesDeleted( const QHash<QString, QString> &files )
+{
+
+}
+
+void
+SqlCollection::emitFileAdded( const QString& path, const QString &id )
+{
+
+}
+
+void
+SqlCollection::emitFileDeleted( const QString& path, const QString &id )
+{
+
+}
+
 QString
 SqlCollection::escape( QString text ) const           //krazy:exclude=constref
 {
--- trunk/extragear/multimedia/amarok/src/collection/sqlcollection/SqlCollection.h #840826:840827
@@ -72,6 +72,10 @@
 
         //sqlcollection internal methods
         void sendChangedSignal();
+        void emitFilesAdded( const QHash<QString, QString> &files );
+        void emitFilesDeleted( const QHash<QString, QString> &files );
+        void emitFileAdded( const QString &path, const QString &id );
+        void emitFileDeleted( const QString &path, const QString &id );
 
         //methods defined in SqlStorage
         virtual int sqlDatabasePriority() const;


More information about the Amarok-devel mailing list