Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/library/dao/playlistdao.cpp

Go to the documentation of this file.
00001 
00002 #include <QtDebug>
00003 #include <QtCore>
00004 #include <QtSql>
00005 #include "trackinfoobject.h"
00006 #include "library/dao/playlistdao.h"
00007 #include "library/queryutil.h"
00008 #include "library/trackcollection.h"
00009 
00010 PlaylistDAO::PlaylistDAO(QSqlDatabase& database)
00011         : m_database(database) {
00012 }
00013 
00014 PlaylistDAO::~PlaylistDAO()
00015 {
00016 }
00017 
00018 void PlaylistDAO::initialize()
00019 {
00020 }
00021 
00025 bool PlaylistDAO::createPlaylist(QString name, bool hidden)
00026 {
00027     // qDebug() << "PlaylistDAO::createPlaylist"
00028     //          << QThread::currentThread()
00029     //          << m_database.connectionName();
00030     //Start the transaction
00031     m_database.transaction();
00032 
00033     //Find out the highest position for the existing playlists so we know what
00034     //position this playlist should have.
00035     QSqlQuery query(m_database);
00036     query.prepare("SELECT max(position) as posmax FROM Playlists");
00037 
00038     if (!query.exec()) {
00039         LOG_FAILED_QUERY(query);
00040         m_database.rollback();
00041         return false;
00042     }
00043 
00044     //Get the id of the last playlist.
00045     int position = 0;
00046     if (query.next()) {
00047         position = query.value(query.record().indexOf("posmax")).toInt();
00048         position++; //Append after the last playlist.
00049     }
00050 
00051     //qDebug() << "Inserting playlist" << name << "at position" << position;
00052 
00053     query.prepare("INSERT INTO Playlists (name, position, hidden) "
00054                   "VALUES (:name, :position, :hidden)");
00055     query.bindValue(":name", name);
00056     query.bindValue(":position", position);
00057     query.bindValue(":hidden", hidden ? 1 : 0);
00058 
00059     if (!query.exec()) {
00060         LOG_FAILED_QUERY(query);
00061         m_database.rollback();
00062         return false;
00063     }
00064 
00065     int playlistId = query.lastInsertId().toInt();
00066     //Commit the transaction
00067     m_database.commit();
00068     emit(added(playlistId));
00069     return true;
00070 }
00071 
00073 QString PlaylistDAO::getPlaylistName(unsigned int position)
00074 {
00075     // qDebug() << "PlaylistDAO::getPlaylistName" << QThread::currentThread() << m_database.connectionName();
00076 
00077     QSqlQuery query(m_database);
00078     query.prepare("SELECT name FROM Playlists "
00079                   "WHERE position = :position");
00080     query.bindValue(":position", position);
00081 
00082     if (!query.exec()) {
00083         LOG_FAILED_QUERY(query);
00084         return "";
00085     }
00086 
00087     // Get the name field
00088     QString name = "";
00089     while (query.next()) {
00090         name = query.value(query.record().indexOf("name")).toString();
00091     }
00092     return name;
00093 }
00094 
00095 int PlaylistDAO::getPlaylistIdFromName(QString name) {
00096     // qDebug() << "PlaylistDAO::getPlaylistIdFromName" << QThread::currentThread() << m_database.connectionName();
00097 
00098     QSqlQuery query(m_database);
00099     query.prepare("SELECT id FROM Playlists WHERE name = :name");
00100     query.bindValue(":name", name);
00101     if (query.exec()) {
00102         if (query.next()) {
00103             return query.value(query.record().indexOf("id")).toInt();
00104         }
00105     } else {
00106         LOG_FAILED_QUERY(query);
00107     }
00108     return -1;
00109 }
00110 
00111 
00113 void PlaylistDAO::deletePlaylist(int playlistId)
00114 {
00115     // qDebug() << "PlaylistDAO::deletePlaylist" << QThread::currentThread() << m_database.connectionName();
00116     m_database.transaction();
00117 
00118     //Get the playlist id for this
00119     QSqlQuery query(m_database);
00120 
00121     //Delete the row in the Playlists table.
00122     query.prepare("DELETE FROM Playlists "
00123                   "WHERE id= :id");
00124     query.bindValue(":id", playlistId);
00125     if (!query.exec()) {
00126         LOG_FAILED_QUERY(query);
00127         m_database.rollback();
00128         return;
00129     }
00130 
00131     //Delete the tracks in this playlist from the PlaylistTracks table.
00132     query.prepare("DELETE FROM PlaylistTracks "
00133                   "WHERE playlist_id = :id");
00134     query.bindValue(":id", playlistId);
00135     if (!query.exec()) {
00136         LOG_FAILED_QUERY(query);
00137         m_database.rollback();
00138         return;
00139     }
00140 
00141     m_database.commit();
00142     //TODO: Crap, we need to shuffle the positions of all the playlists?
00143 
00144     emit(deleted(playlistId));
00145 }
00146 
00147 
00148 void PlaylistDAO::renamePlaylist(int playlistId, const QString& newName) {
00149     QSqlQuery query(m_database);
00150     query.prepare("UPDATE Playlists SET name = :name WHERE id = :id");
00151     query.bindValue(":name", newName);
00152     query.bindValue(":id", playlistId);
00153     if (!query.exec()) {
00154         LOG_FAILED_QUERY(query);
00155     }
00156 }
00157 
00158 
00159 bool PlaylistDAO::setPlaylistLocked(int playlistId, bool locked) {
00160     // SQLite3 doesn't support boolean value. Using integer instead.
00161     int lock = locked ? 1 : 0;
00162 
00163     QSqlQuery query(m_database);
00164     query.prepare("UPDATE Playlists SET locked = :lock WHERE id = :id");
00165     query.bindValue(":lock", lock);
00166     query.bindValue(":id", playlistId);
00167 
00168     if (!query.exec()) {
00169         LOG_FAILED_QUERY(query);
00170         return false;
00171     }
00172     return true;
00173 }
00174 
00175 bool PlaylistDAO::isPlaylistLocked(int playlistId) {
00176     QSqlQuery query(m_database);
00177     query.prepare("SELECT locked FROM Playlists WHERE id = :id");
00178     query.bindValue(":id", playlistId);
00179 
00180     if (query.exec()) {
00181         if (query.next()) {
00182             int lockValue = query.value(0).toInt();
00183             return lockValue == 1;
00184         }
00185     } else {
00186         LOG_FAILED_QUERY(query);
00187     }
00188     return false;
00189 }
00190 
00192 void PlaylistDAO::appendTrackToPlaylist(int trackId, int playlistId)
00193 {
00194     // qDebug() << "PlaylistDAO::appendTrackToPlaylist"
00195     //          << QThread::currentThread() << m_database.connectionName();
00196 
00197     // Start the transaction
00198     m_database.transaction();
00199 
00200     //Find out the highest position existing in the playlist so we know what
00201     //position this track should have.
00202     QSqlQuery query(m_database);
00203     query.prepare("SELECT max(position) as position FROM PlaylistTracks "
00204                   "WHERE playlist_id = :id");
00205     query.bindValue(":id", playlistId);
00206     if (!query.exec()) {
00207         LOG_FAILED_QUERY(query);
00208     }
00209 
00210     // Get the position of the highest playlist...
00211     int position = 0;
00212     if (query.next()) {
00213         position = query.value(query.record().indexOf("position")).toInt();
00214     }
00215     position++; //Append after the last song.
00216 
00217     //Insert the song into the PlaylistTracks table
00218     query.prepare("INSERT INTO PlaylistTracks (playlist_id, track_id, position)"
00219                   "VALUES (:playlist_id, :track_id, :position)");
00220     query.bindValue(":playlist_id", playlistId);
00221     query.bindValue(":track_id", trackId);
00222     query.bindValue(":position", position);
00223 
00224     if (!query.exec()) {
00225         LOG_FAILED_QUERY(query);
00226     }
00227 
00228     // Commit the transaction
00229     m_database.commit();
00230 
00231     emit(trackAdded(playlistId, trackId, position));
00232     emit(changed(playlistId));
00233 }
00234 
00236 unsigned int PlaylistDAO::playlistCount()
00237 {
00238     // qDebug() << "PlaylistDAO::playlistCount" << QThread::currentThread() << m_database.connectionName();
00239     QSqlQuery query(m_database);
00240     query.prepare("SELECT count(*) as count FROM Playlists");
00241     if (!query.exec()) {
00242         LOG_FAILED_QUERY(query);
00243     }
00244 
00245     int numRecords = 0;
00246     if (query.next()) {
00247         numRecords = query.value(query.record().indexOf("count")).toInt();
00248     }
00249     return numRecords;
00250 }
00251 
00252 int PlaylistDAO::getPlaylistId(int position)
00253 {
00254     // qDebug() << "PlaylistDAO::getPlaylistId"
00255     //          << QThread::currentThread() << m_database.connectionName();
00256 
00257     QSqlQuery query(m_database);
00258     query.prepare("SELECT id FROM Playlists");
00259 
00260     if (query.exec()) {
00261         int currentRow = 0;
00262         while(query.next()) {
00263             if (currentRow++ == position) {
00264                 int id = query.value(0).toInt();
00265                 return id;
00266             }
00267         }
00268     } else {
00269         LOG_FAILED_QUERY(query);
00270     }
00271 
00272     return -1;
00273 }
00274 
00275 bool PlaylistDAO::isHidden(int playlistId) {
00276     // qDebug() << "PlaylistDAO::isHidden"
00277     //          << QThread::currentThread() << m_database.connectionName();
00278 
00279     QSqlQuery query(m_database);
00280     query.prepare("SELECT hidden FROM Playlists WHERE id = :id");
00281     query.bindValue(":id", playlistId);
00282 
00283     if (query.exec()) {
00284         if (query.next()) {
00285             return query.value(0).toBool();
00286         }
00287     } else {
00288         LOG_FAILED_QUERY(query);
00289     }
00290     return false;
00291 }
00292 
00293 void PlaylistDAO::removeTrackFromPlaylists(int trackId) {
00294     QSqlQuery query(m_database);
00295     QString queryString = QString("SELECT %1, %2 FROM %3 ORDER BY %2 DESC")
00296             .arg(PLAYLISTTRACKSTABLE_PLAYLISTID)
00297             .arg(PLAYLISTTRACKSTABLE_POSITION)
00298             .arg(PLAYLIST_TRACKS_TABLE);
00299     query.prepare(queryString);
00300     if (!query.exec()) {
00301         LOG_FAILED_QUERY(query);
00302         return;
00303     }
00304 
00305     int positionIndex = query.record().indexOf(PLAYLISTTRACKSTABLE_POSITION);
00306     int playlistIdIndex = query.record().indexOf(
00307         PLAYLISTTRACKSTABLE_PLAYLISTID);
00308     while (query.next()) {
00309         int position = query.value(positionIndex).toInt();
00310         int playlistId = query.value(playlistIdIndex).toInt();
00311         removeTrackFromPlaylist(playlistId, position);
00312     }
00313 }
00314 
00315 void PlaylistDAO::removeTrackFromPlaylist(int playlistId, int position)
00316 {
00317     // qDebug() << "PlaylistDAO::removeTrackFromPlaylist"
00318     //          << QThread::currentThread() << m_database.connectionName();
00319     m_database.transaction();
00320     QSqlQuery query(m_database);
00321 
00322     query.prepare("SELECT id FROM PlaylistTracks WHERE playlist_id=:id "
00323                   "AND position=:position");
00324     query.bindValue(":id", playlistId);
00325     query.bindValue(":position", position);
00326 
00327     if (!query.exec()) {
00328         LOG_FAILED_QUERY(query);
00329         m_database.rollback();
00330         return;
00331     }
00332 
00333     if (!query.next()) {
00334         qDebug() << "removeTrackFromPlaylist no track exists at position:"
00335                  << position << "in playlist:" << playlistId;
00336         return;
00337     }
00338     int trackId = query.value(query.record().indexOf("id")).toInt();
00339 
00340     //Delete the track from the playlist.
00341     query.prepare("DELETE FROM PlaylistTracks "
00342                   "WHERE playlist_id=:id AND position= :position");
00343     query.bindValue(":id", playlistId);
00344     query.bindValue(":position", position);
00345 
00346     if (!query.exec()) {
00347         LOG_FAILED_QUERY(query);
00348         m_database.rollback();
00349         return;
00350     }
00351 
00352     QString queryString;
00353     queryString = QString("UPDATE PlaylistTracks SET position=position-1 "
00354                           "WHERE position>=%1 AND "
00355                           "playlist_id=%2").arg(position).arg(playlistId);
00356     if (!query.exec(queryString)) {
00357         LOG_FAILED_QUERY(query);
00358     }
00359     m_database.commit();
00360 
00361     emit(trackRemoved(playlistId, trackId, position));
00362     emit(changed(playlistId));
00363 }
00364 
00365 void PlaylistDAO::insertTrackIntoPlaylist(int trackId, int playlistId, int position)
00366 {
00367     if (playlistId < 0 || trackId < 0 || position < 0)
00368         return;
00369 
00370     m_database.transaction();
00371 
00372     // Move all the tracks in the playlist up by one
00373     QString queryString =
00374             QString("UPDATE PlaylistTracks SET position=position+1 "
00375                     "WHERE position>=%1 AND "
00376                     "playlist_id=%2").arg(position).arg(playlistId);
00377 
00378     QSqlQuery query(m_database);
00379     if (!query.exec(queryString)) {
00380         LOG_FAILED_QUERY(query);
00381     }
00382 
00383     //Insert the song into the PlaylistTracks table
00384     query.prepare("INSERT INTO PlaylistTracks (playlist_id, track_id, position)"
00385                   "VALUES (:playlist_id, :track_id, :position)");
00386     query.bindValue(":playlist_id", playlistId);
00387     query.bindValue(":track_id", trackId);
00388     query.bindValue(":position", position);
00389 
00390     if (!query.exec()) {
00391         LOG_FAILED_QUERY(query);
00392     }
00393     m_database.commit();
00394 
00395     emit(trackAdded(playlistId, trackId, position));
00396     emit(changed(playlistId));
00397 }
00398 
00399 void PlaylistDAO::addToAutoDJQueue(int playlistId) {
00400     //qDebug() << "Adding tracks from playlist " << playlistId << " to the Auto-DJ Queue";
00401 
00402     // Query the PlaylistTracks database to locate tracks in the selected playlist
00403     QSqlQuery query(m_database);
00404     query.prepare("SELECT track_id FROM PlaylistTracks "
00405                   "WHERE playlist_id = :plid");
00406     query.bindValue(":plid", playlistId);
00407     if (!query.exec()) {
00408         LOG_FAILED_QUERY(query);
00409     }
00410 
00411     // Get the ID of the Auto-DJ playlist
00412     int autoDJId = getPlaylistIdFromName(AUTODJ_TABLE);
00413     // Loop through the tracks, adding them to the Auto-DJ Queue
00414     while(query.next()) {
00415         appendTrackToPlaylist(query.value(0).toInt(), autoDJId);
00416     }
00417 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines