From dea7f976dc7be16aad0fc76c250cdb70763bebd6 Mon Sep 17 00:00:00 2001 From: montellese Date: Thu, 12 Jul 2012 15:54:34 +0200 Subject: [PATCH] musicdb: use CDatabase::Filter --- xbmc/PartyModeManager.cpp | 14 +- .../DirectoryNodeOverview.cpp | 3 +- .../DirectoryNodeSingles.cpp | 5 +- xbmc/filesystem/SmartPlaylistDirectory.cpp | 21 +- xbmc/interfaces/http-api/XBMChttp.cpp | 1 - xbmc/interfaces/json-rpc/AudioLibrary.cpp | 5 +- xbmc/music/MusicDatabase.cpp | 268 +++++++++--------- xbmc/music/MusicDatabase.h | 12 +- 8 files changed, 161 insertions(+), 168 deletions(-) diff --git a/xbmc/PartyModeManager.cpp b/xbmc/PartyModeManager.cpp index 8ebfa308059b1..53737b786fe09 100644 --- a/xbmc/PartyModeManager.cpp +++ b/xbmc/PartyModeManager.cpp @@ -113,11 +113,7 @@ bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUS { set playlists; if ( playlistLoaded ) - { m_strCurrentFilterMusic = playlist.GetWhereClause(db, playlists); - if (!m_strCurrentFilterMusic.empty()) - m_strCurrentFilterMusic = "WHERE " + m_strCurrentFilterMusic; - } CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterMusic.c_str()); m_iMatchingSongs = (int)db.GetSongIDs(m_strCurrentFilterMusic, songIDs); @@ -146,11 +142,7 @@ bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUS { set playlists; if ( playlistLoaded ) - { m_strCurrentFilterVideo = playlist.GetWhereClause(db, playlists); - if (!m_strCurrentFilterVideo.empty()) - m_strCurrentFilterVideo = "WHERE " + m_strCurrentFilterVideo; - } CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterVideo.c_str()); m_iMatchingSongs += (int)db.GetMusicVideoIDs(m_strCurrentFilterVideo, songIDs2); @@ -594,8 +586,8 @@ bool CPartyModeManager::AddInitialSongs(vector > &songIDs) vector > chosenSongIDs; GetRandomSelection(songIDs, iMissingSongs, chosenSongIDs); - CStdString sqlWhereMusic = "where songview.idSong in ("; - CStdString sqlWhereVideo = "idMVideo in ("; + CStdString sqlWhereMusic = "songview.idSong IN ("; + CStdString sqlWhereVideo = "idMVideo IN ("; for (vector< pair >::iterator it = chosenSongIDs.begin(); it != chosenSongIDs.end(); it++) { @@ -644,7 +636,7 @@ pair CPartyModeManager::GetWhereClauseWithHistory() const if (m_history.size()) { if (m_strCurrentFilterMusic.IsEmpty()) - historyWhereMusic = "where songview.idSong not in ("; + historyWhereMusic = "songview.idSong not in ("; else historyWhereMusic = m_strCurrentFilterMusic + " and songview.idSong not in ("; if (m_strCurrentFilterVideo.IsEmpty()) diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp index c218021141ce5..c8968738ca6d6 100644 --- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp +++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp @@ -74,7 +74,8 @@ bool CDirectoryNodeOverview::GetContent(CFileItemList& items) const bool showSingles = false; if (musicDatabase.Open()) { - if (musicDatabase.GetSongsCount("where idAlbum in (select idAlbum from album where strAlbum='')") > 0) + CDatabase::Filter filter("idAlbum IN (SELECT idAlbum FROM album WHERE strAlbum = '')"); + if (musicDatabase.GetSongsCount(filter) > 0) showSingles = true; } diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeSingles.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeSingles.cpp index 8ce6438f133ed..16d095af97b86 100644 --- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeSingles.cpp +++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeSingles.cpp @@ -37,8 +37,9 @@ bool CDirectoryNodeSingles::GetContent(CFileItemList& items) const if (!musicdatabase.Open()) return false; - CStdString strBaseDir=BuildPath(); - bool bSuccess=musicdatabase.GetSongsByWhere(strBaseDir, "where idAlbum in (select idAlbum from album where strAlbum='')", items); + CDatabase::Filter filter; + filter.where = "idAlbum IN (SELECT idAlbum FROM album WHERE strAlbum = '')"; + bool bSuccess=musicdatabase.GetSongsByWhere(BuildPath(), filter, items); musicdatabase.Close(); diff --git a/xbmc/filesystem/SmartPlaylistDirectory.cpp b/xbmc/filesystem/SmartPlaylistDirectory.cpp index 14bedc95816c4..bc300294641fe 100644 --- a/xbmc/filesystem/SmartPlaylistDirectory.cpp +++ b/xbmc/filesystem/SmartPlaylistDirectory.cpp @@ -106,10 +106,9 @@ namespace XFILE CMusicDatabase db; if (db.Open()) { - CStdString whereClause = playlist.GetWhereClause(db, playlists); - if (!whereClause.empty()) - whereClause = "WHERE " + whereClause; - success = db.GetAlbumsByWhere("musicdb://3/", whereClause, "", items, sorting); + CDatabase::Filter filter; + filter.where = playlist.GetWhereClause(db, playlists); + success = db.GetAlbumsByWhere("musicdb://3/", filter, items, sorting); items.SetContent("albums"); db.Close(); } @@ -119,20 +118,14 @@ namespace XFILE CMusicDatabase db; if (db.Open()) { - CStdString whereClause; + CDatabase::Filter filter; + CSmartPlaylist songPlaylist(playlist); if (playlist.GetType().IsEmpty() || playlist.GetType().Equals("mixed")) - { - CSmartPlaylist songPlaylist(playlist); songPlaylist.SetType("songs"); - whereClause = songPlaylist.GetWhereClause(db, playlists); - } - else - whereClause = playlist.GetWhereClause(db, playlists); - if (!whereClause.empty()) - whereClause = "WHERE " + whereClause; + filter.where = songPlaylist.GetWhereClause(db, playlists); - success = db.GetSongsByWhere("", whereClause, items, sorting); + success = db.GetSongsByWhere("", filter, items, sorting); items.SetContent("songs"); db.Close(); } diff --git a/xbmc/interfaces/http-api/XBMChttp.cpp b/xbmc/interfaces/http-api/XBMChttp.cpp index 54e496cb61111..13efcec010652 100644 --- a/xbmc/interfaces/http-api/XBMChttp.cpp +++ b/xbmc/interfaces/http-api/XBMChttp.cpp @@ -1033,7 +1033,6 @@ int CXbmcHttp::xbmcAddToPlayListFromDB(int numParas, CStdString paras[]) if (type.Equals("songs")) { playList = PLAYLIST_MUSIC; - where = " where " + where; CMusicDatabase musicdatabase; if (!musicdatabase.Open()) diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp index 7e0623d83b5a3..f6f86bd38e4f0 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp +++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp @@ -73,9 +73,8 @@ JSONRPC_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransp return InternalError; CFileItemList items; - CStdString where; - where.Format("idArtist = %d", artistID); - if (!musicdatabase.GetArtistsByWhere("musicdb://2/", where, items) || items.Size() != 1) + CDatabase::Filter filter(musicdatabase.PrepareSQL("idArtist = %d", artistID)); + if (!musicdatabase.GetArtistsByWhere("musicdb://2/", filter, items) || items.Size() != 1) return InvalidParams; HandleFileItem("artistid", false, "artistdetails", items[0], parameterObject, parameterObject["properties"], result, false); diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index 3a3f3fbdb69de..32a16ad0f15f5 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -2716,9 +2716,10 @@ bool CMusicDatabase::GetYearsNav(const CStdString& strBaseDir, CFileItemList& it bool CMusicDatabase::GetAlbumsByYear(const CStdString& strBaseDir, CFileItemList& items, int year) { - CStdString where = PrepareSQL("where iYear=%ld", year); + Filter filter; + filter.where = PrepareSQL("iYear=%ld", year); - return GetAlbumsByWhere(strBaseDir, where, "", items); + return GetAlbumsByWhere(strBaseDir, filter, items); } bool CMusicDatabase::GetArtistsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, bool albumArtistsOnly) @@ -2790,16 +2791,24 @@ bool CMusicDatabase::GetArtistsNav(const CStdString& strBaseDir, CFileItemList& return false; } -bool CMusicDatabase::GetArtistsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items) +bool CMusicDatabase::GetArtistsByWhere(const CStdString& strBaseDir, const Filter &filter, CFileItemList& items) { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; try { - CStdString strSQL = "select * from artistview"; - if (!where.empty()) - strSQL += " WHERE " + where; + CStdString strSQL = PrepareSQL("select %s from artistview ", !filter.fields.empty() ? filter.fields.c_str() : "*"); + if (!filter.join.empty()) + strSQL += filter.join; + if (!filter.where.empty()) + strSQL += " WHERE " + filter.where; + if (!filter.group.empty()) + strSQL += " GROUP BY " + filter.group; + if (!filter.order.empty()) + strSQL += " ORDER BY " + filter.order; + if (!filter.limit.empty()) + strSQL += " LIMIT " + filter.limit; // run query CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); @@ -2908,60 +2917,31 @@ bool CMusicDatabase::GetAlbumFromSong(const CSong &song, CAlbum &album) bool CMusicDatabase::GetAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, int idArtist, int start, int end, const SortDescription &sortDescription /* = SortDescription() */) { + Filter filter; //Create limit - CStdString limit; if (start >= 0 && end >= 0) - { - limit.Format(" limit %i,%i", start, end); - } + filter.limit = PrepareSQL("%i,%i", start, end); // where clause - CStdString strWhere; - if (idGenre!=-1) - { - strWhere+=PrepareSQL("where (idAlbum IN " - "(" - "select song.idAlbum from song " // All song genres - "JOIN song_genre ON song.idSong=song_genre.idSong " - "where song_genre.idGenre=%i" - ")" - ") " + limit - , idGenre); - } - - if (idArtist!=-1) - { - if (strWhere.IsEmpty()) - strWhere += "where "; - else - strWhere += "and "; - - strWhere +=PrepareSQL("(idAlbum IN " - "(" - "select song.idAlbum from song " // All albums linked to this artist via songs - "JOIN song_artist ON song.idSong=song_artist.idSong " - "WHERE song_artist.idArtist=%i" - ")" - " or idAlbum IN " - "(" - "select album_artist.idAlbum from album_artist " // All albums where album artists fit - "where album_artist.idArtist=%i" - ")" - ") " + limit - , idArtist, idArtist); - } + if (idGenre != -1) + filter.where = PrepareSQL("(idAlbum IN (SELECT song.idAlbum FROM song JOIN song_genre ON song.idSong = song_genre.idSong WHERE song_genre.idGenre = %i))", idGenre); + + if (idArtist != -1) + filter.AppendWhere(PrepareSQL("(idAlbum IN " + // All albums linked to this artist via songs + "(SELECT song.idAlbum FROM song JOIN song_artist ON song.idSong = song_artist.idSong WHERE song_artist.idArtist = %i)" + " OR idAlbum IN " + // All albums where album artists fit + "(SELECT album_artist.idAlbum FROM album_artist WHERE album_artist.idArtist = %i)" + ")", idArtist, idArtist)); else - { // no artist given, so exclude any single albums (aka empty tagged albums) - if (strWhere.IsEmpty()) - strWhere += "where albumview.strAlbum <> ''" + limit; - else - strWhere += "and albumview.strAlbum <> ''" + limit; - } + // no artist given, so exclude any single albums (aka empty tagged albums) + filter.AppendWhere("albumview.strAlbum <> ''"); - return GetAlbumsByWhere(strBaseDir, strWhere, "", items, sortDescription); + return GetAlbumsByWhere(strBaseDir, filter, items, sortDescription); } -bool CMusicDatabase::GetAlbumsByWhere(const CStdString &baseDir, const CStdString &where, const CStdString &order, CFileItemList &items, const SortDescription &sortDescription /* = SortDescription() */) +bool CMusicDatabase::GetAlbumsByWhere(const CStdString &baseDir, const Filter &filter, CFileItemList &items, const SortDescription &sortDescription /* = SortDescription() */) { if (m_pDB.get() == NULL || m_pDS.get() == NULL) return false; @@ -2970,22 +2950,32 @@ bool CMusicDatabase::GetAlbumsByWhere(const CStdString &baseDir, const CStdStrin { int total = -1; - CStdString sql = "select * from albumview " + where; + CStdString strSQL = "select %s from albumview "; + CStdString strSQLExtra; + if (!filter.join.empty()) + strSQLExtra += filter.join; + if (!filter.where.empty()) + strSQLExtra += " WHERE " + filter.where; + if (!filter.group.empty()) + strSQLExtra += " GROUP BY " + filter.group; + if (!filter.order.empty()) + strSQLExtra += " ORDER BY " + filter.order; + if (!filter.limit.empty()) + strSQLExtra += " LIMIT " + filter.limit; // Apply the limiting directly here if there's no special sorting but limiting - CStdString whereLower = where; - whereLower.ToLower(); - if (whereLower.find(" limit ") == string::npos && - sortDescription.sortBy == SortByNone && - (sortDescription.limitStart > 0 || sortDescription.limitEnd > 0)) + else if (sortDescription.sortBy == SortByNone && + (sortDescription.limitStart > 0 || sortDescription.limitEnd > 0)) { - total = (int)strtol(GetSingleValue("SELECT COUNT(1) FROM albumview " + where, m_pDS).c_str(), NULL, 10); - sql += DatabaseUtils::BuildLimitClause(sortDescription.limitEnd, sortDescription.limitStart); + total = (int)strtol(GetSingleValue(PrepareSQL(strSQL, "COUNT(1)") + strSQLExtra, m_pDS).c_str(), NULL, 10); + strSQLExtra += DatabaseUtils::BuildLimitClause(sortDescription.limitEnd, sortDescription.limitStart); } - CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, sql.c_str()); + strSQL = PrepareSQL(strSQL, !filter.fields.empty() ? filter.fields.c_str() : "*") + strSQLExtra; + + CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); // run query unsigned int time = XbmcThreads::SystemClockMillis(); - if (!m_pDS->query(sql.c_str())) + if (!m_pDS->query(strSQL.c_str())) return false; CLog::Log(LOGDEBUG, "%s - query took %i ms", __FUNCTION__, XbmcThreads::SystemClockMillis() - time); time = XbmcThreads::SystemClockMillis(); @@ -3038,12 +3028,12 @@ bool CMusicDatabase::GetAlbumsByWhere(const CStdString &baseDir, const CStdStrin catch (...) { m_pDS->close(); - CLog::Log(LOGERROR, "%s (%s) failed", __FUNCTION__, where.c_str()); + CLog::Log(LOGERROR, "%s (%s) failed", __FUNCTION__, filter.where.c_str()); } return false; } -bool CMusicDatabase::GetSongsByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList &items, const SortDescription &sortDescription /* = SortDescription() */) +bool CMusicDatabase::GetSongsByWhere(const CStdString &baseDir, const Filter &filter, CFileItemList &items, const SortDescription &sortDescription /* = SortDescription() */) { if (m_pDB.get() == NULL || m_pDS.get() == NULL) return false; @@ -3053,19 +3043,28 @@ bool CMusicDatabase::GetSongsByWhere(const CStdString &baseDir, const CStdString unsigned int time = XbmcThreads::SystemClockMillis(); int total = -1; - // We don't use PrepareSQL here, as the WHERE clause is already formatted. - CStdString strSQL = "select * from songview " + whereClause; + CStdString strSQL = "select %s from songview "; + CStdString strSQLExtra; + if (!filter.join.empty()) + strSQLExtra += filter.join; + if (!filter.where.empty()) + strSQLExtra += " WHERE " + filter.where; + if (!filter.group.empty()) + strSQLExtra += " GROUP BY " + filter.group; + if (!filter.order.empty()) + strSQLExtra += " ORDER BY " + filter.order; + if (!filter.limit.empty()) + strSQLExtra += " LIMIT " + filter.limit; // Apply the limiting directly here if there's no special sorting but limiting - CStdString whereLower = whereClause; - whereLower.ToLower(); - if (whereLower.find(" limit ") == string::npos && - sortDescription.sortBy == SortByNone && - (sortDescription.limitStart > 0 || sortDescription.limitEnd > 0)) + else if (sortDescription.sortBy == SortByNone && + (sortDescription.limitStart > 0 || sortDescription.limitEnd > 0)) { - total = (int)strtol(GetSingleValue("SELECT COUNT(1) FROM songview " + whereClause, m_pDS).c_str(), NULL, 10); - strSQL += DatabaseUtils::BuildLimitClause(sortDescription.limitEnd, sortDescription.limitStart); + total = (int)strtol(GetSingleValue(PrepareSQL(strSQL, "COUNT(1)") + strSQLExtra, m_pDS).c_str(), NULL, 10); + strSQLExtra += DatabaseUtils::BuildLimitClause(sortDescription.limitEnd, sortDescription.limitStart); } + strSQL = PrepareSQL(strSQL, !filter.fields.empty() ? filter.fields.c_str() : "*") + strSQLExtra; + CLog::Log(LOGDEBUG, "%s query = %s", __FUNCTION__, strSQL.c_str()); // run query if (!m_pDS->query(strSQL.c_str())) @@ -3108,77 +3107,48 @@ bool CMusicDatabase::GetSongsByWhere(const CStdString &baseDir, const CStdString catch (...) { m_pDS->close(); - CLog::Log(LOGERROR, "%s: out of memory loading query: %s", __FUNCTION__, whereClause.c_str()); + CLog::Log(LOGERROR, "%s: out of memory loading query: %s", __FUNCTION__, filter.where.c_str()); return (items.Size() > 0); } } // cleanup m_pDS->close(); - CLog::Log(LOGDEBUG, "%s(%s) - took %d ms", __FUNCTION__, whereClause.c_str(), XbmcThreads::SystemClockMillis() - time); + CLog::Log(LOGDEBUG, "%s(%s) - took %d ms", __FUNCTION__, filter.where.c_str(), XbmcThreads::SystemClockMillis() - time); return true; } catch (...) { // cleanup m_pDS->close(); - CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, whereClause.c_str()); + CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, filter.where.c_str()); } return false; } bool CMusicDatabase::GetSongsByYear(const CStdString& baseDir, CFileItemList& items, int year) { - CStdString where=PrepareSQL("where (iYear=%ld)", year); - return GetSongsByWhere(baseDir, where, items); + Filter filter(PrepareSQL("iYear = %ld", year)); + return GetSongsByWhere(baseDir, filter, items); } bool CMusicDatabase::GetSongsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, int idArtist,int idAlbum, const SortDescription &sortDescription /* = SortDescription() */) { - CStdString strWhere; - + Filter filter; if (idAlbum!=-1) - strWhere=PrepareSQL("where (idAlbum=%ld) ", idAlbum); + filter.where = PrepareSQL("idAlbum = %ld", idAlbum); if (idGenre!=-1) - { - if (strWhere.IsEmpty()) - strWhere += "where "; - else - strWhere += "and "; - - strWhere += PrepareSQL("(idSong IN " - "(" - "SELECT song_genre.idSong FROM song_genre " - "WHERE song_genre.idGenre = %i" - ")" - ") " - , idGenre); - } + filter.AppendWhere(PrepareSQL("idSong IN (SELECT song_genre.idSong FROM song_genre WHERE song_genre.idGenre = %i)", idGenre)); if (idArtist!=-1) - { - if (strWhere.IsEmpty()) - strWhere += "where "; - else - strWhere += "and "; - - strWhere += PrepareSQL("(idSong IN " // song artists - "(" - "SELECT song_artist.idSong FROM song_artist " - "WHERE song_artist.idArtist=%i" - ") " - "or idSong IN " // album artists - "(" - "SELECT song.idSong FROM song " - "JOIN album_artist ON song.idAlbum=album_artist.idAlbum " - "WHERE album_artist.idArtist=%i" - ")" - ") " - , idArtist, idArtist); - } + filter.AppendWhere(PrepareSQL("idSong IN (" // song artists + "SELECT song_artist.idSong FROM song_artist WHERE song_artist.idArtist = %i" + ") OR idSong IN (" // album artists + "SELECT song.idSong FROM song JOIN album_artist ON song.idAlbum=album_artist.idAlbum WHERE album_artist.idArtist = %i" + ")", idArtist, idArtist)); // run query - return GetSongsByWhere(strBaseDir, strWhere, items, sortDescription); + return GetSongsByWhere(strBaseDir, filter, items, sortDescription); } bool CMusicDatabase::UpdateOldVersion(int version) @@ -3522,14 +3492,25 @@ bool CMusicDatabase::UpdateOldVersion(int version) return true; } -unsigned int CMusicDatabase::GetSongIDs(const CStdString& strWhere, vector > &songIDs) +unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, vector > &songIDs) { try { if (NULL == m_pDB.get()) return 0; if (NULL == m_pDS.get()) return 0; - CStdString strSQL = "select idSong from songview " + strWhere; + CStdString strSQL = "select idSong from songview "; + if (!filter.join.empty()) + strSQL += filter.join; + if (!filter.where.empty()) + strSQL += " WHERE " + filter.where; + if (!filter.group.empty()) + strSQL += " GROUP BY " + filter.group; + if (!filter.order.empty()) + strSQL += " ORDER BY " + filter.order; + if (!filter.limit.empty()) + strSQL += " LIMIT " + filter.limit; + if (!m_pDS->query(strSQL.c_str())) return 0; songIDs.clear(); if (m_pDS->num_rows() == 0) @@ -3548,19 +3529,30 @@ unsigned int CMusicDatabase::GetSongIDs(const CStdString& strWhere, vectorquery(strSQL.c_str())) return false; if (m_pDS->num_rows() == 0) { @@ -3575,7 +3567,7 @@ int CMusicDatabase::GetSongsCount(const CStdString& strWhere) } catch (...) { - CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, strWhere.c_str()); + CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, filter.where.c_str()); } return 0; } @@ -3790,13 +3782,13 @@ int CMusicDatabase::GetGenreByName(const CStdString& strGenre) return -1; } -bool CMusicDatabase::GetRandomSong(CFileItem* item, int& idSong, const CStdString& strWhere) +bool CMusicDatabase::GetRandomSong(CFileItem* item, int& idSong, const Filter &filter) { try { idSong = -1; - int iCount = GetSongsCount(strWhere); + int iCount = GetSongsCount(filter); if (iCount <= 0) return false; int iRandom = rand() % iCount; @@ -3805,8 +3797,22 @@ bool CMusicDatabase::GetRandomSong(CFileItem* item, int& idSong, const CStdStrin if (NULL == m_pDS.get()) return false; // We don't use PrepareSQL here, as the WHERE clause is already formatted - CStdString strSQL; - strSQL.Format("select * from songview %s order by idSong limit 1 offset %i", strWhere.c_str(), iRandom); + CStdString strSQL = PrepareSQL("select %s from songview ", !filter.fields.empty() ? filter.fields.c_str() : "*"); + Filter extFilter = filter; + extFilter.AppendOrder("idSong"); + extFilter.limit = "1"; + + if (!extFilter.join.empty()) + strSQL += extFilter.join; + if (!extFilter.where.empty()) + strSQL += " WHERE " + extFilter.where; + if (!extFilter.group.empty()) + strSQL += " GROUP BY " + extFilter.group; + if (!extFilter.order.empty()) + strSQL += " ORDER BY " + extFilter.order; + if (!extFilter.limit.empty()) + strSQL += " LIMIT " + extFilter.limit; + strSQL += PrepareSQL(" OFFSET %i", iRandom); CLog::Log(LOGDEBUG, "%s query = %s", __FUNCTION__, strSQL.c_str()); // run query @@ -3825,19 +3831,21 @@ bool CMusicDatabase::GetRandomSong(CFileItem* item, int& idSong, const CStdStrin } catch(...) { - CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, strWhere.c_str()); + CLog::Log(LOGERROR, "%s(%s) failed", __FUNCTION__, filter.where.c_str()); } return false; } bool CMusicDatabase::GetCompilationAlbums(const CStdString& strBaseDir, CFileItemList& items) { - return GetAlbumsByWhere(strBaseDir, "WHERE bCompilation = 1", "", items); + Filter filter("bCompilation = 1"); + return GetAlbumsByWhere(strBaseDir, filter, items); } bool CMusicDatabase::GetCompilationSongs(const CStdString& strBaseDir, CFileItemList& items) { - return GetSongsByWhere(strBaseDir, "WHERE bCompilation = 1", items); + Filter filter("bCompilation = 1"); + return GetSongsByWhere(strBaseDir, filter, items); } int CMusicDatabase::GetCompilationAlbumsCount() @@ -4090,7 +4098,7 @@ bool CMusicDatabase::CommitTransaction() { if (CDatabase::CommitTransaction()) { // number of items in the db has likely changed, so reset the infomanager cache - g_infoManager.SetLibraryBool(LIBRARY_HAS_MUSIC, GetSongsCount("") > 0); + g_infoManager.SetLibraryBool(LIBRARY_HAS_MUSIC, GetSongsCount() > 0); return true; } return false; diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index f3ae57b3c3529..e8d74d303a3c9 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -156,13 +156,13 @@ class CMusicDatabase : public CDatabase bool GetAlbumsByYear(const CStdString &strBaseDir, CFileItemList& items, int year); bool GetSongsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre, int idArtist,int idAlbum, const SortDescription &sortDescription = SortDescription()); bool GetSongsByYear(const CStdString& baseDir, CFileItemList& items, int year); - bool GetSongsByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items, const SortDescription &sortDescription = SortDescription()); - bool GetAlbumsByWhere(const CStdString &baseDir, const CStdString &where, const CStdString &order, CFileItemList &items, const SortDescription &sortDescription = SortDescription()); - bool GetArtistsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items); - bool GetRandomSong(CFileItem* item, int& idSong, const CStdString& strWhere); + bool GetSongsByWhere(const CStdString &baseDir, const Filter &filter, CFileItemList& items, const SortDescription &sortDescription = SortDescription()); + bool GetAlbumsByWhere(const CStdString &baseDir, const Filter &filter, CFileItemList &items, const SortDescription &sortDescription = SortDescription()); + bool GetArtistsByWhere(const CStdString& strBaseDir, const Filter &filter, CFileItemList& items); + bool GetRandomSong(CFileItem* item, int& idSong, const Filter &filter); int GetKaraokeSongsCount(); - int GetSongsCount(const CStdString& strWhere = ""); - unsigned int GetSongIDs(const CStdString& strWhere, std::vector > &songIDs); + int GetSongsCount(const Filter &filter = Filter()); + unsigned int GetSongIDs(const Filter &filter, std::vector > &songIDs); bool GetAlbumPath(int idAlbum, CStdString &path); bool SaveAlbumThumb(int idAlbum, const CStdString &thumb);