Index: mythmusic/mythmusic/playbackbox.cpp
===================================================================
--- mythmusic/mythmusic/playbackbox.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/playbackbox.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -541,7 +541,7 @@
         return;
 
    closePlaylistPopup();
-   updatePlaylistFromQuickPlaylist("ORDER BY artist, album, tracknum");
+   updatePlaylistFromQuickPlaylist("ORDER BY artist_name, album_name, track");
 }
 
 void PlaybackBoxMusic::fromCD()
@@ -597,8 +597,8 @@
         return;
 
     QString value = formattedFieldValue(curMeta->Artist().utf8());
-    QString whereClause = "WHERE artist = " + value +
-                          " ORDER BY album, tracknum"; 
+    QString whereClause = "WHERE artist_name = " + value +
+                          " ORDER BY album_name, track"; 
 
     closePlaylistPopup();
     updatePlaylistFromQuickPlaylist(whereClause);
@@ -610,8 +610,8 @@
         return;
 
     QString value = formattedFieldValue(curMeta->Album().utf8());
-    QString whereClause = "WHERE album = " + value + 
-                          " ORDER BY tracknum";
+    QString whereClause = "WHERE album_name = " + value + 
+                          " ORDER BY track";
     closePlaylistPopup();
     updatePlaylistFromQuickPlaylist(whereClause);
 }
@@ -623,7 +623,7 @@
 
     QString value = formattedFieldValue(curMeta->Genre().utf8()); 
     QString whereClause = "WHERE genre = " + value +
-                          " ORDER BY artist, album, tracknum";   
+                          " ORDER BY artist_name, album_name, track";   
     closePlaylistPopup();
     updatePlaylistFromQuickPlaylist(whereClause);
 }
@@ -635,7 +635,7 @@
 
     QString value = formattedFieldValue(curMeta->Year()); 
     QString whereClause = "WHERE year = " + value + 
-                          " ORDER BY artist, album, tracknum";
+                          " ORDER BY artist_name, album_name, track";
     closePlaylistPopup();
     updatePlaylistFromQuickPlaylist(whereClause);
 }
Index: mythmusic/mythmusic/search.cpp
===================================================================
--- mythmusic/mythmusic/search.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/search.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -66,7 +66,7 @@
 
 void SearchDialog::runQuery(QString searchText)
 {
-    // This method will perform a search in the 'musicmetadata' table and fill
+    // This method will perform a search in the various music_* tables and fill
     // the 'listbox' widget with the results.
     // The following columns are searched: filename, artist, album, title.
     // To facilitate usage with a remote, two search modes exist and
@@ -103,8 +103,10 @@
 
     MSqlQuery query(MSqlQuery::InitCon());
 
-    QString queryString("SELECT filename, artist, album, title, intid "
-                        "FROM musicmetadata ");
+    QString queryString("SELECT filename, artist_name, album_name, name, song_id "
+                        "FROM music_songs "
+                        "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+                        "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id ");      
 
     QStringList list = QStringList::split(QRegExp("[>,]"), searchText);
     whereClause = "";
@@ -117,10 +119,10 @@
                  QString stxt = list[i];
                  whereClause += (i) ? " AND ( " : "WHERE (";
                  whereClause +=
-                    "filename LIKE '%" + stxt + "%' OR "
-                    "artist   LIKE '%" + stxt + "%' OR "
-                    "album    LIKE '%" + stxt + "%' OR "
-                    "title    LIKE '%" + stxt + "%')";
+                    "filename    LIKE '%" + stxt + "%' OR "
+                    "artist_name LIKE '%" + stxt + "%' OR "
+                    "album_name  LIKE '%" + stxt + "%' OR "
+                    "name    LIKE '%" + stxt + "%')";
              }
              VERBOSE(VB_GENERAL, QString("alpha whereClause " + whereClause ));
         }
@@ -131,17 +133,17 @@
                 QString stxt = list[i].stripWhiteSpace();
                 whereClause += (i) ? " AND ( " : "WHERE (";
                 whereClause +=
-                    "filename REGEXP '" + stxt + "' OR "
-                    "artist   REGEXP '" + stxt + "' OR "
-                    "album    REGEXP '" + stxt + "' OR "
-                    "title    REGEXP '" + stxt + "')";
+                    "filename    REGEXP '" + stxt + "' OR "
+                    "artist_name REGEXP '" + stxt + "' OR "
+                    "album_name  REGEXP '" + stxt + "' OR "
+                    "name        REGEXP '" + stxt + "')";
             }
             VERBOSE(VB_GENERAL,QString("numeric whereClause " + whereClause ));
         }
     }
 
     queryString += whereClause;
-    queryString += " ORDER BY artist, album, title, intid, filename ";
+    queryString += " ORDER BY artist_name, album_name, name, song_id, filename ";
 
     query.prepare(queryString);
 
@@ -217,7 +219,7 @@
 void SearchDialog::itemSelected(int i)
 {
     unsigned int id = ((SearchListBoxItem*)listbox->item(i))->getId();
-    whereClause = QString("WHERE intid='%1';").arg(id);
+    whereClause = QString("WHERE song_id='%1';").arg(id);
     done(0);
 }
 
Index: mythmusic/mythmusic/playlist.h
===================================================================
--- mythmusic/mythmusic/playlist.h	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/playlist.h	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -83,8 +83,7 @@
     void loadPlaylist(QString a_name, QString a_host);
     void loadPlaylistByID(int id, QString a_host);
 
-    void savePlaylist(QString a_name);
-    void saveNewPlaylist(QString a_host);
+    void savePlaylist(QString a_name, QString a_host);
 
     void putYourselfOnTheListView(UIListGenericTree *a_parent);
 
Index: mythmusic/mythmusic/cdrip.h
===================================================================
--- mythmusic/mythmusic/cdrip.h	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/cdrip.h	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -38,8 +38,6 @@
     void reject();
 
   private:
-    void fillComboBox (MythComboBox &, const QString &);
-
     int ripTrack(QString &cddevice, Encoder *encoder, int tracknum);
     static QString fixFileToken(QString token);
     void handleFileTokens(QString &filename, Metadata *track);
Index: mythmusic/mythmusic/metadata.cpp
===================================================================
--- mythmusic/mythmusic/metadata.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/metadata.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -31,23 +31,23 @@
 
 Metadata& Metadata::operator=(Metadata *rhs)
 {
-    artist = rhs->Artist();
-    compilation_artist = rhs->CompilationArtist();
-    album = rhs->Album();
-    title = rhs->Title();
-    formattedartist = rhs->FormatArtist();
-    formattedtitle = rhs->FormatTitle();
-    genre = rhs->Genre();
-    year = rhs->Year();
-    tracknum = rhs->Track();
-    length = rhs->Length();
-    rating = rhs->Rating();
-    lastplay = rhs->LastPlayStr();
-    playcount = rhs->Playcount();
-    compilation = rhs->Compilation();
-    id = rhs->ID();
-    filename = rhs->Filename();
-    changed = rhs->hasChanged();
+    artist = rhs->artist;
+    compilation_artist = rhs->compilation_artist;
+    album = rhs->album;
+    title = rhs->title;
+    formattedartist = rhs->formattedartist;
+    formattedtitle = rhs->formattedtitle;
+    genre = rhs->genre;
+    year = rhs->year;
+    tracknum = rhs->tracknum;
+    length = rhs->length;
+    rating = rhs->rating;
+    lastplay = rhs->lastplay;
+    playcount = rhs->playcount;
+    compilation = rhs->compilation;
+    id = rhs->id;
+    filename = rhs->filename;
+    changed = rhs->changed;
 
     return *this;
 }
@@ -62,9 +62,9 @@
 void Metadata::persist()
 {
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("UPDATE musicmetadata set rating = :RATING , "
-                  "playcount = :PLAYCOUNT , lastplay = :LASTPLAY "
-                  "where intid = :ID ;");
+    query.prepare("UPDATE music_songs set rating = :RATING , "
+                  "numplays = :PLAYCOUNT , lastplay = :LASTPLAY "
+                  "where song_id = :ID ;");
     query.bindValue(":RATING", rating);
     query.bindValue(":PLAYCOUNT", playcount);
     query.bindValue(":LASTPLAY", lastplay);
@@ -100,9 +100,17 @@
         sqlfilename.remove(0, m_startdir.length());
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT artist,compilation_artist,album,title,genre,year,tracknum,"
-                  "length,intid,rating,playcount,lastplay,compilation,format FROM "
-                  "musicmetadata WHERE filename = :FILENAME ;");
+    query.prepare("SELECT music_artists.artist_name, music_comp_artists.artist_name AS compilation_artist, "
+                  "music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
+                  "music_songs.track, music_songs.length, music_songs.song_id, music_songs.rating, "
+                  "music_songs.numplays, music_songs.lastplay, music_albums.compilation, "
+                  "music_songs.format "
+                  "FROM music_songs "
+                  "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+                  "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+                  "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
+                  "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
+                  "WHERE music_songs.filename = :FILENAME ;");
     query.bindValue(":FILENAME", sqlfilename.utf8());
 
     if (query.exec() && query.isActive() && query.size() > 0)
@@ -150,14 +158,22 @@
     // Don't update the database if a song with the exact same
     // metadata is already there
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT filename FROM musicmetadata WHERE "
-                  "( ( artist = :ARTIST ) AND "
-                  "( compilation_artist = :COMPILATION_ARTIST ) "
-                  "( album = :ALBUM ) AND ( title = :TITLE ) "
-                  "AND ( genre = :GENRE ) AND "
-                  "( year = :YEAR ) AND ( tracknum = :TRACKNUM ) "
-                  "AND ( length = :LENGTH ) "
-                  "AND ( format = :FORMAT) );");
+    query.prepare("SELECT music_songs.filename "
+                  "FROM music_songs "
+                  "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+                  "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+                  "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
+                  "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
+                  "WHERE music_artists.artist_name = :ARTIST"
+                  " AND music_comp_artists.artist_name = :COMPILATION_ARTIST"
+                  " AND music_albums.album_name = :ALBUM"
+                  " AND music_songs.name = :TITLE"
+                  " AND music_genres.genre = :GENRE"
+                  " AND music_songs.year = :YEAR"
+                  " AND music_songs.track = :TRACKNUM"
+                  " AND music_songs.length = :LENGTH"
+                  " AND music_songs.format = :FORMAT ;");
+
     query.bindValue(":ARTIST", artist.utf8());
     query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
     query.bindValue(":ALBUM", album.utf8());
@@ -171,34 +187,189 @@
     if (query.exec() && query.isActive() && query.size() > 0)
         return;
 
-    query.prepare("INSERT INTO musicmetadata "
-                  "(artist,   compilation_artist, album,      title,  "
-                  " genre,    year,               tracknum,   length, "
-                  " filename, compilation,        date_added, date_modified, "
-                  " format ) "
-                  "VALUES "
-                  "(:ARTIST,  :COMPILATION_ARTIST,:ALBUM,     :TITLE,   "
-                  " :GENRE,   :YEAR,              :TRACKNUM,  :LENGTH,  "
-                  " :FILENAME,:COMPILATION,       :DATE_ADDED,:DATE_MOD,"
-                  " :FORMAT)");
+    // Load the artist id or insert it and get the id
+    unsigned int artistId;
+    query.prepare("SELECT artist_id FROM music_artists "
+                  "WHERE artist_name = :ARTIST ;");
     query.bindValue(":ARTIST", artist.utf8());
-    query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
+
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("music select artist id", query);
+        return;
+    }
+    if (query.size() > 0)
+    {
+        query.next();
+        artistId = query.value(0).toInt();
+    }
+    else
+    {
+        query.prepare("INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
+        query.bindValue(":ARTIST", artist.utf8());
+
+        if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
+        {
+            MythContext::DBError("music insert artist", query);
+            return;
+        }
+        artistId = query.lastInsertId().toInt();
+    }
+
+    // Compilation Artist
+    unsigned int compilationArtistId;
+    query.prepare("SELECT artist_id FROM music_artists "
+                  "WHERE artist_name = :ARTIST ;");
+    query.bindValue(":ARTIST", compilation_artist.utf8());
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("music select compilation artist id", query);
+        return;
+    }
+    if (query.size() > 0)
+    {
+        query.next();
+        compilationArtistId = query.value(0).toInt();
+    }
+    else
+    {
+        query.prepare("INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
+        query.bindValue(":ARTIST", compilation_artist.utf8());
+
+        if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
+        {
+            MythContext::DBError("music insert compilation artist", query);
+            return;
+        }
+        compilationArtistId = query.lastInsertId().toInt();
+    }
+
+    // Album
+    unsigned int albumId;
+    query.prepare("SELECT album_id FROM music_albums "
+                  "WHERE artist_id = :COMP_ARTIST_ID "
+                  " AND album_name = :ALBUM ;");
+    query.bindValue(":COMP_ARTIST_ID", compilationArtistId);
     query.bindValue(":ALBUM", album.utf8());
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("music select album id", query);
+        return;
+    }
+    if (query.size() > 0)
+    {
+        query.next();
+        albumId = query.value(0).toInt();
+    }
+    else
+    {
+        query.prepare("INSERT INTO music_albums (artist_id, album_name, compilation, year) VALUES (:COMP_ARTIST_ID, :ALBUM, :COMPILATION, :YEAR);");
+        query.bindValue(":COMP_ARTIST_ID", compilationArtistId);
+        query.bindValue(":ALBUM", album.utf8());
+        query.bindValue(":COMPILATION", compilation);
+        query.bindValue(":YEAR", year);
+
+        if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
+        {
+            MythContext::DBError("music insert album", query);
+            return;
+        }
+        albumId = query.lastInsertId().toInt();
+    }
+
+    // Genres
+    unsigned int genreId;
+    query.prepare("SELECT genre_id FROM music_genres "
+                  "WHERE genre = :GENRE ;");
+    query.bindValue(":GENRE", genre.utf8());
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("music select genre id", query);
+        return;
+    }
+    if (query.size() > 0)
+    {
+        query.next();
+        genreId = query.value(0).toInt();
+    }
+    else
+    {
+        query.prepare("INSERT INTO music_genres (genre) VALUES (:GENRE);");
+        query.bindValue(":GENRE", genre.utf8());
+
+        if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
+        {
+            MythContext::DBError("music insert genre", query);
+            return;
+        }
+        genreId = query.lastInsertId().toInt();
+    }
+
+    // We have all the id's now. We can insert it.
+    QString strQuery;
+    if (id < 1)
+    {
+        strQuery = "INSERT INTO music_songs ("
+                   " artist_id, album_id,  name,         genre_id,"
+                   " year,      track,     length,       filename,"
+                   " rating,    format,    date_entered, date_modified ) "
+                   "VALUES ("
+                   " :ARTIST,   :ALBUM,    :TITLE,       :GENRE,"
+                   " :YEAR,     :TRACKNUM, :LENGTH,      :FILENAME,"
+                   " :RATING,   :FORMAT,   :DATE_ADD,    :DATE_MOD );";
+    }
+    else
+    {
+        strQuery = "UPDATE music_songs SET"
+                   "  artist_id = :ARTIST"
+                   ", album_id = :ALBUM"
+                   ", name = :TITLE"
+                   ", genre_id = :GENRE"
+                   ", year = :YEAR"
+                   ", track = :TRACKNUM"
+                   ", length = :LENGTH"
+                   ", filename = :FILENAME"
+                   ", rating = :RATING"
+                   ", format = :FORMAT"
+                   ", date_modified = :DATE_MOD "
+                   "WHERE song_id= :ID ;";
+    }
+
+    query.prepare(strQuery);
+    /*
+    query.prepare("INSERT INTO music_songs "
+                  "  (artist_id, album_id,     name,"
+                  "   genre_id,  year,         track,                length,"
+                  "   filename,  date_entered, date_modified,"
+                  "   format,    size,         bitrate) "
+                  "VALUES "
+                  "  (:ARTIST,   :ALBUM,       :TITLE,"
+                  "   :GENRE,    :YEAR,        :TRACKNUM,            :LENGTH,"
+                  "   :FILENAME, :DATE_ADDED,  :DATE_MOD,"
+                  "   :FORMAT,   :FILESIZE,    :BITRATE)"
+                  );
+    */
+    query.bindValue(":ARTIST", artistId);
+    query.bindValue(":ALBUM", albumId);
     query.bindValue(":TITLE", title.utf8());
-    query.bindValue(":GENRE", genre.utf8());
+    query.bindValue(":GENRE", genreId);
     query.bindValue(":YEAR", year);
     query.bindValue(":TRACKNUM", tracknum);
     query.bindValue(":LENGTH", length);
     query.bindValue(":FILENAME", sqlfilename.utf8());
-    query.bindValue(":COMPILATION", compilation);
-    query.bindValue(":DATE_ADDED",  QDateTime::currentDateTime());
-    query.bindValue(":DATE_MOD",    QDateTime::currentDateTime());
+    query.bindValue(":RATING", rating);
     query.bindValue(":FORMAT", format);
-    
+    query.bindValue(":DATE_MOD", QDateTime::currentDateTime());
+
+    if (id < 1)
+        query.bindValue(":DATE_ADDED",  QDateTime::currentDateTime());
+    else
+        query.bindValue(":ID", id);
+
     query.exec();
 
-    // easiest way to ensure we've got 'id' filled.
-    fillData();
+    if (id < 1 && query.isActive() && 1 == query.numRowsAffected())
+        id = query.lastInsertId().toInt();
 }
 
 // Default values for formats
@@ -328,54 +499,6 @@
 }
 
 
