MythTV  0.26-pre
dbcheck.cpp
Go to the documentation of this file.
00001 #include <QString>
00002 #include <QDir>
00003 #include <QSqlError>
00004 
00005 #include <iostream>
00006 using namespace std;
00007 
00008 #include "dbcheck.h"
00009 #include "metadata.h"
00010 #include "mythtv/mythcontext.h"
00011 #include "mythtv/mythdb.h"
00012 #include "mythtv/schemawizard.h"
00013 
00014 const QString currentDatabaseVersion = "1019";
00015 
00016 static bool doUpgradeMusicDatabaseSchema(QString &dbver);
00017 
00018 static bool UpdateDBVersionNumber(const QString &newnumber)
00019 {
00020 
00021     if (!gCoreContext->SaveSettingOnHost("MusicDBSchemaVer",newnumber,NULL))
00022     {
00023         LOG(VB_GENERAL, LOG_ERR,
00024             QString("DB Error (Setting new DB version number): %1\n")
00025                 .arg(newnumber));
00026 
00027         return false;
00028     }
00029 
00030     return true;
00031 }
00032 
00033 static bool performActualUpdate(const QString updates[], QString version,
00034                                 QString &dbver)
00035 {
00036     MSqlQuery query(MSqlQuery::InitCon());
00037 
00038     LOG(VB_GENERAL, LOG_NOTICE,
00039         QString("Upgrading to MythMusic schema version ") + version);
00040 
00041     int counter = 0;
00042     QString thequery = updates[counter];
00043 
00044     while (!thequery.isEmpty())
00045     {
00046         if (!query.exec(thequery))
00047         {
00048             QString msg =
00049                 QString("DB Error (Performing database upgrade): \n"
00050                         "Query was: %1 \nError was: %2 \nnew version: %3")
00051                 .arg(thequery)
00052                 .arg(MythDB::DBErrorMessage(query.lastError()))
00053                 .arg(version);
00054             LOG(VB_GENERAL, LOG_ERR, msg);
00055             return false;
00056         }
00057 
00058         counter++;
00059         thequery = updates[counter];
00060     }
00061 
00062     if (!UpdateDBVersionNumber(version))
00063         return false;
00064 
00065     dbver = version;
00066     return true;
00067 }
00068 
00069 bool UpgradeMusicDatabaseSchema(void)
00070 {
00071 #ifdef IGNORE_SCHEMA_VER_MISMATCH
00072     return true;
00073 #endif
00074     SchemaUpgradeWizard *schema_wizard = NULL;
00075 
00076     // Suppress DB messages and turn of the settings cache,
00077     // These are likely to confuse the users and the code, respectively.
00078     GetMythDB()->SetSuppressDBMessages(true);
00079     gCoreContext->ActivateSettingsCache(false);
00080 
00081     // Get the schema upgrade lock
00082     MSqlQuery query(MSqlQuery::InitCon());
00083     bool locked = DBUtil::TryLockSchema(query, 1);
00084     for (uint i = 0; i < 2*60 && !locked; i++)
00085     {
00086         LOG(VB_GENERAL, LOG_INFO, "Waiting for database schema upgrade lock");
00087         locked = DBUtil::TryLockSchema(query, 1);
00088         if (locked)
00089             LOG(VB_GENERAL, LOG_INFO, "Got schema upgrade lock");
00090     }
00091     if (!locked)
00092     {
00093         LOG(VB_GENERAL, LOG_INFO, "Failed to get schema upgrade lock");
00094         goto upgrade_error_exit;
00095     }
00096 
00097     schema_wizard = SchemaUpgradeWizard::Get(
00098         "MusicDBSchemaVer", "MythMusic", currentDatabaseVersion);
00099 
00100     if (schema_wizard->Compare() == 0) // DB schema is what we need it to be..
00101         goto upgrade_ok_exit;
00102 
00103     if (schema_wizard->DBver.isEmpty())
00104     {
00105         // We need to create a database from scratch
00106         if (doUpgradeMusicDatabaseSchema(schema_wizard->DBver))
00107             goto upgrade_ok_exit;
00108         else
00109             goto upgrade_error_exit;
00110     }
00111 
00112     // Pop up messages, questions, warnings, et c.
00113     switch (schema_wizard->PromptForUpgrade("Music", true, false))
00114     {
00115         case MYTH_SCHEMA_USE_EXISTING:
00116             goto upgrade_ok_exit;
00117         case MYTH_SCHEMA_ERROR:
00118         case MYTH_SCHEMA_EXIT:
00119             goto upgrade_error_exit;
00120         case MYTH_SCHEMA_UPGRADE:
00121             break;
00122     }
00123 
00124     if (!doUpgradeMusicDatabaseSchema(schema_wizard->DBver))
00125     {
00126         LOG(VB_GENERAL, LOG_ERR, "Database schema upgrade failed.");
00127         goto upgrade_error_exit;
00128     }
00129 
00130     LOG(VB_GENERAL, LOG_INFO, "MythMusic database schema upgrade complete.");
00131 
00132     // On any exit we want to re-enable the DB messages so errors
00133     // are reported and we want to make sure the setting cache is
00134     // enabled for good performance and we must unlock the schema
00135     // lock. We use gotos with labels so it's impossible to miss
00136     // these steps.
00137   upgrade_ok_exit:
00138     GetMythDB()->SetSuppressDBMessages(false);
00139     gCoreContext->ActivateSettingsCache(true);
00140     if (locked)
00141         DBUtil::UnlockSchema(query);
00142     return true;
00143 
00144   upgrade_error_exit:
00145     GetMythDB()->SetSuppressDBMessages(false);
00146     gCoreContext->ActivateSettingsCache(true);
00147     if (locked)
00148         DBUtil::UnlockSchema(query);
00149     return false;
00150 }
00151 
00152 
00153 static bool doUpgradeMusicDatabaseSchema(QString &dbver)
00154 {
00155     if (dbver.isEmpty())
00156     {
00157         LOG(VB_GENERAL, LOG_NOTICE,
00158             "Inserting MythMusic initial database information.");
00159 
00160         const QString updates[] = {
00161 "CREATE TABLE IF NOT EXISTS musicmetadata ("
00162 "    intid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
00163 "    artist VARCHAR(128) NOT NULL,"
00164 "    album VARCHAR(128) NOT NULL,"
00165 "    title VARCHAR(128) NOT NULL,"
00166 "    genre VARCHAR(128) NOT NULL,"
00167 "    year INT UNSIGNED NOT NULL,"
00168 "    tracknum INT UNSIGNED NOT NULL,"
00169 "    length INT UNSIGNED NOT NULL,"
00170 "    filename TEXT NOT NULL,"
00171 "    rating INT UNSIGNED NOT NULL DEFAULT 5,"
00172 "    lastplay TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP "
00173 "                       ON UPDATE CURRENT_TIMESTAMP,"
00174 "    playcount INT UNSIGNED NOT NULL DEFAULT 0,"
00175 "    INDEX (artist),"
00176 "    INDEX (album),"
00177 "    INDEX (title),"
00178 "    INDEX (genre)"
00179 ");",
00180 "CREATE TABLE IF NOT EXISTS musicplaylist ("
00181 "    playlistid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
00182 "    name VARCHAR(128) NOT NULL,"
00183 "    hostname VARCHAR(255),"
00184 "    songlist TEXT NOT NULL"
00185 ");",
00186 ""
00187 };
00188         if (!performActualUpdate(updates, "1000", dbver))
00189             return false;
00190     }
00191 
00192     if (dbver == "1000")
00193     {
00194         QString startdir = gCoreContext->GetSetting("MusicLocation");
00195         startdir = QDir::cleanPath(startdir);
00196         if (!startdir.endsWith("/"))
00197             startdir += "/";
00198 
00199         MSqlQuery query(MSqlQuery::InitCon());
00200         // urls as filenames are NOT officially supported yet
00201         if (query.exec("SELECT filename, intid FROM musicmetadata WHERE "
00202                        "filename NOT LIKE ('%://%');"))
00203         {
00204             int i = 0;
00205             QString intid, name, newname;
00206 
00207             MSqlQuery modify(MSqlQuery::InitCon());
00208             while (query.next())
00209             {
00210                 name = query.value(0).toString();
00211                 newname = name;
00212                 intid = query.value(1).toString();
00213 
00214                 if (newname.startsWith(startdir))
00215                 {
00216                     newname.remove(0, startdir.length());
00217                     if (modify.exec(QString("UPDATE musicmetadata SET "
00218                                     "filename = \"%1\" "
00219                                     "WHERE filename = \"%2\" AND intid = %3;")
00220                                     .arg(newname).arg(name).arg(intid)))
00221                         i += modify.numRowsAffected();
00222                 }
00223             }
00224             LOG(VB_GENERAL, LOG_NOTICE,
00225                 QString("Modified %1 entries for db schema 1001").arg(i));
00226         }
00227 
00228         const QString updates[] = {
00229 ""
00230 };
00231         if (!performActualUpdate(updates, "1001", dbver))
00232             return false;
00233     }
00234 
00235     if (dbver == "1001")
00236     {
00237         const QString updates[] = {
00238 "ALTER TABLE musicmetadata ADD mythdigest      VARCHAR(255);",
00239 "ALTER TABLE musicmetadata ADD size            BIGINT UNSIGNED;",
00240 "ALTER TABLE musicmetadata ADD date_added      DATETIME;",
00241 "ALTER TABLE musicmetadata ADD date_modified   DATETIME;",
00242 "ALTER TABLE musicmetadata ADD format          VARCHAR(4);",
00243 "ALTER TABLE musicmetadata ADD description     VARCHAR(255);",
00244 "ALTER TABLE musicmetadata ADD comment         VARCHAR(255);",
00245 "ALTER TABLE musicmetadata ADD compilation     TINYINT DEFAULT 0;",
00246 "ALTER TABLE musicmetadata ADD composer        VARCHAR(255);",
00247 "ALTER TABLE musicmetadata ADD disc_count      SMALLINT UNSIGNED DEFAULT 0;",
00248 "ALTER TABLE musicmetadata ADD disc_number     SMALLINT UNSIGNED DEFAULT 0;",
00249 "ALTER TABLE musicmetadata ADD track_count     SMALLINT UNSIGNED DEFAULT 0;",
00250 "ALTER TABLE musicmetadata ADD start_time      INT UNSIGNED DEFAULT 0;",
00251 "ALTER TABLE musicmetadata ADD stop_time       INT UNSIGNED;",
00252 "ALTER TABLE musicmetadata ADD eq_preset       VARCHAR(255);",
00253 "ALTER TABLE musicmetadata ADD relative_volume TINYINT DEFAULT 0;",
00254 "ALTER TABLE musicmetadata ADD sample_rate     INT UNSIGNED;",
00255 "ALTER TABLE musicmetadata ADD bpm             SMALLINT UNSIGNED;",
00256 "ALTER TABLE musicmetadata ADD INDEX (mythdigest);",
00257 ""
00258 };
00259         if (!performActualUpdate(updates, "1002", dbver))
00260             return false;
00261     }
00262 
00263     if (dbver == "1002")
00264     {
00265         LOG(VB_GENERAL, LOG_NOTICE,
00266             "Updating music metadata to be UTF-8 in the database");
00267 
00268         MSqlQuery query(MSqlQuery::InitCon());
00269         query.prepare("SELECT intid, artist, album, title, genre, "
00270                       "filename FROM musicmetadata ORDER BY intid;");
00271 
00272         if (query.exec() && query.isActive() && query.size() > 0)
00273         {
00274             while (query.next())
00275             {
00276                 int id = query.value(0).toInt();
00277                 QString artist = query.value(1).toString();
00278                 QString album = query.value(2).toString();
00279                 QString title = query.value(3).toString();
00280                 QString genre = query.value(4).toString();
00281                 QString filename = query.value(5).toString();
00282 
00283                 MSqlQuery subquery(MSqlQuery::InitCon());
00284                 subquery.prepare("UPDATE musicmetadata SET "
00285                                  "artist = :ARTIST, album = :ALBUM, "
00286                                  "title = :TITLE, genre = :GENRE, "
00287                                  "filename = :FILENAME "
00288                                  "WHERE intid = :ID;");
00289                 subquery.bindValue(":ARTIST",   QString(artist.toUtf8()));
00290                 subquery.bindValue(":ALBUM",    QString(album.toUtf8()));
00291                 subquery.bindValue(":TITLE",    QString(title.toUtf8()));
00292                 subquery.bindValue(":GENRE",    QString(genre.toUtf8()));
00293                 subquery.bindValue(":FILENAME", QString(filename.toUtf8()));
00294                 subquery.bindValue(":ID", id);
00295 
00296                 if (!subquery.exec() || !subquery.isActive())
00297                     MythDB::DBError("music utf8 update", subquery);
00298             }
00299         }
00300 
00301         query.prepare("SELECT playlistid, name FROM musicplaylist "
00302                       "ORDER BY playlistid;");
00303 
00304         if (query.exec() && query.isActive() && query.size() > 0)
00305         {
00306             while (query.next())
00307             {
00308                 int id = query.value(0).toInt();
00309                 QString name = query.value(1).toString();
00310 
00311                 MSqlQuery subquery(MSqlQuery::InitCon());
00312                 subquery.prepare("UPDATE musicplaylist SET "
00313                                  "name = :NAME WHERE playlistid = :ID ;");
00314                 subquery.bindValue(":NAME", QString(name.toUtf8()));
00315                 subquery.bindValue(":ID", id);
00316 
00317                 if (!subquery.exec() || !subquery.isActive())
00318                     MythDB::DBError("music playlist utf8 update", subquery);
00319             }
00320         }
00321 
00322         LOG(VB_GENERAL, LOG_NOTICE, "Done updating music metadata to UTF-8");
00323 
00324         const QString updates[] = {
00325 ""
00326 };
00327         if (!performActualUpdate(updates, "1003", dbver))
00328             return false;
00329     }
00330 
00331     if (dbver == "1003")
00332     {
00333         const QString updates[] = {
00334 "DROP TABLE IF EXISTS smartplaylistcategory;",
00335 "CREATE TABLE smartplaylistcategory ("
00336 "    categoryid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
00337 "    name VARCHAR(128) NOT NULL,"
00338 "    INDEX (name)"
00339 ");",
00340 
00341 "INSERT INTO smartplaylistcategory SET categoryid = 1, "
00342 "    name = \"Decades\";",
00343 "INSERT INTO smartplaylistcategory SET categoryid = 2, "
00344 "    name = \"Favourite Tracks\";",
00345 "INSERT INTO smartplaylistcategory SET categoryid = 3, "
00346 "    name = \"New Tracks\";",
00347 
00348 "DROP TABLE IF EXISTS smartplaylist;",
00349 "CREATE TABLE smartplaylist ("
00350 "    smartplaylistid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
00351 "    name VARCHAR(128) NOT NULL,"
00352 "    categoryid INT UNSIGNED NOT NULL,"
00353 "    matchtype SET('All', 'Any') NOT NULL DEFAULT 'All',"
00354 "    orderby VARCHAR(128) NOT NULL DEFAULT '',"
00355 "    limitto INT UNSIGNED NOT NULL DEFAULT 0,"
00356 "    INDEX (name),"
00357 "    INDEX (categoryid)"
00358 ");",
00359 "DROP TABLE IF EXISTS smartplaylistitem;",
00360 "CREATE TABLE smartplaylistitem ("
00361 "    smartplaylistitemid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
00362 "    smartplaylistid INT UNSIGNED NOT NULL,"
00363 "    field VARCHAR(50) NOT NULL,"
00364 "    operator VARCHAR(20) NOT NULL,"
00365 "    value1 VARCHAR(255) NOT NULL,"
00366 "    value2 VARCHAR(255) NOT NULL,"
00367 "    INDEX (smartplaylistid)"
00368 ");",
00369 "INSERT INTO smartplaylist SET smartplaylistid = 1, name = \"1960's\", "
00370 "    categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
00371 "    limitto = 0;",
00372 "INSERT INTO smartplaylistitem SET smartplaylistid = 1, field = \"Year\","
00373 "    operator = \"is between\", value1 = \"1960\", value2 = \"1969\";",
00374 
00375 "INSERT INTO smartplaylist SET smartplaylistid = 2, name = \"1970's\", "
00376 "    categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
00377 "    limitto = 0;",
00378 "INSERT INTO smartplaylistitem SET smartplaylistid = 2, field = \"Year\","
00379 "    operator = \"is between\", value1 = \"1970\", value2 = \"1979\";",
00380 
00381 "INSERT INTO smartplaylist SET smartplaylistid = 3, name = \"1980's\", "
00382 "    categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
00383 "    limitto = 0;",
00384 "INSERT INTO smartplaylistitem SET smartplaylistid = 3, field = \"Year\","
00385 "    operator = \"is between\", value1 = \"1980\", value2 = \"1989\";",
00386 
00387 "INSERT INTO smartplaylist SET smartplaylistid = 4, name = \"1990's\", "
00388 "    categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
00389 "    limitto = 0;",
00390 "INSERT INTO smartplaylistitem SET smartplaylistid = 4, field = \"Year\","
00391 "    operator = \"is between\", value1 = \"1990\", value2 = \"1999\";",
00392 
00393 "INSERT INTO smartplaylist SET smartplaylistid = 5, name = \"2000's\", "
00394 "    categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
00395 "    limitto = 0;",
00396 "INSERT INTO smartplaylistitem SET smartplaylistid = 5, field = \"Year\","
00397 "    operator = \"is between\", value1 = \"2000\", value2 = \"2009\";",
00398 
00399 "INSERT INTO smartplaylist SET smartplaylistid = 6, name = \"Favorite Tracks\", "
00400 "    categoryid = 2, matchtype = \"All\","
00401 "    orderby = \"Artist (A), Album (A)\", limitto = 0;",
00402 "INSERT INTO smartplaylistitem SET smartplaylistid = 6, field = \"Rating\","
00403 "    operator = \"is greater than\", value1 = \"7\", value2 = \"0\";",
00404 
00405 "INSERT INTO smartplaylist SET smartplaylistid = 7, name = \"100 Most Played Tracks\", "
00406 "    categoryid = 2, matchtype = \"All\", orderby = \"Play Count (D)\","
00407 "    limitto = 100;",
00408 "INSERT INTO smartplaylistitem SET smartplaylistid = 7, field = \"Play Count\","
00409 "    operator = \"is greater than\", value1 = \"0\", value2 = \"0\";",
00410 
00411 "INSERT INTO smartplaylist SET smartplaylistid = 8, name = \"Never Played Tracks\", "
00412 "    categoryid = 3, matchtype = \"All\", orderby = \"Artist (A), Album (A)\","
00413 "    limitto = 0;",
00414 "INSERT INTO smartplaylistitem SET smartplaylistid = 8, field = \"Play Count\","
00415 "    operator = \"is equal to\", value1 = \"0\", value2 = \"0\";",
00416 
00417 ""
00418 };
00419 
00420         if (!performActualUpdate(updates, "1004", dbver))
00421             return false;
00422     }
00423 
00424     if (dbver == "1004")
00425     {
00426         const QString updates[] = {
00427 "ALTER TABLE musicmetadata ADD compilation_artist VARCHAR(128) NOT NULL AFTER artist;",
00428 "ALTER TABLE musicmetadata ADD INDEX (compilation_artist);",
00429 ""
00430 };
00431 
00432         if (!performActualUpdate(updates, "1005", dbver))
00433             return false;
00434     }
00435 
00436 
00437     if (dbver == "1005")
00438     {
00439         const QString updates[] = {
00440 "CREATE TABLE music_albums ("
00441 "    album_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
00442 "    artist_id int(11) unsigned NOT NULL default '0',"
00443 "    album_name varchar(255) NOT NULL default '',"
00444 "    year smallint(6) NOT NULL default '0',"
00445 "    compilation tinyint(1) unsigned NOT NULL default '0',"
00446 "    INDEX idx_album_name(album_name)"
00447 ");",
00448 "CREATE TABLE music_artists ("
00449 "    artist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
00450 "    artist_name varchar(255) NOT NULL default '',"
00451 "    INDEX idx_artist_name(artist_name)"
00452 ");",
00453 "CREATE TABLE music_genres ("
00454 "    genre_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
00455 "    genre varchar(25) NOT NULL default '',"
00456 "    INDEX idx_genre(genre)"
00457 ");",
00458 "CREATE TABLE music_playlists ("
00459 "    playlist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
00460 "    playlist_name varchar(255) NOT NULL default '',"
00461 "    playlist_songs text NOT NULL,"
00462 "    last_accessed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP "
00463 "                            ON UPDATE CURRENT_TIMESTAMP,"
00464 "    length int(11) unsigned NOT NULL default '0',"
00465 "    songcount smallint(8) unsigned NOT NULL default '0',"
00466 "    hostname VARCHAR(255) NOT NULL default ''"
00467 ");",
00468 "CREATE TABLE music_songs ("
00469 "    song_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
00470 "    filename text NOT NULL,"
00471 "    name varchar(255) NOT NULL default '',"
00472 "    track smallint(6) unsigned NOT NULL default '0',"
00473 "    artist_id int(11) unsigned NOT NULL default '0',"
00474 "    album_id int(11) unsigned NOT NULL default '0',"
00475 "    genre_id int(11) unsigned NOT NULL default '0',"
00476 "    year smallint(6) NOT NULL default '0',"
00477 "    length int(11) unsigned NOT NULL default '0',"
00478 "    numplays int(11) unsigned NOT NULL default '0',"
00479 "    rating tinyint(4) unsigned NOT NULL default '0',"
00480 "    lastplay timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP "
00481 "                       ON UPDATE CURRENT_TIMESTAMP,"
00482 "    date_entered datetime default NULL,"
00483 "    date_modified datetime default NULL,"
00484 "    format varchar(4) NOT NULL default '0',"
00485 "    mythdigest VARCHAR(255),"
00486 "    size BIGINT(20) unsigned,"
00487 "    description VARCHAR(255),"
00488 "    comment VARCHAR(255),"
00489 "    disc_count SMALLINT(5) UNSIGNED DEFAULT '0',"
00490 "    disc_number SMALLINT(5) UNSIGNED DEFAULT '0',"
00491 "    track_count SMALLINT(5) UNSIGNED DEFAULT '0',"
00492 "    start_time INT(10) UNSIGNED DEFAULT '0',"
00493 "    stop_time INT(10) UNSIGNED,"
00494 "    eq_preset VARCHAR(255),"
00495 "    relative_volume TINYINT DEFAULT '0',"
00496 "    sample_rate INT(10) UNSIGNED DEFAULT '0',"
00497 "    bitrate INT(10) UNSIGNED DEFAULT '0',"
00498 "    bpm SMALLINT(5) UNSIGNED,"
00499 "    INDEX idx_name(name),"
00500 "    INDEX idx_mythdigest(mythdigest)"
00501 ");",
00502 "CREATE TABLE music_stats ("
00503 "    num_artists smallint(5) unsigned NOT NULL default '0',"
00504 "    num_albums smallint(5) unsigned NOT NULL default '0',"
00505 "    num_songs mediumint(8) unsigned NOT NULL default '0',"
00506 "    num_genres tinyint(3) unsigned NOT NULL default '0',"
00507 "    total_time varchar(12) NOT NULL default '0',"
00508 "    total_size varchar(10) NOT NULL default '0'"
00509 ");",
00510 "RENAME TABLE smartplaylist TO music_smartplaylists;",
00511 "RENAME TABLE smartplaylistitem TO music_smartplaylist_items;",
00512 "RENAME TABLE smartplaylistcategory TO music_smartplaylist_categories;",
00513 // Run necessary SQL to migrate the table structure
00514 "CREATE TEMPORARY TABLE tmp_artists"
00515 "  SELECT DISTINCT artist FROM musicmetadata;",
00516 "INSERT INTO tmp_artists"
00517 "  SELECT DISTINCT compilation_artist"
00518 "  FROM musicmetadata"
00519 "  WHERE compilation_artist<>artist;",
00520 "INSERT INTO music_artists (artist_name) SELECT DISTINCT artist FROM tmp_artists;",
00521 "INSERT INTO music_albums (artist_id, album_name, year, compilation) "
00522 "  SELECT artist_id, album, ROUND(AVG(year)) AS year, IF(SUM(compilation),1,0) AS compilation"
00523 "  FROM musicmetadata"
00524 "  LEFT JOIN music_artists ON compilation_artist=artist_name"
00525 "  GROUP BY artist_id, album;",
00526 "INSERT INTO music_genres (genre) SELECT DISTINCT genre FROM musicmetadata;",
00527 "INSERT INTO music_songs "
00528 "   (song_id, artist_id, album_id, genre_id, year, lastplay,"
00529 "    date_entered, date_modified, name, track, length, size, numplays,"
00530 "    rating, filename)"
00531 "  SELECT intid, ma.artist_id, mb.album_id, mg.genre_id, mmd.year, lastplay,"
00532 "         date_added, date_modified, title, tracknum, length, IFNULL(size,0), playcount,"
00533 "         rating, filename"
00534 "  FROM musicmetadata AS mmd"
00535 "  LEFT JOIN music_artists AS ma ON mmd.artist=ma.artist_name"
00536 "  LEFT JOIN music_artists AS mc ON mmd.compilation_artist=mc.artist_name"
00537 "  LEFT JOIN music_albums AS mb ON mmd.album=mb.album_name AND mc.artist_id=mb.artist_id"
00538 "  LEFT JOIN music_genres AS mg ON mmd.genre=mg.genre;",
00539 "INSERT INTO music_playlists"
00540 "  (playlist_id,playlist_name,playlist_songs,hostname)"
00541 "  SELECT playlistid, name, songlist, hostname"
00542 "  FROM musicplaylist;",
00543 // Set all real playlists to be global by killing the hostname
00544 "UPDATE music_playlists"
00545 "  SET hostname=''"
00546 "  WHERE playlist_name<>'default_playlist_storage'"
00547 "    AND playlist_name<>'backup_playlist_storage';",
00548 ""
00549 };
00550         if (!performActualUpdate(updates, "1006", dbver))
00551             return false;
00552     }
00553 
00554     if (dbver == "1006")
00555     {
00556         const QString updates[] = {
00557 "ALTER TABLE music_genres MODIFY genre VARCHAR(255) NOT NULL default '';",
00558 ""
00559 };
00560         if (!performActualUpdate(updates, "1007", dbver))
00561             return false;
00562     }
00563 
00564     if (dbver == "1007")
00565     {
00566         const QString updates[] = {
00567 "ALTER TABLE music_songs MODIFY lastplay DATETIME DEFAULT NULL;",
00568 "CREATE TABLE music_directories (directory_id int(20) NOT NULL AUTO_INCREMENT "
00569 "PRIMARY KEY, path TEXT NOT NULL, "
00570 "parent_id INT(20) NOT NULL DEFAULT '0') ;",
00571 "INSERT IGNORE INTO music_directories (path) SELECT DISTINCT"
00572 " SUBSTRING(filename FROM 1 FOR INSTR(filename, "
00573 "SUBSTRING_INDEX(filename, '/', -1))-2) FROM music_songs;",
00574 "CREATE TEMPORARY TABLE tmp_songs SELECT music_songs.*, directory_id "
00575 "FROM music_songs, music_directories WHERE "
00576 "music_directories.path=SUBSTRING(filename FROM 1 FOR "
00577 "INSTR(filename, SUBSTRING_INDEX(filename, '/', -1))-2);",
00578 "UPDATE tmp_songs SET filename=SUBSTRING_INDEX(filename, '/', -1);",
00579 "DELETE FROM music_songs;",
00580 "ALTER TABLE music_songs ADD COLUMN directory_id int(20) NOT NULL DEFAULT '0';",
00581 "INSERT INTO music_songs SELECT * FROM tmp_songs;",
00582 "ALTER TABLE music_songs ADD INDEX (directory_id);",
00583 ""
00584 };
00585 
00586         if (!performActualUpdate(updates, "1008", dbver))
00587             return false;
00588     }
00589 
00590     if (dbver == "1008")
00591     {
00592         const QString updates[] = {
00593 "CREATE TABLE music_albumart (albumart_id int(20) NOT NULL AUTO_INCREMENT "
00594 "PRIMARY KEY, filename VARCHAR(255) NOT NULL DEFAULT '', directory_id INT(20) "
00595 "NOT NULL DEFAULT '0');",
00596 ""
00597 };
00598 
00599         if (!performActualUpdate(updates, "1009", dbver))
00600             return false;
00601     }
00602 
00603     if (dbver == "1009")
00604     {
00605         const QString updates[] = {
00606 "ALTER TABLE music_albumart ADD COLUMN imagetype tinyint(3) NOT NULL DEFAULT '0';",
00607         ""
00608 };
00609 
00610     if (!performActualUpdate(updates, "1010", dbver))
00611         return false;
00612 
00613     // scan though the music_albumart table and make a guess at what
00614     // each image represents from the filename
00615 
00616     LOG(VB_GENERAL, LOG_NOTICE, "Updating music_albumart image types");
00617 
00618     MSqlQuery query(MSqlQuery::InitCon());
00619     query.prepare("SELECT albumart_id, filename, directory_id, imagetype FROM music_albumart;");
00620 
00621     if (query.exec())
00622     {
00623         while (query.next())
00624         {
00625             int id = query.value(0).toInt();
00626             QString filename = query.value(1).toString();
00627             int directoryID = query.value(2).toInt();
00628             int type = IT_UNKNOWN;
00629             MSqlQuery subquery(MSqlQuery::InitCon());
00630 
00631             // guess the type from the filename
00632             type = AlbumArtImages::guessImageType(filename);
00633 
00634             // if type is still unknown check to see how many images are available in the dir
00635             // and assume that if this is the only image it must be the front cover
00636             if (type == IT_UNKNOWN)
00637             {
00638                 subquery.prepare("SELECT count(directory_id) FROM music_albumart "
00639                                  "WHERE directory_id = :DIR;");
00640                 subquery.bindValue(":DIR", directoryID);
00641                 if (!subquery.exec() || !subquery.isActive())
00642                     MythDB::DBError("album art image count", subquery);
00643                 subquery.first();
00644                 if (query.value(0).toInt() == 1)
00645                     type = IT_FRONTCOVER;
00646             }
00647 
00648             // finally set the type in the music_albumart table
00649             subquery.prepare("UPDATE music_albumart "
00650                     "SET imagetype = :TYPE "
00651                     "WHERE albumart_id = :ID;");
00652             subquery.bindValue(":TYPE", type);
00653             subquery.bindValue(":ID", id);
00654             if (!subquery.exec() || !subquery.isActive())
00655                 MythDB::DBError("album art image type update", subquery);
00656         }
00657     }
00658  }
00659 
00660     if (dbver == "1010")
00661     {
00662         const QString updates[] = {"", ""};
00663 
00664         // update the VisualMode setting to the new format
00665         QString setting = gCoreContext->GetSetting("VisualMode");
00666         setting = setting.simplified();
00667         setting = setting.replace(' ', ";");
00668         gCoreContext->SaveSetting("VisualMode", setting);
00669 
00670         if (!performActualUpdate(updates, "1011", dbver))
00671             return false;
00672 
00673     }
00674 
00675     if (dbver == "1011")
00676     {
00677         const QString updates[] = {
00678 "ALTER TABLE music_albumart ADD COLUMN song_id int(11) NOT NULL DEFAULT '0', ADD COLUMN embedded TINYINT(1) NOT NULL DEFAULT '0';",
00679         ""
00680 };
00681 
00682         if (!performActualUpdate(updates, "1012", dbver))
00683             return false;
00684 
00685     }
00686 
00687     if (dbver == "1012")
00688     {
00689         const QString updates[] = {
00690 "ALTER TABLE music_songs ADD INDEX album_id (album_id);",
00691 "ALTER TABLE music_songs ADD INDEX genre_id (genre_id);",
00692 "ALTER TABLE music_songs ADD INDEX artist_id (artist_id);",
00693         ""
00694 };
00695 
00696         if (!performActualUpdate(updates, "1013", dbver))
00697             return false;
00698 
00699     }
00700 
00701     if (dbver == "1013")
00702     {
00703         const QString updates[] = {
00704 "DROP TABLE musicmetadata;",
00705 "DROP TABLE musicplaylist;",
00706 ""
00707 };
00708 
00709         if (!performActualUpdate(updates, "1014", dbver))
00710             return false;
00711     }
00712 
00713     if (dbver == "1014")
00714     {
00715         const QString updates[] = {
00716 QString("ALTER DATABASE %1 DEFAULT CHARACTER SET latin1;")
00717         .arg(gContext->GetDatabaseParams().dbName),
00718 "ALTER TABLE music_albumart"
00719 "  MODIFY filename varbinary(255) NOT NULL default '';",
00720 "ALTER TABLE music_albums"
00721 "  MODIFY album_name varbinary(255) NOT NULL default '';",
00722 "ALTER TABLE music_artists"
00723 "  MODIFY artist_name varbinary(255) NOT NULL default '';",
00724 "ALTER TABLE music_directories"
00725 "  MODIFY path blob NOT NULL;",
00726 "ALTER TABLE music_genres"
00727 "  MODIFY genre varbinary(255) NOT NULL default '';",
00728 "ALTER TABLE music_playlists"
00729 "  MODIFY playlist_name varbinary(255) NOT NULL default '',"
00730 "  MODIFY playlist_songs blob NOT NULL,"
00731 "  MODIFY hostname varbinary(64) NOT NULL default '';",
00732 "ALTER TABLE music_smartplaylist_categories"
00733 "  MODIFY name varbinary(128) NOT NULL;",
00734 "ALTER TABLE music_smartplaylist_items"
00735 "  MODIFY field varbinary(50) NOT NULL,"
00736 "  MODIFY operator varbinary(20) NOT NULL,"
00737 "  MODIFY value1 varbinary(255) NOT NULL,"
00738 "  MODIFY value2 varbinary(255) NOT NULL;",
00739 "ALTER TABLE music_smartplaylists"
00740 "  MODIFY name varbinary(128) NOT NULL,"
00741 "  MODIFY orderby varbinary(128) NOT NULL default '';",
00742 "ALTER TABLE music_songs"
00743 "  MODIFY filename blob NOT NULL,"
00744 "  MODIFY name varbinary(255) NOT NULL default '',"
00745 "  MODIFY format varbinary(4) NOT NULL default '0',"
00746 "  MODIFY mythdigest varbinary(255) default NULL,"
00747 "  MODIFY description varbinary(255) default NULL,"
00748 "  MODIFY comment varbinary(255) default NULL,"
00749 "  MODIFY eq_preset varbinary(255) default NULL;",
00750 "ALTER TABLE music_stats"
00751 "  MODIFY total_time varbinary(12) NOT NULL default '0',"
00752 "  MODIFY total_size varbinary(10) NOT NULL default '0';",
00753 ""
00754 };
00755 
00756         if (!performActualUpdate(updates, "1015", dbver))
00757             return false;
00758     }
00759 
00760 
00761     if (dbver == "1015")
00762     {
00763         const QString updates[] = {
00764 QString("ALTER DATABASE %1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;")
00765         .arg(gContext->GetDatabaseParams().dbName),
00766 "ALTER TABLE music_albumart"
00767 "  DEFAULT CHARACTER SET default,"
00768 "  MODIFY filename varchar(255) CHARACTER SET utf8 NOT NULL default '';",
00769 "ALTER TABLE music_albums"
00770 "  DEFAULT CHARACTER SET default,"
00771 "  MODIFY album_name varchar(255) CHARACTER SET utf8 NOT NULL default '';",
00772 "ALTER TABLE music_artists"
00773 "  DEFAULT CHARACTER SET default,"
00774 "  MODIFY artist_name varchar(255) CHARACTER SET utf8 NOT NULL default '';",
00775 "ALTER TABLE music_directories"
00776 "  DEFAULT CHARACTER SET default,"
00777 "  MODIFY path text CHARACTER SET utf8 NOT NULL;",
00778 "ALTER TABLE music_genres"
00779 "  DEFAULT CHARACTER SET default,"
00780 "  MODIFY genre varchar(255) CHARACTER SET utf8 NOT NULL default '';",
00781 "ALTER TABLE music_playlists"
00782 "  DEFAULT CHARACTER SET default,"
00783 "  MODIFY playlist_name varchar(255) CHARACTER SET utf8 NOT NULL default '',"
00784 "  MODIFY playlist_songs text CHARACTER SET utf8 NOT NULL,"
00785 "  MODIFY hostname varchar(64) CHARACTER SET utf8 NOT NULL default '';",
00786 "ALTER TABLE music_smartplaylist_categories"
00787 "  DEFAULT CHARACTER SET default,"
00788 "  MODIFY name varchar(128) CHARACTER SET utf8 NOT NULL;",
00789 "ALTER TABLE music_smartplaylist_items"
00790 "  DEFAULT CHARACTER SET default,"
00791 "  MODIFY field varchar(50) CHARACTER SET utf8 NOT NULL,"
00792 "  MODIFY operator varchar(20) CHARACTER SET utf8 NOT NULL,"
00793 "  MODIFY value1 varchar(255) CHARACTER SET utf8 NOT NULL,"
00794 "  MODIFY value2 varchar(255) CHARACTER SET utf8 NOT NULL;",
00795 "ALTER TABLE music_smartplaylists"
00796 "  DEFAULT CHARACTER SET default,"
00797 "  MODIFY name varchar(128) CHARACTER SET utf8 NOT NULL,"
00798 "  MODIFY orderby varchar(128) CHARACTER SET utf8 NOT NULL default '';",
00799 "ALTER TABLE music_songs"
00800 "  DEFAULT CHARACTER SET default,"
00801 "  MODIFY filename text CHARACTER SET utf8 NOT NULL,"
00802 "  MODIFY name varchar(255) CHARACTER SET utf8 NOT NULL default '',"
00803 "  MODIFY format varchar(4) CHARACTER SET utf8 NOT NULL default '0',"
00804 "  MODIFY mythdigest varchar(255) CHARACTER SET utf8 default NULL,"
00805 "  MODIFY description varchar(255) CHARACTER SET utf8 default NULL,"
00806 "  MODIFY comment varchar(255) CHARACTER SET utf8 default NULL,"
00807 "  MODIFY eq_preset varchar(255) CHARACTER SET utf8 default NULL;",
00808 "ALTER TABLE music_stats"
00809 "  DEFAULT CHARACTER SET default,"
00810 "  MODIFY total_time varchar(12) CHARACTER SET utf8 NOT NULL default '0',"
00811 "  MODIFY total_size varchar(10) CHARACTER SET utf8 NOT NULL default '0';",
00812 ""
00813 };
00814 
00815         if (!performActualUpdate(updates, "1016", dbver))
00816             return false;
00817     }
00818 
00819     if (dbver == "1016")
00820     {
00821         const QString updates[] = {
00822 "DELETE FROM keybindings "
00823 " WHERE action = 'DELETE' AND context = 'Music';",
00824 ""
00825 };
00826 
00827         if (!performActualUpdate(updates, "1017", dbver))
00828             return false;
00829     }
00830 
00831     if (dbver == "1017")
00832     {
00833         const QString updates[] = {
00834 "ALTER TABLE music_playlists MODIFY COLUMN last_accessed "
00835 "  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;",
00836 ""
00837 };
00838 
00839         if (!performActualUpdate(updates, "1018", dbver))
00840             return false;
00841     }
00842 
00843     if (dbver == "1018")
00844     {
00845         const QString updates[] = {
00846 "CREATE TEMPORARY TABLE arttype_tmp ( type INT, name VARCHAR(30) );",
00847 "INSERT INTO arttype_tmp VALUES (0,'unknown'),(1,'front'),(2,'back'),(3,'cd'),(4,'inlay');",
00848 "UPDATE music_albumart LEFT JOIN arttype_tmp ON type = imagetype "
00849 "SET filename = CONCAT(song_id, '-', name, '.jpg') WHERE embedded=1;",
00850 ""
00851 };
00852 
00853         if (!performActualUpdate(updates, "1019", dbver))
00854             return false;
00855     }
00856 
00857     return true;
00858 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends