Use the Jamendo track id as the ROWID for tracks, and implement reloading the database.

This commit is contained in:
David Sansome 2010-11-25 23:05:37 +00:00
parent 17da224283
commit 4e60558053
6 changed files with 65 additions and 17 deletions

View File

@ -287,7 +287,7 @@ void LibraryBackend::AddOrUpdateSubdirs(const SubdirectoryList& subdirs) {
transaction.Commit();
}
void LibraryBackend::AddOrUpdateSongs(const SongList& songs) {
void LibraryBackend::AddOrUpdateSongs(const SongList& songs, bool insert_with_id) {
QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect());
@ -296,6 +296,9 @@ void LibraryBackend::AddOrUpdateSongs(const SongList& songs) {
QSqlQuery add_song(QString("INSERT INTO %1 (" + Song::kColumnSpec + ")"
" VALUES (" + Song::kBindSpec + ")")
.arg(songs_table_), db);
QSqlQuery add_song_id(QString("INSERT INTO %1 (ROWID, " + Song::kColumnSpec + ")"
" VALUES (:id, " + Song::kBindSpec + ")")
.arg(songs_table_), db);
QSqlQuery update_song(QString("UPDATE %1 SET " + Song::kUpdateSpec +
" WHERE ROWID = :id").arg(songs_table_), db);
QSqlQuery add_song_fts(QString("INSERT INTO %1 (ROWID, " + Song::kFtsColumnSpec + ")"
@ -323,14 +326,27 @@ void LibraryBackend::AddOrUpdateSongs(const SongList& songs) {
}
if (song.id() == -1) {
if (insert_with_id || song.id() == -1) {
// Create
song.BindToQuery(&add_song);
add_song.exec();
if (db_->CheckErrors(add_song.lastError())) continue;
const int id = add_song.lastInsertId().toInt();
int id = song.id();
if (insert_with_id) {
// Insert the row with the existing ID
add_song_id.bindValue(":id", song.id());
song.BindToQuery(&add_song_id);
add_song_id.exec();
if (db_->CheckErrors(add_song_id.lastError())) continue;
} else {
// Insert the row and create a new ID
song.BindToQuery(&add_song);
add_song.exec();
if (db_->CheckErrors(add_song.lastError())) continue;
// Get the new ID
id = add_song.lastInsertId().toInt();
}
// Add to the FTS index
add_song_fts.bindValue(":id", id);
song.BindToFtsQuery(&add_song_fts);
add_song_fts.exec();
@ -897,3 +913,25 @@ void LibraryBackend::UpdateSongRating(int id, float rating) {
Song new_song = GetSongById(id, db);
emit SongsStatisticsChanged(SongList() << new_song);
}
void LibraryBackend::DeleteAll() {
{
QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect());
ScopedTransaction t(&db);
QSqlQuery q("DELETE FROM " + songs_table_, db);
q.exec();
if (db_->CheckErrors(q.lastError()))
return;
q = QSqlQuery("DELETE FROM " + fts_table_, db);
q.exec();
if (db_->CheckErrors(q.lastError()))
return;
t.Commit();
}
emit DatabaseReset();
}

View File

@ -140,10 +140,12 @@ class LibraryBackend : public LibraryBackendInterface {
void IncrementSkipCountAsync(int id, float progress);
void UpdateSongRatingAsync(int id, float rating);
void DeleteAll();
public slots:
void LoadDirectories();
void UpdateTotalSongCount();
void AddOrUpdateSongs(const SongList& songs);
void AddOrUpdateSongs(const SongList& songs, bool insert_with_id = false);
void UpdateMTimesOnly(const SongList& songs);
void DeleteSongs(const SongList& songs);
void AddOrUpdateSubdirs(const SubdirectoryList& subdirs);
@ -161,6 +163,7 @@ class LibraryBackend : public LibraryBackendInterface {
void SongsDiscovered(const SongList& songs);
void SongsDeleted(const SongList& songs);
void SongsStatisticsChanged(const SongList& songs);
void DatabaseReset();
void TotalSongCountUpdated(int total);

View File

@ -70,6 +70,7 @@ void LibraryModel::Init() {
connect(backend_, SIGNAL(SongsDiscovered(SongList)), SLOT(SongsDiscovered(SongList)));
connect(backend_, SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList)));
connect(backend_, SIGNAL(SongsStatisticsChanged(SongList)), SLOT(SongsStatisticsChanged(SongList)));
connect(backend_, SIGNAL(DatabaseReset()), SLOT(Reset()));
connect(backend_, SIGNAL(TotalSongCountUpdated(int)), SIGNAL(TotalSongCountUpdated(int)));
backend_->UpdateTotalSongCountAsync();

View File

@ -166,6 +166,9 @@ void JamendoService::ParseDirectory(QIODevice* device) const {
disconnect(library_backend_, SIGNAL(SongsDiscovered(SongList)),
library_model_, SLOT(SongsDiscovered(SongList)));
// Delete all existing songs in the db
library_backend_->DeleteAll();
SongList songs;
QXmlStreamReader reader(device);
while (!reader.atEnd()) {
@ -177,7 +180,7 @@ void JamendoService::ParseDirectory(QIODevice* device) const {
if (songs.count() >= kBatchSize) {
// Add the songs to the database in batches
library_backend_->AddOrUpdateSongs(songs);
library_backend_->AddOrUpdateSongs(songs, true);
total_count += songs.count();
songs.clear();
@ -187,7 +190,7 @@ void JamendoService::ParseDirectory(QIODevice* device) const {
}
}
library_backend_->AddOrUpdateSongs(songs);
library_backend_->AddOrUpdateSongs(songs, true);
connect(library_backend_, SIGNAL(SongsDiscovered(SongList)),
library_model_, SLOT(SongsDiscovered(SongList)));
@ -279,11 +282,16 @@ Song JamendoService::ReadTrack(const QString& artist,
song.set_genre(genre_id);
}
} else if (name == "id") {
QString id = reader->readElementText();
QString ogg_url = QString(kOggStreamUrl).arg(id);
QString id_text = reader->readElementText();
int id = id_text.toInt();
if (id == 0)
continue;
QString ogg_url = QString(kOggStreamUrl).arg(id_text);
song.set_filename(ogg_url);
song.set_art_automatic(album_cover);
song.set_id(id);
song.set_valid(true);
}
} else if (reader->isEndElement() && reader->name() == "track") {
@ -314,7 +322,7 @@ void JamendoService::EnsureMenuCreated() {
tr("Download this album..."), this, SLOT(DownloadAlbum()));
context_menu_->addSeparator();
context_menu_->addAction(IconLoader::Load("download"), tr("Open jamendo.com in browser"), this, SLOT(Homepage()));
context_menu_->addAction(IconLoader::Load("view-refresh"), tr("Refresh catalogue"), this, SLOT(ReloadDatabase()));
context_menu_->addAction(IconLoader::Load("view-refresh"), tr("Refresh catalogue"), this, SLOT(DownloadDirectory()));
library_filter_ = new LibraryFilterWidget(0);
library_filter_->SetSettingsGroup(kSettingsGroup);

View File

@ -64,7 +64,6 @@ class JamendoService : public RadioService {
static const int kApproxDatabaseSize;
private:
void DownloadDirectory();
void ParseDirectory(QIODevice* device) const;
SongList ReadArtist(QXmlStreamReader* reader) const;
@ -78,6 +77,7 @@ class JamendoService : public RadioService {
void EnsureMenuCreated();
private slots:
void DownloadDirectory();
void DownloadDirectoryProgress(qint64 received, qint64 total);
void DownloadDirectoryFinished();
void ParseDirectoryFinished();

View File

@ -169,13 +169,11 @@ void MagnatuneService::ReloadDatabaseFinished() {
}
// Remove all existing songs in the database
// FindSongsByDirectory isn't the nicest way to do it, but it's easy
SongList songs = library_backend_->FindSongsInDirectory(0);
library_backend_->DeleteSongs(songs);
songs.clear();
library_backend_->DeleteAll();
// Parse the XML we got from Magnatune
QXmlStreamReader reader(&gzip);
SongList songs;
while (!reader.atEnd()) {
reader.readNext();