db/Interface: migrate visitor methods from class Error to C++ exceptions

This commit is contained in:
Max Kellermann 2016-10-29 10:21:57 +02:00
parent 9a9da7b077
commit fac8edd47a
27 changed files with 190 additions and 331 deletions

View File

@ -26,7 +26,6 @@
#include "db/Selection.hxx" #include "db/Selection.hxx"
#include "db/Interface.hxx" #include "db/Interface.hxx"
#include "db/Stats.hxx" #include "db/Stats.hxx"
#include "util/Error.hxx"
#include "system/Clock.hxx" #include "system/Clock.hxx"
#include "Log.hxx" #include "Log.hxx"
@ -79,20 +78,12 @@ stats_update(const Database &db)
return false; return false;
} }
Error error;
const DatabaseSelection selection("", true); const DatabaseSelection selection("", true);
try { try {
if (db.GetStats(selection, stats, error)) { stats = db.GetStats(selection);
stats_validity = StatsValidity::VALID; stats_validity = StatsValidity::VALID;
return true; return true;
} else {
LogError(error);
stats_validity = StatsValidity::FAILED;
return false;
}
} catch (const std::runtime_error &e) { } catch (const std::runtime_error &e) {
LogError(e); LogError(e);
stats_validity = StatsValidity::FAILED; stats_validity = StatsValidity::FAILED;

View File

@ -30,7 +30,6 @@
#include "client/Response.hxx" #include "client/Response.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include "util/Error.hxx"
#include "util/StringAPI.hxx" #include "util/StringAPI.hxx"
#include "SongFilter.hxx" #include "SongFilter.hxx"
#include "BulkEdit.hxx" #include "BulkEdit.hxx"
@ -41,12 +40,8 @@ CommandResult
handle_listfiles_db(Client &client, Response &r, const char *uri) handle_listfiles_db(Client &client, Response &r, const char *uri)
{ {
const DatabaseSelection selection(uri, false); const DatabaseSelection selection(uri, false);
db_selection_print(r, client.partition,
Error error; selection, false, true);
if (!db_selection_print(r, client.partition,
selection, false, true, error))
return print_error(r, error);
return CommandResult::OK; return CommandResult::OK;
} }
@ -54,12 +49,8 @@ CommandResult
handle_lsinfo2(Client &client, const char *uri, Response &r) handle_lsinfo2(Client &client, const char *uri, Response &r)
{ {
const DatabaseSelection selection(uri, false); const DatabaseSelection selection(uri, false);
db_selection_print(r, client.partition,
Error error; selection, true, false);
if (!db_selection_print(r, client.partition,
selection, true, false, error))
return print_error(r, error);
return CommandResult::OK; return CommandResult::OK;
} }
@ -83,12 +74,10 @@ handle_match(Client &client, Request args, Response &r, bool fold_case)
const DatabaseSelection selection("", true, &filter); const DatabaseSelection selection("", true, &filter);
Error error; db_selection_print(r, client.partition,
return db_selection_print(r, client.partition,
selection, true, false, selection, true, false,
window.start, window.end, error) window.start, window.end);
? CommandResult::OK return CommandResult::OK;
: print_error(r, error);
} }
CommandResult CommandResult
@ -115,10 +104,8 @@ handle_match_add(Client &client, Request args, Response &r, bool fold_case)
const ScopeBulkEdit bulk_edit(client.partition); const ScopeBulkEdit bulk_edit(client.partition);
const DatabaseSelection selection("", true, &filter); const DatabaseSelection selection("", true, &filter);
Error error; AddFromDatabase(client.partition, selection);
return AddFromDatabase(client.partition, selection, error) return CommandResult::OK;
? CommandResult::OK
: print_error(r, error);
} }
CommandResult CommandResult
@ -144,13 +131,11 @@ handle_searchaddpl(Client &client, Request args, Response &r)
return CommandResult::ERROR; return CommandResult::ERROR;
} }
Error error;
const Database &db = client.GetDatabaseOrThrow(); const Database &db = client.GetDatabaseOrThrow();
return search_add_to_playlist(db, *client.GetStorage(), search_add_to_playlist(db, *client.GetStorage(),
"", playlist, &filter, error) "", playlist, &filter);
? CommandResult::OK return CommandResult::OK;
: print_error(r, error);
} }
CommandResult CommandResult
@ -176,10 +161,8 @@ handle_count(Client &client, Request args, Response &r)
return CommandResult::ERROR; return CommandResult::ERROR;
} }
Error error; PrintSongCount(r, client.partition, "", &filter, group);
return PrintSongCount(r, client.partition, "", &filter, group, error) return CommandResult::OK;
? CommandResult::OK
: print_error(r, error);
} }
CommandResult CommandResult
@ -188,12 +171,10 @@ handle_listall(Client &client, Request args, Response &r)
/* default is root directory */ /* default is root directory */
const auto uri = args.GetOptional(0, ""); const auto uri = args.GetOptional(0, "");
Error error; db_selection_print(r, client.partition,
return db_selection_print(r, client.partition,
DatabaseSelection(uri, true), DatabaseSelection(uri, true),
false, false, error) false, false);
? CommandResult::OK return CommandResult::OK;
: print_error(r, error);
} }
CommandResult CommandResult
@ -255,14 +236,9 @@ handle_list(Client &client, Request args, Response &r)
return CommandResult::ERROR; return CommandResult::ERROR;
} }
Error error;
CommandResult ret =
PrintUniqueTags(r, client.partition, PrintUniqueTags(r, client.partition,
tagType, group_mask, filter.get(), error) tagType, group_mask, filter.get());
? CommandResult::OK return CommandResult::OK;
: print_error(r, error);
return ret;
} }
CommandResult CommandResult
@ -271,10 +247,8 @@ handle_listallinfo(Client &client, Request args, Response &r)
/* default is root directory */ /* default is root directory */
const auto uri = args.GetOptional(0, ""); const auto uri = args.GetOptional(0, "");
Error error; db_selection_print(r, client.partition,
return db_selection_print(r, client.partition,
DatabaseSelection(uri, true), DatabaseSelection(uri, true),
true, false, error) true, false);
? CommandResult::OK return CommandResult::OK;
: print_error(r, error);
} }

