Mixxx
|
00001 // cuedao.cpp 00002 // Created 10/26/2009 by RJ Ryan (rryan@mit.edu) 00003 00004 #include <QtDebug> 00005 #include <QtSql> 00006 #include <QVariant> 00007 00008 #include "library/dao/cuedao.h" 00009 #include "library/dao/cue.h" 00010 #include "trackinfoobject.h" 00011 00012 CueDAO::CueDAO(QSqlDatabase& database) 00013 : m_database(database) { 00014 } 00015 00016 CueDAO::~CueDAO() { 00017 00018 } 00019 00020 void CueDAO::initialize() { 00021 qDebug() << "CueDAO::initialize" << QThread::currentThread() << m_database.connectionName(); 00022 } 00023 00024 int CueDAO::cueCount() { 00025 qDebug() << "CueDAO::cueCount" << QThread::currentThread() << m_database.connectionName(); 00026 QSqlQuery query(m_database); 00027 query.prepare("SELECT COUNT(*) FROM " CUE_TABLE); 00028 if (query.exec()) { 00029 if (query.next()) { 00030 return query.value(0).toInt(); 00031 } 00032 } else { 00033 qDebug() << query.lastError(); 00034 } 00035 //query.finish(); 00036 return 0; 00037 } 00038 00039 int CueDAO::numCuesForTrack(int trackId) { 00040 qDebug() << "CueDAO::numCuesForTrack" << QThread::currentThread() << m_database.connectionName(); 00041 QSqlQuery query(m_database); 00042 query.prepare("SELECT COUNT(*) FROM " CUE_TABLE " WHERE track_id = :id"); 00043 query.bindValue(":id", trackId); 00044 if (query.exec()) { 00045 if (query.next()) { 00046 return query.value(0).toInt(); 00047 } 00048 } else { 00049 qDebug() << query.lastError(); 00050 } 00051 return 0; 00052 } 00053 00054 Cue* CueDAO::cueFromRow(QSqlQuery& query) const { 00055 QSqlRecord record = query.record(); 00056 int id = record.value(record.indexOf("id")).toInt(); 00057 int trackId = record.value(record.indexOf("track_id")).toInt(); 00058 int type = record.value(record.indexOf("type")).toInt(); 00059 int position = record.value(record.indexOf("position")).toInt(); 00060 int length = record.value(record.indexOf("length")).toInt(); 00061 int hotcue = record.value(record.indexOf("hotcue")).toInt(); 00062 QString label = record.value(record.indexOf("label")).toString(); 00063 Cue* cue = new Cue(id, trackId, (Cue::CueType)type, 00064 position, length, hotcue, label); 00065 m_cues[id] = cue; 00066 return cue; 00067 } 00068 00069 Cue* CueDAO::getCue(int cueId) { 00070 qDebug() << "CueDAO::getCue" << QThread::currentThread() << m_database.connectionName(); 00071 if (m_cues.contains(cueId)) { 00072 return m_cues[cueId]; 00073 } 00074 00075 QSqlQuery query(m_database); 00076 query.prepare("SELECT * FROM " CUE_TABLE " WHERE id = :id"); 00077 query.bindValue(":id", cueId); 00078 if (query.exec()) { 00079 if (query.next()) { 00080 return cueFromRow(query); 00081 } 00082 } else { 00083 qDebug() << query.lastError(); 00084 } 00085 return NULL; 00086 } 00087 00088 QList<Cue*> CueDAO::getCuesForTrack(int trackId) const { 00089 //qDebug() << "CueDAO::getCuesForTrack" << QThread::currentThread() << m_database.connectionName(); 00090 QList<Cue*> cues; 00091 QSqlQuery query(m_database); 00092 query.prepare("SELECT * FROM " CUE_TABLE " WHERE track_id = :id"); 00093 query.bindValue(":id", trackId); 00094 if (query.exec()) { 00095 while (query.next()) { 00096 Cue* cue = NULL; 00097 int cueId = query.value(query.record().indexOf("id")).toInt(); 00098 if (m_cues.contains(cueId)) { 00099 cue = m_cues[cueId]; 00100 } 00101 if (cue == NULL) { 00102 cue = cueFromRow(query); 00103 } 00104 if (cue != NULL) { 00105 cues.push_back(cue); 00106 } 00107 } 00108 } else { 00109 qDebug() << query.lastError(); 00110 } 00111 return cues; 00112 } 00113 00114 bool CueDAO::deleteCuesForTrack(int trackId) { 00115 qDebug() << "CueDAO::deleteCuesForTrack" << QThread::currentThread() << m_database.connectionName(); 00116 QSqlQuery query(m_database); 00117 query.prepare("DELETE FROM " CUE_TABLE " WHERE track_id = :track_id"); 00118 query.bindValue(":track_id", trackId); 00119 if (query.exec()) { 00120 return true; 00121 } else { 00122 qDebug() << query.lastError(); 00123 } 00124 return false; 00125 } 00126 00127 bool CueDAO::saveCue(Cue* cue) { 00128 //qDebug() << "CueDAO::saveCue" << QThread::currentThread() << m_database.connectionName(); 00129 Q_ASSERT(cue); 00130 if (cue->getId() == -1) { 00131 // New cue 00132 QSqlQuery query(m_database); 00133 query.prepare("INSERT INTO " CUE_TABLE " (track_id, type, position, length, hotcue, label) VALUES (:track_id, :type, :position, :length, :hotcue, :label)"); 00134 query.bindValue(":track_id", cue->getTrackId()); 00135 query.bindValue(":type", cue->getType()); 00136 query.bindValue(":position", cue->getPosition()); 00137 query.bindValue(":length", cue->getLength()); 00138 query.bindValue(":hotcue", cue->getHotCue()); 00139 query.bindValue(":label", cue->getLabel()); 00140 00141 if (query.exec()) { 00142 int id = query.lastInsertId().toInt(); 00143 cue->setId(id); 00144 cue->setDirty(false); 00145 return true; 00146 } 00147 qDebug() << query.executedQuery() << query.lastError(); 00148 } else { 00149 // Update cue 00150 QSqlQuery query(m_database); 00151 query.prepare("UPDATE " CUE_TABLE " SET " 00152 "track_id = :track_id," 00153 "type = :type," 00154 "position = :position," 00155 "length = :length," 00156 "hotcue = :hotcue," 00157 "label = :label" 00158 " WHERE id = :id"); 00159 query.bindValue(":id", cue->getId()); 00160 query.bindValue(":track_id", cue->getTrackId()); 00161 query.bindValue(":type", cue->getType()); 00162 query.bindValue(":position", cue->getPosition()); 00163 query.bindValue(":length", cue->getLength()); 00164 query.bindValue(":hotcue", cue->getHotCue()); 00165 query.bindValue(":label", cue->getLabel()); 00166 00167 if (query.exec()) { 00168 cue->setDirty(false); 00169 return true; 00170 } else { 00171 qDebug() << query.executedQuery() << query.lastError(); 00172 } 00173 } 00174 return false; 00175 } 00176 00177 bool CueDAO::deleteCue(Cue* cue) { 00178 //qDebug() << "CueDAO::deleteCue" << QThread::currentThread() << m_database.connectionName(); 00179 if (cue->getId() != -1) { 00180 QSqlQuery query(m_database); 00181 query.prepare("DELETE FROM " CUE_TABLE " WHERE id = :id"); 00182 query.bindValue(":id", cue->getId()); 00183 if (query.exec()) { 00184 return true; 00185 } else { 00186 qDebug() << query.lastError(); 00187 } 00188 } else { 00189 return true; 00190 } 00191 return false; 00192 } 00193 00194 void CueDAO::saveTrackCues(int trackId, TrackInfoObject* pTrack) { 00195 //qDebug() << "CueDAO::saveTrackCues" << QThread::currentThread() << m_database.connectionName(); 00196 // TODO(XXX) transaction, but people who are already in a transaction call 00197 // this. 00198 QTime time; 00199 00200 const QList<Cue*>& cueList = pTrack->getCuePoints(); 00201 00202 // qDebug() << "CueDAO::saveTrackCues old size:" << oldCueList.size() 00203 // << "new size:" << cueList.size(); 00204 00205 QString list = ""; 00206 00207 time.start(); 00208 // For each id still in the TIO, save or delete it. 00209 QListIterator<Cue*> cueIt(cueList); 00210 while (cueIt.hasNext()) { 00211 Cue* cue = cueIt.next(); 00212 int cueId = cue->getId(); 00213 bool newCue = cueId == -1; 00214 if (newCue) { 00215 // New cue 00216 cue->setTrackId(trackId); 00217 } else { 00218 //idList.append(QString("%1").arg(cueId)); 00219 list.append(QString("%1,").arg(cueId)); 00220 } 00221 // Update or save cue 00222 if (cue->isDirty()) { 00223 saveCue(cue); 00224 00225 // Since this cue didn't have an id until now, add it to the list of 00226 // cues not to delete. 00227 if (newCue) 00228 list.append(QString("%1,").arg(cue->getId())); 00229 } 00230 } 00231 //qDebug() << "Saving cues took " << time.elapsed() << "ms"; 00232 time.start(); 00233 00234 // Strip the last , 00235 if (list.count() > 0) 00236 list.truncate(list.count()-1); 00237 00238 // Delete cues that are no longer on the track. 00239 QSqlQuery query(m_database); 00240 query.prepare(QString("DELETE FROM cues where track_id=:track_id and not id in (%1)").arg(list)); 00241 query.bindValue(":track_id", trackId); 00242 00243 if (!query.exec()) { 00244 qDebug() << "Delete cues failed:" << query.lastError(); 00245 qDebug() << query.executedQuery(); 00246 } 00247 //qDebug() << "Deleting cues took " << time.elapsed() << "ms"; 00248 }