1313#include " util/math.h"
1414
1515PlaylistDAO::PlaylistDAO ()
16- : m_pAutoDJProcessor(nullptr ) {
16+ : m_currentHistoryPlaylist(kInvalidPlaylistId ),
17+ m_pAutoDJProcessor(nullptr ) {
1718}
1819
1920void PlaylistDAO::initialize (const QSqlDatabase& database) {
@@ -330,19 +331,35 @@ bool PlaylistDAO::deleteUnlockedPlaylists(QStringList&& idStringList) {
330331}
331332
332333bool PlaylistDAO::deleteAllUnlockedPlaylistsWithFewerTracks (
333- PlaylistDAO::HiddenType type, int minNumberOfTracks) {
334+ PlaylistDAO::HiddenType type,
335+ int minNumberOfTracks,
336+ bool skipCurrHistory) {
337+ // Note: this slot is also called after purging tracks in order to delete
338+ // now empty history playlists.
339+ // Though, if the current History is now also empty, we must not delete that!
340+ // Else the following session log is lost -- or rather not recorded in the
341+ // first place since the id passed to appendTrackToPlaylist() does not exist
342+ // anymore.
343+ // skipCurrHistory prevents that.
334344 VERIFY_OR_DEBUG_ASSERT (minNumberOfTracks > 0 ) {
335345 return false ; // nothing to do, probably unintended invocation
336346 }
337347
338348 QSqlQuery query (m_database);
339- query. prepare ( QStringLiteral (
349+ QString queryString = QStringLiteral (
340350 " SELECT id FROM Playlists "
341351 " WHERE (SELECT count(playlist_id) FROM PlaylistTracks WHERE "
342352 " Playlists.ID = PlaylistTracks.playlist_id) < :length AND "
343- " Playlists.hidden = :hidden AND Playlists.locked = 0" ));
353+ " Playlists.hidden = :hidden AND Playlists.locked = 0" );
354+ if (skipCurrHistory) {
355+ queryString.append (QStringLiteral (" AND Playlists.ID != :currHistoryId" ));
356+ }
357+ query.prepare (queryString);
344358 query.bindValue (" :hidden" , static_cast <int >(type));
345359 query.bindValue (" :length" , minNumberOfTracks);
360+ if (skipCurrHistory) {
361+ query.bindValue (" :currHistoryId" , m_currentHistoryPlaylist);
362+ }
346363 if (!query.exec ()) {
347364 LOG_FAILED_QUERY (query);
348365 return false ;
@@ -352,6 +369,11 @@ bool PlaylistDAO::deleteAllUnlockedPlaylistsWithFewerTracks(
352369 while (query.next ()) {
353370 idStringList.append (query.value (0 ).toString ());
354371 }
372+
373+ if (idStringList.isEmpty ()) {
374+ return false ;
375+ }
376+
355377 qInfo () << " Prepared deletion of" << idStringList.size () << " playlists of type" << type
356378 << " that contain fewer than" << minNumberOfTracks << " tracks" ;
357379
@@ -481,9 +503,29 @@ bool PlaylistDAO::removeTracksFromPlaylist(int playlistId, int startIndex) {
481503 return true ;
482504}
483505
506+ bool PlaylistDAO::playlistExists (const int playlistId) const {
507+ ScopedTransaction transaction (m_database);
508+ QSqlQuery query (m_database);
509+ query.prepare (QStringLiteral (" SELECT id FROM Playlists WHERE id = :id" ));
510+ query.bindValue (" :id" , playlistId);
511+
512+ if (!query.exec ()) {
513+ LOG_FAILED_QUERY (query);
514+ return false ;
515+ }
516+
517+ if (query.next ()) {
518+ // id is guaranteed to be unique, so we can return here
519+ return true ;
520+ }
521+ // not found
522+ return false ;
523+ }
524+
484525bool PlaylistDAO::appendTracksToPlaylist (const QList<TrackId>& trackIds, const int playlistId) {
485526 // qDebug() << "PlaylistDAO::appendTracksToPlaylist"
486527 // << QThread::currentThread() << m_database.connectionName();
528+ DEBUG_ASSERT (playlistExists (playlistId));
487529
488530 // Start the transaction
489531 ScopedTransaction transaction (m_database);
@@ -1094,7 +1136,8 @@ void PlaylistDAO::removeTracksFromPlaylists(const QList<TrackId>& trackIds, bool
10941136 transaction.commit ();
10951137
10961138 // We may now have empty history playlists. Remove them.
1097- deleteAllUnlockedPlaylistsWithFewerTracks (PlaylistDAO::PLHT_SET_LOG , 1 );
1139+ // Note: does not delete current History playlist.
1140+ deleteAllUnlockedPlaylistsWithFewerTracks (PlaylistDAO::PLHT_SET_LOG , 1 , true );
10981141
10991142 // update the sidebar
11001143 emit playlistContentChanged (playlistIds);
0 commit comments