-void Metadata::updateDatabase()
-{
-    // only save to DB if something changed
-    //if (!hasChanged())
-    //    return;
-
-    if (artist == "")
-        artist = QObject::tr("Unknown Artist");
-    if (album == "")
-        album = QObject::tr("Unknown Album");
-    if (title == "")
-        title = filename;
-    if (genre == "")
-        genre = QObject::tr("Unknown Genre");
-
-    MSqlQuery query(MSqlQuery::InitCon());
-
-    query.prepare("UPDATE musicmetadata    "
-                  "SET artist   = :ARTIST,   "
-                  "    album    = :ALBUM,    "
-                  "    title    = :TITLE,    "
-                  "    genre    = :GENRE,    "
-                  "    year     = :YEAR,     "
-                  "    tracknum = :TRACKNUM, "
-                  "    rating   = :RATING,   " 
-                  "    date_modified      = :DATE_MODIFIED, "
-                  "    compilation        = :COMPILATION,   "
-                  "    compilation_artist = :COMPILATION_ARTIST, "
-                  "    format             = :FORMAT "
-                  "WHERE intid = :ID;");
-    query.bindValue(":ARTIST",             artist.utf8());
-    query.bindValue(":ALBUM",              album.utf8());
-    query.bindValue(":TITLE",              title.utf8());
-    query.bindValue(":GENRE",              genre.utf8());
-    query.bindValue(":YEAR",               year);
-    query.bindValue(":TRACKNUM",           tracknum);
-    query.bindValue(":RATING",             rating);
-    query.bindValue(":DATE_MODIFIED",      QDateTime::currentDateTime());
-    query.bindValue(":COMPILATION",        compilation);
-    query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
-    query.bindValue(":FORMAT", format);
-    query.bindValue(":ID", id);
-
-    if (!query.exec())
-         MythContext::DBError("Update musicmetadata", query);
-}
-
-
 void Metadata::setField(const QString &field, const QString &data)
 {
     if (field == "artist")
@@ -426,92 +549,6 @@
     }
 }
 
-void Metadata::fillData()
-{
-    if (title == "")
-        return;
-
-    QString thequery = "SELECT artist,compilation_artist,album,title,genre,year,tracknum,length,"
-                       "filename,intid,rating,playcount,lastplay,compilation,format "
-                       "FROM musicmetadata WHERE title = :TITLE";
-
-    if (album != "")
-        thequery += " AND album = :ALBUM";
-    if (artist != "")
-        thequery += " AND artist = :ARTIST";
-    if (compilation_artist != "")
-        thequery += " AND compilation_artist = :COMPILATION_ARTIST";
-
-    thequery += ";";
-
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(thequery);
-    query.bindValue(":TITLE", title.utf8());
-    query.bindValue(":ALBUM", album.utf8());
-    query.bindValue(":ARTIST", artist.utf8());
-    query.bindValue(":COMPILATION_ARTIST", compilation_artist.utf8());
-
-    if (query.exec() && query.isActive() && query.size() > 0)
-    {
-        query.next();
-
-        artist = QString::fromUtf8(query.value(0).toString());
-        compilation_artist = QString::fromUtf8(query.value(1).toString());
-        album = QString::fromUtf8(query.value(2).toString());
-        title = QString::fromUtf8(query.value(3).toString());
-        genre = QString::fromUtf8(query.value(4).toString());
-        year = query.value(5).toInt();
-        tracknum = query.value(6).toInt();
-        length = query.value(7).toInt();
-        filename = QString::fromUtf8(query.value(8).toString());
-        id = query.value(9).toUInt();
-        rating = query.value(10).toInt();
-        playcount = query.value(11).toInt();
-        lastplay = query.value(12).toString();
-        compilation = (query.value(13).toInt() > 0);
-        format = query.value(14).toString();
-
-        if (!filename.contains("://"))
-            filename = m_startdir + filename;
-    }
-}
-
-void Metadata::fillDataFromID()
-{       
-    if (id == 0)
-        return; 
-        
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT title,artist,compilation_artist,album,title,genre,year,tracknum,"
-                  "length,filename,rating,playcount,lastplay,compilation,format FROM "
-                  "musicmetadata WHERE intid = :ID ;");
-    query.bindValue(":ID", id);
-        
-    if (query.exec() && query.isActive() && query.numRowsAffected() > 0)
-    {
-        query.next();
-
-        title = QString::fromUtf8(query.value(0).toString());
-        artist = QString::fromUtf8(query.value(1).toString());
-        compilation_artist = QString::fromUtf8(query.value(2).toString());
-        album = QString::fromUtf8(query.value(3).toString());
-        title = QString::fromUtf8(query.value(4).toString());
-        genre = QString::fromUtf8(query.value(5).toString());
-        year = query.value(6).toInt();
-        tracknum = query.value(7).toInt();
-        length = query.value(8).toInt();
-        filename = QString::fromUtf8(query.value(9).toString());
-        rating = query.value(10).toInt();
-        playcount = query.value(11).toInt();
-        lastplay = query.value(12).toString();
-        compilation = (query.value(13).toInt() > 0);
-        format = query.value(14).toString();
-
-        if (!filename.contains("://"))
-            filename = m_startdir + filename;
-    }
-}
-
 void Metadata::decRating()
 {
     if (rating > 0)
@@ -553,6 +590,43 @@
     changed = true;
 }
 
+QStringList Metadata::fillFieldList(QString field)
+{
+    QStringList searchList;
+    searchList.clear();
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    if ("artist" == field || "compilation_artist" == field)
+    {
+        query.prepare("SELECT artist_name FROM music_artists ORDER BY artist_name;");
+    }
+    else if ("album" == field)
+    {
+        query.prepare("SELECT album_name FROM music_albums ORDER BY album_name;");
+    }
+    else if ("title" == field)
+    {
+        query.prepare("SELECT name FROM music_songs ORDER BY name;");
+    }
+    else if ("genre" == field)
+    {
+        query.prepare("SELECT genre FROM music_genres ORDER BY genre;");
+    }
+    else
+    {
+        return searchList;
+    }
+
+    if (query.exec() && query.isActive() && query.size())
+    {
+        while (query.next())
+        {
+            searchList << QString::fromUtf8(query.value(0).toString());
+        }
+    }
+    return searchList;
+}
+
 MetadataLoadingThread::MetadataLoadingThread(AllMusic *parent_ptr)
 {
     parent = parent_ptr;
@@ -648,12 +722,19 @@
 void AllMusic::resync()
 {
     done_loading = false;
-    QString aquery =    "SELECT intid, artist, compilation_artist, album, title, genre, "
-                        "year, tracknum, length, filename, rating, "
-                        "lastplay, playcount, compilation, format "
-                        "FROM musicmetadata "
-                        "ORDER BY intid;";
 
+    QString aquery = "SELECT music_songs.song_id, music_artists.artist_name, music_comp_artists.artist_name AS compilation_artist, "
+                     "music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
+                     "music_songs.track, music_songs.length, music_songs.filename, "
+                     "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_albums.compilation, "
+                     "music_songs.format "
+                     "FROM music_songs "
+                     "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+                     "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+                     "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
+                     "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
+                     "ORDER BY music_songs.song_id;";
+
     QString filename, artist, album, title;
 
     MSqlQuery query(MSqlQuery::InitCon());
@@ -696,12 +777,12 @@
                 query.value(7).toInt(),
                 query.value(8).toInt(),
                 query.value(0).toInt(),
-                query.value(10).toInt(),
-                query.value(12).toInt(),
-                query.value(11).toString(),
-                (query.value(13).toInt() > 0),
-                query.value(14).toString());
-            
+                query.value(10).toInt(), //rating
+                query.value(11).toInt(), //playcount
+                query.value(12).toString(), //lastplay
+                (query.value(13).toInt() > 0), //compilation
+                query.value(14).toString()); //format
+
             //  Don't delete temp, as PtrList now owns it
             all_music.append(temp);
 
Index: mythmusic/mythmusic/dbcheck.cpp
===================================================================
--- mythmusic/mythmusic/dbcheck.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/dbcheck.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -9,7 +9,7 @@
 #include "mythtv/mythcontext.h"
 #include "mythtv/mythdbcon.h"
 
-const QString currentDatabaseVersion = "1005";
+const QString currentDatabaseVersion = "1006";
 
 static void UpdateDBVersionNumber(const QString &newnumber)
 {
@@ -323,5 +323,121 @@
 
         performActualUpdate(updates, "1005", dbver);
     }
