void MusicSearchEngine::watchForChanges() { // Gather all folders registered on music locations QFileInfoList dirs; for (QString musicPath : SettingsPrivate::instance()->musicLocations()) { QFileInfo location(musicPath); QDirIterator it(location.absoluteFilePath(), QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while (it.hasNext()) { QString entry = it.next(); QFileInfo qFileInfo(entry); dirs << qFileInfo; } } SqlDatabase *db = SqlDatabase::instance(); db->open(); db->exec("PRAGMA journal_mode = MEMORY"); db->exec("PRAGMA synchronous = OFF"); db->exec("PRAGMA temp_store = 2"); db->exec("PRAGMA foreign_keys = 1"); QStringList newFoldersToAddInLibrary; // Add folders that were not found first for (QFileInfo f : dirs) { QSqlQuery query = db->exec("SELECT * FROM filesystem WHERE path = \"" + f.absoluteFilePath() + "\""); if (!query.next()) { newFoldersToAddInLibrary << f.absoluteFilePath(); QSqlQuery prepared(*db); prepared.prepare("INSERT INTO filesystem (path, lastModified) VALUES (?, ?)"); prepared.addBindValue(f.absoluteFilePath()); prepared.addBindValue(f.lastModified().toTime_t()); prepared.exec(); } } if (!newFoldersToAddInLibrary.isEmpty()) { this->doSearch(newFoldersToAddInLibrary); } // Process in reverse mode to clean cache: from database file and check if entry exists in database QStringList oldLocations; QSqlQuery cache = db->exec("SELECT * FROM filesystem"); while (cache.next()) { QDir d(cache.record().value(0).toString()); d.exists(); QFileInfo fileInfo(cache.record().value(0).toString()); // Remove folder in database because it couldn't be find in the filesystem if (!fileInfo.exists()) { db->exec("DELETE FROM filesystem WHERE path = \"" + fileInfo.absoluteFilePath() + "\""); oldLocations << fileInfo.absoluteFilePath(); } } if (!oldLocations.isEmpty()) { db->rebuild(oldLocations, QStringList()); } }
/** Redefined from MiamSortFilterProxyModel. */ bool UniqueLibraryFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QStandardItem *item = _model->itemFromIndex(_model->index(sourceRow, 1, sourceParent)); if (!item) { return false; } bool result = false; switch (item->type()) { case Miam::IT_Artist: if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) { result = true; } else { SqlDatabase db; db.open(); QSqlQuery getArtist(db); getArtist.setForwardOnly(true); getArtist.prepare("SELECT * FROM tracks WHERE title LIKE ? AND artistId = ?"); getArtist.addBindValue("%" + filterRegExp().pattern() + "%"); getArtist.addBindValue(item->data(Miam::DF_ID).toUInt()); result = getArtist.exec() && getArtist.next(); } break; case Miam::IT_Album: if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) { result = true; } else if (filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1) { result = true; } else { SqlDatabase db; db.open(); QSqlQuery getAlbum(db); getAlbum.setForwardOnly(true); getAlbum.prepare("SELECT * FROM tracks WHERE title LIKE ? AND albumId = ?"); getAlbum.addBindValue("%" + filterRegExp().pattern() + "%"); getAlbum.addBindValue(item->data(Miam::DF_ID).toUInt()); result = getAlbum.exec() && getAlbum.next(); } break; case Miam::IT_Disc: if (filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1) { result = true; } else { SqlDatabase db; db.open(); QSqlQuery getDiscAlbum(db); getDiscAlbum.setForwardOnly(true); getDiscAlbum.prepare("SELECT * FROM tracks WHERE disc > 0 AND title LIKE ? AND albumId = ?"); getDiscAlbum.addBindValue("%" + filterRegExp().pattern() + "%"); getDiscAlbum.addBindValue(item->data(Miam::DF_ID).toUInt()); result = getDiscAlbum.exec() && getDiscAlbum.next(); } break; case Miam::IT_Track: if (MiamSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)) { result = true; } else { result = filterRegExp().indexIn(item->data(Miam::DF_Artist).toString()) != -1 || filterRegExp().indexIn(item->data(Miam::DF_Album).toString()) != -1; } break; case Miam::IT_Separator: for (QModelIndex index : _topLevelItems.values(static_cast<SeparatorItem*>(item))) { if (filterAcceptsRow(index.row(), sourceParent)) { result = true; } } break; default: break; } return result; }