Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mythmusic: Save playlists to DB when changed not at frontend exit
This changes things so any changes to playlists are saved to the database
immediately rather than cached and saved when the frontend exits.

This fixes a problem were you could lose edits to a playlist if the FE is not
shutdown cleanly like when using the idle timer to shutdown or if you shutdown
the computer from the FE exit menu.
(cherry picked from commit ed20979)

Fixes #11228

Signed-off-by: Stuart Morgan <smorgan@mythtv.org>
  • Loading branch information
Paul Harrison authored and stuartm committed Nov 10, 2012
1 parent 92d3fcc commit 70143c3
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 38 deletions.
3 changes: 1 addition & 2 deletions mythplugins/mythmusic/mythmusic/main.cpp
Expand Up @@ -183,8 +183,7 @@ static void loadMusic()
AllMusic *all_music = new AllMusic();

// Load all playlists into RAM (once!)
PlaylistContainer *all_playlists = new PlaylistContainer(
all_music, gCoreContext->GetHostName());
PlaylistContainer *all_playlists = new PlaylistContainer(all_music);

gMusicData->all_music = all_music;
gMusicData->all_streams = new AllStream();
Expand Down
4 changes: 4 additions & 0 deletions mythplugins/mythmusic/mythmusic/metadata.cpp
Expand Up @@ -1451,13 +1451,17 @@ void AllStream::updateStream(Metadata* mdata)

void AllStream::createPlaylist(void)
{
gMusicData->all_playlists->getStreamPlaylist()->disableSaves();

gMusicData->all_playlists->getStreamPlaylist()->removeAllTracks();

for (int x = 0; x < m_streamList.count(); x++)
{
Metadata *mdata = m_streamList.at(x);
gMusicData->all_playlists->getStreamPlaylist()->addTrack(mdata->ID(), false);
}

gMusicData->all_playlists->getStreamPlaylist()->enableSaves();
}

/**************************************************************************/
Expand Down
64 changes: 44 additions & 20 deletions mythplugins/mythmusic/mythmusic/playlist.cpp
Expand Up @@ -43,13 +43,19 @@ bool Playlist::checkTrack(int a_track_id) const
return false;
}

void Playlist::copyTracks(Playlist *to_ptr, bool update_display) const
void Playlist::copyTracks(Playlist *to_ptr, bool update_display)
{
disableSaves();

SongList::const_iterator it = m_songs.begin();
for (; it != m_songs.end(); ++it)
{
to_ptr->addTrack(*it, update_display);
}

enableSaves();

changed();
}

/// Given a tracks ID, add that track to this playlist
Expand All @@ -76,7 +82,7 @@ void Playlist::addTrack(Metadata *mdata, bool update_display)
m_shuffledSongs.push_back(mdata);
m_songMap.insert(mdata->ID(), mdata);

m_changed = true;
changed();

if (update_display)
gPlayer->activePlaylistChanged(mdata->ID(), false);
Expand All @@ -88,7 +94,7 @@ void Playlist::removeAllTracks(void)
m_songMap.clear();
m_shuffledSongs.clear();

m_changed = true;
changed();
}

void Playlist::removeTrack(int the_track)
Expand All @@ -101,6 +107,8 @@ void Playlist::removeTrack(int the_track)
m_shuffledSongs.removeAll(*it);
}

changed();

gPlayer->activePlaylistChanged(the_track, true);
}

Expand Down Expand Up @@ -137,14 +145,15 @@ void Playlist::moveTrackUpDown(bool flag, Metadata* mdata)
m_shuffledSongs.removeAt(where_its_at);
m_shuffledSongs.insert(insertion_point, mdata);

m_changed = true;
changed();
}

Playlist::Playlist(void) :
m_playlistid(0),
m_name(QObject::tr("oops")),
m_parent(NULL),
m_changed(false),
m_doSave(true),
m_progress(NULL),
m_proc(NULL),
m_procExitVal(0)
Expand Down Expand Up @@ -573,7 +582,6 @@ void Playlist::loadPlaylist(QString a_name, QString a_host)
// of an existing playlist
rawSonglist.clear();
savePlaylist(a_name, a_host);
m_changed = true;
}