+
+
+        if (dbver == "1005")
+        {
+            const QString updates[] = {
+"CREATE TABLE music_albums ("
+"    album_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
+"    artist_id int(11) unsigned NOT NULL default '0',"
+"    album_name varchar(255) NOT NULL default '',"
+"    year smallint(6) NOT NULL default '0',"
+"    compilation tinyint(1) unsigned NOT NULL default '0',"
+"    INDEX idx_album_name(album_name)"
+");",
+"CREATE TABLE music_artists ("
+"    artist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
+"    artist_name varchar(255) NOT NULL default '',"
+"    INDEX idx_artist_name(artist_name)"
+");",
+"CREATE TABLE music_genres ("
+"    genre_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
+"    genre varchar(25) NOT NULL default '',"
+"    INDEX idx_genre(genre)"
+");",
+"CREATE TABLE music_playlists ("
+"    playlist_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
+"    playlist_name varchar(255) NOT NULL default '',"
+"    playlist_songs text NOT NULL default '',"
+"    last_accessed timestamp NOT NULL,"
+"    length int(11) unsigned NOT NULL default '0',"
+"    songcount smallint(8) unsigned NOT NULL default '0',"
+"    hostname VARCHAR(255) NOT NULL default ''"
+");",
+"CREATE TABLE music_songs ("
+"    song_id int(11) unsigned NOT NULL auto_increment PRIMARY KEY,"
+"    filename text NOT NULL default '',"
+"    name varchar(255) NOT NULL default '',"
+"    track smallint(6) unsigned NOT NULL default '0',"
+"    artist_id int(11) unsigned NOT NULL default '0',"
+"    album_id int(11) unsigned NOT NULL default '0',"
+"    genre_id int(11) unsigned NOT NULL default '0',"
+"    year smallint(6) NOT NULL default '0',"
+"    length int(11) unsigned NOT NULL default '0',"
+"    numplays int(11) unsigned NOT NULL default '0',"
+"    rating tinyint(4) unsigned NOT NULL default '0',"
+"    lastplay timestamp NOT NULL,"
+"    date_entered datetime default NULL,"
+"    date_modified datetime default NULL,"
+"    format varchar(4) NOT NULL default '0',"
+"    mythdigest VARCHAR(255),"
+"    size BIGINT(20) unsigned,"
+"    description VARCHAR(255),"
+"    comment VARCHAR(255),"
+"    disc_count SMALLINT(5) UNSIGNED DEFAULT '0',"
+"    disc_number SMALLINT(5) UNSIGNED DEFAULT '0',"
+"    track_count SMALLINT(5) UNSIGNED DEFAULT '0',"
+"    start_time INT(10) UNSIGNED DEFAULT '0',"
+"    stop_time INT(10) UNSIGNED,"
+"    eq_preset VARCHAR(255),"
+"    relative_volume TINYINT DEFAULT '0',"
+"    bpm SMALLINT(5) UNSIGNED,"
+"    INDEX idx_name(name),"
+"    INDEX idx_mythdigest(mythdigest)"
+");",
+"CREATE TABLE music_stats ("
+"    num_artists smallint(5) unsigned NOT NULL default '0',"
+"    num_albums smallint(5) unsigned NOT NULL default '0',"
+"    num_songs mediumint(8) unsigned NOT NULL default '0',"
+"    num_genres tinyint(3) unsigned NOT NULL default '0',"
+"    total_time varchar(12) NOT NULL default '0',"
+"    total_size varchar(10) NOT NULL default '0'"
+");",
+"RENAME TABLE smartplaylist TO music_smartplaylists;",
+"RENAME TABLE smartplaylistitem TO music_smartplaylist_items;",
+"RENAME TABLE smartplaylistcategory TO music_smartplaylist_categories;",
+// Run necessary SQL to migrate the table structure
+"CREATE TEMPORARY TABLE tmp_artists"
+"  SELECT DISTINCT artist FROM musicmetadata;",
+"INSERT INTO tmp_artists"
+"  SELECT DISTINCT compilation_artist"
+"  FROM musicmetadata"
+"  WHERE compilation_artist<>artist;",
+"INSERT INTO music_artists (artist_name) SELECT DISTINCT artist FROM tmp_artists;",
+"INSERT INTO music_albums (artist_id, album_name, year, compilation) "
+"  SELECT artist_id, album, ROUND(AVG(year)) AS year, IF(SUM(compilation),1,0) AS compilation"
+"  FROM musicmetadata"
+"  LEFT JOIN music_artists ON compilation_artist=artist_name"
+"  GROUP BY artist_id, album;",
+"INSERT INTO music_genres (genre) SELECT DISTINCT genre FROM musicmetadata;",
+"INSERT INTO music_songs "
+"   (song_id, artist_id, album_id, genre_id, year, lastplay,"
+"    date_entered, date_modified, name, track, length, size, numplays,"
+"    rating, filename)"
+"  SELECT intid, ma.artist_id, mb.album_id, mg.genre_id, mmd.year, lastplay,"
+"         date_added, date_modified, title, tracknum, length, IFNULL(size,0), playcount,"
+"         rating, filename"
+"  FROM musicmetadata AS mmd"
+"  LEFT JOIN music_artists AS ma ON mmd.artist=ma.artist_name"
+"  LEFT JOIN music_artists AS mc ON mmd.compilation_artist=mc.artist_name"
+"  LEFT JOIN music_albums AS mb ON mmd.album=mb.album_name AND mc.artist_id=mb.artist_id"
+"  LEFT JOIN music_genres AS mg ON mmd.genre=mg.genre;",
+"INSERT INTO music_playlists"
+"  (playlist_id,playlist_name,playlist_songs,hostname)"
+"  SELECT playlistid, name, songlist, hostname"
+"  FROM musicplaylist;",
+// Set all playlists to be global by killing the hostname
+"UPDATE music_playlists"
+"  SET hostname=''"
+"  WHERE playlist_name='default_playlist_storage'"
+"    OR playlist_name='backup_playlist_storage';",
+//"DROP TABLE musicmetadata;",
+//"DROP TABLE musicplaylist;",
+//RENAME TABLE music_smartplaylists TO smartplaylist;RENAME TABLE music_smartplaylist_categories TO smartplaylistcategory;RENAME TABLE music_smartplaylist_items TO smartplaylistitem; DROP TABLE music_albums; DROP TABLE music_artists; DROP TABLE music_genres; DROP TABLE music_playlists; DROP TABLE music_songs; DROP TABLE music_stats;UPDATE settings SET data=1005 WHERE value='MusicDBSchemaVer';
+""
+};
+        performActualUpdate(updates, "1006", dbver);
+    }
 }
 
Index: mythmusic/mythmusic/playlist.cpp
===================================================================
--- mythmusic/mythmusic/playlist.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/playlist.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -35,7 +35,7 @@
     if (index_value > 0) // Normal Track
         label = all_available_music->getLabel(index_value, &bad_reference);
     else if (index_value < 0)
-        label = grandparent->getPlaylistName( index_value,  bad_reference);
+        label = grandparent->getPlaylistName( (-1 * index_value),  bad_reference);
     else
     {
         cerr << "playlist.o: Not sure how I got 0 as a track number, but "
@@ -69,18 +69,17 @@
 {
     // XXX SPEED THIS UP
     // Should be a straight lookup against cached index
-    bool result = false;
     Track *it;
 
     for (it = songs.first(); it; it = songs.next())
     {
         if (it->getValue() == a_track_id && it->getCDFlag() == cd_flag)
         {
-            result = true;
+            return true;
         }
     }  
 
-    return result;    
+    return false;
 }
 
 void Playlist::copyTracks(Playlist *to_ptr, bool update_display)
@@ -327,10 +326,11 @@
     all_other_playlists->clear();
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT playlistid FROM musicplaylist "
-                  "WHERE name != :DEFAULT  "
-                  "AND name != :BACKUP  "
-                  "AND hostname = :HOST ORDER BY playlistid ;");
+    query.prepare("SELECT playlist_id FROM music_playlists "
+                  "WHERE playlist_name != :DEFAULT"
+                  " AND playlist_name != :BACKUP "
+                  " AND (hostname = '' OR hostname = :HOST) "
+                  "ORDER BY playlist_id;");
     query.bindValue(":DEFAULT", "default_playlist_storage");
     query.bindValue(":BACKUP", "backup_playlist_storage"); 
     query.bindValue(":HOST", my_host);
@@ -469,19 +469,33 @@
     }
    
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT playlistid, name, songlist FROM "
-                  "musicplaylist WHERE name = :NAME AND "
-                  "hostname = :HOST ;");
-    query.bindValue(":NAME", a_name);
+
+    if (name == "default_playlist_storage" || name == "backup_playlist_storage")
+    {
+        query.prepare("SELECT playlist_id, playlist_name, playlist_songs "
+                      "FROM  music_playlists "
+                      "WHERE playlist_name = :NAME"
+                      " AND hostname = :HOST;");
+    }
+    else
+    {
+        // Technically this is never called as this function is only used to load
+        // the default/backup playlists.
+        query.prepare("SELECT playlist_id, playlist_name, playlist_songs "
+                      "FROM music_playlists "
+                      "WHERE playlist_name = :NAME"
+                      " AND (hostname = '' OR hostname = :HOST);");
+    }
+    query.bindValue(":NAME", a_name.utf8());
     query.bindValue(":HOST", a_host);
 
     if (query.exec() && query.size() > 0)
     {
         while (query.next())
         {
-            this->playlistid = query.value(0).toInt();
-            this->name = QString::fromUtf8(query.value(1).toString());
-            this->raw_songlist = query.value(2).toString();
+            playlistid = query.value(0).toInt();
+            name = QString::fromUtf8(query.value(1).toString());
+            raw_songlist = query.value(2).toString();
         }
         if (name == "default_playlist_storage")
             name = "the user should never see this";
@@ -490,8 +504,11 @@
     }
     else
     {
-        name = a_name;
-        saveNewPlaylist(a_host);
+        // Asked me to load a playlist I can't find so let's create a new one :)
+        playlistid = 0; // Be safe just in case we call load over the top
+                        // of an existing playlist
+        raw_songlist = "";
+        savePlaylist(a_name, a_host);
         changed = true;
     }
 }
@@ -499,9 +516,10 @@
 void Playlist::loadPlaylistByID(int id, QString a_host)
 {
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT playlistid, name, songlist FROM "
-                  "musicplaylist WHERE playlistid = :ID AND "
-                  "hostname = :HOST ;");
+    query.prepare("SELECT playlist_id, playlist_name, playlist_songs "
+                  "FROM music_playlists "
+                  "WHERE playlist_id = :ID"
+                  " AND (hostname = '' OR hostname = :HOST);");
     query.bindValue(":ID", id);
     query.bindValue(":HOST", a_host);
 
