Permalink
Browse files

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 7, 2012
1 parent 92d3fcc commit 70143c30dfb67812ecd6cb29e66a10353579054f
@@ -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();
@@ -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();
}
/**************************************************************************/
@@ -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
@@ -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);
@@ -88,7 +94,7 @@ void Playlist::removeAllTracks(void)
m_songMap.clear();
m_shuffledSongs.clear();
m_changed = true;
changed();
}
void Playlist::removeTrack(int the_track)
@@ -101,6 +107,8 @@ void Playlist::removeTrack(int the_track)
m_shuffledSongs.removeAll(*it);
}
changed();
gPlayer->activePlaylistChanged(the_track, true);
}
@@ -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)
@@ -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);
@@ -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();
@@ -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));
}
}
@@ -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));
}
}
@@ -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,
@@ -669,6 +678,7 @@ void Playlist::fillSonglistFromQuery(QString whereClause,
QString orig_songlist = toRawSonglist();
QString new_songlist;
disableSaves();
removeAllTracks();
MSqlQuery query(MSqlQuery::InitCon());
@@ -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;
}
@@ -749,6 +761,9 @@ void Playlist::fillSonglistFromQuery(QString whereClause,
}
fillSongsFromSonglist(new_songlist);
enableSaves();
changed();
}
// songList is a list of trackIDs to add
@@ -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++)
@@ -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)
@@ -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);
@@ -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)
@@ -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,
@@ -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; }
@@ -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;
@@ -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)),
@@ -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);
}
@@ -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);
}
@@ -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();
}
}
@@ -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);
@@ -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);
}
@@ -338,5 +335,4 @@ bool PlaylistContainer::cleanOutThreads()
void PlaylistContainer::clearActive()
{
m_activePlaylist->removeAllTracks();
m_activePlaylist->Changed();
}
@@ -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();

0 comments on commit 70143c3

Please sign in to comment.