Ticket #341: dbupdate-short.patch

File dbupdate-short.patch, 9.4 KB (added by eskil <myth@…>, 19 years ago)

check file timestamps against db when updating

  • mythplugins/mythmusic/mythmusic/main.cpp

    diff -ru ../123/mythplugins/mythmusic/mythmusic/main.cpp mythplugins/mythmusic/mythmusic/main.cpp
    old new  
    66#include <qapplication.h>
    77#include <qsqldatabase.h>
    88#include <qregexp.h>
     9#include <sys/types.h>
     10#include <sys/stat.h>
    911#include <unistd.h>
    1012
    1113#include <cdaudio.h>
     
    9395    query.exec();
    9496}
    9597
     98void UpdateFileInDB (const QString &directory, const QString &filename)
     99{
     100    Decoder *decoder = getDecoder (filename);
     101   
     102    if (decoder)
     103    {
     104        Metadata *db_meta = decoder->getMetadata ();
     105        Metadata *disk_meta = decoder->readMetadata ();
     106       
     107        if (db_meta && disk_meta)
     108        {
     109            disk_meta->setID (db_meta->ID ());
     110            disk_meta->updateDatabase (directory);
     111        }
     112       
     113        if (disk_meta)
     114            delete disk_meta;
     115       
     116        if (db_meta)
     117            delete db_meta;
     118       
     119        delete decoder;
     120    }
     121}
     122
    96123enum MusicFileLocation
    97124{
    98125    kFileSystem,
    99126    kDatabase,
     127    kNeedUpdate,
    100128    kBoth
    101129};
    102130
     
    139167    }
    140168}
    141169
     170bool HasFileChanged (const QString &filename, const QString &date_modified)
     171{
     172    struct stat sbuf;
     173    if (stat (filename.ascii (), &sbuf) == 0) {
     174        if (sbuf.st_mtime > (time_t)QDateTime::fromString (date_modified,
     175                                                           Qt::ISODate).toTime_t ()) {
     176            return true;
     177        }
     178    }
     179    return false;
     180}
     181
    142182void SavePending(int pending)
    143183{
    144184    //  Temporary Hack until mythmusic
     
    208248    delete busy;
    209249
    210250    MSqlQuery query(MSqlQuery::InitCon());
    211     query.exec("SELECT filename FROM musicmetadata "
     251    query.exec("SELECT filename, date_modified FROM musicmetadata "
    212252                    "WHERE filename NOT LIKE ('%://%');");
    213253
    214254    int counter = 0;
     
    224264            QString name = directory + QString::fromUtf8(query.value(0).toString());
    225265            if (name != QString::null)
    226266            {
    227                 if ((iter = music_files.find(name)) != music_files.end())
    228                     music_files.remove(iter);
    229                 else
     267                if ((iter = music_files.find(name)) != music_files.end()) {
     268                    if (HasFileChanged(name, query.value(1).toString())) {
     269                        music_files[name] = kNeedUpdate;
     270                    } else {
     271                        music_files.remove(iter);
     272                    }
     273                } else {
    230274                    music_files[name] = kDatabase;
     275                }
    231276            }
    232277            file_checking->setProgress(++counter);
    233278        }
     
    239284    file_checking = new MythProgressDialog(QObject::tr("Updating music database"),
    240285                                           music_files.size());
    241286
    242     QRegExp quote_regex("\"");
     287    /*
     288      This can be optimised quite a bit by consolidating all commands
     289      via a lot of refactoring.
     290     
     291      1) group all files of the same decoder type, and don't
     292      create/delete a Decoder pr. AddFileToDB. Or make Decoders be
     293      singletons, it should be a fairly simple change.
     294     
     295      2) RemoveFileFromDB should group the remove into one big SQL.
     296     
     297      3) UpdateFileInDB, same as 1.
     298    */
     299   
    243300    for (iter = music_files.begin(); iter != music_files.end(); iter++)
    244301    {
    245302        if (*iter == kFileSystem)
    246303            AddFileToDB(directory, iter.key());
    247304        else if (*iter == kDatabase)
    248305            RemoveFileFromDB(directory, iter.key ());
     306        else if (*iter == kNeedUpdate)
     307            UpdateFileInDB(directory, iter.key ());
    249308
    250309        file_checking->setProgress(++counter);
    251310    }
     
    301360    AllMusic *all_music;
    302361};
    303362
     363void RebuildMusicTree (MusicData *mdata) {
     364    MythBusyDialog busy (QObject::tr("Rebuilding music tree"));
     365    busy.start ();
     366    mdata->all_music->startLoading ();
     367    while (!mdata->all_music->doneLoading ()) {
     368        qApp->processEvents ();
     369        usleep (50000);
     370    }
     371    mdata->all_playlists->postLoad();
     372    busy.Close ();
     373}
     374
    304375void MusicCallback(void *data, QString &selection)
    305376{
    306377    MusicData *mdata = (MusicData *)data;
     
    320391            //  Reconcile with the database
    321392            SearchDir(mdata->startdir);
    322393            //  Tell the metadata to reset itself
    323             mdata->all_music->resync();
    324             mdata->all_playlists->postLoad();
     394            RebuildMusicTree(mdata);
    325395        }
    326396    }
    327397    else if (sel == "settings_scan")
     
    329399        if ("" != mdata->startdir)
    330400        {
    331401            SearchDir(mdata->startdir);
    332             mdata->all_music->resync();
    333             mdata->all_playlists->postLoad();
     402            RebuildMusicTree(mdata);
    334403        }
    335404    }
    336405    else if (sel == "music_set_general")
     
    602671        // if startRipper returns true, then new files should be present
    603672        // so we should look for them.
    604673        SearchDir(mdata.startdir);
    605         mdata.all_music->resync();
    606         mdata.all_playlists->postLoad();
     674        RebuildMusicTree(&mdata);
    607675    }
    608676    postMusic(&mdata);
    609677}
  • mythplugins/mythmusic/mythmusic/metadata.cpp

    diff -ru ../123/mythplugins/mythmusic/mythmusic/metadata.cpp mythplugins/mythmusic/mythmusic/metadata.cpp
    old new  
    11#include <iostream>
     2#include <qapplication.h>
    23#include <qregexp.h>
    34#include <qdatetime.h>
    45#include <qdir.h>
     
    194195        return;
    195196
    196197    query.prepare("INSERT INTO musicmetadata (artist,compilation_artist,album,title,"
    197                   "genre,year,tracknum,length,filename,compilation,date_added) VALUES "
     198                  "genre,year,tracknum,length,filename,compilation,date_added,"
     199                  "date_modified) VALUES "
    198200                  "(:ARTIST, :COMPILATION_ARTIST, :ALBUM, :TITLE, :GENRE, :YEAR, :TRACKNUM, "
    199                   ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED );");
     201                  ":LENGTH, :FILENAME, :COMPILATION, :DATE_ADDED, :DATE_MODIFIED );");
    200202    query.bindValue(":ARTIST", artist.utf8());
    201203    query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
    202204    query.bindValue(":ALBUM", album.utf8());
     
    207209    query.bindValue(":LENGTH", length);
    208210    query.bindValue(":FILENAME", sqlfilename.utf8());
    209211    query.bindValue(":COMPILATION", compilation);
    210     query.bindValue(":DATE_ADDED", QDate::currentDate());
     212    query.bindValue(":DATE_ADDED", QDateTime::currentDateTime());
     213    query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime());
    211214   
    212215    query.exec();
    213216
     
    364367                  "compilation_artist = :COMPILATION_ARTIST, "
    365368                  "title = :TITLE, genre = :GENRE, year = :YEAR, "
    366369                  "tracknum = :TRACKNUM, rating = :RATING, "
    367                   "compilation = :COMPILATION "
     370                  "compilation = :COMPILATION, "
     371                  "date_modified= :DATE_MODIFIED "
    368372                  "WHERE intid = :ID;");
    369373    query.bindValue(":ARTIST", artist.utf8());
    370374    query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
     
    375379    query.bindValue(":TRACKNUM", tracknum);
    376380    query.bindValue(":RATING", rating);
    377381    query.bindValue(":COMPILATION", compilation);
     382    query.bindValue(":DATE_MODIFIED", QDateTime::currentDateTime());
    378383    query.bindValue(":ID", id);
    379384
    380385    if (!query.exec())
     
    683688    //  loading and sorting
    684689    //
    685690   
    686     metadata_loader = new MetadataLoadingThread(this);
    687     metadata_loader->start();
     691    metadata_loader = NULL;
     692    startLoading ();
    688693
    689694    all_music.setAutoDelete(true);
    690695    top_nodes.setAutoDelete(true);
     
    718723    return false;
    719724}
    720725
     726bool AllMusic::startLoading () {
     727    // Set this to false early rather than letting it be delayed till
     728    // the thread calls resync.
     729    done_loading = false;
     730
     731    if (metadata_loader) {
     732        cleanOutThreads ();
     733        delete metadata_loader;
     734    }
     735
     736    metadata_loader = new MetadataLoadingThread(this);
     737    metadata_loader->start ();   
     738   
     739    return true;
     740}
     741
    721742void AllMusic::resync()
    722743{
    723744    done_loading = false;
     
    11611182        if( *it != "genre"  &&
    11621183            *it != "artist" &&
    11631184            *it != "splitartist" &&
     1185            *it != "splitartist1" &&
    11641186            *it != "album"  &&
    11651187            *it != "title")
    11661188        {
  • mythplugins/mythmusic/mythmusic/metadata.h

    diff -ru ../123/mythplugins/mythmusic/mythmusic/metadata.h mythplugins/mythmusic/mythmusic/metadata.h
    old new  
    274274    Metadata*   getMetadata(int an_id);
    275275    bool        updateMetadata(int an_id, Metadata *the_track);
    276276    void        save();
     277        /** \brief Start loading metadata.
     278                Makes the AllMusic object run it's resync in a thread. Once done, it's
     279                doneLoading method will return true.
     280
     281                \note Alternatively, it could be made to emit a signal so the
     282                caller won't have to poll for completion.
     283
     284                \returns true if the loader thread was started
     285        */
     286        bool        startLoading ();
    277287    void        resync();   //  After a CD rip, for example
    278288    void        clearCDData();
    279289    void        addCDTrack(Metadata *the_track);