fixed: update mysql database contents on non-UTF-8 systems now that UTF-8 is set...
authorfirnsy <firnsy@securixlive.com>
Thu, 27 Jan 2011 10:44:06 +0000 (21:44 +1100)
committerfirnsy <firnsy@securixlive.com>
Mon, 14 Feb 2011 08:35:38 +0000 (19:35 +1100)
xbmc/dbwrappers/dataset.h
xbmc/dbwrappers/mysqldataset.cpp
xbmc/music/MusicDatabase.cpp
xbmc/music/MusicDatabase.h
xbmc/video/VideoDatabase.cpp
xbmc/video/VideoDatabase.h

index 1599ffe..3347eb5 100644 (file)
@@ -70,7 +70,8 @@ protected:
   bool active;
   std::string error, // Error description
     host, port, db, login, passwd, //Login info
-    sequence_table; //Sequence table for nextid
+    sequence_table, //Sequence table for nextid
+    default_charset; //Default character set
 
 public:
 /* constructor */
@@ -104,7 +105,8 @@ public:
   void setSequenceTable(const char *new_seq_table) { sequence_table = new_seq_table; };
 /* Get name of sequence table */
   const char *getSequenceTable(void) { return sequence_table.c_str(); }
-
+/* Get the default character set */
+  const char *getDefaultCharset(void) { return default_charset.c_str(); }
 
 /* virtual methods that must be overloaded in derived classes */
 
