diff options
author | Jonathan Marshall <jmarshall@xbmc.org> | 2013-12-01 21:30:52 +1300 |
---|---|---|
committer | Jonathan Marshall <jmarshall@xbmc.org> | 2013-12-24 13:48:53 +1300 |
commit | 2b5408215494be7baf11ce29008272af2bba2ab4 (patch) | |
tree | 29bb7e98a517e4b97e9865a552bf32900c662c6d | |
parent | 7f9ecd9c44473673f1158eb56c881e90d463d3b0 (diff) |
[musicdb] Adds GetAlbum() and drop GetAlbumInfo(). Allows retrieval of full album detail, including local songs and scraped songs.
-rw-r--r-- | xbmc/interfaces/json-rpc/AudioLibrary.cpp | 9 | ||||
-rw-r--r-- | xbmc/music/MusicDatabase.cpp | 174 | ||||
-rw-r--r-- | xbmc/music/MusicDatabase.h | 9 | ||||
-rw-r--r-- | xbmc/music/MusicInfoLoader.cpp | 2 | ||||
-rw-r--r-- | xbmc/music/dialogs/GUIDialogMusicInfo.cpp | 2 | ||||
-rw-r--r-- | xbmc/music/infoscanner/MusicInfoScanner.cpp | 4 | ||||
-rw-r--r-- | xbmc/music/windows/GUIWindowMusicBase.cpp | 2 | ||||
-rw-r--r-- | xbmc/music/windows/GUIWindowMusicNav.cpp | 2 | ||||
-rw-r--r-- | xbmc/network/upnp/UPnPServer.cpp | 2 |
9 files changed, 124 insertions, 82 deletions
diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp index cb78955ddf..7acd916474 100644 --- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp +++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp @@ -179,7 +179,7 @@ JSONRPC_STATUS CAudioLibrary::GetAlbumDetails(const CStdString &method, ITranspo return InternalError; CAlbum album; - if (!musicdatabase.GetAlbumInfo(albumID, album, NULL)) + if (!musicdatabase.GetAlbum(albumID, album, false)) return InvalidParams; CStdString path; @@ -439,8 +439,7 @@ JSONRPC_STATUS CAudioLibrary::SetAlbumDetails(const CStdString &method, ITranspo return InternalError; CAlbum album; - VECSONGS songs; - if (!musicdatabase.GetAlbumInfo(id, album, &songs) || album.idAlbum <= 0) + if (!musicdatabase.GetAlbum(id, album) || album.idAlbum <= 0) return InvalidParams; if (ParameterNotNull(parameterObject, "title")) @@ -466,7 +465,7 @@ JSONRPC_STATUS CAudioLibrary::SetAlbumDetails(const CStdString &method, ITranspo if (ParameterNotNull(parameterObject, "year")) album.iYear = (int)parameterObject["year"].asInteger(); - if (musicdatabase.SetAlbumInfo(id, album, songs) <= 0) + if (musicdatabase.SetAlbumInfo(id, album, album.infoSongs) <= 0) return InternalError; CJSONRPCUtils::NotifyItemUpdated(); @@ -563,7 +562,7 @@ bool CAudioLibrary::FillFileItem(const CStdString &strFilename, CFileItemPtr &it { CAlbum album; int albumid = musicdatabase.GetAlbumIdByPath(strFilename); - if (musicdatabase.GetAlbumInfo(albumid, album, NULL)) + if (musicdatabase.GetAlbum(albumid, album, false)) { item->SetFromAlbum(album); diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp index df301dbefb..0e4a63544f 100644 --- a/xbmc/music/MusicDatabase.cpp +++ b/xbmc/music/MusicDatabase.cpp @@ -650,6 +650,110 @@ int CMusicDatabase::AddAlbum(const CStdString& strAlbum, const CStdString& strMu return -1; } +bool CMusicDatabase::GetAlbum(int idAlbum, CAlbum& album, bool getSongs /* = true */) +{ + try + { + if (NULL == m_pDB.get()) return false; + if (NULL == m_pDS.get()) return false; + + if (idAlbum == -1) + return false; // not in the database + + CStdString sql; + if (getSongs) + { + sql = PrepareSQL("SELECT albumview.*,albumartistview.*,songview.*,songartistview.*,albuminfosong.* " + " FROM albumview " + " JOIN albumartistview ON albumview.idAlbum = albumartistview.idAlbum " + " JOIN songview ON albumview.idAlbum = songview.idAlbum " + " JOIN songartistview ON songview.idSong = songartistview.idSong " + " LEFT JOIN albuminfosong ON albumview.idAlbum = albuminfosong.idAlbumInfo " + " WHERE albumview.idAlbum = %ld " + " ORDER BY iOrder, iTrack", idAlbum); + } + else + { + sql = PrepareSQL("SELECT albumview.*,albumartistview.* " + " FROM albumview " + " JOIN albumartistview ON albumview.idAlbum = albumartistview.idAlbum " + " WHERE albumview.idAlbum = %ld " + " ORDER BY iOrder", idAlbum); + } + + CLog::Log(LOGDEBUG, "%s", sql.c_str()); + if (!m_pDS->query(sql.c_str())) return false; + if (m_pDS->num_rows() == 0) + { + m_pDS->close(); + return false; + } + + int albumArtistOffset = album_enumCount; + int songOffset = albumArtistOffset + artistCredit_enumCount; + int songArtistOffset = songOffset + song_enumCount; + int infoSongOffset = songArtistOffset + artistCredit_enumCount; + + set<int> artistcredits; + set<int> songs; + set<pair<int, int> > songartistcredits; + set<int> infosongs; + album = GetAlbumFromDataset(m_pDS.get()->get_sql_record(), 0, true); // true to grab and parse the imageURL + while (!m_pDS->eof()) + { + const dbiplus::sql_record* const record = m_pDS->get_sql_record(); + + // Because rows repeat in the joined query (cartesian join) we may see each + // entity (album artist, song, song artist) multiple times in the result set. + // Since there should never be a song with the same artist twice, or an album + // with the same song (by id) listed twice, we key on the entity ID and only + // create an entity for the first occurence of each entity in the data set. + int idAlbumArtist = record->at(albumArtistOffset + artistCredit_idArtist).get_asInt(); + if (artistcredits.find(idAlbumArtist) == artistcredits.end()) + { + album.artistCredits.push_back(GetArtistCreditFromDataset(record, albumArtistOffset)); + artistcredits.insert(idAlbumArtist); + } + + if (getSongs) + { + int idSong = record->at(songOffset + song_idSong).get_asInt(); + if (songs.find(idSong) == songs.end()) + { + album.songs.push_back(GetSongFromDataset(record, songOffset)); + songs.insert(idSong); + } + + int idSongArtistSong = record->at(songArtistOffset + artistCredit_idEntity).get_asInt(); + int idSongArtistArtist = record->at(songArtistOffset + artistCredit_idArtist).get_asInt(); + if (songartistcredits.find(make_pair(idSongArtistSong, idSongArtistArtist)) == songartistcredits.end()) + { + for (VECSONGS::iterator si = album.songs.begin(); si != album.songs.end(); ++si) + if (si->idSong == idSongArtistSong) + si->artistCredits.push_back(GetArtistCreditFromDataset(record, songArtistOffset)); + songartistcredits.insert(make_pair(idSongArtistSong, idSongArtistArtist)); + } + + int idAlbumInfoSong = m_pDS.get()->get_sql_record()->at(infoSongOffset + albumInfoSong_idAlbumInfoSong).get_asInt(); + if (infosongs.find(idAlbumInfoSong) == infosongs.end()) + { + album.infoSongs.push_back(GetAlbumInfoSongFromDataset(record, infoSongOffset)); + infosongs.insert(idAlbumInfoSong); + } + } + m_pDS->next(); + } + m_pDS->close(); // cleanup recordset data + return true; + } + catch (...) + { + CLog::Log(LOGERROR, "%s(%i) failed", __FUNCTION__, idAlbum); + } + + return false; +} + int CMusicDatabase::AddGenre(const CStdString& strGenre1) { CStdString strSQL; @@ -1361,72 +1465,6 @@ bool CMusicDatabase::SearchArtists(const CStdString& search, CFileItemList &arti return false; } -bool CMusicDatabase::GetAlbumInfo(int idAlbum, CAlbum &info, VECSONGS* vecSongs, bool scrapedInfo /* = false */) -{ - try - { - if (NULL == m_pDB.get()) return false; - if (NULL == m_pDS2.get()) return false; - - if (idAlbum == -1) - return false; // not in the database - - CStdString strSQL; - if (vecSongs) - strSQL=PrepareSQL("SELECT albumview.*, albumartistview.*, albuminfosong.* FROM albumview JOIN albumartistview ON albumview.idAlbum = albumartistview.idAlbum LEFT JOIN albuminfosong ON albumview.idAlbum = albuminfosong.idAlbumInfo WHERE albumview.idAlbum = %ld", idAlbum); - else - strSQL=PrepareSQL("SELECT albumview.*, albumartistview.* FROM albumview JOIN albumartistview ON albumview.idAlbum = albumartistview.idAlbum WHERE albumview.idAlbum = %ld", idAlbum); - if (scrapedInfo) // require additional information - strSQL += " and lastScraped NOT NULL"; - - if (!m_pDS2->query(strSQL.c_str())) return false; - if (m_pDS2->num_rows() == 0) - { - m_pDS2->close(); - return false; - } - - int albumArtistOffset = album_enumCount; - int infoSongOffset = albumArtistOffset + artistCredit_enumCount; - - set<int> artistcredits; - set<int> songs; - info = GetAlbumFromDataset(m_pDS2.get()->get_sql_record(), 0, true); // true to grab the thumburl rather than the thumb - while (!m_pDS2->eof()) - { - const dbiplus::sql_record* const record = m_pDS2.get()->get_sql_record(); - - int idAlbumArtist = record->at(albumArtistOffset + artistCredit_idArtist).get_asInt(); - if (artistcredits.find(idAlbumArtist) == artistcredits.end()) - { - info.artistCredits.push_back(GetArtistCreditFromDataset(m_pDS2.get()->get_sql_record(), albumArtistOffset)); - artistcredits.insert(idAlbumArtist); - } - - if (vecSongs) - { - int idAlbumInfoSong = record->at(infoSongOffset + albumInfoSong_idAlbumInfoSong).get_asInt(); - if (songs.find(idAlbumInfoSong) == songs.end()) - { - vecSongs->push_back(GetAlbumInfoSongFromDataset(record, infoSongOffset)); - songs.insert(idAlbumInfoSong); - } - } - - m_pDS2->next(); - } - - m_pDS2->close(); // cleanup recordset data - return true; - } - catch (...) - { - CLog::Log(LOGERROR, "%s(%i) failed", __FUNCTION__, idAlbum); - } - - return false; -} - bool CMusicDatabase::HasAlbumInfo(int idAlbum) { try @@ -4659,7 +4697,7 @@ void CMusicDatabase::ExportToXML(const CStdString &xmlFile, bool singleFiles, bo for (vector<int>::iterator albumId = albumIds.begin(); albumId != albumIds.end(); ++albumId) { CAlbum album; - GetAlbumInfo(*albumId, album, &album.infoSongs); + GetAlbum(*albumId, album); CStdString strPath; GetAlbumPath(*albumId, strPath); album.Save(pMain, "album", strPath); @@ -5312,7 +5350,7 @@ void CMusicDatabase::SetPropertiesForFileItem(CFileItem& item) if (idAlbum > -1) { CAlbum album; - if (GetAlbumInfo(idAlbum,album,NULL,true)) // true to force additional information + if (GetAlbum(idAlbum, album, false)) SetPropertiesFromAlbum(item,album); } } diff --git a/xbmc/music/MusicDatabase.h b/xbmc/music/MusicDatabase.h index 297f21d4dd..ebca036d6a 100644 --- a/xbmc/music/MusicDatabase.h +++ b/xbmc/music/MusicDatabase.h @@ -200,7 +200,13 @@ public: int AddAlbum(const CStdString& strAlbum, const CStdString& strMusicBrainzAlbumID, const CStdString& strArtist, const CStdString& strGenre, int year, bool bCompilation); - bool GetAlbum(int idAlbum, CAlbum& album); + /*! \brief retrieve an album, optionally with all songs. + \param idAlbum the database id of the album. + \param album [out] the album to fill. + \param getSongs whether or not to retrieve songs, defaults to true. + \return true if the album is retrieved, false otherwise. + */ + bool GetAlbum(int idAlbum, CAlbum& album, bool getSongs = true); int UpdateAlbum(int idAlbum, const CAlbum &album); bool DeleteAlbum(int idAlbum); /*! \brief Checks if the given path is inside a folder that has already been scanned into the library @@ -249,7 +255,6 @@ public: ///////////////////////////////////////////////// bool HasAlbumInfo(int idAlbum); int SetAlbumInfo(int idAlbum, const CAlbum& album, const VECSONGS& songs, bool bTransaction=true); - bool GetAlbumInfo(int idAlbum, CAlbum &info, VECSONGS* songs, bool scrapedInfo = false); bool DeleteAlbumInfo(int idArtist); ///////////////////////////////////////////////// diff --git a/xbmc/music/MusicInfoLoader.cpp b/xbmc/music/MusicInfoLoader.cpp index 85425f3f9d..7170df0744 100644 --- a/xbmc/music/MusicInfoLoader.cpp +++ b/xbmc/music/MusicInfoLoader.cpp @@ -101,7 +101,7 @@ bool CMusicInfoLoader::LoadAdditionalTagInfo(CFileItem* pItem) CMusicDatabase::SetPropertiesFromArtist(*pItem,artist); CAlbum album; - if (database.GetAlbumInfo(param.GetAlbumId(),album,NULL)) + if (database.GetAlbum(param.GetAlbumId(), album, false)) CMusicDatabase::SetPropertiesFromAlbum(*pItem,album); path = pItem->GetMusicInfoTag()->GetURL(); diff --git a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp index 7d0dbc98bc..dc2cc4ee06 100644 --- a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp +++ b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp @@ -558,7 +558,7 @@ void CGUIDialogMusicInfo::OnSearch(const CFileItem* pItem) pItem->GetMusicInfoTag()->GetDatabaseId() > 0) { CAlbum album; - if (database.GetAlbumInfo(pItem->GetMusicInfoTag()->GetDatabaseId(), album, &album.infoSongs)) + if (database.GetAlbum(pItem->GetMusicInfoTag()->GetDatabaseId(), album)) { CStdString strPath; database.GetAlbumPath(pItem->GetMusicInfoTag()->GetDatabaseId(), strPath); diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp index ae060b2c89..6f544900a1 100644 --- a/xbmc/music/infoscanner/MusicInfoScanner.cpp +++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp @@ -176,7 +176,7 @@ void CMusicInfoScanner::Process() continue; CAlbum album; - m_musicDatabase.GetAlbumInfo(params.GetAlbumId(), album, &album.infoSongs); + m_musicDatabase.GetAlbum(params.GetAlbumId(), album); if (m_handle) { float percentage = (float) std::distance(it, m_pathsToScan.end()) / m_pathsToScan.size(); @@ -1014,7 +1014,7 @@ INFO_RET CMusicInfoScanner::UpdateDatabaseAlbumInfo(const CStdString& strPath, C return INFO_ERROR; CAlbum album; - m_musicDatabase.GetAlbumInfo(params.GetAlbumId(), album, &album.infoSongs); + m_musicDatabase.GetAlbum(params.GetAlbumId(), album); // find album info ADDON::ScraperPtr scraper; diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp index 40ca26dbb3..ac77d544df 100644 --- a/xbmc/music/windows/GUIWindowMusicBase.cpp +++ b/xbmc/music/windows/GUIWindowMusicBase.cpp @@ -433,7 +433,7 @@ bool CGUIWindowMusicBase::ShowAlbumInfo(const CFileItem *pItem, bool bShowInfo / while (1) { if (!m_musicdatabase.HasAlbumInfo(params.GetAlbumId()) || - !m_musicdatabase.GetAlbumInfo(params.GetAlbumId(), albumInfo.GetAlbum(), &albumInfo.GetAlbum().infoSongs)) + !m_musicdatabase.GetAlbum(params.GetAlbumId(), albumInfo.GetAlbum())) { if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() && !g_passwordManager.bMasterUser) { diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp index d3d2aacaca..8b2ce40d78 100644 --- a/xbmc/music/windows/GUIWindowMusicNav.cpp +++ b/xbmc/music/windows/GUIWindowMusicNav.cpp @@ -588,7 +588,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) return false; CStdString path = StringUtils::Format("musicdb://albums/%ld/", idAlbum); CAlbum album; - m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL); + m_musicdatabase.GetAlbum(idAlbum, album, false); *item = CFileItem(path,album); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp index 5c9e982f74..5db3cf9dee 100644 --- a/xbmc/network/upnp/UPnPServer.cpp +++ b/xbmc/network/upnp/UPnPServer.cpp @@ -297,7 +297,7 @@ CUPnPServer::Build(CFileItemPtr item, } else if (params.GetAlbumId() >= 0 ) { CAlbum album; - if (db.GetAlbumInfo(params.GetAlbumId(), album, NULL)) + if (db.GetAlbum(params.GetAlbumId(), album, false)) item->GetMusicInfoTag()->SetAlbum(album); } else if (params.GetArtistId() >= 0 ) { |