@@ -509,9 +527,9 @@
 
     while (query.next())
     {
-        this->playlistid = query.value(0).toInt();
-        this->name = QString::fromUtf8(query.value(1).toString());
-        this->raw_songlist = query.value(2).toString();
+        playlistid = query.value(0).toInt();
+        name = QString::fromUtf8(query.value(1).toString());
+        raw_songlist = query.value(2).toString();
     }
 
     if (name == "default_playlist_storage")
@@ -570,24 +588,19 @@
 
 void Playlist::fillSonglistFromSongs()
 {
-    bool first = true;
-    QString a_list;
+    QString a_list = "";
     Track *it;
     for (it = songs.first(); it; it = songs.next())
     {
         if (!it->getCDFlag())
         {
-            if (first)
-            {
-                first = false;
-                a_list = QString("%1").arg(it->getValue());
-            }
-            else
-                a_list += QString(",%1").arg(it->getValue());
+            a_list += QString(",%1").arg(it->getValue());
         }
     }
 
-    raw_songlist = a_list;
+    raw_songlist = "";
+    if (a_list.length() > 1)
+        raw_songlist = a_list.remove(0, 1);
 }
 
 void Playlist::fillSonglistFromQuery(QString whereClause,
@@ -604,7 +617,10 @@
 
     QString theQuery;
 
-    theQuery = "SELECT intid FROM musicmetadata ";
+    theQuery = "SELECT song_id FROM music_songs "
+               "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+               "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+               "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id ";
 
     if (whereClause.length() > 0)
       theQuery += whereClause;
@@ -719,13 +735,13 @@
     int limitTo;
     
     query.prepare("SELECT smartplaylistid, matchtype, orderby, limitto "
-                  "FROM smartplaylist WHERE categoryid = :CATEGORYID AND name = :NAME;");
+                  "FROM music_smartplaylists WHERE categoryid = :CATEGORYID AND name = :NAME;");
     query.bindValue(":NAME", name.utf8());
     query.bindValue(":CATEGORYID", categoryID);
         
     if (query.exec())
     {
-        if (query.isActive() && query.numRowsAffected() > 0)
+        if (query.isActive() && query.size() > 0)
         {
             query.first();
             ID = query.value(0).toInt();
@@ -749,10 +765,10 @@
     QString whereClause = "WHERE ";
     
     query.prepare("SELECT field, operator, value1, value2 "
-                  "FROM smartplaylistitem WHERE smartplaylistid = :ID;");
+                  "FROM music_smartplaylist_items WHERE smartplaylistid = :ID;");
     query.bindValue(":ID", ID);
     query.exec();
-    if (query.isActive() && query.numRowsAffected() > 0)
+    if (query.isActive() && query.size() > 0)
     {
         bool bFirst = true;
         while (query.next())
@@ -770,96 +786,109 @@
             }
         }
     }
-    
+
     // add order by clause
     whereClause += getOrderBySQL(orderBy);
-    
+
     // add limit
     if (limitTo > 0)
-        whereClause +=  " LIMIT " + QString::number(limitTo); 
+        whereClause +=  " LIMIT " + QString::number(limitTo);
 
     fillSonglistFromQuery(whereClause, removeDuplicates, insertOption, currentTrackID);
 }
-    
-void Playlist::savePlaylist(QString a_name)
+
+void Playlist::savePlaylist(QString a_name, QString a_host)
 {
-    name = name.simplifyWhiteSpace();
+    name = a_name.simplifyWhiteSpace();
     if (name.length() < 1)
-        return;
-
-    fillSonglistFromSongs();
-
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT NULL FROM musicplaylist WHERE playlistid = :ID ;");
-    query.bindValue(":ID", playlistid);
-
-    if (query.exec() && query.isActive() && query.size() > 0)
     {
-        query.prepare("UPDATE musicplaylist SET songlist = :LIST , "
-                      "name = :NAME WHERE playlistid = :ID ;");
-        query.bindValue(":LIST", raw_songlist);
-        query.bindValue(":NAME", a_name.utf8());
-        query.bindValue(":ID", playlistid);
-    }
-    else
-    {
-        query.prepare("INSERT INTO musicplaylist (name,songlist) "
-                      "VALUES(:NAME, :LIST);");
-        query.bindValue(":LIST", raw_songlist);
-        query.bindValue(":NAME", a_name.utf8());
-    }
-
-    query.exec();
-}
-
-void Playlist::saveNewPlaylist(QString a_host)
-{
-    name = name.simplifyWhiteSpace();
-    if(name.length() < 1)
-    {
         cerr << "playlist.o: Not going to save a playlist with no name" << endl ;
         return;
     }
 
-    if(a_host.length() < 1)
+    if (a_host.length() < 1)
     {
         cerr << "playlist.o: Not going to save a playlist with no hostname" << endl;
         return;
     }
+    if (name.length() < 1)
+        return;
 
     fillSonglistFromSongs();
-    
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("INSERT musicplaylist (name, hostname) "
-                  "VALUES(:NAME, :HOST);");
-    query.bindValue(":NAME", name.utf8());
-    query.bindValue(":HOST", a_host);
 
-    query.exec();
-
-    query.prepare("SELECT playlistid FROM musicplaylist WHERE "
-                  "name = :NAME AND hostname = :HOST ;");
-    query.bindValue(":NAME", name.utf8());
-    query.bindValue(":HOST", a_host);
-
-    if (query.exec() && query.isActive() && query.size() > 0)
+    int songcount = 0, playtime = 0, an_int;
+    QStringList list = QStringList::split(",", raw_songlist);
+    QStringList::iterator it = list.begin();
+    for (; it != list.end(); it++)
     {
-        while(query.next())
+        an_int = QString(*it).toInt();
+        if (an_int != 0)
         {
-            //  If multiple rows with same name,
-            //  make sure we get the last one
-            playlistid = query.value(0).toInt();
+            songcount++;
+            if (an_int > 0)
+            {
+                query.prepare("SELECT length FROM music_songs WHERE song_id = :ID ;");
+            }
+            else
+            {
+                query.prepare("SELECT length FROM music_playlists WHERE playlist_id = :ID ;");
+                an_int *= -1;
+            }
+            query.bindValue(":ID", an_int);
+            query.exec();
+            if (query.size() > 0)
+            {
+                query.next();
+                playtime += query.value(0).toInt();
+            }
         }
     }
+
+    bool save_host = ("default_playlist_storage" == a_name || "backup_playlist_storage" == a_name);
+    if (playlistid > 0)
+    {
+        QString str_query = "UPDATE music_playlists SET playlist_songs = :LIST,"
+                            " playlist_name = :NAME, songcount = :SONGCOUNT, length = :PLAYTIME";
+        if (save_host)
+            str_query += ", hostname = :HOSTNAME";
+        str_query += " WHERE playlist_id = :ID ;";
+
+        query.prepare(str_query);
+        query.bindValue(":ID", playlistid);
+    }
     else
     {
-        MythContext::DBError("playlist insert", query);
+        QString str_query = "INSERT INTO music_playlists"
+                            " (playlist_name, playlist_songs, songcount, length";
+        if (save_host)
+            str_query += ", hostname";
+        str_query += ") VALUES(:NAME, :LIST, :SONGCOUNT, :PLAYTIME";
+        if (save_host)
+            str_query += ", :HOSTNAME";
+        str_query += ");";
+
+        query.prepare(str_query);
     }
+    query.bindValue(":LIST", raw_songlist);
+    query.bindValue(":NAME", a_name.utf8());
+    query.bindValue(":SONGCOUNT", songcount);
+    query.bindValue(":PLAYTIME", playtime);
+    if (save_host)
+        query.bindValue(":HOSTNAME", a_host);
+
+    if (!query.exec() || (playlistid < 1 && query.numRowsAffected() < 1))
+    {
+        MythContext::DBError("Problem saving playlist", query);
+    }
+
+    if (playlistid < 1)
+        playlistid = query.lastInsertId().toInt();
 }
 
 QString Playlist::removeDuplicateTracks(const QString &new_songlist)
 {
-    raw_songlist = raw_songlist.remove(' '); 
+    raw_songlist.remove(' ');
 
     QStringList curList = QStringList::split(",", raw_songlist);
     QStringList newList = QStringList::split(",", new_songlist);
@@ -1095,22 +1124,21 @@
         if(a_list->hasChanged())
         {
             a_list->fillSonglistFromSongs();
-            a_list->savePlaylist(a_list->getName());
+            a_list->savePlaylist(a_list->getName(), my_host);
         }
     }
