aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Marshall <jmarshall@xbmc.org>2013-12-01 21:30:52 +1300
committerJonathan Marshall <jmarshall@xbmc.org>2013-12-24 13:48:53 +1300
commit2b5408215494be7baf11ce29008272af2bba2ab4 (patch)
tree29bb7e98a517e4b97e9865a552bf32900c662c6d
parent7f9ecd9c44473673f1158eb56c881e90d463d3b0 (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.cpp9
-rw-r--r--xbmc/music/MusicDatabase.cpp174
-rw-r--r--xbmc/music/MusicDatabase.h9
-rw-r--r--xbmc/music/MusicInfoLoader.cpp2
-rw-r--r--xbmc/music/dialogs/GUIDialogMusicInfo.cpp2
-rw-r--r--xbmc/music/infoscanner/MusicInfoScanner.cpp4
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp2
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.cpp2
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp2
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 ) {