MythTV  master
musicdbcheck.cpp
Go to the documentation of this file.
1 // C++
2 #include <iostream>
3 
4 // Qt
5 #include <QString>
6 #include <QDir>
7 #include <QSqlError>
8 
9 // MythTV
10 #include <libmyth/mythcontext.h>
11 #include <libmyth/schemawizard.h>
12 #include <libmythbase/mythdb.h>
15 
16 // MythMusic
17 #include "musicdbcheck.h"
18 
19 const QString currentDatabaseVersion = "1025";
20 const QString MythMusicVersionName = "MusicDBSchemaVer";
21 
22 static bool doUpgradeMusicDatabaseSchema(QString &dbver);
23 
25 {
26 #ifdef IGNORE_SCHEMA_VER_MISMATCH
27  return true;
28 #endif
29  SchemaUpgradeWizard *schema_wizard = nullptr;
30 
31  // Suppress DB messages and turn of the settings cache,
32  // These are likely to confuse the users and the code, respectively.
33  GetMythDB()->SetSuppressDBMessages(true);
35 
36  // Get the schema upgrade lock
38  bool locked = DBUtil::TryLockSchema(query, 1);
39  for (uint i = 0; i < 2*60 && !locked; i++)
40  {
41  LOG(VB_GENERAL, LOG_INFO, "Waiting for database schema upgrade lock");
42  locked = DBUtil::TryLockSchema(query, 1);
43  if (locked)
44  LOG(VB_GENERAL, LOG_INFO, "Got schema upgrade lock");
45  }
46  if (!locked)
47  {
48  LOG(VB_GENERAL, LOG_INFO, "Failed to get schema upgrade lock");
49  goto upgrade_error_exit;
50  }
51 
52  schema_wizard = SchemaUpgradeWizard::Get(
53  "MusicDBSchemaVer", "MythMusic", currentDatabaseVersion);
54 
55  if (schema_wizard->Compare() == 0) // DB schema is what we need it to be..
56  goto upgrade_ok_exit;
57 
58  if (schema_wizard->m_DBver.isEmpty())
59  {
60  // We need to create a database from scratch
61  if (doUpgradeMusicDatabaseSchema(schema_wizard->m_DBver))
62  goto upgrade_ok_exit;
63  else
64  goto upgrade_error_exit;
65  }
66 
67  // Pop up messages, questions, warnings, et c.
68  switch (schema_wizard->PromptForUpgrade("Music", true, false))
69  {
71  goto upgrade_ok_exit;
72  case MYTH_SCHEMA_ERROR:
73  case MYTH_SCHEMA_EXIT:
74  goto upgrade_error_exit;
76  break;
77  }
78 
79  if (!doUpgradeMusicDatabaseSchema(schema_wizard->m_DBver))
80  {
81  LOG(VB_GENERAL, LOG_ERR, "Database schema upgrade failed.");
82  goto upgrade_error_exit;
83  }
84 
85  LOG(VB_GENERAL, LOG_INFO, "MythMusic database schema upgrade complete.");
86 
87  // On any exit we want to re-enable the DB messages so errors
88  // are reported and we want to make sure the setting cache is
89  // enabled for good performance and we must unlock the schema
90  // lock. We use gotos with labels so it's impossible to miss
91  // these steps.
92  upgrade_ok_exit:
93  GetMythDB()->SetSuppressDBMessages(false);
95  if (locked)
96  DBUtil::UnlockSchema(query);
97  return true;
98 
99  upgrade_error_exit:
100  GetMythDB()->SetSuppressDBMessages(false);
102  if (locked)
103  DBUtil::UnlockSchema(query);
104  return false;
105 }
106 
107 
108 static bool doUpgradeMusicDatabaseSchema(QString &dbver)
109 {
110  if (dbver.isEmpty())
111  {
112  LOG(VB_GENERAL, LOG_NOTICE,
113  "Inserting MythMusic initial database information.");
114 
115  DBUpdates updates
116  {
117  "CREATE TABLE IF NOT EXISTS musicmetadata ("
118  " intid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
119  " artist VARCHAR(128) NOT NULL,"
120  " album VARCHAR(128) NOT NULL,"
121  " title VARCHAR(128) NOT NULL,"
122  " genre VARCHAR(128) NOT NULL,"
123  " year INT UNSIGNED NOT NULL,"
124  " tracknum INT UNSIGNED NOT NULL,"
125  " length INT UNSIGNED NOT NULL,"
126  " filename TEXT NOT NULL,"
127  " rating INT UNSIGNED NOT NULL DEFAULT 5,"
128  " lastplay TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP "
129  " ON UPDATE CURRENT_TIMESTAMP,"
130  " playcount INT UNSIGNED NOT NULL DEFAULT 0,"
131  " INDEX (artist),"
132  " INDEX (album),"
133  " INDEX (title),"
134  " INDEX (genre)"
135  ");",
136  "CREATE TABLE IF NOT EXISTS musicplaylist ("
137  " playlistid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
138  " name VARCHAR(128) NOT NULL,"
139  " hostname VARCHAR(255),"
140  " songlist TEXT NOT NULL"
141  ");"
142  };
143 
144  if (!performActualUpdate("MythMusic", MythMusicVersionName,
145  updates, "1000", dbver))
146  return false;
147  }
148 
149  if (dbver == "1000")
150  {
151  QString startdir = gCoreContext->GetSetting("MusicLocation");
152  startdir = QDir::cleanPath(startdir);
153  if (!startdir.endsWith("/"))
154  startdir += "/";
155 
156  MSqlQuery query(MSqlQuery::InitCon());
157  // urls as filenames are NOT officially supported yet
158  if (query.exec("SELECT filename, intid FROM musicmetadata WHERE "
159  "filename NOT LIKE ('%://%');"))
160  {
161  int i = 0;
162  QString intid;
163  QString name;
164  QString newname;
165 
166  MSqlQuery modify(MSqlQuery::InitCon());
167  while (query.next())
168  {
169  name = query.value(0).toString();
170  newname = name;
171  intid = query.value(1).toString();
172 
173  if (newname.startsWith(startdir))
174  {
175  newname.remove(0, startdir.length());
176  if (modify.exec(QString("UPDATE musicmetadata SET "
177  "filename = \"%1\" "
178  "WHERE filename = \"%2\" AND intid = %3;")
179  .arg(newname, name, intid)))
180  i += modify.numRowsAffected();
181  }
182  }
183  LOG(VB_GENERAL, LOG_NOTICE,
184  QString("Modified %1 entries for db schema 1001").arg(i));
185  }
186 
187  if (!UpdateDBVersionNumber("MythMusic", MythMusicVersionName, "1001", dbver))
188  return false;
189  }
190 
191  if (dbver == "1001")
192  {
193  DBUpdates updates
194  {
195  "ALTER TABLE musicmetadata ADD mythdigest VARCHAR(255);",
196  "ALTER TABLE musicmetadata ADD size BIGINT UNSIGNED;",
197  "ALTER TABLE musicmetadata ADD date_added DATETIME;",
198  "ALTER TABLE musicmetadata ADD date_modified DATETIME;",
199  "ALTER TABLE musicmetadata ADD format VARCHAR(4);",
200  "ALTER TABLE musicmetadata ADD description VARCHAR(255);",
201  "ALTER TABLE musicmetadata ADD comment VARCHAR(255);",
202  "ALTER TABLE musicmetadata ADD compilation TINYINT DEFAULT 0;",
203  "ALTER TABLE musicmetadata ADD composer VARCHAR(255);",
204  "ALTER TABLE musicmetadata ADD disc_count SMALLINT UNSIGNED DEFAULT 0;",
205  "ALTER TABLE musicmetadata ADD disc_number SMALLINT UNSIGNED DEFAULT 0;",
206  "ALTER TABLE musicmetadata ADD track_count SMALLINT UNSIGNED DEFAULT 0;",
207  "ALTER TABLE musicmetadata ADD start_time INT UNSIGNED DEFAULT 0;",
208  "ALTER TABLE musicmetadata ADD stop_time INT UNSIGNED;",
209  "ALTER TABLE musicmetadata ADD eq_preset VARCHAR(255);",
210  "ALTER TABLE musicmetadata ADD relative_volume TINYINT DEFAULT 0;",
211  "ALTER TABLE musicmetadata ADD sample_rate INT UNSIGNED;",
212  "ALTER TABLE musicmetadata ADD bpm SMALLINT UNSIGNED;",
213  "ALTER TABLE musicmetadata ADD INDEX (mythdigest);"
214  };
215 
216  if (!performActualUpdate("MythMusic", MythMusicVersionName,
217  updates, "1002", dbver))
218  return false;
219  }
220 
221  if (dbver == "1002")
222  {
223  LOG(VB_GENERAL, LOG_NOTICE,
224  "Updating music metadata to be UTF-8 in the database");
225 
226  MSqlQuery query(MSqlQuery::InitCon());
227  query.prepare("SELECT intid, artist, album, title, genre, "
228  "filename FROM musicmetadata ORDER BY intid;");
229 
230  if (query.exec() && query.isActive() && query.size() > 0)
231  {
232  while (query.next())
233  {
234  int id = query.value(0).toInt();
235  QString artist = query.value(1).toString();
236  QString album = query.value(2).toString();
237  QString title = query.value(3).toString();
238  QString genre = query.value(4).toString();
239  QString filename = query.value(5).toString();
240 
241  MSqlQuery subquery(MSqlQuery::InitCon());
242  subquery.prepare("UPDATE musicmetadata SET "
243  "artist = :ARTIST, album = :ALBUM, "
244  "title = :TITLE, genre = :GENRE, "
245  "filename = :FILENAME "
246  "WHERE intid = :ID;");
247  subquery.bindValue(":ARTIST", QString(artist.toUtf8()));
248  subquery.bindValue(":ALBUM", QString(album.toUtf8()));
249  subquery.bindValue(":TITLE", QString(title.toUtf8()));
250  subquery.bindValue(":GENRE", QString(genre.toUtf8()));
251  subquery.bindValue(":FILENAME", QString(filename.toUtf8()));
252  subquery.bindValue(":ID", id);
253 
254  if (!subquery.exec() || !subquery.isActive())
255  MythDB::DBError("music utf8 update", subquery);
256  }
257  }
258 
259  query.prepare("SELECT playlistid, name FROM musicplaylist "
260  "ORDER BY playlistid;");
261 
262  if (query.exec() && query.isActive() && query.size() > 0)
263  {
264  while (query.next())
265  {
266  int id = query.value(0).toInt();
267  QString name = query.value(1).toString();
268 
269  MSqlQuery subquery(MSqlQuery::InitCon());
270  subquery.prepare("UPDATE musicplaylist SET "
271  "name = :NAME WHERE playlistid = :ID ;");
272  subquery.bindValue(":NAME", QString(name.toUtf8()));
273  subquery.bindValue(":ID", id);
274 
275  if (!subquery.exec() || !subquery.isActive())
276  MythDB::DBError("music playlist utf8 update", subquery);
277  }
278  }
279 
280  LOG(VB_GENERAL, LOG_NOTICE, "Done updating music metadata to UTF-8");
281 
282  if (!UpdateDBVersionNumber("MythMusic", MythMusicVersionName, "1003", dbver))
283  return false;
284  }
285 
286  if (dbver == "1003")
287  {
288  DBUpdates updates
289  {
290  "DROP TABLE IF EXISTS smartplaylistcategory;",
291  "CREATE TABLE smartplaylistcategory ("
292  " categoryid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
293  " name VARCHAR(128) NOT NULL,"
294  " INDEX (name)"
295  ");",
296 
297  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
298  "INSERT INTO smartplaylistcategory SET categoryid = 1, "
299  " name = \"Decades\";",
300  "INSERT INTO smartplaylistcategory SET categoryid = 2, "
301  " name = \"Favourite Tracks\";",
302  "INSERT INTO smartplaylistcategory SET categoryid = 3, "
303  " name = \"New Tracks\";",
304 
305  "DROP TABLE IF EXISTS smartplaylist;",
306  "CREATE TABLE smartplaylist ("
307  " smartplaylistid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
308  " name VARCHAR(128) NOT NULL,"
309  " categoryid INT UNSIGNED NOT NULL,"
310  " matchtype SET('All', 'Any') NOT NULL DEFAULT 'All',"
311  " orderby VARCHAR(128) NOT NULL DEFAULT '',"
312  " limitto INT UNSIGNED NOT NULL DEFAULT 0,"
313  " INDEX (name),"
314  " INDEX (categoryid)"
315  ");",
316  "DROP TABLE IF EXISTS smartplaylistitem;",
317  "CREATE TABLE smartplaylistitem ("
318  " smartplaylistitemid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
319  " smartplaylistid INT UNSIGNED NOT NULL,"
320  " field VARCHAR(50) NOT NULL,"
321  " operator VARCHAR(20) NOT NULL,"
322  " value1 VARCHAR(255) NOT NULL,"
323  " value2 VARCHAR(255) NOT NULL,"
324  " INDEX (smartplaylistid)"
325  ");",
326  "INSERT INTO smartplaylist SET smartplaylistid = 1, name = \"1960's\", "
327  " categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
328  " limitto = 0;",
329  "INSERT INTO smartplaylistitem SET smartplaylistid = 1, field = \"Year\","
330  " operator = \"is between\", value1 = \"1960\", value2 = \"1969\";",
331 
332  "INSERT INTO smartplaylist SET smartplaylistid = 2, name = \"1970's\", "
333  " categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
334  " limitto = 0;",
335  "INSERT INTO smartplaylistitem SET smartplaylistid = 2, field = \"Year\","
336  " operator = \"is between\", value1 = \"1970\", value2 = \"1979\";",
337 
338  "INSERT INTO smartplaylist SET smartplaylistid = 3, name = \"1980's\", "
339  " categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
340  " limitto = 0;",
341  "INSERT INTO smartplaylistitem SET smartplaylistid = 3, field = \"Year\","
342  " operator = \"is between\", value1 = \"1980\", value2 = \"1989\";",
343 
344  "INSERT INTO smartplaylist SET smartplaylistid = 4, name = \"1990's\", "
345  " categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
346  " limitto = 0;",
347  "INSERT INTO smartplaylistitem SET smartplaylistid = 4, field = \"Year\","
348  " operator = \"is between\", value1 = \"1990\", value2 = \"1999\";",
349 
350  "INSERT INTO smartplaylist SET smartplaylistid = 5, name = \"2000's\", "
351  " categoryid = 1, matchtype = \"All\", orderby = \"Artist (A)\","
352  " limitto = 0;",
353  "INSERT INTO smartplaylistitem SET smartplaylistid = 5, field = \"Year\","
354  " operator = \"is between\", value1 = \"2000\", value2 = \"2009\";",
355 
356  "INSERT INTO smartplaylist SET smartplaylistid = 6, name = \"Favorite Tracks\", "
357  " categoryid = 2, matchtype = \"All\","
358  " orderby = \"Artist (A), Album (A)\", limitto = 0;",
359  "INSERT INTO smartplaylistitem SET smartplaylistid = 6, field = \"Rating\","
360  " operator = \"is greater than\", value1 = \"7\", value2 = \"0\";",
361 
362  "INSERT INTO smartplaylist SET smartplaylistid = 7, name = \"100 Most Played Tracks\", "
363  " categoryid = 2, matchtype = \"All\", orderby = \"Play Count (D)\","
364  " limitto = 100;",
365  "INSERT INTO smartplaylistitem SET smartplaylistid = 7, field = \"Play Count\","
366  " operator = \"is greater than\", value1 = \"0\", value2 = \"0\";",
367 
368  "INSERT INTO smartplaylist SET smartplaylistid = 8, name = \"Never Played Tracks\", "
369  " categoryid = 3, matchtype = \"All\", orderby = \"Artist (A), Album (A)\","
370  " limitto = 0;",
371  "INSERT INTO smartplaylistitem SET smartplaylistid = 8, field = \"Play Count\","
372  " operator = \"is equal to\", value1 = \"0\", value2 = \"0\";"
373  };
374 
375  if (!performActualUpdate("MythMusic", MythMusicVersionName,
376  updates, "1004", dbver))
377  return false;
378  }
379 
380  if (dbver == "1004")
381  {
382  DBUpdates updates
383  {
384  "ALTER TABLE musicmetadata ADD compilation_artist VARCHAR(128) NOT NULL AFTER artist;",
385  "ALTER TABLE musicmetadata ADD INDEX (compilation_artist);"
386  };
387 
388  if (!performActualUpdate("MythMusic", MythMusicVersionName,
389  updates, "1005", dbver))
390  return false;
391  }
392 
393 
394  if (dbver == "1005")
395  {
396  DBUpdates updates
397  {
398  "CREATE TABLE music_albums ("
399  " album_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
400  " artist_id int(11) unsigned NOT NULL default '0',"
401  " album_name varchar(255) NOT NULL default '',"
402  " year smallint(6) NOT NULL default '0',"
403  " compilation tinyint(1) unsigned NOT NULL default '0',"
404  " INDEX idx_album_name(album_name)"
405  ");",
406  "CREATE TABLE music_artists ("
407  " artist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
408  " artist_name varchar(255) NOT NULL default '',"
409  " INDEX idx_artist_name(artist_name)"
410  ");",
411  "CREATE TABLE music_genres ("
412  " genre_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
413  " genre varchar(25) NOT NULL default '',"
414  " INDEX idx_genre(genre)"
415  ");",
416  "CREATE TABLE music_playlists ("
417  " playlist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
418  " playlist_name varchar(255) NOT NULL default '',"
419  " playlist_songs text NOT NULL,"
420  " last_accessed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP "
421  " ON UPDATE CURRENT_TIMESTAMP,"
422  " length int(11) unsigned NOT NULL default '0',"
423  " songcount smallint(8) unsigned NOT NULL default '0',"
424  " hostname VARCHAR(255) NOT NULL default ''"
425  ");",
426  "CREATE TABLE music_songs ("
427  " song_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
428  " filename text NOT NULL,"
429  " name varchar(255) NOT NULL default '',"
430  " track smallint(6) unsigned NOT NULL default '0',"
431  " artist_id int(11) unsigned NOT NULL default '0',"
432  " album_id int(11) unsigned NOT NULL default '0',"
433  " genre_id int(11) unsigned NOT NULL default '0',"
434  " year smallint(6) NOT NULL default '0',"
435  " length int(11) unsigned NOT NULL default '0',"
436  " numplays int(11) unsigned NOT NULL default '0',"
437  " rating tinyint(4) unsigned NOT NULL default '0',"
438  " lastplay timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP "
439  " ON UPDATE CURRENT_TIMESTAMP,"
440  " date_entered datetime default NULL,"
441  " date_modified datetime default NULL,"
442  " format varchar(4) NOT NULL default '0',"
443  " mythdigest VARCHAR(255),"
444  " size BIGINT(20) unsigned,"
445  " description VARCHAR(255),"
446  " comment VARCHAR(255),"
447  " disc_count SMALLINT(5) UNSIGNED DEFAULT '0',"
448  " disc_number SMALLINT(5) UNSIGNED DEFAULT '0',"
449  " track_count SMALLINT(5) UNSIGNED DEFAULT '0',"
450  " start_time INT(10) UNSIGNED DEFAULT '0',"
451  " stop_time INT(10) UNSIGNED,"
452  " eq_preset VARCHAR(255),"
453  " relative_volume TINYINT DEFAULT '0',"
454  " sample_rate INT(10) UNSIGNED DEFAULT '0',"
455  " bitrate INT(10) UNSIGNED DEFAULT '0',"
456  " bpm SMALLINT(5) UNSIGNED,"
457  " INDEX idx_name(name),"
458  " INDEX idx_mythdigest(mythdigest)"
459  ");",
460  "CREATE TABLE music_stats ("
461  " num_artists smallint(5) unsigned NOT NULL default '0',"
462  " num_albums smallint(5) unsigned NOT NULL default '0',"
463  " num_songs mediumint(8) unsigned NOT NULL default '0',"
464  " num_genres tinyint(3) unsigned NOT NULL default '0',"
465  " total_time varchar(12) NOT NULL default '0',"
466  " total_size varchar(10) NOT NULL default '0'"
467  ");",
468  "RENAME TABLE smartplaylist TO music_smartplaylists;",
469  "RENAME TABLE smartplaylistitem TO music_smartplaylist_items;",
470  "RENAME TABLE smartplaylistcategory TO music_smartplaylist_categories;",
471  // Run necessary SQL to migrate the table structure
472  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
473  "CREATE TEMPORARY TABLE tmp_artists"
474  " SELECT DISTINCT artist FROM musicmetadata;",
475  "INSERT INTO tmp_artists"
476  " SELECT DISTINCT compilation_artist"
477  " FROM musicmetadata"
478  " WHERE compilation_artist<>artist;",
479  "INSERT INTO music_artists (artist_name) SELECT DISTINCT artist FROM tmp_artists;",
480  "INSERT INTO music_albums (artist_id, album_name, year, compilation) "
481  " SELECT artist_id, album, ROUND(AVG(year)) AS year, IF(SUM(compilation),1,0) AS compilation"
482  " FROM musicmetadata"
483  " LEFT JOIN music_artists ON compilation_artist=artist_name"
484  " GROUP BY artist_id, album;",
485  "INSERT INTO music_genres (genre) SELECT DISTINCT genre FROM musicmetadata;",
486  "INSERT INTO music_songs "
487  " (song_id, artist_id, album_id, genre_id, year, lastplay,"
488  " date_entered, date_modified, name, track, length, size, numplays,"
489  " rating, filename)"
490  " SELECT intid, ma.artist_id, mb.album_id, mg.genre_id, mmd.year, lastplay,"
491  " date_added, date_modified, title, tracknum, length, IFNULL(size,0), playcount,"
492  " rating, filename"
493  " FROM musicmetadata AS mmd"
494  " LEFT JOIN music_artists AS ma ON mmd.artist=ma.artist_name"
495  " LEFT JOIN music_artists AS mc ON mmd.compilation_artist=mc.artist_name"
496  " LEFT JOIN music_albums AS mb ON mmd.album=mb.album_name AND mc.artist_id=mb.artist_id"
497  " LEFT JOIN music_genres AS mg ON mmd.genre=mg.genre;",
498  "INSERT INTO music_playlists"
499  " (playlist_id,playlist_name,playlist_songs,hostname)"
500  " SELECT playlistid, name, songlist, hostname"
501  " FROM musicplaylist;",
502  // Set all real playlists to be global by killing the hostname
503  "UPDATE music_playlists"
504  " SET hostname=''"
505  " WHERE playlist_name<>'default_playlist_storage'"
506  " AND playlist_name<>'backup_playlist_storage';"
507  };
508 
509  if (!performActualUpdate("MythMusic", MythMusicVersionName,
510  updates, "1006", dbver))
511  return false;
512  }
513 
514  if (dbver == "1006")
515  {
516  DBUpdates updates
517  {
518  "ALTER TABLE music_genres MODIFY genre VARCHAR(255) NOT NULL default '';"
519  };
520 
521  if (!performActualUpdate("MythMusic", MythMusicVersionName,
522  updates, "1007", dbver))
523  return false;
524  }
525 
526  if (dbver == "1007")
527  {
528  DBUpdates updates
529  {
530  "ALTER TABLE music_songs MODIFY lastplay DATETIME DEFAULT NULL;",
531  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
532  "CREATE TABLE music_directories (directory_id int(20) NOT NULL AUTO_INCREMENT "
533  "PRIMARY KEY, path TEXT NOT NULL, "
534  "parent_id INT(20) NOT NULL DEFAULT '0') ;",
535  "INSERT IGNORE INTO music_directories (path) SELECT DISTINCT"
536  " SUBSTRING(filename FROM 1 FOR INSTR(filename, "
537  "SUBSTRING_INDEX(filename, '/', -1))-2) FROM music_songs;",
538  "CREATE TEMPORARY TABLE tmp_songs SELECT music_songs.*, directory_id "
539  "FROM music_songs, music_directories WHERE "
540  "music_directories.path=SUBSTRING(filename FROM 1 FOR "
541  "INSTR(filename, SUBSTRING_INDEX(filename, '/', -1))-2);",
542  "UPDATE tmp_songs SET filename=SUBSTRING_INDEX(filename, '/', -1);",
543  "DELETE FROM music_songs;",
544  "ALTER TABLE music_songs ADD COLUMN directory_id int(20) NOT NULL DEFAULT '0';",
545  "INSERT INTO music_songs SELECT * FROM tmp_songs;",
546  "ALTER TABLE music_songs ADD INDEX (directory_id);"
547  };
548 
549  if (!performActualUpdate("MythMusic", MythMusicVersionName,
550  updates, "1008", dbver))
551  return false;
552  }
553 
554  if (dbver == "1008")
555  {
556  DBUpdates updates
557  {
558  "CREATE TABLE music_albumart (albumart_id int(20) NOT NULL AUTO_INCREMENT "
559  "PRIMARY KEY, filename VARCHAR(255) NOT NULL DEFAULT '', directory_id INT(20) "
560  "NOT NULL DEFAULT '0');"
561  };
562 
563  if (!performActualUpdate("MythMusic", MythMusicVersionName,
564  updates, "1009", dbver))
565  return false;
566  }
567 
568  if (dbver == "1009")
569  {
570  DBUpdates updates
571  {
572  "ALTER TABLE music_albumart ADD COLUMN imagetype tinyint(3) NOT NULL DEFAULT '0';"
573  };
574 
575  if (!performActualUpdate("MythMusic", MythMusicVersionName,
576  updates, "1010", dbver))
577  return false;
578 
579  // scan though the music_albumart table and make a guess at what
580  // each image represents from the filename
581 
582  LOG(VB_GENERAL, LOG_NOTICE, "Updating music_albumart image types");
583 
584  MSqlQuery query(MSqlQuery::InitCon());
585  query.prepare("SELECT albumart_id, filename, directory_id, imagetype FROM music_albumart;");
586 
587  if (query.exec())
588  {
589  while (query.next())
590  {
591  int id = query.value(0).toInt();
592  QString filename = query.value(1).toString();
593  int directoryID = query.value(2).toInt();
594  MSqlQuery subquery(MSqlQuery::InitCon());
595 
596  // guess the type from the filename
598 
599  // if type is still unknown check to see how many images are available in the dir
600  // and assume that if this is the only image it must be the front cover
601  if (type == IT_UNKNOWN)
602  {
603  subquery.prepare("SELECT count(directory_id) FROM music_albumart "
604  "WHERE directory_id = :DIR;");
605  subquery.bindValue(":DIR", directoryID);
606  if (!subquery.exec() || !subquery.isActive())
607  MythDB::DBError("album art image count", subquery);
608  subquery.first();
609  if (query.value(0).toInt() == 1)
611  }
612 
613  // finally set the type in the music_albumart table
614  subquery.prepare("UPDATE music_albumart "
615  "SET imagetype = :TYPE "
616  "WHERE albumart_id = :ID;");
617  subquery.bindValue(":TYPE", type);
618  subquery.bindValue(":ID", id);
619  if (!subquery.exec() || !subquery.isActive())
620  MythDB::DBError("album art image type update", subquery);
621  }
622  }
623  }
624 
625  if (dbver == "1010")
626  {
627  // update the VisualMode setting to the new format
628  QString setting = gCoreContext->GetSetting("VisualMode");
629  setting = setting.simplified();
630  setting = setting.replace(' ', ";");
631  gCoreContext->SaveSetting("VisualMode", setting);
632 
633  if (!UpdateDBVersionNumber("MythMusic", MythMusicVersionName, "1011", dbver))
634  return false;
635 
636  }
637 
638  if (dbver == "1011")
639  {
640  DBUpdates updates
641  {
642  "ALTER TABLE music_albumart ADD COLUMN song_id int(11) NOT NULL DEFAULT '0', "
643  " ADD COLUMN embedded TINYINT(1) NOT NULL DEFAULT '0';"
644  };
645 
646  if (!performActualUpdate("MythMusic", MythMusicVersionName,
647  updates, "1012", dbver))
648  return false;
649 
650  }
651 
652  if (dbver == "1012")
653  {
654  DBUpdates updates
655  {
656  "ALTER TABLE music_songs ADD INDEX album_id (album_id);",
657  "ALTER TABLE music_songs ADD INDEX genre_id (genre_id);",
658  "ALTER TABLE music_songs ADD INDEX artist_id (artist_id);"
659  };
660 
661  if (!performActualUpdate("MythMusic", MythMusicVersionName,
662  updates, "1013", dbver))
663  return false;
664 
665  }
666 
667  if (dbver == "1013")
668  {
669  DBUpdates updates
670  {
671  "DROP TABLE musicmetadata;",
672  "DROP TABLE musicplaylist;"
673  };
674 
675  if (!performActualUpdate("MythMusic", MythMusicVersionName,
676  updates, "1014", dbver))
677  return false;
678  }
679 
680  if (dbver == "1014")
681  {
682  DBUpdates updates
683  {
684  qPrintable(QString("ALTER DATABASE %1 DEFAULT CHARACTER SET latin1;")
685  .arg(GetMythDB()->GetDatabaseName())),
686  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
687  "ALTER TABLE music_albumart"
688  " MODIFY filename varbinary(255) NOT NULL default '';",
689  "ALTER TABLE music_albums"
690  " MODIFY album_name varbinary(255) NOT NULL default '';",
691  "ALTER TABLE music_artists"
692  " MODIFY artist_name varbinary(255) NOT NULL default '';",
693  "ALTER TABLE music_directories"
694  " MODIFY path blob NOT NULL;",
695  "ALTER TABLE music_genres"
696  " MODIFY genre varbinary(255) NOT NULL default '';",
697  "ALTER TABLE music_playlists"
698  " MODIFY playlist_name varbinary(255) NOT NULL default '',"
699  " MODIFY playlist_songs blob NOT NULL,"
700  " MODIFY hostname varbinary(64) NOT NULL default '';",
701  "ALTER TABLE music_smartplaylist_categories"
702  " MODIFY name varbinary(128) NOT NULL;",
703  "ALTER TABLE music_smartplaylist_items"
704  " MODIFY field varbinary(50) NOT NULL,"
705  " MODIFY operator varbinary(20) NOT NULL,"
706  " MODIFY value1 varbinary(255) NOT NULL,"
707  " MODIFY value2 varbinary(255) NOT NULL;",
708  "ALTER TABLE music_smartplaylists"
709  " MODIFY name varbinary(128) NOT NULL,"
710  " MODIFY orderby varbinary(128) NOT NULL default '';",
711  "ALTER TABLE music_songs"
712  " MODIFY filename blob NOT NULL,"
713  " MODIFY name varbinary(255) NOT NULL default '',"
714  " MODIFY format varbinary(4) NOT NULL default '0',"
715  " MODIFY mythdigest varbinary(255) default NULL,"
716  " MODIFY description varbinary(255) default NULL,"
717  " MODIFY comment varbinary(255) default NULL,"
718  " MODIFY eq_preset varbinary(255) default NULL;",
719  "ALTER TABLE music_stats"
720  " MODIFY total_time varbinary(12) NOT NULL default '0',"
721  " MODIFY total_size varbinary(10) NOT NULL default '0';"
722  };
723 
724  if (!performActualUpdate("MythMusic", MythMusicVersionName,
725  updates, "1015", dbver))
726  return false;
727  }
728 
729 
730  if (dbver == "1015")
731  {
732  DBUpdates updates
733  {
734  qPrintable(QString("ALTER DATABASE %1 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;")
735  .arg(GetMythDB()->GetDatabaseName())),
736  // NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
737  "ALTER TABLE music_albumart"
738  " DEFAULT CHARACTER SET utf8,"
739  " MODIFY filename varchar(255) CHARACTER SET utf8 NOT NULL default '';",
740  "ALTER TABLE music_albums"
741  " DEFAULT CHARACTER SET utf8,"
742  " MODIFY album_name varchar(255) CHARACTER SET utf8 NOT NULL default '';",
743  "ALTER TABLE music_artists"
744  " DEFAULT CHARACTER SET utf8,"
745  " MODIFY artist_name varchar(255) CHARACTER SET utf8 NOT NULL default '';",
746  "ALTER TABLE music_directories"
747  " DEFAULT CHARACTER SET utf8,"
748  " MODIFY path text CHARACTER SET utf8 NOT NULL;",
749  "ALTER TABLE music_genres"
750  " DEFAULT CHARACTER SET utf8,"
751  " MODIFY genre varchar(255) CHARACTER SET utf8 NOT NULL default '';",
752  "ALTER TABLE music_playlists"
753  " DEFAULT CHARACTER SET utf8,"
754  " MODIFY playlist_name varchar(255) CHARACTER SET utf8 NOT NULL default '',"
755  " MODIFY playlist_songs text CHARACTER SET utf8 NOT NULL,"
756  " MODIFY hostname varchar(64) CHARACTER SET utf8 NOT NULL default '';",
757  "ALTER TABLE music_smartplaylist_categories"
758  " DEFAULT CHARACTER SET utf8,"
759  " MODIFY name varchar(128) CHARACTER SET utf8 NOT NULL;",
760  "ALTER TABLE music_smartplaylist_items"
761  " DEFAULT CHARACTER SET utf8,"
762  " MODIFY field varchar(50) CHARACTER SET utf8 NOT NULL,"
763  " MODIFY operator varchar(20) CHARACTER SET utf8 NOT NULL,"
764  " MODIFY value1 varchar(255) CHARACTER SET utf8 NOT NULL,"
765  " MODIFY value2 varchar(255) CHARACTER SET utf8 NOT NULL;",
766  "ALTER TABLE music_smartplaylists"
767  " DEFAULT CHARACTER SET utf8,"
768  " MODIFY name varchar(128) CHARACTER SET utf8 NOT NULL,"
769  " MODIFY orderby varchar(128) CHARACTER SET utf8 NOT NULL default '';",
770  "ALTER TABLE music_songs"
771  " DEFAULT CHARACTER SET utf8,"
772  " MODIFY filename text CHARACTER SET utf8 NOT NULL,"
773  " MODIFY name varchar(255) CHARACTER SET utf8 NOT NULL default '',"
774  " MODIFY format varchar(4) CHARACTER SET utf8 NOT NULL default '0',"
775  " MODIFY mythdigest varchar(255) CHARACTER SET utf8 default NULL,"
776  " MODIFY description varchar(255) CHARACTER SET utf8 default NULL,"
777  " MODIFY comment varchar(255) CHARACTER SET utf8 default NULL,"
778  " MODIFY eq_preset varchar(255) CHARACTER SET utf8 default NULL;",
779  "ALTER TABLE music_stats"
780  " DEFAULT CHARACTER SET utf8,"
781  " MODIFY total_time varchar(12) CHARACTER SET utf8 NOT NULL default '0',"
782  " MODIFY total_size varchar(10) CHARACTER SET utf8 NOT NULL default '0';"
783  };
784 
785  if (!performActualUpdate("MythMusic", MythMusicVersionName,
786  updates, "1016", dbver))
787  return false;
788  }
789 
790  if (dbver == "1016")
791  {
792  DBUpdates updates
793  {
794  "DELETE FROM keybindings "
795  " WHERE action = 'DELETE' AND context = 'Music';"
796  };
797 
798  if (!performActualUpdate("MythMusic", MythMusicVersionName,
799  updates, "1017", dbver))
800  return false;
801  }
802 
803  if (dbver == "1017")
804  {
805  DBUpdates updates
806  {
807  "ALTER TABLE music_playlists MODIFY COLUMN last_accessed "
808  " TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;"
809  };
810 
811  if (!performActualUpdate("MythMusic", MythMusicVersionName,
812  updates, "1018", dbver))
813  return false;
814  }
815 
816  if (dbver == "1018")
817  {
818  DBUpdates updates
819  {
820  "CREATE TEMPORARY TABLE arttype_tmp ( type INT, name VARCHAR(30) );",
821  "INSERT INTO arttype_tmp VALUES (0,'unknown'),(1,'front'),(2,'back'),(3,'cd'),(4,'inlay');",
822  "UPDATE music_albumart LEFT JOIN arttype_tmp ON type = imagetype "
823  "SET filename = CONCAT(song_id, '-', name, '.jpg') WHERE embedded=1;"
824  };
825 
826  if (!performActualUpdate("MythMusic", MythMusicVersionName,
827  updates, "1019", dbver))
828  return false;
829  }
830 
831  if (dbver == "1019")
832  {
833  DBUpdates updates
834  {
835  "DROP TABLE IF EXISTS music_radios;",
836  "CREATE TABLE music_radios ("
837  " intid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
838  " station VARCHAR(128) NOT NULL,"
839  " channel VARCHAR(128) NOT NULL,"
840  " url VARCHAR(128) NOT NULL,"
841  " logourl VARCHAR(128) NOT NULL,"
842  " genre VARCHAR(128) NOT NULL,"
843  " metaformat VARCHAR(128) NOT NULL,"
844  " format VARCHAR(10) NOT NULL,"
845  " INDEX (station),"
846  " INDEX (channel)"
847  ");"
848  };
849 
850  if (!performActualUpdate("MythMusic", MythMusicVersionName,
851  updates, "1020", dbver))
852  return false;
853  }
854 
855  if (dbver == "1020")
856  {
857  DBUpdates updates
858  {
859  "ALTER TABLE music_songs ADD COLUMN hostname VARCHAR(255) NOT NULL default '';",
860  qPrintable(QString("UPDATE music_songs SET hostname = '%1';")
862  };
863 
864  if (!performActualUpdate("MythMusic", MythMusicVersionName,
865  updates, "1021", dbver))
866  return false;
867  }
868 
869  if (dbver == "1021")
870  {
871  DBUpdates updates
872  {
873  "ALTER TABLE music_albumart ADD COLUMN hostname VARCHAR(255) NOT NULL default '';",
874  qPrintable(QString("UPDATE music_albumart SET hostname = '%1';")
876  };
877 
878  if (!performActualUpdate("MythMusic", MythMusicVersionName,
879  updates, "1022", dbver))
880  return false;
881  }
882 
883  if (dbver == "1022")
884  {
885  DBUpdates updates
886  {
887  "CREATE INDEX `song_id` ON music_albumart (song_id);",
888  "CREATE INDEX `artist_id` ON music_albums (artist_id);"
889  };
890 
891  if (!performActualUpdate("MythMusic", MythMusicVersionName,
892  updates, "1023", dbver))
893  return false;
894  }
895 
896  if (dbver == "1023")
897  {
898  DBUpdates updates
899  {
900  "DROP INDEX station ON music_radios;",
901  "ALTER TABLE music_radios CHANGE COLUMN station broadcaster VARCHAR(100) NOT NULL default '';",
902  "ALTER TABLE music_radios MODIFY COLUMN channel VARCHAR(200) NOT NULL default '';",
903  "ALTER TABLE music_radios ADD description TEXT NOT NULL default '' AFTER channel;",
904  "ALTER TABLE music_radios CHANGE COLUMN url url1 VARCHAR(300) NOT NULL default '';",
905  "ALTER TABLE music_radios ADD COLUMN url2 VARCHAR(300) NOT NULL default '' AFTER url1;",
906  "ALTER TABLE music_radios ADD COLUMN url3 VARCHAR(300) NOT NULL default '' AFTER url2;",
907  "ALTER TABLE music_radios ADD COLUMN url4 VARCHAR(300) NOT NULL default '' AFTER url3;",
908  "ALTER TABLE music_radios ADD COLUMN url5 VARCHAR(300) NOT NULL default '' AFTER url4;",
909  "ALTER TABLE music_radios MODIFY COLUMN logourl VARCHAR(300) NOT NULL default '';",
910  "ALTER TABLE music_radios MODIFY COLUMN metaformat VARCHAR(50) NOT NULL default '';",
911  "ALTER TABLE music_radios ADD COLUMN country VARCHAR(50) NOT NULL default '' AFTER logourl;",
912  "ALTER TABLE music_radios ADD COLUMN language VARCHAR(50) NOT NULL default '' AFTER country;",
913  "CREATE INDEX broadcaster ON music_radios (broadcaster);",
914  "DROP TABLE IF EXISTS music_streams;",
915  "CREATE TABLE music_streams ("
916  " intid INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,"
917  " broadcaster VARCHAR(100) NOT NULL default '',"
918  " channel VARCHAR(200) NOT NULL default '',"
919  " description TEXT NOT NULL default '',"
920  " url1 VARCHAR(300) NOT NULL default '',"
921  " url2 VARCHAR(300) NOT NULL default '',"
922  " url3 VARCHAR(300) NOT NULL default '',"
923  " url4 VARCHAR(300) NOT NULL default '',"
924  " url5 VARCHAR(300) NOT NULL default '',"
925  " logourl VARCHAR(300) NOT NULL default '',"
926  " genre VARCHAR(100) NOT NULL default '',"
927  " metaformat VARCHAR(50) NOT NULL default '',"
928  " country VARCHAR(50) NOT NULL default '',"
929  " language VARCHAR(50) NOT NULL default '',"
930  " INDEX (broadcaster),"
931  " INDEX (channel),"
932  " INDEX (country),"
933  " INDEX (language)"
934  ");"
935  };
936 
937  if (!performActualUpdate("MythMusic", MythMusicVersionName,
938  updates, "1024", dbver))
939  return false;
940  }
941 
942  // Repeat 1016 DBs pre MySQL v8 systems that may have not be set to utf8
943 
944  if (dbver == "1024")
945  {
946  DBUpdates updates
947  {
948  "ALTER TABLE music_albumart DEFAULT CHARACTER SET utf8;",
949  "ALTER TABLE music_albums DEFAULT CHARACTER SET utf8;",
950  "ALTER TABLE music_artists DEFAULT CHARACTER SET utf8;",
951  "ALTER TABLE music_directories DEFAULT CHARACTER SET utf8;",
952  "ALTER TABLE music_genres DEFAULT CHARACTER SET utf8;",
953  "ALTER TABLE music_playlists DEFAULT CHARACTER SET utf8;",
954  "ALTER TABLE music_smartplaylist_categories DEFAULT CHARACTER SET utf8;",
955  "ALTER TABLE music_smartplaylist_items DEFAULT CHARACTER SET utf8;",
956  "ALTER TABLE music_smartplaylists DEFAULT CHARACTER SET utf8;",
957  "ALTER TABLE music_songs DEFAULT CHARACTER SET utf8;",
958  "ALTER TABLE music_stats DEFAULT CHARACTER SET utf8;"
959  };
960 
961  if (!performActualUpdate("MythMusic", MythMusicVersionName,
962  updates, "1025", dbver))
963  return false;
964  }
965 
966  return true;
967 
968 }
doUpgradeMusicDatabaseSchema
static bool doUpgradeMusicDatabaseSchema(QString &dbver)
Definition: musicdbcheck.cpp:108
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
MYTH_SCHEMA_ERROR
@ MYTH_SCHEMA_ERROR
Definition: schemawizard.h:17
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:807
SchemaUpgradeWizard::Get
static SchemaUpgradeWizard * Get(const QString &DBSchemaSetting, const QString &appName, const QString &upgradeSchemaVal)
Instead of creating a new wizard, use the existing one for its DB backup file & results and expert se...
Definition: schemawizard.cpp:54
mythdb.h
MYTH_SCHEMA_UPGRADE
@ MYTH_SCHEMA_UPGRADE
Definition: schemawizard.h:18
SchemaUpgradeWizard::Compare
int Compare(void)
How many schema versions old is the DB?
Definition: schemawizard.cpp:100
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
SchemaUpgradeWizard::PromptForUpgrade
enum MythSchemaUpgrade PromptForUpgrade(const char *name, bool upgradeAllowed, bool upgradeIfNoUI, int minDBMSmajor=0, int minDBMSminor=0, int minDBMSpoint=0)
Query user, to prevent silent, automatic database upgrades.
Definition: schemawizard.cpp:224
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMusicVersionName
const QString MythMusicVersionName
Definition: musicdbcheck.cpp:20
AlbumArtImages::guessImageType
static ImageType guessImageType(const QString &filename)
Definition: musicmetadata.cpp:2190
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
MYTH_SCHEMA_USE_EXISTING
@ MYTH_SCHEMA_USE_EXISTING
Definition: schemawizard.h:19
MYTH_SCHEMA_EXIT
@ MYTH_SCHEMA_EXIT
Definition: schemawizard.h:16
MSqlQuery::first
bool first(void)
Wrap QSqlQuery::first() so we can display the query results.
Definition: mythdbcon.cpp:823
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
mythdbcheck.h
currentDatabaseVersion
const QString currentDatabaseVersion
Definition: musicdbcheck.cpp:19
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
DBUtil::TryLockSchema
static bool TryLockSchema(MSqlQuery &query, uint timeout_secs)
Try to get a lock on the table schemalock.
Definition: dbutil.cpp:844
UpdateDBVersionNumber
bool UpdateDBVersionNumber(const QString &component, const QString &versionkey, const QString &newnumber, QString &dbver)
Updates the schema version stored in the database.
Definition: dbcheckcommon.cpp:28
UpgradeMusicDatabaseSchema
bool UpgradeMusicDatabaseSchema(void)
Definition: musicdbcheck.cpp:24
IT_UNKNOWN
@ IT_UNKNOWN
Definition: musicmetadata.h:30
performActualUpdate
bool performActualUpdate(const QString &component, const QString &versionkey, const DBUpdates &updates, const QString &version, QString &dbver)
Definition: dbcheckcommon.cpp:113
schemawizard.h
SchemaUpgradeWizard
Provides UI and helper functions for DB Schema updates.
Definition: schemawizard.h:25
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
musicdbcheck.h
mythcontext.h
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:833
IT_FRONTCOVER
@ IT_FRONTCOVER
Definition: musicmetadata.h:31
DBUtil::UnlockSchema
static void UnlockSchema(MSqlQuery &query)
Definition: dbutil.cpp:851
MSqlQuery::numRowsAffected
int numRowsAffected() const
Definition: mythdbcon.h:217
DBUpdates
std::vector< std::string > DBUpdates
Definition: mythdbcheck.h:9
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:881
build_compdb.filename
filename
Definition: build_compdb.py:21
musicmetadata.h
SchemaUpgradeWizard::m_DBver
QString m_DBver
Schema version in the database.
Definition: schemawizard.h:55
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838