-    
-    active_playlist->savePlaylist("default_playlist_storage");
-    backup_playlist->savePlaylist("backup_playlist_storage");
+
+    active_playlist->savePlaylist("default_playlist_storage", my_host);
+    backup_playlist->savePlaylist("backup_playlist_storage", my_host);
 }
 
 void PlaylistsContainer::createNewPlaylist(QString name)
 {
     Playlist *new_list = new Playlist(all_available_music);
     new_list->setParent(this);
-    new_list->setName(name);
-    
+
     //  Need to touch the database to get persistent ID
-    new_list->saveNewPlaylist(my_host);
+    new_list->savePlaylist(name, my_host);
     new_list->Changed();
     all_other_playlists->append(new_list);
     //if(my_widget)
@@ -1123,9 +1151,9 @@
 {
     Playlist *new_list = new Playlist(all_available_music);
     new_list->setParent(this);
-    new_list->setName(name);
+
     //  Need to touch the database to get persistent ID
-    new_list->saveNewPlaylist(my_host);
+    new_list->savePlaylist(name, my_host);
     new_list->Changed();
     all_other_playlists->append(new_list);
     active_playlist->copyTracks(new_list, false);
@@ -1196,7 +1224,7 @@
 void PlaylistsContainer::renamePlaylist(int index, QString new_name)
 {
     Playlist *list_to_rename = getPlaylist(index);
-    if(list_to_rename)
+    if (list_to_rename)
     {
         list_to_rename->setName(new_name);
         list_to_rename->Changed();
@@ -1237,10 +1265,10 @@
     }
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("DELETE FROM musicplaylist WHERE playlistid = :ID ;");
+    query.prepare("DELETE FROM music_playlists WHERE playlist_id = :ID ;");
     query.bindValue(":ID", kill_me);
 
-    if (query.exec() || query.size() < 1)
+    if (!query.exec() || query.numRowsAffected() < 1)
     {
         MythContext::DBError("playlist delete", query);
     }
@@ -1261,7 +1289,7 @@
         Playlist *a_list;
         for(a_list = all_other_playlists->last(); a_list; a_list = all_other_playlists->prev())
         {
-            if (a_list->getID() * -1 == index)
+            if (a_list->getID() == index)
             {
                 return a_list->getName();   
             }
@@ -1538,7 +1566,7 @@
                 level_down->computeSize(child_MB, child_sec);
                 size_in_MB += child_MB;
                 size_in_sec += child_sec;
-	    }
+            }
         }
     }
 }
Index: mythmusic/mythmusic/cdrip.cpp
===================================================================
--- mythmusic/mythmusic/cdrip.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/cdrip.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -104,8 +104,9 @@
     // which totally messes up the rest of the page.
     artistedit->setMaximumWidth((int)(0.7 * screenwidth));
 
-    fillComboBox(*artistedit, "artist");
-
+    QStringList strlist = Metadata::fillFieldList("artist");
+    artistedit->insertStringList(strlist);
+    
     QLabel *albuml = new QLabel(tr("Album: "), firstdiag);
     albuml->setBackgroundOrigin(WindowOrigin);
     albumedit = new MythLineEdit(firstdiag);
@@ -114,7 +115,8 @@
     QLabel *genrelabel = new QLabel(tr("Genre: "), firstdiag);
     genrelabel->setBackgroundOrigin(WindowOrigin);
     genreedit = new MythComboBox(true, firstdiag);
-    fillComboBox (*genreedit, "genre");
+    strlist = Metadata::fillFieldList("genre");
+    genreedit->insertStringList(strlist);
 
 
     compilation = new MythCheckBox(firstdiag);
@@ -196,30 +198,30 @@
 
                 length = track->Length() / 1000;
 
-		QString title = track->Title();
-		newTune = isNewTune(artistname, albumname, title);
+                QString title = track->Title();
+                newTune = isNewTune(artistname, albumname, title);
 
-		if (newTune)
-		{
-		    min = length / 60;
+                if (newTune)
+                {
+                    min = length / 60;
                     sec = length % 60;
 
-		    table->setNumRows(row + 1);
-                
-		    table->setRowHeight(row, (int)(30 * hmult));
-		    
-		    label.sprintf("%d", trackno + 1);
-		    table->setText(row, 0, label);
-		    
-		    table->setText(row, 1, track->Title());
-		    
-		    table->setText(row, 2, track->Artist());
-		    
-		    label.sprintf("%02d:%02d", min, sec);
-		    table->setText(row, 3, label);
-                
-		    row++;
-		}
+                    table->setNumRows(row + 1);
+
+                    table->setRowHeight(row, (int)(30 * hmult));
+
+                    label.sprintf("%d", trackno + 1);
+                    table->setText(row, 0, label);
+
+                    table->setText(row, 1, track->Title());
+
+                    table->setText(row, 2, track->Artist());
+
+                    label.sprintf("%02d:%02d", min, sec);
+                    table->setText(row, 3, label);
+
+                    row++;
+                }
                 delete track;
             }
         }
@@ -283,31 +285,34 @@
 {
     if (gContext->GetNumSetting("OnlyImportNewMusic",1))
     {
-        MSqlQuery query(MSqlQuery::InitCon());	
-	QString queryString("SELECT filename, artist, album, title, intid "
-			    "FROM musicmetadata WHERE artist REGEXP \'");      
-	QString token = artist;
-	token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
+        MSqlQuery query(MSqlQuery::InitCon());
+        QString queryString("SELECT filename, artist_name, album_name, name, song_id "
+                            "FROM music_songs "
+                            "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+                            "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+                            "WHERE artist_name REGEXP \'");      
+        QString token = artist;
+        token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
       
-	queryString += token + "\' AND " + "album REGEXP \'";
-	token = album;
-	token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
-	queryString += token + "\' AND " + "title    REGEXP \'";
-	token = title;
-	token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
-	queryString += token + "\' ORDER BY artist, album, title, intid, filename";      
-	query.prepare(queryString);
-	
-	bool has_entries = true;     
-	if (!query.exec() || !query.isActive())
-	{
-	    MythContext::DBError("Search music database", query);
-	    has_entries = false;
-	}
-      	if (query.numRowsAffected() > 0)
-	{
-	    return false;
-	}
+        queryString += token + "\' AND " + "album_name REGEXP \'";
+        token = album;
+        token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
+        queryString += token + "\' AND " + "name    REGEXP \'";
+        token = title;
+        token.replace(QRegExp("(/|\\\\|:|\'|\\,|\\!|\\(|\\)|\"|\\?|\\|)"), QString("."));
+        queryString += token + "\' ORDER BY artist_name, album_name, name, song_id, filename";      
+        query.prepare(queryString);
+        
+        bool has_entries = true;     
+        if (!query.exec() || !query.isActive())
+        {
+            MythContext::DBError("Search music database", query);
+            has_entries = false;
+        }
+        if (query.numRowsAffected() > 0)
+        {
+            return false;
+        }
     }       
     return true;
 }
@@ -524,31 +529,6 @@
     delete decoder;
 }
 
-void Ripper::fillComboBox(MythComboBox &box, const QString &db_column)
-{
-    QString querystr = QString("SELECT DISTINCT %1 FROM musicmetadata;")
-                               .arg(db_column);
-      
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.exec(querystr);
-   
-    QValueList<QString> list;
-   
-    if (query.isActive() && query.size() > 0)
-    { 
-        while (query.next())
-        {
-            list.push_front(query.value(0).toString());
-        }
-    }
-   
-    QStringList strlist(list);
-   
-    strlist.sort();
-   
-    box.insertStringList(strlist);
-}
-
 void Ripper::handleFileTokens(QString &filename, Metadata *track)
 {
     QString original = filename;
Index: mythmusic/mythmusic/smartplaylist.cpp
===================================================================
--- mythmusic/mythmusic/smartplaylist.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/smartplaylist.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -13,6 +13,7 @@
 using namespace std;
 
 #include "smartplaylist.h"
+#include "metadata.h"
 
 #include <mythtv/mythcontext.h>
 #include <mythtv/dialogbox.h>
@@ -33,19 +34,21 @@
 static SmartPLField SmartPLFields[] = 
 {
     { "",              "",                               ftString,   0,    0,    0 },
-    { "Artist",        "artist",                         ftString,   0,    0,    0 },
-    { "Album",         "album",                          ftString,   0,    0,    0 },
-    { "Title",         "title",                          ftString,   0,    0,    0 },
-    { "Genre",         "genre",                          ftString,   0,    0,    0 },
-    { "Year",          "year",                           ftNumeric,  1900, 2099, 2000 },
-    { "Track No.",     "tracknum",                       ftNumeric,  0,    99,   0 },
-    { "Rating",        "rating",                         ftNumeric,  0,    10,   0 },
-    { "Play Count",    "playcount",                      ftNumeric,  0,    9999, 0 },
-    { "Compilation",   "compilation",                    ftBoolean,  0,    0,    0 },
-    { "Comp. Artist",  "compilation_artist",             ftString,   0,    0,    0 },
-    { "Last Play",     "FROM_DAYS(TO_DAYS(lastplay))",   ftDate,     0,    0,    0 },
-    { "Date Imported", "FROM_DAYS(TO_DAYS(date_added))", ftDate,     0,    0,    0 },
-};        
+    { "Artist",        "music_artists.artist_name",      ftString,   0,    0,    0 },
+    { "Album",         "music_songs.album_name",         ftString,   0,    0,    0 },
+    { "Title",         "music_songs.name",               ftString,   0,    0,    0 },
+    { "Genre",         "music_genres.genre",             ftString,   0,    0,    0 },
+    { "Year",          "music_songs.year",               ftNumeric,  1900, 2099, 2000 },
+    { "Track No.",     "music_songs.track",              ftNumeric,  0,    99,   0 },
+    { "Rating",        "music_songs.rating",             ftNumeric,  0,    10,   0 },
+    { "Play Count",    "music_songs.numplays",           ftNumeric,  0,    9999, 0 },
+    { "Compilation",   "music_albums.compilation",       ftBoolean,  0,    0,    0 },
+    { "Comp. Artist",  "music_comp_artists.artist_name", ftString,   0,    0,    0 },
+    { "Last Play",     "FROM_DAYS(TO_DAYS(music_songs.lastplay))",
+                                                         ftDate,     0,    0,    0 },
+    { "Date Imported", "FROM_DAYS(TO_DAYS(music_songs.date_added))",
+                                                         ftDate,     0,    0,    0 },
+};
 
 struct SmartPLOperator
 {
@@ -644,36 +647,18 @@
         value = searchDialog->getResult();
         res = true;
     }