View File

@ -156,35 +156,27 @@ handle_playlistclear(gcc_unused Client &client,
} }
CommandResult CommandResult
handle_playlistadd(Client &client, Request args, Response &r) handle_playlistadd(Client &client, Request args, gcc_unused Response &r)
{ {
const char *const playlist = args[0]; const char *const playlist = args[0];
const char *const uri = args[1]; const char *const uri = args[1];
bool success;
Error error;
if (uri_has_scheme(uri)) { if (uri_has_scheme(uri)) {
const SongLoader loader(client); const SongLoader loader(client);
spl_append_uri(playlist, loader, uri); spl_append_uri(playlist, loader, uri);
success = true;
} else { } else {
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const Database &db = client.GetDatabaseOrThrow(); const Database &db = client.GetDatabaseOrThrow();
success = search_add_to_playlist(db, *client.GetStorage(), search_add_to_playlist(db, *client.GetStorage(),
uri, playlist, nullptr, uri, playlist, nullptr);
error);
#else #else
success = false; r.Error(ACK_ERROR_NO_EXIST, "directory or file not found");
return CommandResult::ERROR;
#endif #endif
} }
if (!success && !error.IsDefined()) { return CommandResult::OK;
r.Error(ACK_ERROR_NO_EXIST, "directory or file not found");
return CommandResult::ERROR;
}
return success ? CommandResult::OK : print_error(r, error);
} }
CommandResult CommandResult

View File

@ -52,16 +52,15 @@ AddUri(Client &client, const LocatedUri &uri)
} }
static CommandResult static CommandResult
AddDatabaseSelection(Client &client, const char *uri, Response &r) AddDatabaseSelection(Client &client, const char *uri,
gcc_unused Response &r)
{ {
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
const ScopeBulkEdit bulk_edit(client.partition); const ScopeBulkEdit bulk_edit(client.partition);
const DatabaseSelection selection(uri, true); const DatabaseSelection selection(uri, true);
Error error; AddFromDatabase(client.partition, selection);
return AddFromDatabase(client.partition, selection, error) return CommandResult::OK;
? CommandResult::OK
: print_error(r, error);
#else #else
(void)client; (void)client;
(void)uri; (void)uri;

View File

@ -107,11 +107,10 @@ GroupCountVisitor(TagCountMap &map, TagType group, const LightSong &song)
return true; return true;
} }
bool void
PrintSongCount(Response &r, const Partition &partition, const char *name, PrintSongCount(Response &r, const Partition &partition, const char *name,
const SongFilter *filter, const SongFilter *filter,
TagType group, TagType group)
Error &error)
{ {
const Database &db = partition.GetDatabaseOrThrow(); const Database &db = partition.GetDatabaseOrThrow();
@ -125,8 +124,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)) db.Visit(selection, f);
return false;
PrintSearchStats(r, stats); PrintSearchStats(r, stats);
} else { } else {
@ -138,11 +136,8 @@ 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)) db.Visit(selection, f);
return false;
Print(r, group, map); Print(r, group, map);
} }
return true;
} }

View File

@ -28,13 +28,11 @@ enum TagType : uint8_t;
struct Partition; struct Partition;
class Response; class Response;
class SongFilter; class SongFilter;
class Error;
gcc_nonnull(3) gcc_nonnull(3)
bool void
PrintSongCount(Response &r, const Partition &partition, const char *name, PrintSongCount(Response &r, const Partition &partition, const char *name,
const SongFilter *filter, const SongFilter *filter,
TagType group, TagType group);
Error &error);
#endif #endif

View File

@ -36,16 +36,15 @@ AddSong(const Storage &storage, const char *playlist_path_utf8,
return true; return true;
} }
bool void
search_add_to_playlist(const Database &db, const Storage &storage, search_add_to_playlist(const Database &db, const Storage &storage,
const char *uri, const char *playlist_path_utf8, const char *uri, const char *playlist_path_utf8,
const SongFilter *filter, const SongFilter *filter)
Error &error)
{ {
const DatabaseSelection selection(uri, true, filter); const DatabaseSelection selection(uri, true, filter);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddSong, std::ref(storage), const auto f = std::bind(AddSong, std::ref(storage),
playlist_path_utf8, _1); playlist_path_utf8, _1);
return db.Visit(selection, f, error); db.Visit(selection, f);
} }

View File

@ -25,13 +25,11 @@
class Database; class Database;
class Storage; class Storage;
class SongFilter; class SongFilter;
class Error;
gcc_nonnull(3,4) gcc_nonnull(3,4)
bool void
search_add_to_playlist(const Database &db, const Storage &storage, search_add_to_playlist(const Database &db, const Storage &storage,
const char *uri, const char *path_utf8, const char *uri, const char *path_utf8,
const SongFilter *filter, const SongFilter *filter);
Error &error);
#endif #endif

View File

@ -148,12 +148,11 @@ PrintPlaylistFull(Response &r, bool base,
return true; return true;
} }
bool void
db_selection_print(Response &r, Partition &partition, db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,
bool full, bool base, bool full, bool base,
unsigned window_start, unsigned window_end, unsigned window_start, unsigned window_end)
Error &error)
{ {
const Database &db = partition.GetDatabaseOrThrow(); const Database &db = partition.GetDatabaseOrThrow();
@ -180,18 +179,16 @@ db_selection_print(Response &r, Partition &partition,
s(song); s(song);
}; };
return db.Visit(selection, d, s, p, error); db.Visit(selection, d, s, p);
} }
bool void
db_selection_print(Response &r, Partition &partition, db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,
bool full, bool base, bool full, bool base)
Error &error)
{ {
return db_selection_print(r, partition, selection, full, base, db_selection_print(r, partition, selection, full, base,
0, std::numeric_limits<int>::max(), 0, std::numeric_limits<int>::max());
error);
} }
static bool static bool
@ -218,11 +215,10 @@ PrintUniqueTag(Response &r, TagType tag_type,
return true; return true;
} }
bool void
PrintUniqueTags(Response &r, Partition &partition, PrintUniqueTags(Response &r, Partition &partition,
unsigned type, tag_mask_t group_mask, unsigned type, tag_mask_t group_mask,
const SongFilter *filter, const SongFilter *filter)
Error &error)
{ {
const Database &db = partition.GetDatabaseOrThrow(); const Database &db = partition.GetDatabaseOrThrow();
@ -232,15 +228,14 @@ 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); db.Visit(selection, f);
} 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, db.VisitUniqueTags(selection, (TagType)type,
group_mask, group_mask, f);
f, error);
} }
} }

View File

@ -26,28 +26,25 @@ class SongFilter;
struct DatabaseSelection; struct DatabaseSelection;
struct Partition; struct Partition;
class Response; class Response;
class Error;
/** /**
* @param full print attributes/tags * @param full print attributes/tags
* @param base print only base name of songs/directories? * @param base print only base name of songs/directories?
*/ */
bool void
db_selection_print(Response &r, Partition &partition, db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,
bool full, bool base, Error &error); bool full, bool base);
bool void
db_selection_print(Response &r, Partition &partition, db_selection_print(Response &r, Partition &partition,
const DatabaseSelection &selection, const DatabaseSelection &selection,
bool full, bool base, bool full, bool base,
unsigned window_start, unsigned window_end, unsigned window_start, unsigned window_end);
Error &error);
bool void
PrintUniqueTags(Response &r, Partition &partition, PrintUniqueTags(Response &r, Partition &partition,
unsigned type, tag_mask_t group_mask, unsigned type, tag_mask_t group_mask,
const SongFilter *filter, const SongFilter *filter);
Error &error);
#endif #endif

View File

@ -37,13 +37,12 @@ AddToQueue(Partition &partition, const LightSong &song)
return true; return true;
} }
bool void
AddFromDatabase(Partition &partition, const DatabaseSelection &selection, AddFromDatabase(Partition &partition, const DatabaseSelection &selection)
Error &error)
{ {
const Database &db = partition.instance.GetDatabaseOrThrow(); const Database &db = partition.instance.GetDatabaseOrThrow();
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); db.Visit(selection, f);
} }

View File

@ -22,10 +22,8 @@
struct Partition; struct Partition;
struct DatabaseSelection; struct DatabaseSelection;
class Error;
bool void
AddFromDatabase(Partition &partition, const DatabaseSelection &selection, AddFromDatabase(Partition &partition, const DatabaseSelection &selection);
Error &error);
#endif #endif

View File

@ -78,10 +78,10 @@ StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums,
return true; return true;
} }
bool DatabaseStats
GetStats(const Database &db, const DatabaseSelection &selection, GetStats(const Database &db, const DatabaseSelection &selection)
DatabaseStats &stats, Error &error)
{ {
DatabaseStats stats;
stats.Clear(); stats.Clear();
StringSet artists, albums; StringSet artists, albums;
@ -89,10 +89,9 @@ GetStats(const Database &db, const DatabaseSelection &selection,
const auto f = std::bind(StatsVisitSong, const auto f = std::bind(StatsVisitSong,
std::ref(stats), std::ref(artists), std::ref(stats), std::ref(artists),
std::ref(albums), _1); std::ref(albums), _1);
if (!db.Visit(selection, f, error)) db.Visit(selection, f);
return false;
stats.artist_count = artists.size(); stats.artist_count = artists.size();
stats.album_count = albums.size(); stats.album_count = albums.size();
return true; return stats;
} }

View File

@ -20,13 +20,11 @@
#ifndef MPD_MEMORY_DATABASE_PLUGIN_HXX #ifndef MPD_MEMORY_DATABASE_PLUGIN_HXX
#define MPD_MEMORY_DATABASE_PLUGIN_HXX #define MPD_MEMORY_DATABASE_PLUGIN_HXX
class Error;
class Database; class Database;
struct DatabaseSelection; struct DatabaseSelection;
struct DatabaseStats; struct DatabaseStats;
bool DatabaseStats
GetStats(const Database &db, const DatabaseSelection &selection, GetStats(const Database &db, const DatabaseSelection &selection);
DatabaseStats &stats, Error &error);
#endif #endif

View File

@ -84,36 +84,31 @@ public:
/** /**
* Visit the selected entities. * Visit the selected entities.
*/ */
virtual bool Visit(const DatabaseSelection &selection, virtual void Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const = 0;
Error &error) const = 0;
bool Visit(const DatabaseSelection &selection, void Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song) const {
Error &error) const { Visit(selection, visit_directory, visit_song, VisitPlaylist());
return Visit(selection, visit_directory, visit_song,
VisitPlaylist(), error);
} }
bool Visit(const DatabaseSelection &selection, VisitSong visit_song, void Visit(const DatabaseSelection &selection,
Error &error) const { VisitSong visit_song) const {
return Visit(selection, VisitDirectory(), visit_song, error); return Visit(selection, VisitDirectory(), visit_song);
} }
/** /**
* Visit all unique tag values. * Visit all unique tag values.
*/ */
virtual bool VisitUniqueTags(const DatabaseSelection &selection, virtual void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const = 0;
Error &error) const = 0;
virtual bool GetStats(const DatabaseSelection &selection, gcc_pure
DatabaseStats &stats, virtual DatabaseStats GetStats(const DatabaseSelection &selection) const = 0;
Error &error) const = 0;
/** /**
* Update the database. Returns the job id on success, 0 on * Update the database. Returns the job id on success, 0 on

View File

@ -36,22 +36,18 @@ CollectTags(TagSet &set, TagType tag_type, tag_mask_t group_mask,
set.InsertUnique(tag, tag_type, group_mask); set.InsertUnique(tag, tag_type, group_mask);
} }
bool void
VisitUniqueTags(const Database &db, const DatabaseSelection &selection, VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag)
Error &error)
{ {
TagSet set; TagSet set;
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(CollectTags, std::ref(set), const auto f = std::bind(CollectTags, std::ref(set),
tag_type, group_mask, _1); tag_type, group_mask, _1);
if (!db.Visit(selection, f, error)) db.Visit(selection, f);
return false;
for (const auto &value : set) for (const auto &value : set)
visit_tag(value); visit_tag(value);
return true;
} }

View File

@ -24,14 +24,12 @@
#include "tag/TagType.h" #include "tag/TagType.h"
#include "tag/Mask.hxx" #include "tag/Mask.hxx"
class Error;
class Database; class Database;
struct DatabaseSelection; struct DatabaseSelection;
bool void
VisitUniqueTags(const Database &db, const DatabaseSelection &selection, VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag);
Error &error);
#endif #endif

View File

@ -33,8 +33,6 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "tag/TagBuilder.hxx" #include "tag/TagBuilder.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
#include "protocol/Ack.hxx" #include "protocol/Ack.hxx"
#include "event/SocketMonitor.hxx" #include "event/SocketMonitor.hxx"
@ -115,20 +113,16 @@ public:
const LightSong *GetSong(const char *uri_utf8) const override; const LightSong *GetSong(const char *uri_utf8) const override;
void ReturnSong(const LightSong *song) const override; void ReturnSong(const LightSong *song) const override;
virtual bool Visit(const DatabaseSelection &selection, void Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const override;
Error &error) const override;
virtual bool VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const override;
Error &error) const override;
virtual bool GetStats(const DatabaseSelection &selection, DatabaseStats GetStats(const DatabaseSelection &selection) const override;
DatabaseStats &stats,
Error &error) const override;
virtual unsigned Update(const char *uri_utf8, bool discard, virtual unsigned Update(const char *uri_utf8, bool discard,
Error &error) override; Error &error) override;
@ -151,8 +145,6 @@ private:
virtual void OnIdle() override; virtual void OnIdle() override;
}; };
static constexpr Domain libmpdclient_domain("libmpdclient");
static constexpr struct { static constexpr struct {
TagType d; TagType d;
enum mpd_tag_type s; enum mpd_tag_type s;
@ -543,18 +535,18 @@ ProxyDatabase::ReturnSong(const LightSong *_song) const
delete song; delete song;
} }
static bool static void
Visit(struct mpd_connection *connection, const char *uri, Visit(struct mpd_connection *connection, const char *uri,
bool recursive, const SongFilter *filter, bool recursive, const SongFilter *filter,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, Error &error); VisitPlaylist visit_playlist);
static bool static void
Visit(struct mpd_connection *connection, Visit(struct mpd_connection *connection,
bool recursive, const SongFilter *filter, bool recursive, const SongFilter *filter,
const struct mpd_directory *directory, const struct mpd_directory *directory,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, Error &error) VisitPlaylist visit_playlist)
{ {
const char *path = mpd_directory_get_path(directory); const char *path = mpd_directory_get_path(directory);
#if LIBMPDCLIENT_CHECK_VERSION(2,9,0) #if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
@ -566,12 +558,9 @@ Visit(struct mpd_connection *connection,
if (visit_directory) if (visit_directory)
visit_directory(LightDirectory(path, mtime)); visit_directory(LightDirectory(path, mtime));
if (recursive && if (recursive)
!Visit(connection, path, recursive, filter, Visit(connection, path, recursive, filter,
visit_directory, visit_song, visit_playlist, error)) visit_directory, visit_song, visit_playlist);
return false;
return true;
} }
gcc_pure gcc_pure
@ -645,11 +634,11 @@ ReceiveEntities(struct mpd_connection *connection)
return entities; return entities;
} }
static bool static void
Visit(struct mpd_connection *connection, const char *uri, Visit(struct mpd_connection *connection, const char *uri,
bool recursive, const SongFilter *filter, bool recursive, const SongFilter *filter,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, Error &error) VisitPlaylist visit_playlist)
{ {
if (!mpd_send_list_meta(connection, uri)) if (!mpd_send_list_meta(connection, uri))
ThrowError(connection); ThrowError(connection);
@ -663,11 +652,9 @@ Visit(struct mpd_connection *connection, const char *uri,
break; break;
case MPD_ENTITY_TYPE_DIRECTORY: case MPD_ENTITY_TYPE_DIRECTORY:
if (!Visit(connection, recursive, filter, Visit(connection, recursive, filter,
mpd_entity_get_directory(entity), mpd_entity_get_directory(entity),
visit_directory, visit_song, visit_playlist, visit_directory, visit_song, visit_playlist);
error))
return false;
break; break;
case MPD_ENTITY_TYPE_SONG: case MPD_ENTITY_TYPE_SONG:
@ -680,8 +667,6 @@ Visit(struct mpd_connection *connection, const char *uri,
break; break;
} }
} }
return true;
} }
static void static void
@ -734,12 +719,11 @@ ServerSupportsSearchBase(const struct mpd_connection *connection)
#endif #endif
} }
bool void
ProxyDatabase::Visit(const DatabaseSelection &selection, ProxyDatabase::Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const
Error &error) const
{ {
// TODO: eliminate the const_cast // TODO: eliminate the const_cast
const_cast<ProxyDatabase *>(this)->EnsureConnected(); const_cast<ProxyDatabase *>(this)->EnsureConnected();
@ -751,31 +735,27 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
/* this optimized code path can only be used under /* this optimized code path can only be used under
certain conditions */ certain conditions */
::SearchSongs(connection, selection, visit_song); ::SearchSongs(connection, selection, visit_song);
return true; return;
} }
/* fall back to recursive walk (slow!) */ /* fall back to recursive walk (slow!) */
return ::Visit(connection, selection.uri.c_str(), ::Visit(connection, selection.uri.c_str(),
selection.recursive, selection.filter, selection.recursive, selection.filter,
visit_directory, visit_song, visit_playlist, visit_directory, visit_song, visit_playlist);
error);
} }
bool void
ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection, ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, TagType tag_type,
gcc_unused tag_mask_t group_mask, gcc_unused tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const
Error &error) const
{ {
// TODO: eliminate the const_cast // TODO: eliminate the const_cast
const_cast<ProxyDatabase *>(this)->EnsureConnected(); const_cast<ProxyDatabase *>(this)->EnsureConnected();
enum mpd_tag_type tag_type2 = Convert(tag_type); enum mpd_tag_type tag_type2 = Convert(tag_type);
if (tag_type2 == MPD_TAG_COUNT) { if (tag_type2 == MPD_TAG_COUNT)
error.Set(libmpdclient_domain, "Unsupported tag"); throw std::runtime_error("Unsupported tag");
return false;
}
if (!mpd_search_db_tags(connection, tag_type2) || if (!mpd_search_db_tags(connection, tag_type2) ||
!SendConstraints(connection, selection)) !SendConstraints(connection, selection))
@ -812,13 +792,10 @@ ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection,
if (!mpd_response_finish(connection)) if (!mpd_response_finish(connection))
ThrowError(connection); ThrowError(connection);
return true;
} }
bool DatabaseStats
ProxyDatabase::GetStats(const DatabaseSelection &selection, ProxyDatabase::GetStats(const DatabaseSelection &selection) const
DatabaseStats &stats, gcc_unused Error &error) const
{ {
// TODO: match // TODO: match
(void)selection; (void)selection;
@ -833,13 +810,13 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection,
update_stamp = (time_t)mpd_stats_get_db_update_time(stats2); update_stamp = (time_t)mpd_stats_get_db_update_time(stats2);
DatabaseStats stats;
stats.song_count = mpd_stats_get_number_of_songs(stats2); stats.song_count = mpd_stats_get_number_of_songs(stats2);
stats.total_duration = std::chrono::seconds(mpd_stats_get_db_play_time(stats2)); stats.total_duration = std::chrono::seconds(mpd_stats_get_db_play_time(stats2));
stats.artist_count = mpd_stats_get_number_of_artists(stats2); stats.artist_count = mpd_stats_get_number_of_artists(stats2);
stats.album_count = mpd_stats_get_number_of_albums(stats2); stats.album_count = mpd_stats_get_number_of_albums(stats2);
mpd_stats_free(stats2); mpd_stats_free(stats2);
return stats;
return true;
} }
unsigned unsigned

View File

@ -32,7 +32,6 @@
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "util/Alloc.hxx" #include "util/Alloc.hxx"
#include "util/DeleteDisposer.hxx" #include "util/DeleteDisposer.hxx"
#include "util/Error.hxx"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -218,14 +217,11 @@ Directory::Sort()
child.Sort(); child.Sort();
} }
bool void
Directory::Walk(bool recursive, const SongFilter *filter, Directory::Walk(bool recursive, const SongFilter *filter,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const
Error &error) const
{ {
assert(!error.IsDefined());
if (IsMount()) { if (IsMount()) {
assert(IsEmpty()); assert(IsEmpty());
@ -233,11 +229,11 @@ Directory::Walk(bool recursive, const SongFilter *filter,
because the child's SimpleDatabasePlugin::Visit() because the child's SimpleDatabasePlugin::Visit()
call will lock it again */ call will lock it again */
const ScopeDatabaseUnlock unlock; const ScopeDatabaseUnlock unlock;
return WalkMount(GetPath(), *mounted_database, WalkMount(GetPath(), *mounted_database,
recursive, filter, recursive, filter,
visit_directory, visit_song, visit_directory, visit_song,
visit_playlist, visit_playlist);
error); return;
} }
if (visit_song) { if (visit_song) {
@ -257,14 +253,11 @@ Directory::Walk(bool recursive, const SongFilter *filter,
if (visit_directory) if (visit_directory)
visit_directory(child.Export()); visit_directory(child.Export());
if (recursive && if (recursive)
!child.Walk(recursive, filter, child.Walk(recursive, filter,
visit_directory, visit_song, visit_playlist, visit_directory, visit_song,
error)) visit_playlist);
return false;
} }
return true;
} }
LightDirectory LightDirectory

View File

@ -44,7 +44,6 @@ static constexpr unsigned DEVICE_INARCHIVE = -1;
static constexpr unsigned DEVICE_CONTAINER = -2; static constexpr unsigned DEVICE_CONTAINER = -2;
class SongFilter; class SongFilter;
class Error;
class Database; class Database;
struct Directory { struct Directory {
@ -266,10 +265,9 @@ public:
/** /**
* Caller must lock #db_mutex. * Caller must lock #db_mutex.
*/ */
bool Walk(bool recursive, const SongFilter *match, void Walk(bool recursive, const SongFilter *match,
VisitDirectory visit_directory, VisitSong visit_song, VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const;
Error &error) const;
gcc_pure gcc_pure
LightDirectory Export() const; LightDirectory Export() const;

View File

@ -63,12 +63,11 @@ PrefixVisitPlaylist(const char *base, const VisitPlaylist &visit_playlist,
PrefixedLightDirectory(directory, base)); PrefixedLightDirectory(directory, base));
} }
bool void
WalkMount(const char *base, const Database &db, WalkMount(const char *base, const Database &db,
bool recursive, const SongFilter *filter, bool recursive, const SongFilter *filter,
const VisitDirectory &visit_directory, const VisitSong &visit_song, const VisitDirectory &visit_directory, const VisitSong &visit_song,
const VisitPlaylist &visit_playlist, const VisitPlaylist &visit_playlist)
Error &error)
{ {
using namespace std::placeholders; using namespace std::placeholders;
@ -87,6 +86,5 @@ WalkMount(const char *base, const Database &db,
vp = std::bind(PrefixVisitPlaylist, vp = std::bind(PrefixVisitPlaylist,
base, std::ref(visit_playlist), _1, _2); base, std::ref(visit_playlist), _1, _2);
return db.Visit(DatabaseSelection("", recursive, filter), db.Visit(DatabaseSelection("", recursive, filter), vd, vs, vp);
vd, vs, vp, error);
} }

View File

@ -24,13 +24,11 @@
class Database; class Database;
class SongFilter; class SongFilter;
class Error;
bool void
WalkMount(const char *base, const Database &db, WalkMount(const char *base, const Database &db,
bool recursive, const SongFilter *filter, bool recursive, const SongFilter *filter,
const VisitDirectory &visit_directory, const VisitSong &visit_song, const VisitDirectory &visit_directory, const VisitSong &visit_song,
const VisitPlaylist &visit_playlist, const VisitPlaylist &visit_playlist);
Error &error);
#endif #endif

View File

@ -23,6 +23,7 @@
#include "db/DatabasePlugin.hxx" #include "db/DatabasePlugin.hxx"
#include "db/Selection.hxx" #include "db/Selection.hxx"
#include "db/Helpers.hxx" #include "db/Helpers.hxx"
#include "db/Stats.hxx"
#include "db/UniqueTags.hxx" #include "db/UniqueTags.hxx"
#include "db/LightDirectory.hxx" #include "db/LightDirectory.hxx"
#include "Directory.hxx" #include "Directory.hxx"
@ -37,7 +38,6 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "fs/FileSystem.hxx" #include "fs/FileSystem.hxx"
#include "util/CharUtil.hxx" #include "util/CharUtil.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "Log.hxx" #include "Log.hxx"
@ -261,12 +261,11 @@ SimpleDatabase::ReturnSong(gcc_unused const LightSong *song) const
#endif #endif
} }
bool void
SimpleDatabase::Visit(const DatabaseSelection &selection, SimpleDatabase::Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const
Error &error) const
{ {
ScopeDatabaseLock protect; ScopeDatabaseLock protect;
@ -277,10 +276,10 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
if (selection.recursive && visit_directory) if (selection.recursive && visit_directory)
visit_directory(r.directory->Export()); visit_directory(r.directory->Export());
return r.directory->Walk(selection.recursive, selection.filter, r.directory->Walk(selection.recursive, selection.filter,
visit_directory, visit_song, visit_directory, visit_song,
visit_playlist, visit_playlist);
error); return;
} }
if (strchr(r.uri, '/') == nullptr) { if (strchr(r.uri, '/') == nullptr) {
@ -298,22 +297,18 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
"No such directory"); "No such directory");
} }
bool void
SimpleDatabase::VisitUniqueTags(const DatabaseSelection &selection, SimpleDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const
Error &error) const
{ {
return ::VisitUniqueTags(*this, selection, tag_type, group_mask, ::VisitUniqueTags(*this, selection, tag_type, group_mask, visit_tag);
visit_tag,
error);
} }
bool DatabaseStats
SimpleDatabase::GetStats(const DatabaseSelection &selection, SimpleDatabase::GetStats(const DatabaseSelection &selection) const
DatabaseStats &stats, Error &error) const
{ {
return ::GetStats(*this, selection, stats, error); return ::GetStats(*this, selection);
} }
void void

View File

@ -112,20 +112,16 @@ public:
const LightSong *GetSong(const char *uri_utf8) const override; const LightSong *GetSong(const char *uri_utf8) const override;
void ReturnSong(const LightSong *song) const override; void ReturnSong(const LightSong *song) const override;
virtual bool Visit(const DatabaseSelection &selection, void Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const override;
Error &error) const override;
virtual bool VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const override;
Error &error) const override;
virtual bool GetStats(const DatabaseSelection &selection, DatabaseStats GetStats(const DatabaseSelection &selection) const override;
DatabaseStats &stats,
Error &error) const override;
virtual time_t GetUpdateStamp() const override { virtual time_t GetUpdateStamp() const override {
return mtime; return mtime;

View File

@ -26,7 +26,6 @@
#include "util/NumberParser.hxx" #include "util/NumberParser.hxx"
#include "util/UriUtil.hxx" #include "util/UriUtil.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
#include "util/Error.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
#include <stdio.h> #include <stdio.h>

View File

@ -35,8 +35,6 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "tag/TagBuilder.hxx" #include "tag/TagBuilder.hxx"
#include "tag/TagTable.hxx" #include "tag/TagTable.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "SongFilter.hxx" #include "SongFilter.hxx"
@ -84,20 +82,17 @@ public:
virtual const LightSong *GetSong(const char *uri_utf8) const override; virtual const LightSong *GetSong(const char *uri_utf8) const override;
void ReturnSong(const LightSong *song) const override; void ReturnSong(const LightSong *song) const override;
virtual bool Visit(const DatabaseSelection &selection, void Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const override;
Error &error) const override;
virtual bool VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const override;
Error &error) const override;
DatabaseStats GetStats(const DatabaseSelection &selection) const override;
virtual bool GetStats(const DatabaseSelection &selection,
DatabaseStats &stats,
Error &error) const override;
time_t GetUpdateStamp() const override { time_t GetUpdateStamp() const override {
return 0; return 0;
} }
@ -576,12 +571,11 @@ UpnpDatabase::VisitServer(const ContentDirectoryService &server,
} }
// Deal with the possibly multiple servers, call VisitServer if needed. // Deal with the possibly multiple servers, call VisitServer if needed.
bool void
UpnpDatabase::Visit(const DatabaseSelection &selection, UpnpDatabase::Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory, VisitDirectory visit_directory,
VisitSong visit_song, VisitSong visit_song,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist) const
Error &) const
{ {
auto vpath = stringToTokens(selection.uri, "/", true); auto vpath = stringToTokens(selection.uri, "/", true);
if (vpath.empty()) { if (vpath.empty()) {
@ -597,7 +591,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection,
visit_playlist); visit_playlist);
} }
return true; return;
} }
// We do have a path: the first element selects the server // We do have a path: the first element selects the server
@ -607,19 +601,17 @@ UpnpDatabase::Visit(const DatabaseSelection &selection,
auto server = discovery->GetServer(servername.c_str()); auto server = discovery->GetServer(servername.c_str());
VisitServer(server, vpath, selection, VisitServer(server, vpath, selection,
visit_directory, visit_song, visit_playlist); visit_directory, visit_song, visit_playlist);
return true;
} }
bool void
UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection, UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag, gcc_unused tag_mask_t group_mask, TagType tag, gcc_unused tag_mask_t group_mask,
VisitTag visit_tag, VisitTag visit_tag) const
Error &) const
{ {
// TODO: use group_mask // TODO: use group_mask
if (!visit_tag) if (!visit_tag)
return true; return;
std::set<std::string> values; std::set<std::string> values;
for (auto& server : discovery->GetDirectories()) { for (auto& server : discovery->GetDirectories()) {
@ -646,18 +638,16 @@ UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
builder.AddItem(tag, value.c_str()); builder.AddItem(tag, value.c_str());
visit_tag(builder.Commit()); visit_tag(builder.Commit());
} }
return true;
} }
bool DatabaseStats
UpnpDatabase::GetStats(const DatabaseSelection &, UpnpDatabase::GetStats(const DatabaseSelection &) const
DatabaseStats &stats, Error &) const
{ {
/* Note: this gets called before the daemonizing so we can't /* Note: this gets called before the daemonizing so we can't
reallyopen this would be a problem if we had real stats */ reallyopen this would be a problem if we had real stats */
DatabaseStats stats;
stats.Clear(); stats.Clear();
return true; return stats;
} }
const DatabasePlugin upnp_db_plugin = { const DatabasePlugin upnp_db_plugin = {

View File

@ -33,7 +33,6 @@
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "event/Loop.hxx" #include "event/Loop.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "util/Error.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
#include <stdexcept> #include <stdexcept>
@ -108,7 +107,6 @@ try {
config_global_init(); config_global_init();
AtScopeExit() { config_global_finish(); }; AtScopeExit() { config_global_finish(); };
Error error;
ReadConfigFile(config_path); ReadConfigFile(config_path);
TagLoadConfig(); TagLoadConfig();
@ -133,11 +131,7 @@ try {
const DatabaseSelection selection("", true); const DatabaseSelection selection("", true);
if (!db->Visit(selection, DumpDirectory, DumpSong, DumpPlaylist, db->Visit(selection, DumpDirectory, DumpSong, DumpPlaylist);
error)) {
cerr << error.GetMessage() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} catch (const std::exception &e) { } catch (const std::exception &e) {