From cf6281a5a758e4b93d67f7fd5804a8cff60ddbf9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 1 Feb 2014 00:26:34 +0100 Subject: Instance: add Database attribute Move from db/DatabaseGlue.cxx, eliminating global variable. --- src/Instance.cxx | 14 ++++- src/Instance.hxx | 10 ++++ src/Main.cxx | 18 ++++--- src/PlaylistPrint.cxx | 5 +- src/SongLoader.cxx | 7 +++ src/SongLoader.hxx | 13 ++--- src/StateFile.cxx | 8 ++- src/Stats.cxx | 7 ++- src/client/Client.cxx | 12 +++++ src/client/Client.hxx | 6 +++ src/command/DatabaseCommands.cxx | 2 +- src/command/PlaylistCommands.cxx | 3 +- src/command/StickerCommands.cxx | 5 +- src/db/DatabaseGlue.cxx | 91 ++------------------------------- src/db/DatabaseGlue.hxx | 28 ++-------- src/db/DatabasePrint.cxx | 7 ++- src/db/DatabaseQueue.cxx | 3 +- src/db/DatabaseSimple.hxx | 4 -- src/db/plugins/SimpleDatabasePlugin.hxx | 3 ++ 19 files changed, 97 insertions(+), 149 deletions(-) (limited to 'src') diff --git a/src/Instance.cxx b/src/Instance.cxx index 229af0268..42d62ac7c 100644 --- a/src/Instance.cxx +++ b/src/Instance.cxx @@ -22,10 +22,18 @@ #include "Partition.hxx" #include "Idle.hxx" #include "Stats.hxx" -#include "db/DatabaseGlue.hxx" +#include "db/DatabaseError.hxx" #ifdef ENABLE_DATABASE +Database * +Instance::GetDatabase(Error &error) +{ + if (database == nullptr) + error.Set(db_domain, DB_DISABLED, "No database"); + return database; +} + void Instance::DeleteSong(const char *uri) { @@ -35,8 +43,10 @@ Instance::DeleteSong(const char *uri) void Instance::DatabaseModified() { + assert(database != nullptr); + stats_invalidate(); - partition->DatabaseModified(*GetDatabase()); + partition->DatabaseModified(*database); idle_add(IDLE_DATABASE); } diff --git a/src/Instance.hxx b/src/Instance.hxx index ea60072cb..9e3f92458 100644 --- a/src/Instance.hxx +++ b/src/Instance.hxx @@ -30,9 +30,11 @@ class NeighborGlue; #ifdef ENABLE_DATABASE #include "db/DatabaseListener.hxx" +class Database; class UpdateService; #endif +class Error; class ClientList; struct Partition; @@ -55,6 +57,8 @@ struct Instance final #endif #ifdef ENABLE_DATABASE + Database *database; + UpdateService *update; #endif @@ -69,6 +73,12 @@ struct Instance final } #ifdef ENABLE_DATABASE + /** + * Returns the global #Database instance. May return nullptr + * if this MPD configuration has no database (no + * music_directory was configured). + */ + Database *GetDatabase(Error &error); void DeleteSong(const char *uri); diff --git a/src/Main.cxx b/src/Main.cxx index d7d13e2b3..8a5ed7506 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -195,22 +195,26 @@ glue_db_init_and_load(void) if (param == nullptr) return true; + bool is_simple; Error error; - if (!DatabaseGlobalInit(*main_loop, *instance, *param, error)) + instance->database = DatabaseGlobalInit(*main_loop, *instance, *param, + is_simple, error); + if (instance->database == nullptr) FatalError(error); delete allocated; - if (!DatabaseGlobalOpen(error)) + if (!instance->database->Open(error)) FatalError(error); - if (!db_is_simple()) + if (!is_simple) return true; - instance->update = new UpdateService(*main_loop, db_get_simple()); + SimpleDatabase &db = *(SimpleDatabase *)instance->database; + instance->update = new UpdateService(*main_loop, db); /* run database update after daemonization? */ - return db_exists(); + return db.FileExists(); } #endif @@ -577,8 +581,8 @@ int mpd_main(int argc, char *argv[]) #ifdef ENABLE_DATABASE delete instance->update; - - DatabaseGlobalDeinit(); + instance->database->Close(); + delete instance->database; #endif #ifdef ENABLE_SQLITE diff --git a/src/PlaylistPrint.cxx b/src/PlaylistPrint.cxx index 377da25c9..2e29ac6a2 100644 --- a/src/PlaylistPrint.cxx +++ b/src/PlaylistPrint.cxx @@ -23,7 +23,8 @@ #include "Playlist.hxx" #include "queue/QueuePrint.hxx" #include "SongPrint.hxx" -#include "db/DatabaseGlue.hxx" +#include "Partition.hxx" +#include "Instance.hxx" #include "db/DatabasePlugin.hxx" #include "client/Client.hxx" #include "input/InputStream.hxx" @@ -115,7 +116,7 @@ playlist_print_changes_position(Client &client, static bool PrintSongDetails(Client &client, const char *uri_utf8) { - const Database *db = GetDatabase(); + const Database *db = client.partition.instance.database; if (db == nullptr) return false; diff --git a/src/SongLoader.cxx b/src/SongLoader.cxx index 90df42824..08aa01296 100644 --- a/src/SongLoader.cxx +++ b/src/SongLoader.cxx @@ -33,6 +33,13 @@ #include #include +#ifdef ENABLE_DATABASE + +SongLoader::SongLoader(const Client &_client) + :client(&_client), db(_client.GetDatabase(IgnoreError())) {} + +#endif + DetachedSong * SongLoader::LoadFile(const char *path_utf8, Error &error) const { diff --git a/src/SongLoader.hxx b/src/SongLoader.hxx index 997c0fb18..9914db8e6 100644 --- a/src/SongLoader.hxx +++ b/src/SongLoader.hxx @@ -45,19 +45,16 @@ class SongLoader { 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 Client &_client); explicit SongLoader(const Database *_db) :client(nullptr), db(_db) {} - explicit SongLoader(std::nullptr_t) - :client(nullptr), db(nullptr) {} + explicit SongLoader(const Client &_client, const Database *_db) + :client(&_client), db(_db) {} #else explicit SongLoader(const Client &_client) :client(&_client) {} - explicit SongLoader(const Client *_client) - :client(_client) {} + explicit SongLoader(std::nullptr_t) + :client(nullptr) {} #endif gcc_nonnull_all diff --git a/src/StateFile.cxx b/src/StateFile.cxx index 6c01be53c..e46af1c3e 100644 --- a/src/StateFile.cxx +++ b/src/StateFile.cxx @@ -23,9 +23,9 @@ #include "PlaylistState.hxx" #include "fs/TextFile.hxx" #include "Partition.hxx" +#include "Instance.hxx" #include "mixer/Volume.hxx" #include "SongLoader.hxx" -#include "db/DatabaseGlue.hxx" #include "fs/FileSystem.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -98,7 +98,11 @@ StateFile::Read() return; } - const SongLoader song_loader(nullptr, GetDatabase()); +#ifdef ENABLE_DATABASE + const SongLoader song_loader(partition.instance.database); +#else + const SongLoader song_loader(nullptr); +#endif const char *line; while ((line = file.ReadLine()) != NULL) { diff --git a/src/Stats.cxx b/src/Stats.cxx index 4051d8049..c5fcc69e2 100644 --- a/src/Stats.cxx +++ b/src/Stats.cxx @@ -21,8 +21,9 @@ #include "Stats.hxx" #include "PlayerControl.hxx" #include "client/Client.hxx" +#include "Partition.hxx" +#include "Instance.hxx" #include "db/Selection.hxx" -#include "db/DatabaseGlue.hxx" #include "db/DatabasePlugin.hxx" #include "util/Error.hxx" #include "system/Clock.hxx" @@ -60,8 +61,6 @@ void stats_global_init(void) void stats_invalidate() { - assert(GetDatabase() != nullptr); - stats_validity = StatsValidity::INVALID; } @@ -132,7 +131,7 @@ stats_print(Client &client) (unsigned long)(client.player_control.GetTotalPlayTime() + 0.5)); #ifdef ENABLE_DATABASE - const Database *db = GetDatabase(); + const Database *db = client.partition.instance.database; if (db != nullptr) db_stats_print(client, *db); #endif diff --git a/src/client/Client.cxx b/src/client/Client.cxx index ce99faa89..c62c759e9 100644 --- a/src/client/Client.cxx +++ b/src/client/Client.cxx @@ -20,5 +20,17 @@ #include "config.h" #include "ClientInternal.hxx" #include "util/Domain.hxx" +#include "Partition.hxx" +#include "Instance.hxx" const Domain client_domain("client"); + +#ifdef ENABLE_DATABASE + +const Database * +Client::GetDatabase(Error &error) const +{ + return partition.instance.GetDatabase(error); +} + +#endif diff --git a/src/client/Client.hxx b/src/client/Client.hxx index 708b0d03d..006ffc98c 100644 --- a/src/client/Client.hxx +++ b/src/client/Client.hxx @@ -38,6 +38,7 @@ struct sockaddr; class EventLoop; class Path; struct Partition; +class Database; class Client final : private FullyBufferedSocket, TimeoutMonitor { public: @@ -169,6 +170,11 @@ public: */ bool AllowFile(Path path_fs, Error &error) const; + /** + * Wrapper for Instance::GetDatabase(). + */ + const Database *GetDatabase(Error &error) const; + private: /* virtual methods from class BufferedSocket */ virtual InputResult OnSocketInput(void *data, size_t length) override; diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx index b458b3756..ef6fb922e 100644 --- a/src/command/DatabaseCommands.cxx +++ b/src/command/DatabaseCommands.cxx @@ -120,7 +120,7 @@ handle_searchaddpl(Client &client, int argc, char *argv[]) } Error error; - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return print_error(client, error); diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx index 07cc177d6..0997cc68d 100644 --- a/src/command/PlaylistCommands.cxx +++ b/src/command/PlaylistCommands.cxx @@ -19,7 +19,6 @@ #include "config.h" #include "PlaylistCommands.hxx" -#include "db/DatabaseGlue.hxx" #include "db/DatabasePlaylist.hxx" #include "CommandError.hxx" #include "PlaylistPrint.hxx" @@ -193,7 +192,7 @@ handle_playlistadd(Client &client, gcc_unused int argc, char *argv[]) success = spl_append_uri(playlist, loader, uri, error); } else { #ifdef ENABLE_DATABASE - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return print_error(client, error); diff --git a/src/command/StickerCommands.cxx b/src/command/StickerCommands.cxx index 9e526b0e0..bf3660b85 100644 --- a/src/command/StickerCommands.cxx +++ b/src/command/StickerCommands.cxx @@ -28,6 +28,9 @@ #include "sticker/StickerDatabase.hxx" #include "CommandError.hxx" #include "protocol/Result.hxx" +#include "client/Client.hxx" +#include "Partition.hxx" +#include "Instance.hxx" #include "util/Error.hxx" #include @@ -52,7 +55,7 @@ static CommandResult handle_sticker_song(Client &client, int argc, char *argv[]) { Error error; - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return print_error(client, error); diff --git a/src/db/DatabaseGlue.cxx b/src/db/DatabaseGlue.cxx index f320633c7..30c244334 100644 --- a/src/db/DatabaseGlue.cxx +++ b/src/db/DatabaseGlue.cxx @@ -19,30 +19,18 @@ #include "config.h" #include "DatabaseGlue.hxx" -#include "DatabaseSimple.hxx" #include "Registry.hxx" #include "DatabaseError.hxx" -#include "Directory.hxx" #include "util/Error.hxx" #include "config/ConfigData.hxx" -#include "Stats.hxx" #include "DatabasePlugin.hxx" -#include "plugins/SimpleDatabasePlugin.hxx" -#include #include -static Database *db; -static bool db_is_open; -static bool is_simple; - -bool +Database * DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener, - const config_param ¶m, Error &error) + const config_param ¶m, bool &is_simple, Error &error) { - assert(db == nullptr); - assert(!db_is_open); - const char *plugin_name = param.GetBlockValue("plugin", "simple"); is_simple = strcmp(plugin_name, "simple") == 0; @@ -51,79 +39,8 @@ DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener, if (plugin == nullptr) { error.Format(db_domain, "No such database plugin: %s", plugin_name); - return false; + return nullptr; } - db = plugin->create(loop, listener, param, error); - return db != nullptr; -} - -void -DatabaseGlobalDeinit(void) -{ - if (db_is_open) - db->Close(); - - if (db != nullptr) - delete db; -} - -const Database * -GetDatabase() -{ - assert(db == nullptr || db_is_open); - - return db; -} - -const Database * -GetDatabase(Error &error) -{ - assert(db == nullptr || db_is_open); - - if (db == nullptr) - error.Set(db_domain, DB_DISABLED, "No database"); - - return db; -} - -bool -db_is_simple(void) -{ - assert(db == nullptr || db_is_open); - - return is_simple; -} - -SimpleDatabase & -db_get_simple() -{ - assert(is_simple); - assert(db != nullptr); - - return *(SimpleDatabase *)db; -} - -bool -DatabaseGlobalOpen(Error &error) -{ - assert(db != nullptr); - assert(!db_is_open); - - if (!db->Open(error)) - return false; - - db_is_open = true; - - return true; -} - -bool -db_exists() -{ - assert(db != nullptr); - assert(db_is_open); - assert(db_is_simple()); - - return ((SimpleDatabase *)db)->GetUpdateStamp() > 0; + return plugin->create(loop, listener, param, error); } diff --git a/src/db/DatabaseGlue.hxx b/src/db/DatabaseGlue.hxx index 78032edb2..f562b6d41 100644 --- a/src/db/DatabaseGlue.hxx +++ b/src/db/DatabaseGlue.hxx @@ -32,31 +32,11 @@ class Error; * Initialize the database library. * * @param param the database configuration block + * @param is_simple returns whether this is the "simple" database + * plugin */ -bool +Database * DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener, - const config_param ¶m, Error &error); - -void -DatabaseGlobalDeinit(void); - -bool -DatabaseGlobalOpen(Error &error); - -/** - * Returns the global #Database instance. May return nullptr if this MPD - * configuration has no database (no music_directory was configured). - */ -gcc_const -const Database * -GetDatabase(); - -/** - * Returns the global #Database instance. May return nullptr if this MPD - * configuration has no database (no music_directory was configured). - */ -gcc_pure -const Database * -GetDatabase(Error &error); + const config_param ¶m, bool &is_simple, Error &error); #endif diff --git a/src/db/DatabasePrint.cxx b/src/db/DatabasePrint.cxx index 9ed0b0826..669a804be 100644 --- a/src/db/DatabasePrint.cxx +++ b/src/db/DatabasePrint.cxx @@ -28,7 +28,6 @@ #include "LightSong.hxx" #include "LightDirectory.hxx" #include "PlaylistInfo.hxx" -#include "DatabaseGlue.hxx" #include "DatabasePlugin.hxx" #include @@ -129,7 +128,7 @@ bool db_selection_print(Client &client, const DatabaseSelection &selection, bool full, Error &error) { - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return false; @@ -173,7 +172,7 @@ searchStatsForSongsIn(Client &client, const char *name, const SongFilter *filter, Error &error) { - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return false; @@ -229,7 +228,7 @@ listAllUniqueTags(Client &client, int type, const SongFilter *filter, Error &error) { - const Database *db = GetDatabase(error); + const Database *db = client.GetDatabase(error); if (db == nullptr) return false; diff --git a/src/db/DatabaseQueue.cxx b/src/db/DatabaseQueue.cxx index ee1dbd57c..f2a0951a6 100644 --- a/src/db/DatabaseQueue.cxx +++ b/src/db/DatabaseQueue.cxx @@ -22,6 +22,7 @@ #include "DatabaseGlue.hxx" #include "DatabasePlugin.hxx" #include "Partition.hxx" +#include "Instance.hxx" #include "util/Error.hxx" #include "DetachedSong.hxx" #include "Mapper.hxx" @@ -47,7 +48,7 @@ bool AddFromDatabase(Partition &partition, const DatabaseSelection &selection, Error &error) { - const Database *db = GetDatabase(error); + const Database *db = partition.instance.GetDatabase(error); if (db == nullptr) return false; diff --git a/src/db/DatabaseSimple.hxx b/src/db/DatabaseSimple.hxx index c0f84ab79..1e527958f 100644 --- a/src/db/DatabaseSimple.hxx +++ b/src/db/DatabaseSimple.hxx @@ -35,10 +35,6 @@ class Error; bool db_is_simple(void); -gcc_pure -SimpleDatabase & -db_get_simple(); - /** * Returns true if there is a valid database file on the disk. * diff --git a/src/db/plugins/SimpleDatabasePlugin.hxx b/src/db/plugins/SimpleDatabasePlugin.hxx index 8c7978a91..83434393c 100644 --- a/src/db/plugins/SimpleDatabasePlugin.hxx +++ b/src/db/plugins/SimpleDatabasePlugin.hxx @@ -59,6 +59,9 @@ public: bool Save(Error &error); + /** + * Returns true if there is a valid database file on the disk. + */ bool FileExists() const { return mtime > 0; } -- cgit v1.2.3