![]() |
Mixxx
|
00001 #include <QtCore> 00002 #include <QtGui> 00003 #include <QtSql> 00004 #include <QtDebug> 00005 00006 #include "trackcollection.h" 00007 00008 #include "defs.h" 00009 #include "library/librarytablemodel.h" 00010 #include "library/schemamanager.h" 00011 #include "soundsourceproxy.h" 00012 #include "trackinfoobject.h" 00013 #include "xmlparse.h" 00014 00015 TrackCollection::TrackCollection(ConfigObject<ConfigValue>* pConfig) 00016 : m_pConfig(pConfig), 00017 m_db(QSqlDatabase::addDatabase("QSQLITE")), // defaultConnection 00018 m_cueDao(m_db), 00019 m_playlistDao(m_db), 00020 m_crateDao(m_db), 00021 m_trackDao(m_db, m_cueDao, m_playlistDao, m_crateDao, pConfig), 00022 m_supportedFileExtensionsRegex( 00023 SoundSourceProxy::supportedFileExtensionsRegex(), 00024 Qt::CaseInsensitive) { 00025 bCancelLibraryScan = false; 00026 qDebug() << "Available QtSQL drivers:" << QSqlDatabase::drivers(); 00027 00028 m_db.setHostName("localhost"); 00029 m_db.setDatabaseName(MIXXX_DB_PATH); 00030 m_db.setUserName("mixxx"); 00031 m_db.setPassword("mixxx"); 00032 bool ok = m_db.open(); 00033 qDebug() << __FILE__ << "DB status:" << ok; 00034 if (m_db.lastError().isValid()) { 00035 qDebug() << "Error loading database:" << m_db.lastError(); 00036 } 00037 // Check for tables and create them if missing 00038 if (!checkForTables()) { 00039 // TODO(XXX) something a little more elegant 00040 exit(-1); 00041 } 00042 } 00043 00044 TrackCollection::~TrackCollection() { 00045 qDebug() << "~TrackCollection()"; 00046 // Save all tracks that haven't been saved yet. 00047 m_trackDao.saveDirtyTracks(); 00048 // TODO(XXX) Maybe fold saveDirtyTracks into TrackDAO::finish now that it 00049 // exists? -- rryan 10/2010 00050 m_trackDao.finish(); 00051 00052 Q_ASSERT(!m_db.rollback()); //Rollback any uncommitted transaction 00053 //The above is an ASSERT because there should never be an outstanding 00054 //transaction when this code is called. If there is, it means we probably 00055 //aren't committing a transaction somewhere that should be. 00056 m_db.close(); 00057 } 00058 00059 bool TrackCollection::checkForTables() { 00060 if (!m_db.open()) { 00061 QMessageBox::critical(0, tr("Cannot open database"), 00062 tr("Unable to establish a database connection.\n" 00063 "Mixxx requires QT with SQLite support. Please read " 00064 "the Qt SQL driver documentation for information on how " 00065 "to build it.\n\n" 00066 "Click OK to exit."), QMessageBox::Ok); 00067 return false; 00068 } 00069 00070 int requiredSchemaVersion = 13; 00071 if (!SchemaManager::upgradeToSchemaVersion(m_pConfig, m_db, 00072 requiredSchemaVersion)) { 00073 QMessageBox::warning(0, tr("Cannot upgrade database schema"), 00074 tr("Unable to upgrade your database schema to version %1.\n" 00075 "Your mixxx.db file may be corrupt.\n" 00076 "Try renaming it and restarting Mixxx.\n\n" 00077 "Click OK to exit.").arg(requiredSchemaVersion), 00078 QMessageBox::Ok); 00079 return false; 00080 } 00081 00082 m_trackDao.initialize(); 00083 m_playlistDao.initialize(); 00084 m_crateDao.initialize(); 00085 m_cueDao.initialize(); 00086 00087 return true; 00088 } 00089 00090 QSqlDatabase& TrackCollection::getDatabase() { 00091 return m_db; 00092 } 00093 00098 bool TrackCollection::importDirectory(QString directory, TrackDAO &trackDao, 00099 QList<TrackInfoObject*>& tracksToAdd) { 00100 //qDebug() << "TrackCollection::importDirectory(" << directory<< ")"; 00101 00102 emit(startedLoading()); 00103 QFileInfoList files; 00104 00105 //Check to make sure the path exists. 00106 QDir dir(directory); 00107 if (dir.exists()) { 00108 files = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot); 00109 } else { 00110 qDebug() << "Error: Import path does not exist." << directory; 00111 return true; 00112 } 00113 00114 //The directory exists, so get a list of the contents of the directory and go through it. 00115 QList<QFileInfo>::iterator it = files.begin(); 00116 while (it != files.end()) { 00117 QFileInfo file = *it; //TODO: THIS IS SLOW! 00118 it++; 00119 00120 //If a flag was raised telling us to cancel the library scan then stop. 00121 m_libraryScanMutex.lock(); 00122 bool cancel = bCancelLibraryScan; 00123 m_libraryScanMutex.unlock(); 00124 if (cancel) { 00125 return false; 00126 } 00127 00128 QString absoluteFilePath = file.absoluteFilePath(); 00129 QString fileName = file.fileName(); 00130 00131 if (fileName.count(m_supportedFileExtensionsRegex)) { 00132 //If the track is in the database, mark it as existing. This code gets exectuted 00133 //when other files in the same directory have changed (the directory hash has changed). 00134 trackDao.markTrackLocationAsVerified(absoluteFilePath); 00135 00136 // If the file already exists in the database, continue and go on to 00137 // the next file. 00138 00139 // If the file doesn't already exist in the database, then add 00140 // it. If it does exist in the database, then it is either in the 00141 // user's library OR the user has "removed" the track via 00142 // "Right-Click -> Remove". These tracks stay in the library, but 00143 // their mixxx_deleted column is 1. 00144 if (!trackDao.trackExistsInDatabase(absoluteFilePath)) 00145 { 00146 //qDebug() << "Loading" << file.fileName(); 00147 emit(progressLoading(fileName)); 00148 00149 // addTrack uses this QFileInfo instead of making a new one now. 00150 //trackDao.addTrack(file); 00151 TrackInfoObject* pTrack = new TrackInfoObject(file.absoluteFilePath()); 00152 tracksToAdd.append(pTrack); 00153 } 00154 } else { 00155 //qDebug() << "Skipping" << file.fileName() << 00156 // "because it did not match thesupported audio files filter:" << 00157 } 00158 } 00159 emit(finishedLoading()); 00160 return true; 00161 } 00162 00163 void TrackCollection::slotCancelLibraryScan() { 00164 m_libraryScanMutex.lock(); 00165 bCancelLibraryScan = 1; 00166 m_libraryScanMutex.unlock(); 00167 } 00168 00169 void TrackCollection::resetLibaryCancellation() { 00170 m_libraryScanMutex.lock(); 00171 bCancelLibraryScan = 0; 00172 m_libraryScanMutex.unlock(); 00173 } 00174 00175 CrateDAO& TrackCollection::getCrateDAO() { 00176 return m_crateDao; 00177 } 00178 00179 TrackDAO& TrackCollection::getTrackDAO() { 00180 return m_trackDao; 00181 } 00182 00183 PlaylistDAO& TrackCollection::getPlaylistDAO() { 00184 return m_playlistDao; 00185 } 00186 00187 QSharedPointer<BaseTrackCache> TrackCollection::getTrackSource( 00188 const QString name) { 00189 return m_trackSources.value(name, QSharedPointer<BaseTrackCache>()); 00190 } 00191 00192 void TrackCollection::addTrackSource( 00193 const QString name, QSharedPointer<BaseTrackCache> trackSource) { 00194 Q_ASSERT(!m_trackSources.contains(name)); 00195 m_trackSources[name] = trackSource; 00196 }