index 32fcced..f1d9438 100644 (file)
@@ -52,6 +52,7 @@ MysqlDatabase::MysqlDatabase() {
   login = "root";
   passwd = "null";
   conn = NULL;
+  default_charset = "";
 }
 
 MysqlDatabase::~MysqlDatabase() {
@@ -121,6 +122,7 @@ int MysqlDatabase::connect() {
     // TODO block to avoid multiple connect on db
     if (mysql_real_connect(conn,host.c_str(),login.c_str(),passwd.c_str(),db.c_str(),atoi(port.c_str()),NULL,0) != NULL)
     {
+      default_charset = mysql_character_set_name(conn);
       if(mysql_set_character_set(conn, "utf8")) // returns 0 on success
       {
         CLog::Log(LOGERROR, "Unable to set utf8 charset: %s [%d](%s)",
@@ -133,6 +135,7 @@ int MysqlDatabase::connect() {
     // Database doesn't exists
     if (mysql_errno(conn) == 1049)
     {
+      default_charset = mysql_character_set_name(conn);
       if (mysql_set_character_set(conn, "utf8")) // returns 0 on success
       {
         CLog::Log(LOGERROR, "Unable to set utf8 charset: %s [%d](%s)",
index be4a5db..76b2b4e 100644 (file)
@@ -3124,6 +3124,89 @@ bool CMusicDatabase::UpdateOldVersion(int version)
       // ensure these scrapers are installed
       CAddonInstaller::InstallFromXBMCRepo(scrapers);
     }
+    if (version < 16)
+    {
+      // only if MySQL is used and default character set is not utf8
+      // string data needs to be converted to proper utf8
+      CStdString charset = m_pDS->getDatabase()->getDefaultCharset();
+      if (!m_sqlite && !charset.empty() && charset != "utf8")
+      {
+        map<CStdString, CStdStringArray> tables;
+        map<CStdString, CStdStringArray>::iterator itt;
+        CStdStringArray::iterator itc;
+
+        //columns that need to be converted
+        CStdStringArray c1;
+        c1.push_back("strAlbum");
+        c1.push_back("strExtraArtists");
+        c1.push_back("strExtraGenres");
+        tables.insert(pair<CStdString, CStdStringArray> ("album", c1));
+
+        CStdStringArray c2;
+        c2.push_back("strExtraGenres");
+        c2.push_back("strMoods");
+        c2.push_back("strStyles");
+        c2.push_back("strThemes");
+        c2.push_back("strReview");
+        c2.push_back("strLabel");
+        tables.insert(pair<CStdString, CStdStringArray> ("albuminfo", c2));
+
+        CStdStringArray c3;
+        c3.push_back("strTitle");
+        tables.insert(pair<CStdString, CStdStringArray> ("albuminfosong", c3));
+
+        CStdStringArray c4;
+        c4.push_back("strArtist");
+        tables.insert(pair<CStdString, CStdStringArray> ("artist", c4));
+
+        CStdStringArray c5;
+        c5.push_back("strBorn");
+        c5.push_back("strFormed");
+        c5.push_back("strGenres");
+        c5.push_back("strMoods");
+        c5.push_back("strStyles");
+        c5.push_back("strInstruments");
+        c5.push_back("strBiography");
+        c5.push_back("strDied");
+        c5.push_back("strDisbanded");
+        c5.push_back("strYearsActive");
+        tables.insert(pair<CStdString, CStdStringArray> ("artistinfo", c5));
+
+        CStdStringArray c6;
+        c6.push_back("strAlbum");
+        tables.insert(pair<CStdString, CStdStringArray> ("discography", c6));
+
+        CStdStringArray c7;
+        c7.push_back("strGenre");
+        tables.insert(pair<CStdString, CStdStringArray> ("genre", c7));
+
+        CStdStringArray c8;
+        c8.push_back("strKaraLyrics");
+        tables.insert(pair<CStdString, CStdStringArray> ("karaokedata", c8));
+
+        CStdStringArray c9;
+        c9.push_back("strTitle");
+        c9.push_back("strFilename");
+        c9.push_back("comment");
+        tables.insert(pair<CStdString, CStdStringArray> ("song", c9));
+
+        for (itt = tables.begin(); itt != tables.end(); ++itt)
+        {
+          CStdString q;
+          q = PrepareSQL("UPDATE `%s` SET", itt->first.c_str());
+          for (itc = itt->second.begin(); itc != itt->second.end(); ++itc)
+          {
+            q += PrepareSQL(" `%s` = CONVERT(CAST(CONVERT(`%s` USING %s) AS BINARY) USING utf8)",
+                            itc->c_str(), itc->c_str(), charset.c_str());
+            if (*itc != itt->second.back())
+            {
+              q += ", ";
+            }
+          }
+          m_pDS->exec(q);
+        }
+      }
+    }
   }
   catch (...)
   {
index 65f5cdc..6a4a3bf 100644 (file)
@@ -214,7 +214,7 @@ protected:
   std::map<CStdString, CAlbumCache> m_albumCache;
 
   virtual bool CreateTables();
-  virtual int GetMinVersion() const { return 15; };
+  virtual int GetMinVersion() const { return 16; };
   const char *GetDefaultDBName() const { return "MyMusic7"; };
 
   int AddAlbum(const CStdString& strAlbum1, int idArtist, const CStdString &extraArtists, const CStdString &strArtist1, int idThumb, int idGenre, const CStdString &extraGenres, int year);
index 0f51914..397f081 100644 (file)
@@ -3361,6 +3361,81 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)
     {
       m_pDS->exec("ALTER table settings add VerticalShift float");
     }
+    if (iVersion < 44)
+    {
+      // only if MySQL is used and default character set is not utf8
+      // string data needs to be converted to proper utf8
+      CStdString charset = m_pDS->getDatabase()->getDefaultCharset();
+      if (!m_sqlite && !charset.empty() && charset != "utf8")
+      {
+        map<CStdString, CStdStringArray> tables;
+        map<CStdString, CStdStringArray>::iterator itt;
+        CStdStringArray::iterator itc;
+
+        // columns that need to be converted
+        // content columns
+        CStdStringArray c_columns;
+        for (int i = 0; i < 22; i++)
+        {
+          CStdString c;
+          c.Format("c%02d", i);
+          c_columns.push_back(c);
+        }
+
+        tables.insert(pair<CStdString, CStdStringArray> ("episode", c_columns));
+        tables.insert(pair<CStdString, CStdStringArray> ("movie", c_columns));
+        tables.insert(pair<CStdString, CStdStringArray> ("musicvideo", c_columns));
+        tables.insert(pair<CStdString, CStdStringArray> ("tvshow", c_columns));
+
+        //common columns
+        CStdStringArray c1;
+        c1.push_back("strRole");
+        tables.insert(pair<CStdString, CStdStringArray> ("actorlinkepisode", c1));
+        tables.insert(pair<CStdString, CStdStringArray> ("actorlinkmovie", c1));
+        tables.insert(pair<CStdString, CStdStringArray> ("actorlinktvshow", c1));
+
+        //remaining columns
+        CStdStringArray c2;
+        c2.push_back("strActor");
+        tables.insert(pair<CStdString, CStdStringArray> ("actors", c2));
+
+        CStdStringArray c3;
+        c3.push_back("strCountry");
+        tables.insert(pair<CStdString, CStdStringArray> ("country", c3));
+
+        CStdStringArray c4;
+        c4.push_back("strFilename");
+        tables.insert(pair<CStdString, CStdStringArray> ("files", c4));
+
+        CStdStringArray c5;
+        c5.push_back("strGenre");
+        tables.insert(pair<CStdString, CStdStringArray> ("genre", c5));
+
+        CStdStringArray c6;
+        c6.push_back("strSet");
+        tables.insert(pair<CStdString, CStdStringArray> ("sets", c6));
+
+        CStdStringArray c7;
+        c7.push_back("strStudio");
+        tables.insert(pair<CStdString, CStdStringArray> ("studio", c7));
+
+        for (itt = tables.begin(); itt != tables.end(); ++itt)
+        {
+          CStdString q;
+          q = PrepareSQL("UPDATE `%s` SET", itt->first.c_str());
+          for (itc = itt->second.begin(); itc != itt->second.end(); ++itc)
+          {
+            q += PrepareSQL(" `%s` = CONVERT(CAST(CONVERT(`%s` USING %s) AS BINARY) USING utf8)",
+                            itc->c_str(), itc->c_str(), charset.c_str());
+            if (*itc != itt->second.back())
+            {
+              q += ",";
+            }
+          }
+          m_pDS->exec(q);
+        }
+      }
+    }
   }
   catch (...)
   {
index d06f4ea..fb2f7a4 100644 (file)
@@ -629,7 +629,7 @@ protected:
 private:
   virtual bool CreateTables();
   virtual bool UpdateOldVersion(int version);
-  virtual int GetMinVersion() const { return 43; };
+  virtual int GetMinVersion() const { return 44; };
   const char *GetDefaultDBName() const { return "MyVideos34.db"; };
 
   void ConstructPath(CStdString& strDest, const CStdString& strPath, const CStdString& strFileName);