Permalink
Browse files

Merge pull request #1776 from Montellese/fix_13544

videodb: remove tag/taglinks connections when removing items
  • Loading branch information...
Montellese committed Nov 19, 2012
2 parents d938545 + efa10aa commit 71f082f90adb0d63f0da6fba6a5130c8150f75c9
Showing with 69 additions and 32 deletions.
  1. +0 −13 xbmc/dbwrappers/mysqldataset.cpp
  2. +68 −16 xbmc/video/VideoDatabase.cpp
  3. +1 −3 xbmc/video/VideoDatabase.h
@@ -1367,19 +1367,6 @@ int MysqlDataset::exec(const string &sql) {
{
qry += " CHARACTER SET utf8 COLLATE utf8_general_ci";
}
// sqlite3 requires the BEGIN and END pragmas when creating triggers. mysql does not.
else if ( ci_find(qry, "CREATE TRIGGER") != string::npos )
{
if ( (loc=ci_find(qry, "BEGIN ")) != string::npos )
{
qry.replace(loc, 6, "");
}

if ( (loc=ci_find(qry, " END")) != string::npos )
{
qry.replace(loc, 4, "");
}
}

CLog::Log(LOGDEBUG,"Mysql execute: %s", qry.c_str());

@@ -309,16 +309,9 @@ bool CVideoDatabase::CreateTables()
m_pDS->exec("CREATE TABLE seasons ( idSeason integer primary key, idShow integer, season integer)");
m_pDS->exec("CREATE INDEX ix_seasons ON seasons (idShow, season)");

CLog::Log(LOGINFO, "create art table and triggers");
CLog::Log(LOGINFO, "create art table");
m_pDS->exec("CREATE TABLE art(art_id INTEGER PRIMARY KEY, media_id INTEGER, media_type TEXT, type TEXT, url TEXT)");
m_pDS->exec("CREATE INDEX ix_art ON art(media_id, media_type(20), type(20))");
m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; END");
m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; END");
m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; END");
m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; END");
m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; END");
m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; END");
m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); END");

CLog::Log(LOGINFO, "create tag table");
m_pDS->exec("CREATE TABLE tag (idTag integer primary key, strTag text)");
@@ -330,6 +323,35 @@ bool CVideoDatabase::CreateTables()
m_pDS->exec("CREATE UNIQUE INDEX ix_taglinks_2 ON taglinks (idMedia, media_type(20), idTag)");
m_pDS->exec("CREATE INDEX ix_taglinks_3 ON taglinks (media_type(20))");

CLog::Log(LOGINFO, "create deletion triggers");
m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; "
"DELETE FROM taglinks WHERE idMedia=old.idMovie AND media_type='movie'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; "
"DELETE FROM taglinks WHERE idMedia=old.idShow AND media_type='tvshow'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; "
"DELETE FROM taglinks WHERE idMedia=old.idMVideo AND media_type='musicvideo'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); "
"END");
m_pDS->exec("CREATE TRIGGER delete_tag AFTER DELETE ON taglinks FOR EACH ROW BEGIN "
"DELETE FROM tag WHERE idTag=old.idTag AND idTag NOT IN (SELECT DISTINCT idTag FROM taglinks); "
"END");

// we create views last to ensure all indexes are rolled in
CreateViews();
}
@@ -1431,7 +1453,6 @@ void CVideoDatabase::RemoveTagFromItem(int idItem, int idTag, const std::string
return;

RemoveFromLinkTable("taglinks", "idTag", idTag, "idMedia", idItem, "media_type", type.c_str());
CleanupTags();
}

void CVideoDatabase::RemoveTagsFromItem(int idItem, const std::string &type)
@@ -1440,12 +1461,6 @@ void CVideoDatabase::RemoveTagsFromItem(int idItem, const std::string &type)
return;

m_pDS2->exec(PrepareSQL("DELETE FROM taglinks WHERE idMedia=%d AND media_type='%s'", idItem, type.c_str()));
CleanupTags();
}

void CVideoDatabase::CleanupTags()
{
m_pDS2->exec("DELETE FROM tag WHERE NOT EXISTS (SELECT 1 FROM taglinks WHERE taglinks.idTag = tag.idTag)");
}

//****Actors****
@@ -2995,7 +3010,6 @@ void CVideoDatabase::DeleteTag(int idTag, VIDEODB_CONTENT_TYPE mediaType)
CStdString strSQL;
strSQL = PrepareSQL("DELETE FROM taglinks WHERE idTag = %i AND media_type = '%s'", idTag, type.c_str());
m_pDS->exec(strSQL.c_str());
CleanupTags();
}
catch (...)
{
@@ -4206,6 +4220,44 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
}
}
}
if (iVersion < 73)
{
m_pDS->exec("DROP TRIGGER IF EXISTS delete_movie");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_tvshow");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_musicvideo");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_episode");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_season");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_set");
m_pDS->exec("DROP TRIGGER IF EXISTS delete_person");

m_pDS->exec("CREATE TRIGGER delete_movie AFTER DELETE ON movie FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idMovie AND media_type='movie'; "
"DELETE FROM taglinks WHERE idMedia=old.idMovie AND media_type='movie'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_tvshow AFTER DELETE ON tvshow FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idShow AND media_type='tvshow'; "
"DELETE FROM taglinks WHERE idMedia=old.idShow AND media_type='tvshow'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_musicvideo AFTER DELETE ON musicvideo FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idMVideo AND media_type='musicvideo'; "
"DELETE FROM taglinks WHERE idMedia=old.idMVideo AND media_type='musicvideo'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_episode AFTER DELETE ON episode FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idEpisode AND media_type='episode'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_season AFTER DELETE ON seasons FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idSeason AND media_type='season'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_set AFTER DELETE ON sets FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idSet AND media_type='set'; "
"END");
m_pDS->exec("CREATE TRIGGER delete_person AFTER DELETE ON actors FOR EACH ROW BEGIN "
"DELETE FROM art WHERE media_id=old.idActor AND media_type IN ('actor','artist','writer','director'); "
"END");
m_pDS->exec("CREATE TRIGGER delete_tag AFTER DELETE ON taglinks FOR EACH ROW BEGIN "
"DELETE FROM tag WHERE idTag=old.idTag AND idTag NOT IN (SELECT DISTINCT idTag FROM taglinks); "
"END");
}
// always recreate the view after any table change
CreateViews();
return true;
@@ -764,8 +764,6 @@ class CVideoDatabase : public CDatabase
void GetDetailsFromDB(const dbiplus::sql_record* const record, int min, int max, const SDbTableOffsets *offsets, CVideoInfoTag &details, int idxOffset = 2);
CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;

void CleanupTags();

private:
virtual bool CreateTables();
virtual bool UpdateOldVersion(int version);
@@ -807,7 +805,7 @@ class CVideoDatabase : public CDatabase
*/
bool LookupByFolders(const CStdString &path, bool shows = false);

virtual int GetMinVersion() const { return 72; };
virtual int GetMinVersion() const { return 73; };
virtual int GetExportVersion() const { return 1; };
const char *GetBaseDBName() const { return "MyVideos"; };

0 comments on commit 71f082f

Please sign in to comment.