-    
+
     delete searchDialog;
-    
-    return res;     
-}
 
-void SmartPLCriteriaRow::fillSearchList(QString field)
-{
-    searchList.clear();
-    
-    MSqlQuery query(MSqlQuery::InitCon());
-    QString querystr;
-    querystr = QString("SELECT DISTINCT %1 FROM musicmetadata ORDER BY %2").arg(field).arg(field);
-        
-    query.exec(querystr);
-    if (query.isActive() && query.numRowsAffected())
-    {
-        while (query.next())
-        {
-            searchList << QString::fromUtf8(query.value(0).toString());
-        }
-    }         
+    return res;
 }
-    
+
 void SmartPLCriteriaRow::searchArtist(MythRemoteLineEdit *editor)
 {
     QString s;
-    
-    fillSearchList("artist");
-    
+
+    searchList = Metadata::fillFieldList("artist");
+
     s = editor->text();
     if (showList(tr("Select an Artist"), s))
     {
@@ -684,9 +669,9 @@
 void SmartPLCriteriaRow::searchCompilationArtist(MythRemoteLineEdit *editor)
 {
     QString s;
-    
-    fillSearchList("compilation_artist");
-    
+
+    searchList = Metadata::fillFieldList("compilation_artist");
+
     s = editor->text();
     if (showList(tr("Select a Compilation Artist"), s))
     {
@@ -697,9 +682,9 @@
 void SmartPLCriteriaRow::searchAlbum(MythRemoteLineEdit *editor)
 {
     QString s;
-    
-    fillSearchList("album");
-    
+
+    searchList = Metadata::fillFieldList("album");
+
     s = editor->text();
     if (showList(tr("Select an Album"), s))
     {
@@ -711,7 +696,7 @@
 {
     QString s;
 
-    fillSearchList("genre");
+    searchList = Metadata::fillFieldList("genre");
 
     s = editor->text();
     if (showList(tr("Select a Genre"), s))
@@ -724,7 +709,7 @@
 {
     QString s;
 
-    fillSearchList("title");
+    searchList = Metadata::fillFieldList("title");
 
     s = editor->text();
     if (showList(tr("Select a Title"), s))
@@ -815,7 +800,7 @@
     }
     
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("INSERT INTO smartplaylistitem (smartplaylistid, field, operator,"
+    query.prepare("INSERT INTO music_smartplaylist_items (smartplaylistid, field, operator,"
                   " value1, value2)"
                   "VALUES (:SMARTPLAYLISTID, :FIELD, :OPERATOR, :VALUE1, :VALUE2);");
     query.bindValue(":SMARTPLAYLISTID", smartPlaylistID);
@@ -1130,7 +1115,7 @@
 {
     bPlaylistIsValid = true;
     
-    QString sql = "select count(*) from musicmetadata ";
+    QString sql = "select count(*) from music_songs ";
     sql += getWhereClause();
     
     MSqlQuery query(MSqlQuery::InitCon());
@@ -1177,7 +1162,7 @@
     
     MSqlQuery query(MSqlQuery::InitCon());
     // insert new smartplaylist
-    query.prepare("INSERT INTO smartplaylist (name, categoryid, matchtype, orderby, limitto) "
+    query.prepare("INSERT INTO music_smartplaylists (name, categoryid, matchtype, orderby, limitto) "
                 "VALUES (:NAME, :CATEGORYID, :MATCHTYPE, :ORDERBY, :LIMIT);");
     query.bindValue(":NAME", name.utf8());
     query.bindValue(":CATEGORYID", categoryid);
@@ -1193,7 +1178,7 @@
     
     // get smartplaylistid
     int ID;
-    query.prepare("SELECT smartplaylistid FROM smartplaylist "
+    query.prepare("SELECT smartplaylistid FROM music_smartplaylists "
                   "WHERE categoryid = :CATEGORYID AND name = :NAME;");
     query.bindValue(":CATEGORYID", categoryid);
     query.bindValue(":NAME", name.utf8());
@@ -1252,8 +1237,8 @@
     MSqlQuery query(MSqlQuery::InitCon());
     int ID;
     
-    query.prepare("SELECT smartplaylistid, name, categoryid, matchtype, orderby, limitto " 
-                  "FROM smartplaylist WHERE name = :NAME AND categoryid = :CATEGORYID;");
+    query.prepare("SELECT smartplaylistid, name, categoryid, matchtype, orderby, limitto "
+                  "FROM music_smartplaylists WHERE name = :NAME AND categoryid = :CATEGORYID;");
     query.bindValue(":NAME", name.utf8());
     query.bindValue(":CATEGORYID", categoryid);
     if (query.exec())
@@ -1284,8 +1269,8 @@
     SmartPLCriteriaRow *row;    
     uint rowCount;
     
-    query.prepare("SELECT field, operator, value1, value2 " 
-                  "FROM smartplaylistitem WHERE smartplaylistid = :ID "
+    query.prepare("SELECT field, operator, value1, value2 "
+                  "FROM music_smartplaylist_items WHERE smartplaylistid = :ID "
                   "ORDER BY smartplaylistitemid;");
     query.bindValue(":ID", ID);
     if (!query.exec())
@@ -1392,7 +1377,7 @@
     // insert new smartplaylistcategory
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("INSERT INTO smartplaylistcategory (name) "
+    query.prepare("INSERT INTO music_smartplaylist_categories (name) "
                 "VALUES (:NAME);");
     query.bindValue(":NAME", categoryEdit->text().utf8());
     
@@ -1438,7 +1423,7 @@
         
     // change the category     
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("UPDATE smartplaylistcategory SET name = :NEW_CATEGORY "
+    query.prepare("UPDATE music_smartplaylist_categories SET name = :NEW_CATEGORY "
                   "WHERE name = :OLD_CATEGORY;");
     query.bindValue(":OLD_CATEGORY", categoryCombo->currentText().utf8());
     query.bindValue(":NEW_CATEGORY", categoryEdit->text().utf8());
@@ -1458,8 +1443,12 @@
 QString SmartPlaylistEditor::getSQL(QString fields)
 {
     QString sql, whereClause, orderByClause, limitClause;
-    
-    sql = "SELECT " + fields + " FROM musicmetadata ";
+    sql = "SELECT " + fields + " FROM music_songs "
+          "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
+          "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
+          "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
+          "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id ";
+
     whereClause = getWhereClause();
     orderByClause = getOrderByClause();
     if (limitSpinEdit->value() > 0)
@@ -1506,8 +1495,8 @@
 
 void SmartPlaylistEditor::showResultsClicked(void)
 {
-    QString sql = getSQL("intid, artist, album, title, genre, year, tracknum");
-    
+    QString sql = getSQL("song_id, music_artists.artist_name, album_name, name, genre, year, track");
+
     SmartPLResultViewer *resultViewer = new SmartPLResultViewer(gContext->GetMainWindow(), "resultviewer");
     resultViewer->setSQL(sql);
     resultViewer->exec();
@@ -1535,7 +1524,7 @@
     categoryCombo->clear();
     MSqlQuery query(MSqlQuery::InitCon());
 
-    if (query.exec("SELECT name FROM smartplaylistcategory ORDER BY name;"))
+    if (query.exec("SELECT name FROM music_smartplaylist_categories ORDER BY name;"))
     {
         if (query.isActive() && query.numRowsAffected() > 0)
         {
@@ -1563,7 +1552,7 @@
     
     // get playlist ID
     int ID;
-    query.prepare("SELECT smartplaylistid FROM smartplaylist WHERE name = :NAME "
+    query.prepare("SELECT smartplaylistid FROM music_smartplaylists WHERE name = :NAME "
                   "AND categoryid = :CATEGORYID;");
     query.bindValue(":NAME", name.utf8());
     query.bindValue(":CATEGORYID", categoryid);
@@ -1588,13 +1577,13 @@
     } 
     
     //delete smartplaylist items
-    query.prepare("DELETE FROM smartplaylistitem WHERE smartplaylistid = :ID;");
+    query.prepare("DELETE FROM music_smartplaylist_items WHERE smartplaylistid = :ID;");
     query.bindValue(":ID", ID);
     if (!query.exec())
         MythContext::DBError("Delete smartplaylist items", query);
 
     //delete smartplaylist
-    query.prepare("DELETE FROM smartplaylist WHERE smartplaylistid = :ID;");
+    query.prepare("DELETE FROM music_smartplaylists WHERE smartplaylistid = :ID;");
     query.bindValue(":ID", ID);
     if (!query.exec())
         MythContext::DBError("Delete smartplaylist", query);
@@ -1608,9 +1597,9 @@
 {
     int categoryid = SmartPlaylistEditor::lookupCategoryID(category);
     MSqlQuery query(MSqlQuery::InitCon());
-    
+
     //delete all smartplaylists with the selected category
-    query.prepare("SELECT name FROM smartplaylist "
+    query.prepare("SELECT name FROM music_smartplaylists "
                   "WHERE categoryid = :CATEGORYID;");
     query.bindValue(":CATEGORYID", categoryid);
     if (!query.exec())
@@ -1629,7 +1618,7 @@
     }
     
     // delete the category
-    query.prepare("DELETE FROM smartplaylistcategory WHERE categoryid = :ID;");
+    query.prepare("DELETE FROM music_smartplaylist_categories WHERE categoryid = :ID;");
     query.bindValue(":ID", categoryid);
     if (!query.exec())
         MythContext::DBError("Delete smartplaylist category", query);
@@ -1639,15 +1628,15 @@
 
 // static function to lookup the categoryid given its name
 int SmartPlaylistEditor::lookupCategoryID(QString category)
-{    
+{
     int ID;
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT categoryid FROM smartplaylistcategory "
+    query.prepare("SELECT categoryid FROM music_smartplaylist_categories "
                   "WHERE name = :CATEGORY;");
     query.bindValue(":CATEGORY", category.utf8());
 
     if (query.exec())
-    {    
+    {
         if (query.isActive() && query.numRowsAffected() > 0)
         {
             query.first();
@@ -2023,7 +2012,7 @@
     categoryCombo->clear();
     MSqlQuery query(MSqlQuery::InitCon());
 
-    if (query.exec("SELECT name FROM smartplaylistcategory ORDER BY name;"))
+    if (query.exec("SELECT name FROM music_smartplaylist_categories ORDER BY name;"))
     {
         if (query.isActive() && query.numRowsAffected() > 0)
         {
@@ -2044,8 +2033,8 @@
 
     listbox->clear();
 
-    MSqlQuery query(MSqlQuery::InitCon());    
-    query.prepare("SELECT name FROM smartplaylist WHERE categoryid = :CATEGORYID "
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT name FROM music_smartplaylists WHERE categoryid = :CATEGORYID "
                   "ORDER BY name;");
     query.bindValue(":CATEGORYID", categoryid);
                    
Index: mythmusic/mythmusic/metadata.h
===================================================================
--- mythmusic/mythmusic/metadata.h	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/metadata.h	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -42,8 +42,11 @@
                 format = lformat;
             }
 
-    Metadata(const Metadata &other) 
+    Metadata(const Metadata &other)
             {
+                *this = other;
+                changed = false;
+                /*
                 filename = other.filename;
                 artist = other.artist;
                 compilation_artist = other.compilation_artist;
@@ -63,6 +66,7 @@
                 show = other.show;
                 changed = false;
                 format = other.format;
+                */
             }
 
     Metadata& operator=(Metadata *rhs);
@@ -125,14 +129,11 @@
     bool Compilation() { return compilation; }
     void setCompilation(bool state) { compilation = state; formattedartist = formattedtitle = ""; }
     bool determineIfCompilation(bool cd = false);
-    
+
     bool isInDatabase(void);
     void dumpToDatabase(void);
-    void updateDatabase(void);
     void setField(const QString &field, const QString &data);
     void getField(const QString& field, QString *data);
-    void fillData();
-    void fillDataFromID();
     void persist();
     bool hasChanged(){return changed;}
     int compare (Metadata *other);
@@ -140,6 +141,8 @@
 
     static void SetStartdir(const QString &dir);
 
+    static QStringList fillFieldList(QString field);
+
   private:
     void setCompilationFormatting(bool cd = false);
     QString formatReplaceSymbols(const QString &format);
Index: mythmusic/mythmusic/editmetadata.cpp
===================================================================
--- mythmusic/mythmusic/editmetadata.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/editmetadata.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -4,6 +4,7 @@
 #include "editmetadata.h"
 #include "decoder.h"
 #include "genres.h"
+#include "metadata.h"
 
 EditMetadataDialog::EditMetadataDialog(Metadata *source_metadata,
                                  MythMainWindow *parent,
@@ -357,38 +358,19 @@
         value = searchDialog->getResult();
         res = true;
     }
-    
+
     delete searchDialog;
     setActiveWindow();
-    
-    return res;     
-}
 
-void EditMetadataDialog::fillSearchList(QString field)
-{
-    searchList.clear();
-    
-    QString querystr;
-    querystr = QString("SELECT DISTINCT %1 FROM musicmetadata ORDER BY %2").arg(field).arg(field);
-         
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.exec(querystr);
-
-    if (query.isActive() && query.size())
-    {
-        while (query.next())
-        {
-            searchList << QString::fromUtf8(query.value(0).toString());
-        }
-    }         
+    return res;
 }
-    
+
 void EditMetadataDialog::searchArtist()
 {
     QString s;
-    
-    fillSearchList("artist");
-    
+
+    searchList = Metadata::fillFieldList("artist");
+
     s = m_metadata->Artist();
     if (showList(tr("Select an Artist"), s))
     {
@@ -400,9 +382,9 @@
 void EditMetadataDialog::searchCompilationArtist()
 {
     QString s;
-    
-    fillSearchList("compilation_artist");
-    
+
+    searchList = Metadata::fillFieldList("compilation_artist");
+
     s = m_metadata->CompilationArtist();
     if (showList(tr("Select a Compilation Artist"), s))
     {
@@ -414,9 +396,9 @@
 void EditMetadataDialog::searchAlbum()
 {
     QString s;
-    
-    fillSearchList("album");
-    
+
+    searchList = Metadata::fillFieldList("album");
+
     s = m_metadata->Album();
     if (showList(tr("Select an Album"), s))
     {
@@ -430,10 +412,13 @@
     QString s;
 
     // load genre list
+    /*
     searchList.clear();
     for (int x = 0; x < genre_table_size; x++)
         searchList.push_back(QString(genre_table[x]));
     searchList.sort();
+    */
+    searchList = Metadata::fillFieldList("genre");
 
     s = m_metadata->Genre();
     if (showList(tr("Select a Genre"), s))
@@ -491,7 +476,7 @@
 {
     cancelPopup();
 
-    m_metadata->updateDatabase();
+    m_metadata->dumpToDatabase();
     *m_sourceMetadata = m_metadata;
     done(1);
 }
Index: mythmusic/mythmusic/smartplaylist.h
===================================================================
--- mythmusic/mythmusic/smartplaylist.h	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/smartplaylist.h	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -72,7 +72,6 @@
     void value2ButtonClicked(void);
   
   private:
-    void fillSearchList(QString field);
     bool showList(QString caption, QString &value);
     void searchGenre(MythRemoteLineEdit *editor);
     void searchArtist(MythRemoteLineEdit *editor);
Index: mythmusic/mythmusic/main.cpp
===================================================================
--- mythmusic/mythmusic/main.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/main.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -91,7 +91,7 @@
     // We know that the filename will not contain :// as the SQL limits this
     sqlfilename.remove(0, directory.length());
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("DELETE FROM musicmetadata WHERE "
+    query.prepare("DELETE FROM music_songs WHERE "
                   "filename = :NAME ;");
     query.bindValue(":NAME", sqlfilename.utf8());
     query.exec();
@@ -110,7 +110,7 @@
         {
             disk_meta->setID(db_meta->ID());
             disk_meta->setRating(db_meta->Rating());
-            disk_meta->updateDatabase();
+            disk_meta->dumpToDatabase();
         }
 
         if (disk_meta)
@@ -261,7 +261,7 @@
 
     MSqlQuery query(MSqlQuery::InitCon());
     query.exec("SELECT filename, date_modified "
-               "FROM musicmetadata "
+               "FROM music_songs "
                "WHERE filename NOT LIKE ('%://%')");
 
     int counter = 0;
@@ -561,7 +561,7 @@
 
 
     MSqlQuery count_query(MSqlQuery::InitCon());
-    count_query.exec("SELECT COUNT(*) FROM musicmetadata;");
+    count_query.exec("SELECT COUNT(*) FROM music_songs;");
 
     bool musicdata_exists = false;
     if (count_query.isActive())
Index: mythmusic/mythmusic/editmetadata.h
===================================================================
--- mythmusic/mythmusic/editmetadata.h	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/editmetadata.h	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -6,7 +6,7 @@
 
 #include <mythtv/mythdialogs.h>
 
-#include "metadata.h"
+class Metadata;
 
 class UIPhoneEntry;
 
@@ -45,7 +45,6 @@
     void checkClicked(bool state);
   private:
 
-    void fillSearchList(QString field);
     bool showList(QString caption, QString &value);
     
     Metadata *m_metadata, *m_sourceMetadata ;
Index: mythmusic/mythmusic/metaiomp4.cpp
===================================================================
--- mythmusic/mythmusic/metaiomp4.cpp	(.../trunk/mythplugins)	(revision 65)
+++ mythmusic/mythmusic/metaiomp4.cpp	(.../branches/music-refactor/mythplugins)	(revision 65)
@@ -348,9 +348,9 @@
                                      genre,
                                      year, 
                                      tracknum, 
-                                     length,
-                                     0, 0, 0, "",
-                                     compilation);
+                                     length);
+    
+    retdata->setCompilation(compilation);
 
     //retdata->setComposer(writer);
     //retdata->setComment(comment);

