db/Interface: GetSong() throws exception on error
This commit is contained in:
parent
7ad7caa2ae
commit
2fd5182608
|
@ -127,9 +127,7 @@ PrintSongDetails(Response &r, Partition &partition, const char *uri_utf8)
|
||||||
|
|
||||||
const LightSong *song;
|
const LightSong *song;
|
||||||
try {
|
try {
|
||||||
song = db->GetSong(uri_utf8, IgnoreError());
|
song = db->GetSong(uri_utf8);
|
||||||
if (song == nullptr)
|
|
||||||
return false;
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,21 +38,20 @@ SongLoader::SongLoader(const Client &_client)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
SongLoader::LoadFromDatabase(const char *uri, Error &error) const
|
SongLoader::LoadFromDatabase(const char *uri) const
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
if (db != nullptr)
|
if (db != nullptr)
|
||||||
return DatabaseDetachSong(*db, *storage, uri, error);
|
return DatabaseDetachSong(*db, *storage, uri);
|
||||||
#else
|
#else
|
||||||
(void)uri;
|
(void)uri;
|
||||||
(void)error;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
throw PlaylistError(PlaylistResult::NO_SUCH_SONG, "No database");
|
throw PlaylistError(PlaylistResult::NO_SUCH_SONG, "No database");
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
SongLoader::LoadFile(const char *path_utf8, Path path_fs, Error &error) const
|
SongLoader::LoadFile(const char *path_utf8, Path path_fs) const
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_DATABASE
|
#ifdef ENABLE_DATABASE
|
||||||
if (storage != nullptr) {
|
if (storage != nullptr) {
|
||||||
|
@ -60,10 +59,8 @@ SongLoader::LoadFile(const char *path_utf8, Path path_fs, Error &error) const
|
||||||
if (suffix != nullptr)
|
if (suffix != nullptr)
|
||||||
/* this path was relative to the music
|
/* this path was relative to the music
|
||||||
directory - obtain it from the database */
|
directory - obtain it from the database */
|
||||||
return LoadFromDatabase(suffix, error);
|
return LoadFromDatabase(suffix);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
(void)error;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DetachedSong song(path_utf8);
|
DetachedSong song(path_utf8);
|
||||||
|
@ -74,7 +71,7 @@ SongLoader::LoadFile(const char *path_utf8, Path path_fs, Error &error) const
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
SongLoader::LoadSong(const LocatedUri &located_uri, Error &error) const
|
SongLoader::LoadSong(const LocatedUri &located_uri) const
|
||||||
{
|
{
|
||||||
switch (located_uri.type) {
|
switch (located_uri.type) {
|
||||||
case LocatedUri::Type::UNKNOWN:
|
case LocatedUri::Type::UNKNOWN:
|
||||||
|
@ -84,11 +81,10 @@ SongLoader::LoadSong(const LocatedUri &located_uri, Error &error) const
|
||||||
return new DetachedSong(located_uri.canonical_uri);
|
return new DetachedSong(located_uri.canonical_uri);
|
||||||
|
|
||||||
case LocatedUri::Type::RELATIVE:
|
case LocatedUri::Type::RELATIVE:
|
||||||
return LoadFromDatabase(located_uri.canonical_uri, error);
|
return LoadFromDatabase(located_uri.canonical_uri);
|
||||||
|
|
||||||
case LocatedUri::Type::PATH:
|
case LocatedUri::Type::PATH:
|
||||||
return LoadFile(located_uri.canonical_uri, located_uri.path,
|
return LoadFile(located_uri.canonical_uri, located_uri.path);
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_unreachable();
|
gcc_unreachable();
|
||||||
|
@ -110,5 +106,5 @@ SongLoader::LoadSong(const char *uri_utf8, Error &error) const
|
||||||
if (located_uri.IsUnknown())
|
if (located_uri.IsUnknown())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return LoadSong(located_uri, error);
|
return LoadSong(located_uri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,18 +68,17 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DetachedSong *LoadSong(const LocatedUri &uri, Error &error) const;
|
DetachedSong *LoadSong(const LocatedUri &uri) const;
|
||||||
|
|
||||||
gcc_nonnull_all
|
gcc_nonnull_all
|
||||||
DetachedSong *LoadSong(const char *uri_utf8, Error &error) const;
|
DetachedSong *LoadSong(const char *uri_utf8, Error &error) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gcc_nonnull_all
|
gcc_nonnull_all
|
||||||
DetachedSong *LoadFromDatabase(const char *uri, Error &error) const;
|
DetachedSong *LoadFromDatabase(const char *uri) const;
|
||||||
|
|
||||||
gcc_nonnull_all
|
gcc_nonnull_all
|
||||||
DetachedSong *LoadFile(const char *path_utf8, Path path_fs,
|
DetachedSong *LoadFile(const char *path_utf8, Path path_fs) const;
|
||||||
Error &error) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,17 +41,14 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
static CommandResult
|
static void
|
||||||
AddUri(Client &client, const LocatedUri &uri, Response &r)
|
AddUri(Client &client, const LocatedUri &uri)
|
||||||
{
|
{
|
||||||
Error error;
|
std::unique_ptr<DetachedSong> song(SongLoader(client).LoadSong(uri));
|
||||||
std::unique_ptr<DetachedSong> song(SongLoader(client).LoadSong(uri, error));
|
assert(song);
|
||||||
if (song == nullptr)
|
|
||||||
return print_error(r, error);
|
|
||||||
|
|
||||||
auto &partition = client.partition;
|
auto &partition = client.partition;
|
||||||
partition.playlist.AppendSong(partition.pc, std::move(*song));
|
partition.playlist.AppendSong(partition.pc, std::move(*song));
|
||||||
return CommandResult::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CommandResult
|
static CommandResult
|
||||||
|
@ -98,7 +95,8 @@ handle_add(Client &client, Request args, Response &r)
|
||||||
|
|
||||||
case LocatedUri::Type::ABSOLUTE:
|
case LocatedUri::Type::ABSOLUTE:
|
||||||
case LocatedUri::Type::PATH:
|
case LocatedUri::Type::PATH:
|
||||||
return AddUri(client, located_uri, r);
|
AddUri(client, located_uri);
|
||||||
|
return CommandResult::OK;
|
||||||
|
|
||||||
case LocatedUri::Type::RELATIVE:
|
case LocatedUri::Type::RELATIVE:
|
||||||
return AddDatabaseSelection(client, located_uri.canonical_uri,
|
return AddDatabaseSelection(client, located_uri.canonical_uri,
|
||||||
|
|
|
@ -62,9 +62,7 @@ handle_sticker_song(Response &r, Partition &partition, Request args)
|
||||||
|
|
||||||
/* 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], error);
|
const LightSong *song = db->GetSong(args[2]);
|
||||||
if (song == nullptr)
|
|
||||||
return print_error(r, error);
|
|
||||||
|
|
||||||
const auto value = sticker_song_get_value(*song, args[3],
|
const auto value = sticker_song_get_value(*song, args[3],
|
||||||
error);
|
error);
|
||||||
|
@ -82,9 +80,8 @@ 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], error);
|
const LightSong *song = db->GetSong(args[2]);
|
||||||
if (song == nullptr)
|
assert(song != nullptr);
|
||||||
return print_error(r, error);
|
|
||||||
|
|
||||||
Sticker *sticker = sticker_song_get(*song, error);
|
Sticker *sticker = sticker_song_get(*song, error);
|
||||||
db->ReturnSong(song);
|
db->ReturnSong(song);
|
||||||
|
@ -97,9 +94,8 @@ 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], error);
|
const LightSong *song = db->GetSong(args[2]);
|
||||||
if (song == nullptr)
|
assert(song != nullptr);
|
||||||
return print_error(r, error);
|
|
||||||
|
|
||||||
bool ret = sticker_song_set_value(*song, args[3], args[4],
|
bool ret = sticker_song_set_value(*song, args[3], args[4],
|
||||||
error);
|
error);
|
||||||
|
@ -117,9 +113,8 @@ 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], error);
|
const LightSong *song = db->GetSong(args[2]);
|
||||||
if (song == nullptr)
|
assert(song != nullptr);
|
||||||
return print_error(r, error);
|
|
||||||
|
|
||||||
bool ret = args.size == 3
|
bool ret = args.size == 3
|
||||||
? sticker_song_delete(*song, error)
|
? sticker_song_delete(*song, error)
|
||||||
|
|
|
@ -41,12 +41,10 @@ DatabaseDetachSong(const Storage &storage, const LightSong &song)
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
DatabaseDetachSong(const Database &db, const Storage &storage, const char *uri,
|
DatabaseDetachSong(const Database &db, const Storage &storage, const char *uri)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
const LightSong *tmp = db.GetSong(uri, error);
|
const LightSong *tmp = db.GetSong(uri);
|
||||||
if (tmp == nullptr)
|
assert(tmp != nullptr);
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
DetachedSong *song = new DetachedSong(DatabaseDetachSong(storage,
|
DetachedSong *song = new DetachedSong(DatabaseDetachSong(storage,
|
||||||
*tmp));
|
*tmp));
|
||||||
|
|
|
@ -26,7 +26,6 @@ struct LightSong;
|
||||||
class Database;
|
class Database;
|
||||||
class Storage;
|
class Storage;
|
||||||
class DetachedSong;
|
class DetachedSong;
|
||||||
class Error;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
|
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
|
||||||
|
@ -44,7 +43,7 @@ DatabaseDetachSong(const Storage &storage, const LightSong &song);
|
||||||
*/
|
*/
|
||||||
gcc_malloc gcc_nonnull_all
|
gcc_malloc gcc_nonnull_all
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
DatabaseDetachSong(const Database &db, const Storage &storage, const char *uri,
|
DatabaseDetachSong(const Database &db, const Storage &storage,
|
||||||
Error &error);
|
const char *uri);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,8 +73,7 @@ public:
|
||||||
* @param uri_utf8 the URI of the song within the music
|
* @param uri_utf8 the URI of the song within the music
|
||||||
* directory (UTF-8)
|
* directory (UTF-8)
|
||||||
*/
|
*/
|
||||||
virtual const LightSong *GetSong(const char *uri_utf8,
|
virtual const LightSong *GetSong(const char *uri_utf8) const = 0;
|
||||||
Error &error) const = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the song object as "unused". Call this on objects
|
* Mark the song object as "unused". Call this on objects
|
||||||
|
|
|
@ -115,8 +115,7 @@ public:
|
||||||
|
|
||||||
virtual void Open() override;
|
virtual void Open() override;
|
||||||
virtual void Close() override;
|
virtual void Close() override;
|
||||||
virtual const LightSong *GetSong(const char *uri_utf8,
|
const LightSong *GetSong(const char *uri_utf8) const override;
|
||||||
Error &error) const override;
|
|
||||||
void ReturnSong(const LightSong *song) const override;
|
void ReturnSong(const LightSong *song) const override;
|
||||||
|
|
||||||
virtual bool Visit(const DatabaseSelection &selection,
|
virtual bool Visit(const DatabaseSelection &selection,
|
||||||
|
@ -519,7 +518,7 @@ ProxyDatabase::OnIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
const LightSong *
|
const LightSong *
|
||||||
ProxyDatabase::GetSong(const char *uri, gcc_unused Error &error) const
|
ProxyDatabase::GetSong(const char *uri) const
|
||||||
{
|
{
|
||||||
// TODO: eliminate the const_cast
|
// TODO: eliminate the const_cast
|
||||||
const_cast<ProxyDatabase *>(this)->EnsureConnected();
|
const_cast<ProxyDatabase *>(this)->EnsureConnected();
|
||||||
|
|
|
@ -229,7 +229,7 @@ SimpleDatabase::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
const LightSong *
|
const LightSong *
|
||||||
SimpleDatabase::GetSong(const char *uri, Error &error) const
|
SimpleDatabase::GetSong(const char *uri) const
|
||||||
{
|
{
|
||||||
assert(root != nullptr);
|
assert(root != nullptr);
|
||||||
assert(prefixed_light_song == nullptr);
|
assert(prefixed_light_song == nullptr);
|
||||||
|
@ -244,7 +244,7 @@ SimpleDatabase::GetSong(const char *uri, Error &error) const
|
||||||
protect.unlock();
|
protect.unlock();
|
||||||
|
|
||||||
const LightSong *song =
|
const LightSong *song =
|
||||||
r.directory->mounted_database->GetSong(r.uri, error);
|
r.directory->mounted_database->GetSong(r.uri);
|
||||||
if (song == nullptr)
|
if (song == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,7 @@ public:
|
||||||
virtual void Open() override;
|
virtual void Open() override;
|
||||||
virtual void Close() override;
|
virtual void Close() override;
|
||||||
|
|
||||||
const LightSong *GetSong(const char *uri_utf8,
|
const LightSong *GetSong(const char *uri_utf8) const override;
|
||||||
Error &error) const override;
|
|
||||||
void ReturnSong(const LightSong *song) const override;
|
void ReturnSong(const LightSong *song) const override;
|
||||||
|
|
||||||
virtual bool Visit(const DatabaseSelection &selection,
|
virtual bool Visit(const DatabaseSelection &selection,
|
||||||
|
|
|
@ -82,8 +82,7 @@ public:
|
||||||
|
|
||||||
virtual void Open() override;
|
virtual void Open() override;
|
||||||
virtual void Close() override;
|
virtual void Close() override;
|
||||||
virtual const LightSong *GetSong(const char *uri_utf8,
|
virtual const LightSong *GetSong(const char *uri_utf8) const override;
|
||||||
Error &error) const override;
|
|
||||||
void ReturnSong(const LightSong *song) const override;
|
void ReturnSong(const LightSong *song) const override;
|
||||||
|
|
||||||
virtual bool Visit(const DatabaseSelection &selection,
|
virtual bool Visit(const DatabaseSelection &selection,
|
||||||
|
@ -202,7 +201,7 @@ UpnpDatabase::ReturnSong(const LightSong *_song) const
|
||||||
// Get song info by path. We can receive either the id path, or the titles
|
// Get song info by path. We can receive either the id path, or the titles
|
||||||
// one
|
// one
|
||||||
const LightSong *
|
const LightSong *
|
||||||
UpnpDatabase::GetSong(const char *uri, gcc_unused Error &error) const
|
UpnpDatabase::GetSong(const char *uri) const
|
||||||
{
|
{
|
||||||
auto vpath = stringToTokens(uri, "/", true);
|
auto vpath = stringToTokens(uri, "/", true);
|
||||||
if (vpath.size() < 2)
|
if (vpath.size() < 2)
|
||||||
|
|
|
@ -35,7 +35,7 @@ UpdatePlaylistSong(const Database &db, DetachedSong &song)
|
||||||
|
|
||||||
const LightSong *original;
|
const LightSong *original;
|
||||||
try {
|
try {
|
||||||
original = db.GetSong(song.GetURI(), IgnoreError());
|
original = db.GetSong(song.GetURI());
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,11 +93,9 @@ sticker_song_find_cb(const char *uri, const char *value, void *user_data)
|
||||||
|
|
||||||
const Database *db = data->db;
|
const Database *db = data->db;
|
||||||
try {
|
try {
|
||||||
const LightSong *song = db->GetSong(uri, IgnoreError());
|
const LightSong *song = db->GetSong(uri);
|
||||||
if (song != nullptr) {
|
data->func(*song, value, data->user_data);
|
||||||
data->func(*song, value, data->user_data);
|
db->ReturnSong(song);
|
||||||
db->ReturnSong(song);
|
|
||||||
}
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,7 @@ static const char *uri2 = "foo/bar.ogg";
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
DatabaseDetachSong(gcc_unused const Database &db,
|
DatabaseDetachSong(gcc_unused const Database &db,
|
||||||
gcc_unused const Storage &_storage,
|
gcc_unused const Storage &_storage,
|
||||||
const char *uri,
|
const char *uri)
|
||||||
gcc_unused Error &error)
|
|
||||||
{
|
{
|
||||||
if (strcmp(uri, uri2) == 0)
|
if (strcmp(uri, uri2) == 0)
|
||||||
return new DetachedSong(uri, MakeTag2a());
|
return new DetachedSong(uri, MakeTag2a());
|
||||||
|
|
Loading…
Reference in New Issue