Skip to content

Commit

Permalink
Add versiontagscan table to track the version of tag processing used …
Browse files Browse the repository at this point in the history
…to populate the library. Replace use of GUI setting MusicNeedsUpdate with read/write to database.
  • Loading branch information
DaveTBlake committed Jan 27, 2017
1 parent fc92c40 commit 5689197
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 13 deletions.
79 changes: 71 additions & 8 deletions xbmc/music/MusicDatabase.cpp
Expand Up @@ -192,6 +192,10 @@ void CMusicDatabase::CreateTables()

CLog::Log(LOGINFO, "create cue table");
m_pDS->exec("CREATE TABLE cue (idPath integer, strFileName text, strCuesheet text)");

CLog::Log(LOGINFO, "create versiontagscan table");
m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)");
m_pDS->exec(PrepareSQL("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(%i, 0)", GetSchemaVersion()));
}

void CMusicDatabase::CreateAnalytics()
Expand Down Expand Up @@ -4662,8 +4666,6 @@ void CMusicDatabase::UpdateTables(int version)
if (version < 53)
{
m_pDS->exec("ALTER TABLE song ADD dateAdded text");
CMediaSettings::GetInstance().SetMusicNeedsUpdate(53);
CServiceBroker::GetSettings().Save();
}
if (version < 54)
{
Expand Down Expand Up @@ -4958,17 +4960,78 @@ void CMusicDatabase::UpdateTables(int version)
//Remove temp indices, full analytics for database created later
m_pDS->exec("DROP INDEX idxSongArtist1 ON song_artist");
m_pDS->exec("DROP INDEX idxAlbumArtist1 ON album_artist");

// Prompt for rescan of library to read tags that were not processed by previous versions
// and accomodate changes to the way some tags are processed
CMediaSettings::GetInstance().SetMusicNeedsUpdate(60);
CServiceBroker::GetSettings().Save();
}
if (version < 61)
{
// Create versiontagscan table
m_pDS->exec("CREATE TABLE versiontagscan (idVersion integer, iNeedsScan integer)");
m_pDS->exec("INSERT INTO versiontagscan (idVersion, iNeedsScan) values(0, 0)");
}

// Set the verion of tag scanning required.
// Not every schema change requires the tags to be rescanned, set to the highest schema version
// that needs this. Forced rescanning (of music files that have not changed since they were
// previously scanned) also accommodates any changes to the way tags are processed
// e.g. read tags that were not processed by previous versions.
// The original db version when the tags were scanned, and the minimal db version needed are
// later used to determine if a forced rescan should be prompted

// The last schema change needing forced rescanning was 60.
// Mostly because of the new tags processed by v17 rather than a schema change.
SetMusicNeedsTagScan(60);

// After all updates, store the original db version.
// This indicates the version of tag processing that was used to populate db
SetMusicTagScanVersion(version);
}

int CMusicDatabase::GetSchemaVersion() const
{
return 60;
return 61;
}

int CMusicDatabase::GetMusicNeedsTagScan()
{
try
{
if (NULL == m_pDB.get()) return -1;
if (NULL == m_pDS.get()) return -1;

std::string sql = "SELECT * FROM versiontagscan";
if (!m_pDS->query(sql)) return -1;

if (m_pDS->num_rows() != 1)
{
m_pDS->close();
return -1;
}

int idVersion = m_pDS->fv("idVersion").get_asInt();
int iNeedsScan = m_pDS->fv("iNeedsScan").get_asInt();
m_pDS->close();
if (idVersion < iNeedsScan)
return idVersion;
else
return 0;
}
catch (...)
{
CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
}
return -1;
}

void CMusicDatabase::SetMusicNeedsTagScan(int version)
{
m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET iNeedsScan=%i", version));
}

void CMusicDatabase::SetMusicTagScanVersion(int version /* = 0 */)
{
if (version == 0)
m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", GetSchemaVersion()));
else
m_pDS->exec(PrepareSQL("UPDATE versiontagscan SET idVersion=%i", version));
}

unsigned int CMusicDatabase::GetSongIDs(const Filter &filter, std::vector<std::pair<int,int> > &songIDs)
Expand Down
20 changes: 20 additions & 0 deletions xbmc/music/MusicDatabase.h
Expand Up @@ -497,6 +497,26 @@ class CMusicDatabase : public CDatabase
*/
std::string GetArtistArtForItem(int mediaId, const std::string &mediaType, const std::string &artType);

/////////////////////////////////////////////////
// Tag Scan Version
/////////////////////////////////////////////////
/*! \brief Check if music files need all tags rescanning regardless of file being unchanged
because the tag processing has changed (which may happen without db version changes) since they
where last scanned.
\return -1 if an error occured, 0 if no scan is needed, or the version number of tags if not the same as current.
*/
virtual int GetMusicNeedsTagScan();

/*! \brief Set minimum version number of db needed when tag data scanned from music files
\param version the version number of db
*/
void SetMusicNeedsTagScan(int version);

/*! \brief Set the version number of tag data
\param version the version number of db when tags last scanned, 0 (default) means current db version
*/
void SetMusicTagScanVersion(int version = 0);

protected:
std::map<std::string, int> m_artistCache;
std::map<std::string, int> m_genreCache;
Expand Down
8 changes: 3 additions & 5 deletions xbmc/music/windows/GUIWindowMusicBase.cpp
Expand Up @@ -1308,7 +1308,7 @@ void CGUIWindowMusicBase::OnInitWindow()
CGUIMediaWindow::OnInitWindow();
// Prompt for rescan of library to read music file tags that were not processed by previous versions
// and accomodate any changes to the way some tags are processed
if (CMediaSettings::GetInstance().GetMusicNeedsUpdate() != 0)
if (m_musicdatabase.GetMusicNeedsTagScan() != 0)
{
if (g_infoManager.GetLibraryBool(LIBRARY_HAS_MUSIC) && !g_application.IsMusicScanning())
{
Expand All @@ -1324,15 +1324,13 @@ void CGUIWindowMusicBase::OnInitWindow()
if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE))
flags |= CMusicInfoScanner::SCAN_BACKGROUND;
g_application.StartMusicScan("", true, flags);
CMediaSettings::GetInstance().SetMusicNeedsUpdate(0); // once is enough (user may interrupt, but that's up to them)
CServiceBroker::GetSettings().Save();
m_musicdatabase.SetMusicTagScanVersion(); // once is enough (user may interrupt, but that's up to them)
}
}
else
{
// no need to force a rescan if there's no music in the library or if a library scan is already active
CMediaSettings::GetInstance().SetMusicNeedsUpdate(0);
CServiceBroker::GetSettings().Save();
m_musicdatabase.SetMusicTagScanVersion();
}
}
}
Expand Down

0 comments on commit 5689197

Please sign in to comment.