From ff665b37cb92e2a1664bbab207030a1eedfbb036 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 4 Feb 2014 19:16:30 +0100
Subject: db/DatabaseListener: add method OnDatabaseSongRemoved()

Decouples db/update/Remove.cpp from global variables.
---
 src/Instance.cxx             | 29 ++++++++++++++++++++++-------
 src/Instance.hxx             |  5 ++---
 src/db/DatabaseListener.hxx  |  8 ++++++++
 src/db/update/Editor.hxx     |  4 ++--
 src/db/update/Remove.cxx     | 22 ++--------------------
 src/db/update/Remove.hxx     |  7 +++++--
 src/db/update/UpdateGlue.cxx |  2 +-
 src/db/update/Walk.cxx       |  4 ++--
 src/db/update/Walk.hxx       |  2 +-
 test/DumpDatabase.cxx        |  4 ++++
 10 files changed, 49 insertions(+), 38 deletions(-)

diff --git a/src/Instance.cxx b/src/Instance.cxx
index db81a2542..232cd21df 100644
--- a/src/Instance.cxx
+++ b/src/Instance.cxx
@@ -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
diff --git a/src/Instance.hxx b/src/Instance.hxx
index 7d517e245..df5fdfbc4 100644
--- a/src/Instance.hxx
+++ b/src/Instance.hxx
@@ -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
diff --git a/src/db/DatabaseListener.hxx b/src/db/DatabaseListener.hxx
index 4da458866..8b410c2f5 100644
--- a/src/db/DatabaseListener.hxx
+++ b/src/db/DatabaseListener.hxx
@@ -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
diff --git a/src/db/update/Editor.hxx b/src/db/update/Editor.hxx
index b1c99095f..fc08c2659 100644
--- a/src/db/update/Editor.hxx
+++ b/src/db/update/Editor.hxx
@@ -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.
diff --git a/src/db/update/Remove.cxx b/src/db/update/Remove.cxx
index e2c172a4b..102347905 100644
--- a/src/db/update/Remove.cxx
+++ b/src/db/update/Remove.cxx
@@ -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();
diff --git a/src/db/update/Remove.hxx b/src/db/update/Remove.hxx
index 1970c0a07..5c09f55df 100644
--- a/src/db/update/Remove.hxx
+++ b/src/db/update/Remove.hxx
@@ -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
diff --git a/src/db/update/UpdateGlue.cxx b/src/db/update/UpdateGlue.cxx
index ea1bf6f09..32e817ff1 100644
--- a/src/db/update/UpdateGlue.cxx
+++ b/src/db/update/UpdateGlue.cxx
@@ -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)
 {
 }
diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx
index ed09c1676..c54d5a8d7 100644
--- a/src/db/update/Walk.cxx
+++ b/src/db/update/Walk.cxx
@@ -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 =
diff --git a/src/db/update/Walk.hxx b/src/db/update/Walk.hxx
index ecb04387d..aa4516917 100644
--- a/src/db/update/Walk.hxx
+++ b/src/db/update/Walk.hxx
@@ -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.
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx
index af1139407..d282e9360 100644
--- a/test/DumpDatabase.cxx
+++ b/test/DumpDatabase.cxx
@@ -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
-- 
cgit v1.2.3