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