diff --git a/src/SongLoader.cxx b/src/SongLoader.cxx index 2ed34671c..90df42824 100644 --- a/src/SongLoader.cxx +++ b/src/SongLoader.cxx @@ -92,11 +92,12 @@ SongLoader::LoadSong(const char *uri_utf8, Error &error) const /* URI relative to the music directory */ #ifdef ENABLE_DATABASE - return DatabaseDetachSong(uri_utf8, error); -#else + if (db != nullptr) + return DatabaseDetachSong(*db, uri_utf8, error); +#endif + error.Set(playlist_domain, int(PlaylistResult::NO_SUCH_SONG), "No database"); return nullptr; -#endif } } diff --git a/src/SongLoader.hxx b/src/SongLoader.hxx index aaa8060db..997c0fb18 100644 --- a/src/SongLoader.hxx +++ b/src/SongLoader.hxx @@ -20,9 +20,13 @@ #ifndef MPD_SONG_LOADER_HXX #define MPD_SONG_LOADER_HXX +#include "check.h" #include "Compiler.h" +#include + class Client; +class Database; class DetachedSong; class Error; @@ -35,11 +39,26 @@ class Error; class SongLoader { const Client *const client; +#ifdef ENABLE_DATABASE + const Database *const db; +#endif + public: +#ifdef ENABLE_DATABASE + SongLoader(const Client *_client, const Database *_db=nullptr) + :client(_client), db(_db) {} + explicit SongLoader(const Client &_client) + :client(&_client), db(nullptr) {} + explicit SongLoader(const Database *_db) + :client(nullptr), db(_db) {} + explicit SongLoader(std::nullptr_t) + :client(nullptr), db(nullptr) {} +#else explicit SongLoader(const Client &_client) :client(&_client) {} explicit SongLoader(const Client *_client) :client(_client) {} +#endif gcc_nonnull_all DetachedSong *LoadSong(const char *uri_utf8, Error &error) const; diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx index 2b871e565..b458b3756 100644 --- a/src/command/DatabaseCommands.cxx +++ b/src/command/DatabaseCommands.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "DatabaseCommands.hxx" +#include "db/DatabaseGlue.hxx" #include "db/DatabaseQueue.hxx" #include "db/DatabasePlaylist.hxx" #include "db/DatabasePrint.hxx" @@ -119,7 +120,11 @@ handle_searchaddpl(Client &client, int argc, char *argv[]) } Error error; - return search_add_to_playlist("", playlist, &filter, error) + const Database *db = GetDatabase(error); + if (db == nullptr) + return print_error(client, error); + + return search_add_to_playlist(*db, "", playlist, &filter, error) ? CommandResult::OK : print_error(client, error); } diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx index 10dfff876..07cc177d6 100644 --- a/src/command/PlaylistCommands.cxx +++ b/src/command/PlaylistCommands.cxx @@ -19,6 +19,7 @@ #include "config.h" #include "PlaylistCommands.hxx" +#include "db/DatabaseGlue.hxx" #include "db/DatabasePlaylist.hxx" #include "CommandError.hxx" #include "PlaylistPrint.hxx" @@ -192,7 +193,11 @@ handle_playlistadd(Client &client, gcc_unused int argc, char *argv[]) success = spl_append_uri(playlist, loader, uri, error); } else { #ifdef ENABLE_DATABASE - success = search_add_to_playlist(uri, playlist, nullptr, + const Database *db = GetDatabase(error); + if (db == nullptr) + return print_error(client, error); + + success = search_add_to_playlist(*db, uri, playlist, nullptr, error); #else success = false; diff --git a/src/db/DatabasePlaylist.cxx b/src/db/DatabasePlaylist.cxx index 64b365d2a..814901227 100644 --- a/src/db/DatabasePlaylist.cxx +++ b/src/db/DatabasePlaylist.cxx @@ -21,7 +21,6 @@ #include "DatabasePlaylist.hxx" #include "Selection.hxx" #include "PlaylistFile.hxx" -#include "DatabaseGlue.hxx" #include "DatabasePlugin.hxx" #include "DetachedSong.hxx" #include "Mapper.hxx" @@ -37,17 +36,14 @@ AddSong(const char *playlist_path_utf8, } bool -search_add_to_playlist(const char *uri, const char *playlist_path_utf8, +search_add_to_playlist(const Database &db, + const char *uri, const char *playlist_path_utf8, const SongFilter *filter, Error &error) { - const Database *db = GetDatabase(error); - if (db == nullptr) - return false; - const DatabaseSelection selection(uri, true, filter); using namespace std::placeholders; const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2); - return db->Visit(selection, f, error); + return db.Visit(selection, f, error); } diff --git a/src/db/DatabasePlaylist.hxx b/src/db/DatabasePlaylist.hxx index 1ee7584d3..5feafa190 100644 --- a/src/db/DatabasePlaylist.hxx +++ b/src/db/DatabasePlaylist.hxx @@ -22,12 +22,14 @@ #include "Compiler.h" +class Database; class SongFilter; class Error; -gcc_nonnull(1,2) +gcc_nonnull(2,3) bool -search_add_to_playlist(const char *uri, const char *path_utf8, +search_add_to_playlist(const Database &db, + const char *uri, const char *path_utf8, const SongFilter *filter, Error &error); diff --git a/src/db/DatabaseSong.cxx b/src/db/DatabaseSong.cxx index 592d38b85..f6229194b 100644 --- a/src/db/DatabaseSong.cxx +++ b/src/db/DatabaseSong.cxx @@ -19,23 +19,18 @@ #include "config.h" #include "DatabaseSong.hxx" -#include "DatabaseGlue.hxx" #include "DatabasePlugin.hxx" #include "DetachedSong.hxx" #include "Mapper.hxx" DetachedSong * -DatabaseDetachSong(const char *uri, Error &error) +DatabaseDetachSong(const Database &db, const char *uri, Error &error) { - const Database *db = GetDatabase(error); - if (db == nullptr) - return nullptr; - - const LightSong *tmp = db->GetSong(uri, error); + const LightSong *tmp = db.GetSong(uri, error); if (tmp == nullptr) return nullptr; DetachedSong *song = new DetachedSong(map_song_detach(*tmp)); - db->ReturnSong(tmp); + db.ReturnSong(tmp); return song; } diff --git a/src/db/DatabaseSong.hxx b/src/db/DatabaseSong.hxx index 0200af6b8..1197068bc 100644 --- a/src/db/DatabaseSong.hxx +++ b/src/db/DatabaseSong.hxx @@ -22,6 +22,7 @@ #include "Compiler.h" +class Database; class DetachedSong; class Error; @@ -33,6 +34,6 @@ class Error; */ gcc_malloc gcc_nonnull_all DetachedSong * -DatabaseDetachSong(const char *uri, Error &error); +DatabaseDetachSong(const Database &db, const char *uri, Error &error); #endif diff --git a/test/test_translate_song.cxx b/test/test_translate_song.cxx index c264c0d1a..3c94ed4bc 100644 --- a/test/test_translate_song.cxx +++ b/test/test_translate_song.cxx @@ -117,7 +117,8 @@ static const char *uri1 = "/foo/bar.ogg"; static const char *uri2 = "foo/bar.ogg"; DetachedSong * -DatabaseDetachSong(const char *uri, gcc_unused Error &error) +DatabaseDetachSong(gcc_unused const Database &db, const char *uri, + gcc_unused Error &error) { if (strcmp(uri, uri2) == 0) return new DetachedSong(uri, MakeTag2a()); @@ -236,7 +237,7 @@ class TranslateSongTest : public CppUnit::TestFixture { } void TestInDatabase() { - const SongLoader loader(nullptr); + const SongLoader loader(reinterpret_cast(1)); DetachedSong song1("doesntexist"); CPPUNIT_ASSERT(!playlist_check_translate_song(song1, nullptr, @@ -258,8 +259,9 @@ class TranslateSongTest : public CppUnit::TestFixture { } void TestRelative() { - const SongLoader secure_loader(nullptr); - const SongLoader insecure_loader(reinterpret_cast(1)); + const Database &db = *reinterpret_cast(1); + const SongLoader secure_loader(&db); + const SongLoader insecure_loader(reinterpret_cast(1), &db); /* map to music_directory */ DetachedSong song1("bar.ogg", MakeTag2b());