Commit a62d5442 authored by Max Kellermann's avatar Max Kellermann

db/proxy: auto-reconnect

parent c8b2591a
...@@ -73,8 +73,12 @@ public: ...@@ -73,8 +73,12 @@ public:
DatabaseStats &stats, DatabaseStats &stats,
Error &error) const override; Error &error) const override;
protected: private:
bool Configure(const config_param &param, Error &error); bool Configure(const config_param &param, Error &error);
bool Connect(Error &error);
bool CheckConnection(Error &error);
bool EnsureConnected(Error &error);
}; };
static constexpr Domain libmpdclient_domain("libmpdclient"); static constexpr Domain libmpdclient_domain("libmpdclient");
...@@ -231,30 +235,65 @@ ProxyDatabase::Configure(const config_param &param, gcc_unused Error &error) ...@@ -231,30 +235,65 @@ ProxyDatabase::Configure(const config_param &param, gcc_unused Error &error)
bool bool
ProxyDatabase::Open(Error &error) ProxyDatabase::Open(Error &error)
{ {
connection = mpd_connection_new(host.empty() ? nullptr : host.c_str(), if (!Connect(error))
port, 0); return false;
root = Directory::NewRoot();
return true;
}
void
ProxyDatabase::Close()
{
root->Free();
if (connection != nullptr)
mpd_connection_free(connection);
}
bool
ProxyDatabase::Connect(Error &error)
{
const char *_host = host.empty() ? nullptr : host.c_str();
connection = mpd_connection_new(_host, port, 0);
if (connection == nullptr) { if (connection == nullptr) {
error.Set(libmpdclient_domain, (int)MPD_ERROR_OOM, "Out of memory"); error.Set(libmpdclient_domain, (int)MPD_ERROR_OOM,
"Out of memory");
return false; return false;
} }
if (!CheckError(connection, error)) { if (!CheckError(connection, error)) {
mpd_connection_free(connection); if (connection != nullptr) {
mpd_connection_free(connection);
connection = nullptr;
}
return false; return false;
} }
root = Directory::NewRoot();
return true; return true;
} }
void bool
ProxyDatabase::Close() ProxyDatabase::CheckConnection(Error &error)
{ {
assert(connection != nullptr); assert(connection != nullptr);
root->Free(); if (!mpd_connection_clear_error(connection)) {
mpd_connection_free(connection); mpd_connection_free(connection);
return Connect(error);
}
return true;
}
bool
ProxyDatabase::EnsureConnected(Error &error)
{
return connection != nullptr
? CheckConnection(error)
: Connect(error);
} }
static Song * static Song *
...@@ -263,8 +302,9 @@ Convert(const struct mpd_song *song); ...@@ -263,8 +302,9 @@ Convert(const struct mpd_song *song);
Song * Song *
ProxyDatabase::GetSong(const char *uri, Error &error) const ProxyDatabase::GetSong(const char *uri, Error &error) const
{ {
// TODO: implement // TODO: eliminate the const_cast
// TODO: auto-reconnect if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
return nullptr;
if (!mpd_send_list_meta(connection, uri)) { if (!mpd_send_list_meta(connection, uri)) {
CheckError(connection, error); CheckError(connection, error);
...@@ -522,7 +562,9 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, ...@@ -522,7 +562,9 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
VisitPlaylist visit_playlist, VisitPlaylist visit_playlist,
Error &error) const Error &error) const
{ {
// TODO: auto-reconnect // TODO: eliminate the const_cast
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
return nullptr;
if (!visit_directory && !visit_playlist && selection.recursive) if (!visit_directory && !visit_playlist && selection.recursive)
/* this optimized code path can only be used under /* this optimized code path can only be used under
...@@ -542,6 +584,10 @@ ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection, ...@@ -542,6 +584,10 @@ ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection,
VisitString visit_string, VisitString visit_string,
Error &error) const Error &error) const
{ {
// TODO: eliminate the const_cast
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
return nullptr;
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"); error.Set(libmpdclient_domain, "Unsupported tag");
...@@ -578,6 +624,10 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection, ...@@ -578,6 +624,10 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection,
// TODO: match // TODO: match
(void)selection; (void)selection;
// TODO: eliminate the const_cast
if (!const_cast<ProxyDatabase *>(this)->EnsureConnected(error))
return nullptr;
struct mpd_stats *stats2 = struct mpd_stats *stats2 =
mpd_run_stats(connection); mpd_run_stats(connection);
if (stats2 == nullptr) if (stats2 == nullptr)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment