Instance: add GetDatabaseOrThrow()

This commit is contained in:
Max Kellermann 2016-10-26 18:47:19 +02:00
parent 6135f0763b
commit 086652dd50
12 changed files with 65 additions and 40 deletions

View File

@ -44,6 +44,16 @@ Instance::GetDatabase(Error &error)
return database; return database;
} }
const Database &
Instance::GetDatabaseOrThrow() const
{
if (database == nullptr)
throw DatabaseError(DatabaseErrorCode::DISABLED,
"No database");
return *database;
}
void void
Instance::OnDatabaseModified() Instance::OnDatabaseModified()
{ {

View File

@ -110,6 +110,14 @@ struct Instance final
* music_directory was configured). * music_directory was configured).
*/ */
Database *GetDatabase(Error &error); Database *GetDatabase(Error &error);
/**
* Returns the global #Database instance. Throws
* DatabaseError if this MPD configuration has no database (no
* music_directory was configured).
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
#endif #endif
private: private:

View File

@ -50,6 +50,12 @@ Partition::GetDatabase(Error &error) const
return instance.GetDatabase(error); return instance.GetDatabase(error);
} }
const Database &
Partition::GetDatabaseOrThrow() const
{
return instance.GetDatabaseOrThrow();
}
void void
Partition::DatabaseModified(const Database &db) Partition::DatabaseModified(const Database &db)
{ {

View File

@ -185,6 +185,9 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
*/ */
const Database *GetDatabase(Error &error) const; const Database *GetDatabase(Error &error) const;
gcc_pure
const Database &GetDatabaseOrThrow() const;
/** /**
* The database has been modified. Propagate the change to * The database has been modified. Propagate the change to
* all subsystems. * all subsystems.

View File

@ -33,6 +33,12 @@ Client::GetDatabase(Error &error) const
return partition.instance.GetDatabase(error); return partition.instance.GetDatabase(error);
} }
const Database &
Client::GetDatabaseOrThrow() const
{
return partition.instance.GetDatabaseOrThrow();
}
const Storage * const Storage *
Client::GetStorage() const Client::GetStorage() const
{ {

View File

@ -187,6 +187,12 @@ public:
gcc_pure gcc_pure
const Database *GetDatabase(Error &error) const; const Database *GetDatabase(Error &error) const;
/**
* Wrapper for Instance::GetDatabaseOrThrow().
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
gcc_pure gcc_pure
const Storage *GetStorage() const; const Storage *GetStorage() const;

View File

@ -143,11 +143,9 @@ handle_searchaddpl(Client &client, Request args, Response &r)
} }
Error error; Error error;
const Database *db = client.GetDatabase(error); const Database &db = client.GetDatabaseOrThrow();
if (db == nullptr)
return print_error(r, error);
return search_add_to_playlist(*db, *client.GetStorage(), return search_add_to_playlist(db, *client.GetStorage(),
"", playlist, &filter, error) "", playlist, &filter, error)
? CommandResult::OK ? CommandResult::OK
: print_error(r, error); : print_error(r, error);

View File

@ -168,11 +168,9 @@ handle_playlistadd(Client &client, Request args, Response &r)
success = spl_append_uri(playlist, loader, uri, error); success = spl_append_uri(playlist, loader, uri, error);
} else { } else {
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Database *db = client.GetDatabase(error); const Database &db = client.GetDatabaseOrThrow();
if (db == nullptr)
return print_error(r, error);
success = search_add_to_playlist(*db, *client.GetStorage(), success = search_add_to_playlist(db, *client.GetStorage(),
uri, playlist, nullptr, uri, playlist, nullptr,
error); error);
#else #else

View File

@ -54,19 +54,17 @@ static CommandResult
handle_sticker_song(Response &r, Partition &partition, Request args) handle_sticker_song(Response &r, Partition &partition, Request args)
{ {
Error error; Error error;
const Database *db = partition.GetDatabase(error); const Database &db = partition.GetDatabaseOrThrow();
if (db == nullptr)
return print_error(r, error);
const char *const cmd = args.front(); const char *const cmd = args.front();
/* get song song_id key */ /* get song song_id key */
if (args.size == 4 && StringIsEqual(cmd, "get")) { if (args.size == 4 && StringIsEqual(cmd, "get")) {
const LightSong *song = db->GetSong(args[2]); const LightSong *song = db.GetSong(args[2]);
const auto value = sticker_song_get_value(*song, args[3], const auto value = sticker_song_get_value(*song, args[3],
error); error);
db->ReturnSong(song); db.ReturnSong(song);
if (value.empty()) { if (value.empty()) {
if (error.IsDefined()) if (error.IsDefined())
return print_error(r, error); return print_error(r, error);
@ -80,11 +78,11 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
return CommandResult::OK; return CommandResult::OK;
/* list song song_id */ /* list song song_id */
} else if (args.size == 3 && StringIsEqual(cmd, "list")) { } else if (args.size == 3 && StringIsEqual(cmd, "list")) {
const LightSong *song = db->GetSong(args[2]); const LightSong *song = db.GetSong(args[2]);
assert(song != nullptr); assert(song != nullptr);
Sticker *sticker = sticker_song_get(*song, error); Sticker *sticker = sticker_song_get(*song, error);
db->ReturnSong(song); db.ReturnSong(song);
if (sticker) { if (sticker) {
sticker_print(r, *sticker); sticker_print(r, *sticker);
sticker_free(sticker); sticker_free(sticker);
@ -94,12 +92,12 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
return CommandResult::OK; return CommandResult::OK;
/* set song song_id id key */ /* set song song_id id key */
} else if (args.size == 5 && StringIsEqual(cmd, "set")) { } else if (args.size == 5 && StringIsEqual(cmd, "set")) {
const LightSong *song = db->GetSong(args[2]); const LightSong *song = db.GetSong(args[2]);
assert(song != nullptr); assert(song != nullptr);
bool ret = sticker_song_set_value(*song, args[3], args[4], bool ret = sticker_song_set_value(*song, args[3], args[4],
error); error);
db->ReturnSong(song); db.ReturnSong(song);
if (!ret) { if (!ret) {
if (error.IsDefined()) if (error.IsDefined())
return print_error(r, error); return print_error(r, error);
@ -113,13 +111,13 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
/* delete song song_id [key] */ /* delete song song_id [key] */
} else if ((args.size == 3 || args.size == 4) && } else if ((args.size == 3 || args.size == 4) &&
StringIsEqual(cmd, "delete")) { StringIsEqual(cmd, "delete")) {
const LightSong *song = db->GetSong(args[2]); const LightSong *song = db.GetSong(args[2]);
assert(song != nullptr); assert(song != nullptr);
bool ret = args.size == 3 bool ret = args.size == 3
? sticker_song_delete(*song, error) ? sticker_song_delete(*song, error)
: sticker_song_delete_value(*song, args[3], error); : sticker_song_delete_value(*song, args[3], error);
db->ReturnSong(song); db.ReturnSong(song);
if (!ret) { if (!ret) {
if (error.IsDefined()) if (error.IsDefined())
return print_error(r, error); return print_error(r, error);
@ -163,7 +161,7 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
args[3], args[3],
}; };
if (!sticker_song_find(*db, base_uri, data.name, if (!sticker_song_find(db, base_uri, data.name,
op, value, op, value,
sticker_song_find_print_cb, &data, sticker_song_find_print_cb, &data,
error)) { error)) {

View File

@ -113,9 +113,7 @@ PrintSongCount(Response &r, const Partition &partition, const char *name,
TagType group, TagType group,
Error &error) Error &error)
{ {
const Database *db = partition.GetDatabase(error); const Database &db = partition.GetDatabaseOrThrow();
if (db == nullptr)
return false;
const DatabaseSelection selection(name, true, filter); const DatabaseSelection selection(name, true, filter);
@ -127,7 +125,7 @@ PrintSongCount(Response &r, const Partition &partition, const char *name,
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(stats_visitor_song, std::ref(stats), const auto f = std::bind(stats_visitor_song, std::ref(stats),
_1); _1);
if (!db->Visit(selection, f, error)) if (!db.Visit(selection, f, error))
return false; return false;
PrintSearchStats(r, stats); PrintSearchStats(r, stats);
@ -140,7 +138,7 @@ PrintSongCount(Response &r, const Partition &partition, const char *name,
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(GroupCountVisitor, std::ref(map), const auto f = std::bind(GroupCountVisitor, std::ref(map),
group, _1); group, _1);
if (!db->Visit(selection, f, error)) if (!db.Visit(selection, f, error))
return false; return false;
Print(r, group, map); Print(r, group, map);

View File

@ -155,9 +155,7 @@ db_selection_print(Response &r, Partition &partition,
unsigned window_start, unsigned window_end, unsigned window_start, unsigned window_end,
Error &error) Error &error)
{ {
const Database *db = partition.GetDatabase(error); const Database &db = partition.GetDatabaseOrThrow();
if (db == nullptr)
return false;
unsigned i = 0; unsigned i = 0;
@ -182,7 +180,7 @@ db_selection_print(Response &r, Partition &partition,
return !in_window || s(song, error2); return !in_window || s(song, error2);
}; };
return db->Visit(selection, d, s, p, error); return db.Visit(selection, d, s, p, error);
} }
bool bool
@ -226,9 +224,7 @@ PrintUniqueTags(Response &r, Partition &partition,
const SongFilter *filter, const SongFilter *filter,
Error &error) Error &error)
{ {
const Database *db = partition.GetDatabase(error); const Database &db = partition.GetDatabaseOrThrow();
if (db == nullptr)
return false;
const DatabaseSelection selection("", true, filter); const DatabaseSelection selection("", true, filter);
@ -236,15 +232,15 @@ PrintUniqueTags(Response &r, Partition &partition,
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(PrintSongURIVisitor, const auto f = std::bind(PrintSongURIVisitor,
std::ref(r), std::ref(partition), _1); std::ref(r), std::ref(partition), _1);
return db->Visit(selection, f, error); return db.Visit(selection, f, error);
} else { } else {
assert(type < TAG_NUM_OF_ITEM_TYPES); assert(type < TAG_NUM_OF_ITEM_TYPES);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(PrintUniqueTag, std::ref(r), const auto f = std::bind(PrintUniqueTag, std::ref(r),
(TagType)type, _1); (TagType)type, _1);
return db->VisitUniqueTags(selection, (TagType)type, return db.VisitUniqueTags(selection, (TagType)type,
group_mask, group_mask,
f, error); f, error);
} }
} }

View File

@ -41,11 +41,9 @@ bool
AddFromDatabase(Partition &partition, const DatabaseSelection &selection, AddFromDatabase(Partition &partition, const DatabaseSelection &selection,
Error &error) Error &error)
{ {
const Database *db = partition.instance.GetDatabase(error); const Database &db = partition.instance.GetDatabaseOrThrow();
if (db == nullptr)
return false;
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddToQueue, std::ref(partition), _1); const auto f = std::bind(AddToQueue, std::ref(partition), _1);
return db->Visit(selection, f, error); return db.Visit(selection, f, error);
} }