db/DatabaseListener: add method OnDatabaseSongRemoved()

Decouples db/update/Remove.cpp from global variables.
This commit is contained in:
Max Kellermann 2014-02-04 19:16:30 +01:00
parent ce73843014
commit ff665b37cb
10 changed files with 49 additions and 38 deletions

View File

@ -22,9 +22,15 @@
#include "Partition.hxx"
#include "Idle.hxx"
#include "Stats.hxx"
#include "db/DatabaseError.hxx"
#ifdef ENABLE_DATABASE
#include "db/DatabaseError.hxx"
#include "db/LightSong.hxx"
#ifdef ENABLE_SQLITE
#include "sticker/StickerDatabase.hxx"
#include "sticker/SongSticker.hxx"
#endif
Database *
Instance::GetDatabase(Error &error)
@ -34,12 +40,6 @@ Instance::GetDatabase(Error &error)
return database;
}
void
Instance::DeleteSong(const char *uri)
{
partition->DeleteSong(uri);
}
#endif
void
@ -68,6 +68,21 @@ Instance::OnDatabaseModified()
idle_add(IDLE_DATABASE);
}
void
Instance::OnDatabaseSongRemoved(const LightSong &song)
{
assert(database != nullptr);
#ifdef ENABLE_SQLITE
/* if the song has a sticker, remove it */
if (sticker_enabled())
sticker_song_delete(song);
#endif
const auto uri = song.GetURI();
partition->DeleteSong(uri.c_str());
}
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS

View File

@ -79,8 +79,6 @@ struct Instance final
* music_directory was configured).
*/
Database *GetDatabase(Error &error);
void DeleteSong(const char *uri);
#endif
/**
@ -96,7 +94,8 @@ struct Instance final
private:
#ifdef ENABLE_DATABASE
virtual void OnDatabaseModified();
virtual void OnDatabaseModified() override;
virtual void OnDatabaseSongRemoved(const LightSong &song) override;
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS

View File

@ -20,6 +20,8 @@
#ifndef MPD_DATABASE_CLIENT_HXX
#define MPD_DATABASE_CLIENT_HXX
struct LightSong;
/**
* An object that listens to events from the #Database.
*
@ -33,6 +35,12 @@ public:
* runs the #EventLoop.
*/
virtual void OnDatabaseModified() = 0;
/**
* During database update, a song is about to be removed from
* the database because the file has disappeared.
*/
virtual void OnDatabaseSongRemoved(const LightSong &song) = 0;
};
#endif

View File

@ -31,8 +31,8 @@ class DatabaseEditor final {
UpdateRemoveService remove;
public:
DatabaseEditor(EventLoop &_loop)
:remove(_loop) {}
DatabaseEditor(EventLoop &_loop, DatabaseListener &_listener)
:remove(_loop, _listener) {}
/**
* Caller must lock the #db_mutex.

View File

@ -20,20 +20,11 @@
#include "config.h" /* must be first for large file support */
#include "Remove.hxx"
#include "UpdateDomain.hxx"
#include "GlobalEvents.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "db/Song.hxx"
#include "db/LightSong.hxx"
#include "Main.hxx"
#include "Instance.hxx"
#include "db/DatabaseListener.hxx"
#include "Log.hxx"
#ifdef ENABLE_SQLITE
#include "sticker/StickerDatabase.hxx"
#include "sticker/SongSticker.hxx"
#endif
#include <assert.h>
/**
@ -50,16 +41,7 @@ UpdateRemoveService::RunDeferred()
FormatDefault(update_domain, "removing %s", uri.c_str());
}
#ifdef ENABLE_SQLITE
/* if the song has a sticker, remove it */
if (sticker_enabled())
sticker_song_delete(removed_song->Export());
#endif
{
const auto uri = removed_song->GetURI();
instance->DeleteSong(uri.c_str());
}
listener.OnDatabaseSongRemoved(removed_song->Export());
/* clear "removed_song" and send signal to update thread */
remove_mutex.lock();

View File

@ -26,20 +26,23 @@
#include "thread/Cond.hxx"
struct Song;
class DatabaseListener;
/**
* This class handles #Song removal. It defers the action to the main
* thread to ensure that all references to the #Song are gone.
*/
class UpdateRemoveService final : DeferredMonitor {
DatabaseListener &listener;
Mutex remove_mutex;
Cond remove_cond;
const Song *removed_song;
public:
UpdateRemoveService(EventLoop &_loop)
:DeferredMonitor(_loop) {}
UpdateRemoveService(EventLoop &_loop, DatabaseListener &_listener)
:DeferredMonitor(_loop), listener(_listener) {}
/**
* Sends a signal to the main thread which will in turn remove

View File

@ -155,6 +155,6 @@ UpdateService::UpdateService(EventLoop &_loop, SimpleDatabase &_db,
:DeferredMonitor(_loop), db(_db), listener(_listener),
progress(UPDATE_PROGRESS_IDLE),
update_task_id(0),
walk(_loop)
walk(_loop, _listener)
{
}

View File

@ -46,8 +46,8 @@
#include <stdlib.h>
#include <errno.h>
UpdateWalk::UpdateWalk(EventLoop &_loop)
:editor(_loop)
UpdateWalk::UpdateWalk(EventLoop &_loop, DatabaseListener &_listener)
:editor(_loop, _listener)
{
#ifndef WIN32
follow_inside_symlinks =

View File

@ -49,7 +49,7 @@ class UpdateWalk final {
DatabaseEditor editor;
public:
UpdateWalk(EventLoop &_loop);
UpdateWalk(EventLoop &_loop, DatabaseListener &_listener);
/**
* Returns true if the database was modified.

View File

@ -55,6 +55,10 @@ public:
virtual void OnDatabaseModified() override {
cout << "DatabaseModified" << endl;
}
virtual void OnDatabaseSongRemoved(const LightSong &song) override {
cout << "SongRemoved " << song.GetURI() << endl;
}
};
static bool