![]() |
Mixxx
|
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 }