void PlaylistTableModel::setTableModel(int playlistId) { //qDebug() << "PlaylistTableModel::setTableModel" << playlistId; if (m_iPlaylistId == playlistId) { qDebug() << "Already focused on playlist " << playlistId; return; } m_iPlaylistId = playlistId; QString playlistTableName = "playlist_" + QString::number(m_iPlaylistId); QSqlQuery query(m_database); FieldEscaper escaper(m_database); QStringList columns; columns << PLAYLISTTRACKSTABLE_TRACKID + " AS " + LIBRARYTABLE_ID << PLAYLISTTRACKSTABLE_POSITION << PLAYLISTTRACKSTABLE_DATETIMEADDED << "'' AS " + LIBRARYTABLE_PREVIEW // For sorting the cover art column we give LIBRARYTABLE_COVERART // the same value as the cover hash. << LIBRARYTABLE_COVERART_HASH + " AS " + LIBRARYTABLE_COVERART; // We drop files that have been explicitly deleted from mixxx // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where // removed files were not removed from playlists, so some users will have // libraries where this is the case. QString queryString = QString("CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " "SELECT %2 FROM PlaylistTracks " "INNER JOIN library ON library.id = PlaylistTracks.track_id " "WHERE PlaylistTracks.playlist_id = %3") .arg(escaper.escapeString(playlistTableName), columns.join(","), QString::number(playlistId)); if (!m_showAll) { queryString.append(" AND library.mixxx_deleted = 0"); } query.prepare(queryString); if (!query.exec()) { LOG_FAILED_QUERY(query); } columns[0] = LIBRARYTABLE_ID; // columns[1] = PLAYLISTTRACKSTABLE_POSITION from above // columns[2] = PLAYLISTTRACKSTABLE_DATETIMEADDED from above columns[3] = LIBRARYTABLE_PREVIEW; columns[4] = LIBRARYTABLE_COVERART; setTable(playlistTableName, LIBRARYTABLE_ID, columns, m_pTrackCollection->getTrackSource()); setSearch(""); setDefaultSort(fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION), Qt::AscendingOrder); setSort(defaultSortColumn(), defaultSortOrder()); connect(&m_playlistDao, SIGNAL(changed(int)), this, SLOT(playlistChanged(int))); }
/** * udisks_daemon_util_escape: * @str: The string to escape. * * Escapes double-quotes (") and back-slashes (\) in a string * using back-slash (\). * * Returns: The escaped string. Free with g_free(). */ gchar * udisks_daemon_util_escape (const gchar *str) { GString *s; g_return_val_if_fail (str != NULL, NULL); s = g_string_new (NULL); escaper (s, str); return g_string_free (s, FALSE); }
/** * udisks_daemon_util_escape_and_quote: * @str: The string to escape. * * Like udisks_daemon_util_escape() but also wraps the result in * double-quotes. * * Returns: The double-quoted and escaped string. Free with g_free(). */ gchar * udisks_daemon_util_escape_and_quote (const gchar *str) { GString *s; g_return_val_if_fail (str != NULL, NULL); s = g_string_new ("\""); escaper (s, str); g_string_append_c (s, '"'); return g_string_free (s, FALSE); }
void DirectoryListing::download(Directory* aDir, const string& aTarget, bool highPrio) { string tmp; string target = (aDir == getRoot()) ? aTarget : aTarget + escaper(aDir->getName(), tmp, getUtf8()) + PATH_SEPARATOR; // First, recurse over the directories Directory::List& lst = aDir->directories; sort(lst.begin(), lst.end(), Directory::DirSort()); for(Directory::Iter j = lst.begin(); j != lst.end(); ++j) { download(*j, target, highPrio); } // Then add the files File::List& l = aDir->files; sort(l.begin(), l.end(), File::FileSort()); for(File::Iter i = aDir->files.begin(); i != aDir->files.end(); ++i) { File* file = *i; try { download(file, target + escaper(file->getName(), tmp, getUtf8()), false, highPrio); } catch(const QueueException&) { // Catch it here to allow parts of directories to be added... } catch(const FileException&) { //.. } } }
void CrateTableModel::setTableModel(int crateId) { //qDebug() << "CrateTableModel::setCrate()" << crateId; if (crateId == m_iCrateId) { qDebug() << "Already focused on crate " << crateId; return; } m_iCrateId = crateId; QString tableName = QString("crate_%1").arg(m_iCrateId); QSqlQuery query(m_database); FieldEscaper escaper(m_database); QString filter = "library.mixxx_deleted = 0"; QStringList columns; columns << "crate_tracks." + CRATETRACKSTABLE_TRACKID + " AS " + LIBRARYTABLE_ID << "'' AS " + LIBRARYTABLE_PREVIEW // For sorting the cover art column we give LIBRARYTABLE_COVERART // the same value as the cover hash. << LIBRARYTABLE_COVERART_HASH + " AS " + LIBRARYTABLE_COVERART; // We drop files that have been explicitly deleted from mixxx // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where // removed files were not removed from crates, so some users will have // libraries where this is the case. QString queryString = QString("CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " "SELECT %2 FROM %3 " "INNER JOIN library ON library.id = %3.%4 " "WHERE %3.%5 = %6 AND %7") .arg(escaper.escapeString(tableName), columns.join(","), CRATE_TRACKS_TABLE, CRATETRACKSTABLE_TRACKID, CRATETRACKSTABLE_CRATEID, QString::number(crateId), filter); query.prepare(queryString); if (!query.exec()) { LOG_FAILED_QUERY(query); } columns[0] = LIBRARYTABLE_ID; columns[1] = LIBRARYTABLE_PREVIEW; columns[2] = LIBRARYTABLE_COVERART; setTable(tableName, columns[0], columns, m_pTrackCollection->getTrackSource()); setSearch(""); setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); }
void LibraryHashDAO::updateDirectoryStatuses(QStringList dirPaths, const bool deleted, const bool verified) { //qDebug() << "LibraryHashDAO::updateDirectoryStatus" << QThread::currentThread() << m_database.connectionName(); FieldEscaper escaper(m_database); QMutableStringListIterator it(dirPaths); while (it.hasNext()) { it.setValue(escaper.escapeString(it.next())); } QSqlQuery query(m_database); query.prepare( QString("UPDATE LibraryHashes " "SET directory_deleted=:directory_deleted, " "needs_verification=:needs_verification " "WHERE directory_path IN (%1)") .arg(dirPaths.join(","))); query.bindValue(":directory_deleted", deleted ? 1 : 0); query.bindValue(":needs_verification", !verified ? 1 : 0); if (!query.exec()) { LOG_FAILED_QUERY(query) << "Updating directory status failed."; } }
QSet<int> DirectoryDAO::relocateDirectory(const QString& oldFolder, const QString& newFolder) { // TODO(rryan): This method could use error reporting. It can fail in // mysterious ways for example if a track in the oldFolder also has a zombie // track location in newFolder then the replace query will fail because the // location column becomes non-unique. ScopedTransaction transaction(m_database); QSqlQuery query(m_database); query.prepare("UPDATE " % DIRECTORYDAO_TABLE % " SET " % DIRECTORYDAO_DIR % "=" ":newFolder WHERE " % DIRECTORYDAO_DIR % " = :oldFolder"); query.bindValue(":newFolder", newFolder); query.bindValue(":oldFolder", oldFolder); if (!query.exec()) { LOG_FAILED_QUERY(query) << "coud not relocate directory" << oldFolder << "to" << newFolder; return QSet<int>(); } FieldEscaper escaper(m_database); QString startsWithOldFolder = escaper.escapeString(escaper.escapeStringForLike(oldFolder % '/', '%') + '%'); // Also update information in the track_locations table. This is where mixxx // gets the location information for a track. query.prepare(QString("SELECT library.id, track_locations.id, track_locations.location " "FROM library INNER JOIN track_locations ON " "track_locations.id = library.location WHERE " "track_locations.location LIKE %1 ESCAPE '%'") .arg(startsWithOldFolder)); if (!query.exec()) { LOG_FAILED_QUERY(query) << "coud not relocate path of tracks"; return QSet<int>(); } QSet<int> ids; QList<int> loc_ids; QStringList old_locs; while (query.next()) { ids.insert(query.value(0).toInt()); loc_ids.append(query.value(1).toInt()); old_locs.append(query.value(2).toString()); } QString replacement("UPDATE track_locations SET location = :newloc " "WHERE id = :id"); query.prepare(replacement); for (int i = 0; i < loc_ids.size(); ++i) { QString newloc = old_locs.at(i); newloc.replace(0, oldFolder.size(), newFolder); query.bindValue("newloc", newloc); query.bindValue("id", loc_ids.at(i)); if (!query.exec()) { LOG_FAILED_QUERY(query) << "coud not relocate path of tracks"; return QSet<int>(); } } qDebug() << "Relocated tracks:" << ids.size(); transaction.commit(); return ids; }