fillSongsFromSonglist(rawSonglist);
Expand Down Expand Up @@ -611,6 +619,7 @@ void Playlist::loadPlaylistByID(int id, QString a_host)
void Playlist::fillSongsFromSonglist(QString songList)
{
Metadata::IdType id;
bool badTrack = false;

QStringList list = songList.split(",", QString::SkipEmptyParts);
QStringList::iterator it = list.begin();
Expand All @@ -629,8 +638,7 @@ void Playlist::fillSongsFromSonglist(QString songList)
}
else
{
m_changed = true;

badTrack = true;
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Got a bad track %1").arg(id));
}
}
Expand All @@ -645,8 +653,7 @@ void Playlist::fillSongsFromSonglist(QString songList)
}
else
{
m_changed = true;

badTrack = true;
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Got a bad track %1").arg(id));
}
}
Expand All @@ -657,10 +664,12 @@ void Playlist::fillSongsFromSonglist(QString songList)
else
shuffleTracks(MusicPlayer::SHUFFLE_OFF);

if (badTrack)
changed();

gPlayer->activePlaylistChanged(-1, false);
}

//FIXME:: this needs checking
void Playlist::fillSonglistFromQuery(QString whereClause,
bool removeDuplicates,
InsertPLOption insertOption,
Expand All @@ -669,6 +678,7 @@ void Playlist::fillSonglistFromQuery(QString whereClause,
QString orig_songlist = toRawSonglist();
QString new_songlist;

disableSaves();
removeAllTracks();

MSqlQuery query(MSqlQuery::InitCon());
Expand All @@ -694,6 +704,8 @@ void Playlist::fillSonglistFromQuery(QString whereClause,
MythDB::DBError("Load songlist from query", query);
new_songlist.clear();
fillSongsFromSonglist(new_songlist);
enableSaves();
changed();
return;
}

Expand Down Expand Up @@ -749,6 +761,9 @@ void Playlist::fillSonglistFromQuery(QString whereClause,
}

fillSongsFromSonglist(new_songlist);

enableSaves();
changed();
}

// songList is a list of trackIDs to add
Expand All @@ -760,6 +775,8 @@ void Playlist::fillSonglistFromList(const QList<int> &songList,
QString orig_songlist = toRawSonglist();
QString new_songlist;

disableSaves();

removeAllTracks();

for (int x = 0; x < songList.count(); x++)
Expand Down Expand Up @@ -814,11 +831,10 @@ void Playlist::fillSonglistFromList(const QList<int> &songList,
}

fillSongsFromSonglist(new_songlist);
}

void Playlist::fillSongsFromCD()
{
//FIXME: is this still needed?
enableSaves();

changed();
}

QString Playlist::toRawSonglist(bool shuffled)
Expand Down Expand Up @@ -934,29 +950,35 @@ void Playlist::fillSonglistFromSmartPlaylist(QString category, QString name,
if (limitTo > 0)
whereClause += " LIMIT " + QString::number(limitTo);

//m_name = name; // Set Playlist name to match smart playlist name

fillSonglistFromQuery(whereClause, removeDuplicates,
insertOption, currentTrackID);
}

void Playlist::changed(void)
{
m_changed = true;

if (m_doSave)
savePlaylist(m_name, gCoreContext->GetHostName());
}

void Playlist::savePlaylist(QString a_name, QString a_host)
{
LOG(VB_GENERAL, LOG_DEBUG, LOC + "Saving playlist: " + a_name);

m_name = a_name.simplified();
if (m_name.length() < 1)
if (m_name.isEmpty())
{
LOG(VB_GENERAL, LOG_WARNING, LOC + "Not saving unnamed playlist");
return;
}

if (a_host.length() < 1)
if (a_host.isEmpty())
{
LOG(VB_GENERAL, LOG_WARNING, LOC +
"Not saving playlist without a host name");
return;
}
if (m_name.length() < 1)
return;

QString rawSonglist = toRawSonglist(true);

Expand Down Expand Up @@ -1008,6 +1030,8 @@ void Playlist::savePlaylist(QString a_name, QString a_host)

if (m_playlistid < 1)
m_playlistid = query.lastInsertId().toInt();

m_changed = false;
}

QString Playlist::removeDuplicateTracks(const QString &orig_songlist, const QString &new_songlist)
Expand Down
11 changes: 8 additions & 3 deletions mythplugins/mythmusic/mythmusic/playlist.h
Expand Up @@ -53,7 +53,6 @@ class Playlist : public QObject

void describeYourself(void) const; // debugging

void fillSongsFromCD();
void fillSongsFromSonglist(QString songList);
void fillSonglistFromQuery(QString whereClause,
bool removeDuplicates = false,
Expand Down Expand Up @@ -85,10 +84,15 @@ class Playlist : public QObject
void removeTrack(int the_track_id);
void removeAllTracks(void);

void copyTracks(Playlist *to_ptr, bool update_display) const;
void copyTracks(Playlist *to_ptr, bool update_display);

bool hasChanged(void) { return m_changed; }
void Changed(void) { m_changed = true; }
void changed(void);

/// whether any changes should be saved to the DB
void disableSaves(void) { m_doSave = false; }
void enableSaves(void) { m_doSave = true; }
bool doSaves(void) { return m_doSave; }

QString getName(void) { return m_name; }
void setName(QString a_name) { m_name = a_name; }
Expand Down Expand Up @@ -118,6 +122,7 @@ class Playlist : public QObject
QMap<int, Metadata*> m_songMap;
PlaylistContainer *m_parent;
bool m_changed;
bool m_doSave;
MythProgressDialog *m_progress;
MythSystem *m_proc;
uint m_procExitVal;
Expand Down
20 changes: 8 additions & 12 deletions mythplugins/mythmusic/mythmusic/playlistcontainer.cpp
Expand Up @@ -46,13 +46,12 @@ bool PlaylistContainer::checkCDTrack(int track)
return m_cdPlaylist.contains(track);
}

PlaylistContainer::PlaylistContainer(
AllMusic *all_music, const QString &host_name) :
PlaylistContainer::PlaylistContainer(AllMusic *all_music) :
m_activePlaylist(NULL), m_streamPlaylist(NULL),
m_allPlaylists(NULL), m_allMusic(all_music),

m_playlistsLoader(new PlaylistLoadingThread(this, all_music)),
m_doneLoading(false), m_myHost(host_name),
m_doneLoading(false), m_myHost(gCoreContext->GetHostName()),

m_ratingWeight( gCoreContext->GetNumSetting("IntelliRatingWeight", 2)),
m_playCountWeight(gCoreContext->GetNumSetting("IntelliPlayCountWeight", 2)),
Expand Down Expand Up @@ -208,7 +207,7 @@ void PlaylistContainer::createNewPlaylist(QString name)

// Need to touch the database to get persistent ID
new_list->savePlaylist(name, m_myHost);
new_list->Changed();

m_allPlaylists->push_back(new_list);
}

