Instance: add Database attribute
Move from db/DatabaseGlue.cxx, eliminating global variable.
This commit is contained in:
parent
f00710a57e
commit
cf6281a5a7
@ -205,7 +205,6 @@ src_mpd_SOURCES += \
|
||||
src/db/Uri.hxx \
|
||||
src/db/Directory.cxx src/db/Directory.hxx \
|
||||
src/db/DirectorySave.cxx src/db/DirectorySave.hxx \
|
||||
src/db/DatabaseSimple.hxx \
|
||||
src/db/DatabaseGlue.cxx src/db/DatabaseGlue.hxx \
|
||||
src/db/DatabaseSong.cxx src/db/DatabaseSong.hxx \
|
||||
src/db/DatabasePrint.cxx src/db/DatabasePrint.hxx \
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
18
src/Main.cxx
18
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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -33,6 +33,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <string.h>
|
||||
@ -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);
|
||||
|
||||
|
@ -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 <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "LightSong.hxx"
|
||||
#include "LightDirectory.hxx"
|
||||
#include "PlaylistInfo.hxx"
|
||||
#include "DatabaseGlue.hxx"
|
||||
#include "DatabasePlugin.hxx"
|
||||
|
||||
#include <functional>
|
||||
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -137,6 +137,12 @@ DetachedSong::Update()
|
||||
return false;
|
||||
}
|
||||
|
||||
const Database *
|
||||
Client::GetDatabase(gcc_unused Error &error) const
|
||||
{
|
||||
return reinterpret_cast<const Database *>(this);
|
||||
}
|
||||
|
||||
bool
|
||||
Client::AllowFile(gcc_unused Path path_fs, gcc_unused Error &error) const
|
||||
{
|
||||
@ -220,7 +226,7 @@ class TranslateSongTest : public CppUnit::TestFixture {
|
||||
void TestInsecure() {
|
||||
/* illegal because secure=false */
|
||||
DetachedSong song1 (uri1);
|
||||
const SongLoader loader(reinterpret_cast<const Client *>(1));
|
||||
const SongLoader loader(*reinterpret_cast<const Client *>(1));
|
||||
CPPUNIT_ASSERT(!playlist_check_translate_song(song1, nullptr,
|
||||
loader));
|
||||
}
|
||||
@ -261,7 +267,8 @@ class TranslateSongTest : public CppUnit::TestFixture {
|
||||
void TestRelative() {
|
||||
const Database &db = *reinterpret_cast<const Database *>(1);
|
||||
const SongLoader secure_loader(&db);
|
||||
const SongLoader insecure_loader(reinterpret_cast<const Client *>(1), &db);
|
||||
const SongLoader insecure_loader(*reinterpret_cast<const Client *>(1),
|
||||
&db);
|
||||
|
||||
/* map to music_directory */
|
||||
DetachedSong song1("bar.ogg", MakeTag2b());
|
||||
|
Loading…
Reference in New Issue
Block a user