Expand All @@ -219,7 +218,7 @@ void PlaylistContainer::copyNewPlaylist(QString name)

// Need to touch the database to get persistent ID
new_list->savePlaylist(name, m_myHost);
new_list->Changed();

m_allPlaylists->push_back(new_list);
m_activePlaylist->copyTracks(new_list, false);
}
Expand All @@ -235,18 +234,15 @@ void PlaylistContainer::copyToActive(int index)
return;
}
copy_from->copyTracks(m_activePlaylist, true);

m_activePlaylist->Changed();
}


void PlaylistContainer::renamePlaylist(int index, QString new_name)
{
Playlist *list_to_rename = getPlaylist(index);
if (list_to_rename)
{
list_to_rename->setName(new_name);
list_to_rename->Changed();
list_to_rename->changed();
}
}

Expand All @@ -260,6 +256,9 @@ void PlaylistContainer::deletePlaylist(int kill_me)
return;
}

list_to_kill->removeAllTracks();
m_allPlaylists->removeAll(list_to_kill);

MSqlQuery query(MSqlQuery::InitCon());
query.prepare("DELETE FROM music_playlists WHERE playlist_id = :ID ;");
query.bindValue(":ID", kill_me);
Expand All @@ -268,8 +267,6 @@ void PlaylistContainer::deletePlaylist(int kill_me)
{
MythDB::DBError("playlist delete", query);
}
list_to_kill->removeAllTracks();
m_allPlaylists->removeAll(list_to_kill);
}


Expand Down Expand Up @@ -338,5 +335,4 @@ bool PlaylistContainer::cleanOutThreads()
void PlaylistContainer::clearActive()
{
m_activePlaylist->removeAllTracks();
m_activePlaylist->Changed();
}
2 changes: 1 addition & 1 deletion mythplugins/mythmusic/mythmusic/playlistcontainer.h
Expand Up @@ -20,7 +20,7 @@ class PlaylistLoadingThread : public MThread
class PlaylistContainer
{
public:
PlaylistContainer(AllMusic *all_music, const QString &host_name);
PlaylistContainer(AllMusic *all_music);
~PlaylistContainer();

void load();
Expand Down

0 comments on commit 70143c3

Please sign in to comment.