diff --git a/src/core/library/QueryRegistry.cpp b/src/core/library/QueryRegistry.cpp index 2a7f17950..54e831379 100644 --- a/src/core/library/QueryRegistry.cpp +++ b/src/core/library/QueryRegistry.cpp @@ -37,16 +37,17 @@ #include "QueryRegistry.h" #include #include -//#include +#include #include #include #include -//#include -//#include +#include +#include #include -// #include -// #include -// #include +#include +#include +#include +#include #include #include #include @@ -67,8 +68,9 @@ namespace musik { namespace core { namespace library { if (name == AllCategoriesQuery::kQueryName) { return AllCategoriesQuery::DeserializeQuery(data); } - //if (name == AppendPlaylistQuery::kQueryName) { - //} + if (name == AppendPlaylistQuery::kQueryName) { + return AppendPlaylistQuery::DeserializeQuery(library, data); + } if (name == GetPlaylistQuery::kQueryName) { return GetPlaylistQuery::DeserializeQuery(library, data); } @@ -78,19 +80,21 @@ namespace musik { namespace core { namespace library { if (name == CategoryTrackListQuery::kQueryName) { return CategoryTrackListQuery::DeserializeQuery(library, data); } - //if (name == DeletePlaylistQuery::kQueryName) { - //} - //if (name == DirectoryTrackListQuery::kQueryName) { - //} + if (name == DeletePlaylistQuery::kQueryName) { + return DeletePlaylistQuery::DeserializeQuery(library, data); + } + if (name == DirectoryTrackListQuery::kQueryName) { + return DirectoryTrackListQuery::DeserializeQuery(library, data); + } if (name == LyricsQuery::kQueryName) { return LyricsQuery::DeserializeQuery(data); } - //if (name == MarkTrackPlayedQuery::kQueryName) { - //} - //if (name == NowPlayingTrackListQuery::kQueryName) { - //} - //if (name == SavePlaylistQuery::kQueryName) { - //} + if (name == MarkTrackPlayedQuery::kQueryName) { + return MarkTrackPlayedQuery::DeserializeQuery(data); + } + if (name == SavePlaylistQuery::kQueryName) { + return SavePlaylistQuery::DeserializeQuery(library, data); + } if (name == SearchTrackListQuery::kQueryName) { return SearchTrackListQuery::DeserializeQuery(library, data); } @@ -102,6 +106,15 @@ namespace musik { namespace core { namespace library { } return std::shared_ptr(); } + + bool IsLocalOnlyQuery(const std::string& queryName) { + static const std::set sLocalOnlyQuerys = { + NowPlayingTrackListQuery::kQueryName, + PersistedPlayQueueQuery::kQueryName + }; + + return sLocalOnlyQuerys.find(queryName) != sLocalOnlyQuerys.end(); + } } } } } diff --git a/src/core/library/QueryRegistry.h b/src/core/library/QueryRegistry.h index 387aa1dc3..518ce42ff 100644 --- a/src/core/library/QueryRegistry.h +++ b/src/core/library/QueryRegistry.h @@ -44,6 +44,8 @@ namespace musik { namespace core { namespace library { namespace QueryRegistry { std::shared_ptr CreateLocalQueryFor( const std::string& name, const std::string& data, musik::core::ILibraryPtr library); + + bool IsLocalOnlyQuery(const std::string& queryName); } } } } diff --git a/src/core/library/RemoteLibrary.cpp b/src/core/library/RemoteLibrary.cpp index a7f43db21..a7f8ec8a9 100644 --- a/src/core/library/RemoteLibrary.cpp +++ b/src/core/library/RemoteLibrary.cpp @@ -131,6 +131,11 @@ void RemoteLibrary::Close() { } int RemoteLibrary::Enqueue(QueryPtr query, unsigned int options, Callback callback) { + if (QueryRegistry::IsLocalOnlyQuery(query->Name())) { + auto defaultLocalLibrary = LibraryFactory::Instance().Default(); + return defaultLocalLibrary->Enqueue(query, options, callback); + } + auto serializableQuery = std::dynamic_pointer_cast(query); if (serializableQuery) { @@ -206,7 +211,7 @@ void RemoteLibrary::RunQuery(QueryContextPtr context, bool notify) { this->QueryCompleted(localQuery.get()); } } - if (context->callback) { + else if (context->callback) { context->callback(context->query); } }; diff --git a/src/core/library/query/AppendPlaylistQuery.cpp b/src/core/library/query/AppendPlaylistQuery.cpp index 708b90788..f3f5d6f9e 100644 --- a/src/core/library/query/AppendPlaylistQuery.cpp +++ b/src/core/library/query/AppendPlaylistQuery.cpp @@ -36,10 +36,12 @@ #include "AppendPlaylistQuery.h" #include #include +#include #include #include #include #include +#include using musik::core::db::Statement; using musik::core::db::Row; @@ -47,10 +49,13 @@ using musik::core::db::Row; using namespace musik::core; using namespace musik::core::db; using namespace musik::core::library::query; +using namespace musik::core::library::query::serialization; using namespace musik::core::library::constants; using namespace musik::core::sdk; using namespace musik::core::runtime; +const std::string AppendPlaylistQuery::kQueryName = "AppendPlaylistQuery"; + static std::string INSERT_PLAYLIST_TRACK_QUERY = "INSERT INTO playlist_tracks (track_external_id, source_id, playlist_id, sort_order) " "VALUES (?, ?, ?, ?)"; @@ -87,9 +92,12 @@ AppendPlaylistQuery::AppendPlaylistQuery( } bool AppendPlaylistQuery::OnRun(musik::core::db::Connection &db) { + this->result = false; + ITrackList* tracks = sharedTracks ? sharedTracks.get() : rawTracks; if (!tracks || !tracks->Count() || playlistId == 0) { + this->result = true; return true; } @@ -148,5 +156,45 @@ bool AppendPlaylistQuery::OnRun(musik::core::db::Connection &db) { this->library->GetMessageQueue().Broadcast( Message::Create(nullptr, message::PlaylistModified, playlistId)); + this->result = true; return true; +} + +/* ISerializableQuery */ + +std::string AppendPlaylistQuery::SerializeQuery() { + ITrackList* tracks = rawTracks ? rawTracks : sharedTracks.get(); + nlohmann::json output = { + { "name", kQueryName }, + { "options", { + { "playlistId", this->playlistId }, + { "offset", this->offset }, + { "tracks", ITrackListToJsonIdList(*tracks) } + }} + }; + return output.dump(); +} + +std::string AppendPlaylistQuery::SerializeResult() { + nlohmann::json output = { { "result", this->result } }; + return output.dump(); +} + +void AppendPlaylistQuery::DeserializeResult(const std::string& data) { + auto input = nlohmann::json::parse(data); + this->SetStatus(input["result"].get() == true + ? IQuery::Finished : IQuery::Failed); +} + +std::shared_ptr AppendPlaylistQuery::DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data) +{ + auto options = nlohmann::json::parse(data)["options"]; + auto trackList = std::make_shared(library); + TrackListFromJson(options["tracks"], *trackList, library, true); + return std::make_shared( + library, + options["playlistId"].get(), + trackList, + options["offset"].get()); } \ No newline at end of file diff --git a/src/core/library/query/AppendPlaylistQuery.h b/src/core/library/query/AppendPlaylistQuery.h index 69ed01e71..7bb81cc2f 100644 --- a/src/core/library/query/AppendPlaylistQuery.h +++ b/src/core/library/query/AppendPlaylistQuery.h @@ -43,6 +43,8 @@ namespace musik { namespace core { namespace library { namespace query { class AppendPlaylistQuery : public musik::core::library::query::QueryBase { public: + static const std::string kQueryName; + AppendPlaylistQuery( musik::core::ILibraryPtr library, const int64_t playlistId, @@ -57,17 +59,24 @@ namespace musik { namespace core { namespace library { namespace query { virtual ~AppendPlaylistQuery() { } - std::string Name() { return "AppendPlaylistQuery"; } + std::string Name() { return kQueryName; } + + /* ISerializableQuery */ + virtual std::string SerializeQuery(); + virtual std::string SerializeResult(); + virtual void DeserializeResult(const std::string& data); + static std::shared_ptr DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data); protected: virtual bool OnRun(musik::core::db::Connection &db); - int64_t playlistId; - musik::core::ILibraryPtr library; std::shared_ptr sharedTracks; musik::core::sdk::ITrackList* rawTracks; + int64_t playlistId; int offset; + bool result{ false }; }; } } } } diff --git a/src/core/library/query/CategoryTrackListQuery.cpp b/src/core/library/query/CategoryTrackListQuery.cpp index f0dbb96df..cbb817a0e 100755 --- a/src/core/library/query/CategoryTrackListQuery.cpp +++ b/src/core/library/query/CategoryTrackListQuery.cpp @@ -214,25 +214,17 @@ std::string CategoryTrackListQuery::SerializeQuery() { { "sortType", sortType } }} }; - return output.dump(); + return FinalizeSerializedQueryWithLimitAndOffset(output); } std::string CategoryTrackListQuery::SerializeResult() { - nlohmann::json output = { - { "result", { - { "headers", *this->headers }, - { "trackList", TrackListToJson(*this->result, true) } - }} - }; - return output.dump(); + return InitializeSerializedResultWithHeadersAndTrackList().dump(); } void CategoryTrackListQuery::DeserializeResult(const std::string& data) { this->SetStatus(IQuery::Failed); nlohmann::json result = nlohmann::json::parse(data)["result"]; - this->result = std::make_shared(this->library); - TrackListFromJson(result["trackList"], *this->result, this->library, true); - JsonArrayToSet, size_t>(result["headers"], *this->headers); + this->DeserializeTrackListAndHeaders(result, this->library, this->result, this->headers); this->SetStatus(IQuery::Finished); } @@ -244,6 +236,7 @@ std::shared_ptr CategoryTrackListQuery::DeserializeQuery library, options["filter"].get(), options["sortType"].get()); + result->ExtractLimitAndOffsetFromDeserializedQuery(options); PredicateListFromJson(options["regularPredicateList"], result->regular); PredicateListFromJson(options["extendedPredicateList"], result->extended); result->ScanPredicateListsForQueryType(); diff --git a/src/core/library/query/DeletePlaylistQuery.cpp b/src/core/library/query/DeletePlaylistQuery.cpp index 5ef25c151..cbfb6c72d 100644 --- a/src/core/library/query/DeletePlaylistQuery.cpp +++ b/src/core/library/query/DeletePlaylistQuery.cpp @@ -40,11 +40,15 @@ #include #include +#include + using namespace musik::core; using namespace musik::core::db; using namespace musik::core::library::query; using namespace musik::core::runtime; +const std::string DeletePlaylistQuery::kQueryName = "DeletePlaylistQuery"; + static std::string DELETE_PLAYLIST_TRACKS_QUERY = "DELETE FROM playlist_tracks WHERE playlist_id=?;"; @@ -68,20 +72,53 @@ bool DeletePlaylistQuery::OnRun(musik::core::db::Connection &db) { if (deleteTracks.Step() == db::Error) { transaction.Cancel(); - return false; + this->result = false; } + else { + /* delete the container */ + Statement deletePlaylist(DELETE_PLAYLIST_QUERY.c_str(), db); + deletePlaylist.BindInt64(0, this->playlistId); - /* delete the container */ - Statement deletePlaylist(DELETE_PLAYLIST_QUERY.c_str(), db); - deletePlaylist.BindInt64(0, this->playlistId); - - if (deletePlaylist.Step() == db::Error) { - transaction.Cancel(); - return false; + if (deletePlaylist.Step() == db::Error) { + transaction.Cancel(); + this->result = false; + } + else { + this->library->GetMessageQueue().Broadcast( + Message::Create(nullptr, message::PlaylistDeleted, playlistId)); + this->result = true; + } } + return this->result; +} - this->library->GetMessageQueue().Broadcast( - Message::Create(nullptr, message::PlaylistDeleted, playlistId)); - return true; +/* ISerializableQuery */ + +std::string DeletePlaylistQuery::SerializeQuery() { + nlohmann::json output = { + { "name", kQueryName }, + { "options", { + { "playlistId", this->playlistId }, + }} + }; + return output.dump(); +} + +std::string DeletePlaylistQuery::SerializeResult() { + nlohmann::json output = { { "result", this->result } }; + return output.dump(); +} + +void DeletePlaylistQuery::DeserializeResult(const std::string& data) { + auto input = nlohmann::json::parse(data); + this->SetStatus(input["result"].get() == true + ? IQuery::Finished : IQuery::Failed); +} + +std::shared_ptr DeletePlaylistQuery::DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data) +{ + auto options = nlohmann::json::parse(data)["options"]; + return std::make_shared(library, options["playlistId"].get()); } \ No newline at end of file diff --git a/src/core/library/query/DeletePlaylistQuery.h b/src/core/library/query/DeletePlaylistQuery.h index fe6fea855..948251d69 100644 --- a/src/core/library/query/DeletePlaylistQuery.h +++ b/src/core/library/query/DeletePlaylistQuery.h @@ -42,13 +42,22 @@ namespace musik { namespace core { namespace library { namespace query { class DeletePlaylistQuery : public musik::core::library::query::QueryBase { public: + static const std::string kQueryName; + DeletePlaylistQuery( musik::core::ILibraryPtr library, const int64_t playlistId); virtual ~DeletePlaylistQuery(); - virtual std::string Name() { return "DeletePlaylistQuery"; } + virtual std::string Name() { return kQueryName; } + + /* ISerializableQuery */ + virtual std::string SerializeQuery(); + virtual std::string SerializeResult(); + virtual void DeserializeResult(const std::string& data); + static std::shared_ptr DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data); protected: virtual bool OnRun(musik::core::db::Connection &db); @@ -56,6 +65,7 @@ namespace musik { namespace core { namespace library { namespace query { private: int64_t playlistId; musik::core::ILibraryPtr library; + bool result{ false }; }; } } } } diff --git a/src/core/library/query/DirectoryTrackListQuery.cpp b/src/core/library/query/DirectoryTrackListQuery.cpp index a90dda9e3..ad44d1ef3 100644 --- a/src/core/library/query/DirectoryTrackListQuery.cpp +++ b/src/core/library/query/DirectoryTrackListQuery.cpp @@ -34,6 +34,7 @@ #include "pch.hpp" #include +#include #include #include "DirectoryTrackListQuery.h" #include "CategoryTrackListQuery.h" @@ -44,8 +45,11 @@ using musik::core::ILibraryPtr; using namespace musik::core::db; using namespace musik::core::library::query; +using namespace musik::core::library::query::serialization; using namespace musik::core::library; +const std::string DirectoryTrackListQuery::kQueryName = "DirectoryTrackListQuery"; + DirectoryTrackListQuery::DirectoryTrackListQuery( ILibraryPtr library, const std::string& directory, @@ -101,3 +105,39 @@ bool DirectoryTrackListQuery::OnRun(Connection& db) { return true; } + +/* ISerializableQuery */ + +std::string DirectoryTrackListQuery::SerializeQuery() { + nlohmann::json output = { + { "name", kQueryName }, + { "options", { + { "directory", directory }, + { "filter", filter }, + }} + }; + return FinalizeSerializedQueryWithLimitAndOffset(output); +} + +std::string DirectoryTrackListQuery::SerializeResult() { + return InitializeSerializedResultWithHeadersAndTrackList().dump(); +} + +void DirectoryTrackListQuery::DeserializeResult(const std::string& data) { + this->SetStatus(IQuery::Failed); + nlohmann::json result = nlohmann::json::parse(data)["result"]; + this->DeserializeTrackListAndHeaders(result, this->library, this->result, this->headers); + this->SetStatus(IQuery::Finished); +} + +std::shared_ptr DirectoryTrackListQuery::DeserializeQuery( + ILibraryPtr library, const std::string& data) +{ + auto options = nlohmann::json::parse(data)["options"]; + auto result = std::make_shared( + library, + options["directory"].get(), + options["filter"].get()); + result->ExtractLimitAndOffsetFromDeserializedQuery(options); + return result; +} diff --git a/src/core/library/query/DirectoryTrackListQuery.h b/src/core/library/query/DirectoryTrackListQuery.h index 1dff7e37a..0635a1d10 100644 --- a/src/core/library/query/DirectoryTrackListQuery.h +++ b/src/core/library/query/DirectoryTrackListQuery.h @@ -41,6 +41,8 @@ namespace musik { namespace core { namespace library { namespace query { class DirectoryTrackListQuery : public TrackListQueryBase { public: + static const std::string kQueryName; + DirectoryTrackListQuery( musik::core::ILibraryPtr library, const std::string& directory, @@ -48,11 +50,18 @@ namespace musik { namespace core { namespace library { namespace query { virtual ~DirectoryTrackListQuery(); - virtual std::string Name() { return "DirectoryTrackListQuery"; } + virtual std::string Name() { return kQueryName; } virtual Result GetResult() { return this->result; } virtual Headers GetHeaders() { return this->headers; } virtual size_t GetQueryHash() { return this->hash; } + /* ISerializableQuery */ + virtual std::string SerializeQuery(); + virtual std::string SerializeResult(); + virtual void DeserializeResult(const std::string& data); + static std::shared_ptr DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data); + protected: virtual bool OnRun(musik::core::db::Connection &db); diff --git a/src/core/library/query/GetPlaylistQuery.cpp b/src/core/library/query/GetPlaylistQuery.cpp index adca22b99..c1961d0e6 100644 --- a/src/core/library/query/GetPlaylistQuery.cpp +++ b/src/core/library/query/GetPlaylistQuery.cpp @@ -111,25 +111,17 @@ std::string GetPlaylistQuery::SerializeQuery() { { "playlistId", playlistId }, }} }; - return output.dump(); + return FinalizeSerializedQueryWithLimitAndOffset(output); } std::string GetPlaylistQuery::SerializeResult() { - nlohmann::json output = { - { "result", { - { "headers", *this->headers }, - { "trackList", TrackListToJson(*this->result, true) } - }} - }; - return output.dump(); + return InitializeSerializedResultWithHeadersAndTrackList().dump(); } void GetPlaylistQuery::DeserializeResult(const std::string& data) { this->SetStatus(IQuery::Failed); nlohmann::json result = nlohmann::json::parse(data)["result"]; - this->result = std::make_shared(this->library); - TrackListFromJson(result["trackList"], *this->result, this->library, true); - JsonArrayToSet, size_t>(result["headers"], *this->headers); + this->DeserializeTrackListAndHeaders(result, this->library, this->result, this->headers); this->SetStatus(IQuery::Finished); } @@ -137,6 +129,8 @@ std::shared_ptr GetPlaylistQuery::DeserializeQuery( musik::core::ILibraryPtr library, const std::string& data) { auto options = nlohmann::json::parse(data)["options"]; - return std::make_shared( + auto result = std::make_shared( library, options["playlistId"].get()); + result->ExtractLimitAndOffsetFromDeserializedQuery(options); + return result; } \ No newline at end of file diff --git a/src/core/library/query/MarkTrackPlayedQuery.cpp b/src/core/library/query/MarkTrackPlayedQuery.cpp index 57f0311fc..b1221175e 100644 --- a/src/core/library/query/MarkTrackPlayedQuery.cpp +++ b/src/core/library/query/MarkTrackPlayedQuery.cpp @@ -34,11 +34,14 @@ #include "pch.hpp" #include "MarkTrackPlayedQuery.h" +#include using namespace musik::core::db; using namespace musik::core::library::query; using namespace musik::core::sdk; +const std::string MarkTrackPlayedQuery::kQueryName = "MarkTrackPlayedQuery"; + MarkTrackPlayedQuery::MarkTrackPlayedQuery(const int64_t trackId) { this->trackId = trackId; } @@ -55,9 +58,34 @@ bool MarkTrackPlayedQuery::OnRun(musik::core::db::Connection &db) { stmt.BindInt64(0, this->trackId); - if (stmt.Step() == db::Done) { - return true; - } + this->result = stmt.Step() == db::Done; + return this->result; +} - return false; +/* ISerializableQuery */ + +std::string MarkTrackPlayedQuery::SerializeQuery() { + nlohmann::json output = { + { "name", kQueryName }, + { "options", { + { "trackId", this->trackId }, + }} + }; + return output.dump(); +} + +std::string MarkTrackPlayedQuery::SerializeResult() { + nlohmann::json output = { { "result", this->result } }; + return output.dump(); +} + +void MarkTrackPlayedQuery::DeserializeResult(const std::string& data) { + auto input = nlohmann::json::parse(data); + this->SetStatus(input["result"].get() == true + ? IQuery::Finished : IQuery::Failed); +} + +std::shared_ptr MarkTrackPlayedQuery::DeserializeQuery(const std::string& data) { + auto options = nlohmann::json::parse(data)["options"]; + return std::make_shared(options["trackId"].get()); } \ No newline at end of file diff --git a/src/core/library/query/MarkTrackPlayedQuery.h b/src/core/library/query/MarkTrackPlayedQuery.h index 73a70e43c..48e08b630 100644 --- a/src/core/library/query/MarkTrackPlayedQuery.h +++ b/src/core/library/query/MarkTrackPlayedQuery.h @@ -40,13 +40,22 @@ namespace musik { namespace core { namespace library { namespace query { class MarkTrackPlayedQuery: public QueryBase { public: + static const std::string kQueryName; + MarkTrackPlayedQuery(const int64_t trackId); virtual ~MarkTrackPlayedQuery(); std::string Name() { return "MarkTrackPlayedQuery"; } + /* ISerializableQuery */ + virtual std::string SerializeQuery(); + virtual std::string SerializeResult(); + virtual void DeserializeResult(const std::string& data); + static std::shared_ptr DeserializeQuery(const std::string& data); + protected: virtual bool OnRun(musik::core::db::Connection &db); int64_t trackId; + bool result{ false }; }; } } } } diff --git a/src/core/library/query/NowPlayingTrackListQuery.cpp b/src/core/library/query/NowPlayingTrackListQuery.cpp index 954dc9aa9..b06a51fab 100755 --- a/src/core/library/query/NowPlayingTrackListQuery.cpp +++ b/src/core/library/query/NowPlayingTrackListQuery.cpp @@ -49,6 +49,8 @@ using namespace musik::core::db; using namespace musik::core::library::constants; using namespace musik::core::library::query; +const std::string NowPlayingTrackListQuery::kQueryName = "NowPlayingTrackListQuery"; + NowPlayingTrackListQuery::NowPlayingTrackListQuery( ILibraryPtr library, musik::core::audio::PlaybackService& playback) : library(library) diff --git a/src/core/library/query/NowPlayingTrackListQuery.h b/src/core/library/query/NowPlayingTrackListQuery.h index 37598324b..39acc00ab 100755 --- a/src/core/library/query/NowPlayingTrackListQuery.h +++ b/src/core/library/query/NowPlayingTrackListQuery.h @@ -43,13 +43,15 @@ namespace musik { namespace core { namespace library { namespace query { class NowPlayingTrackListQuery : public TrackListQueryBase { public: + static const std::string kQueryName; + NowPlayingTrackListQuery( musik::core::ILibraryPtr library, musik::core::audio::PlaybackService& playback); virtual ~NowPlayingTrackListQuery(); - virtual std::string Name() { return "NowPlayingTrackListQuery"; } + virtual std::string Name() { return kQueryName; } virtual Result GetResult(); virtual Headers GetHeaders(); virtual size_t GetQueryHash(); diff --git a/src/core/library/query/PersistedPlayQueueQuery.cpp b/src/core/library/query/PersistedPlayQueueQuery.cpp index 093affbb5..e6cb82987 100644 --- a/src/core/library/query/PersistedPlayQueueQuery.cpp +++ b/src/core/library/query/PersistedPlayQueueQuery.cpp @@ -42,6 +42,8 @@ using namespace musik::core; using namespace musik::core::db; using namespace musik::core::library::query; +const std::string PersistedPlayQueueQuery::kQueryName = "PersistedPlayQueueQuery"; + PersistedPlayQueueQuery::PersistedPlayQueueQuery( musik::core::ILibraryPtr library, musik::core::audio::PlaybackService& playback, diff --git a/src/core/library/query/PersistedPlayQueueQuery.h b/src/core/library/query/PersistedPlayQueueQuery.h index 10411c2b7..21beaabc5 100644 --- a/src/core/library/query/PersistedPlayQueueQuery.h +++ b/src/core/library/query/PersistedPlayQueueQuery.h @@ -41,6 +41,8 @@ namespace musik { namespace core { namespace library { namespace query { class PersistedPlayQueueQuery : public musik::core::library::query::QueryBase { public: + static const std::string kQueryName; + static PersistedPlayQueueQuery* Save( musik::core::ILibraryPtr library, musik::core::audio::PlaybackService& playback) @@ -57,7 +59,7 @@ namespace musik { namespace core { namespace library { namespace query { virtual ~PersistedPlayQueueQuery(); - virtual std::string Name() { return "PersistedPlayQueueQuery"; } + virtual std::string Name() { return kQueryName; } protected: virtual bool OnRun(musik::core::db::Connection &db); diff --git a/src/core/library/query/SavePlaylistQuery.cpp b/src/core/library/query/SavePlaylistQuery.cpp index 4508833de..ab677e736 100644 --- a/src/core/library/query/SavePlaylistQuery.cpp +++ b/src/core/library/query/SavePlaylistQuery.cpp @@ -38,18 +38,25 @@ #include #include +#include +#include #include #include #include #include using namespace musik::core; +using namespace musik::core::sdk; using namespace musik::core::db; +using namespace musik::core::library; using namespace musik::core::library::query; +using namespace musik::core::library::query::serialization; using namespace musik::core::runtime; /* CONSTANTS */ +const std::string SavePlaylistQuery::kQueryName = "SavePlaylistQuery"; + static std::string CREATE_PLAYLIST_QUERY = "INSERT INTO playlists (name) VALUES (?);"; @@ -130,7 +137,7 @@ std::shared_ptr SavePlaylistQuery::Append( auto result = std::shared_ptr( new SavePlaylistQuery(library, playlistId, tracks)); - result->op = AppendOp; + result->op = Operation::Append; return result; } @@ -146,7 +153,7 @@ std::shared_ptr SavePlaylistQuery::Append( auto result = std::shared_ptr( new SavePlaylistQuery(library, playlistId, categoryType, categoryId)); - result->op = AppendOp; + result->op = Operation::Append; return result; } @@ -162,7 +169,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->playlistName = playlistName; this->tracks.rawTracks = nullptr; this->tracks.sharedTracks = tracks; - this->op = CreateOp; + this->op = Operation::Create; } SavePlaylistQuery::SavePlaylistQuery( @@ -175,7 +182,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->categoryId = -1; this->playlistName = playlistName; this->tracks.rawTracks = tracks; - this->op = CreateOp; + this->op = Operation::Create; } SavePlaylistQuery::SavePlaylistQuery( @@ -189,7 +196,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->categoryId = categoryId; this->categoryType = categoryType; this->playlistName = playlistName; - this->op = CreateOp; + this->op = Operation::Create; } SavePlaylistQuery::SavePlaylistQuery( @@ -200,7 +207,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->library = library; this->playlistId = playlistId; this->tracks.sharedTracks = tracks; - this->op = ReplaceOp; + this->op = Operation::Replace; } SavePlaylistQuery::SavePlaylistQuery( @@ -211,7 +218,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->library = library; this->playlistId = playlistId; this->tracks.rawTracks = tracks; - this->op = ReplaceOp; + this->op = Operation::Replace; } SavePlaylistQuery::SavePlaylistQuery( @@ -224,7 +231,7 @@ SavePlaylistQuery::SavePlaylistQuery( this->playlistId = playlistId; this->categoryId = categoryId; this->categoryType = categoryType; - this->op = AppendOp; + this->op = Operation::Append; } SavePlaylistQuery::SavePlaylistQuery( @@ -236,7 +243,12 @@ SavePlaylistQuery::SavePlaylistQuery( this->categoryId = -1; this->playlistId = playlistId; this->playlistName = playlistName; - this->op = RenameOp; + this->op = Operation::Rename; +} + +SavePlaylistQuery::SavePlaylistQuery(musik::core::ILibraryPtr library) { + this->library = library; + this->categoryId = -1; } SavePlaylistQuery::~SavePlaylistQuery() { @@ -394,13 +406,14 @@ bool SavePlaylistQuery::AppendToPlaylist(musik::core::db::Connection& db) { } bool SavePlaylistQuery::OnRun(musik::core::db::Connection &db) { + this->result = false; switch (this->op) { - case RenameOp: return this->RenamePlaylist(db); - case ReplaceOp: return this->ReplacePlaylist(db); - case CreateOp: return this->CreatePlaylist(db); - case AppendOp: return this->AppendToPlaylist(db); + case Operation::Rename: this->result = this->RenamePlaylist(db); break; + case Operation::Replace: this->result = this->ReplacePlaylist(db); break; + case Operation::Create: this->result = this->CreatePlaylist(db); break; + case Operation::Append: this->result = this->AppendToPlaylist(db); break; } - return false; + return this->result; } /* SUPPORTING TYPES */ @@ -445,3 +458,53 @@ TrackPtr SavePlaylistQuery::TrackListWrapper::Get( return result; } + +ITrackList* SavePlaylistQuery::TrackListWrapper::Get() { + if (sharedTracks) { + return sharedTracks.get(); + } + return rawTracks; +} + +/* ISerializableQuery */ + +std::string SavePlaylistQuery::SerializeQuery() { + nlohmann::json output = { + { "name", kQueryName }, + { "options", { + { "op", this->op }, + { "playlistName", this->playlistName }, + { "categoryType", this->categoryType }, + { "playlistId", this->playlistId }, + { "categoryId", this->categoryId }, + { "tracks", ITrackListToJsonIdList(*tracks.Get()) } + }} + }; + return output.dump(); +} + +std::string SavePlaylistQuery::SerializeResult() { + nlohmann::json output = { { "result", this->result } }; + return output.dump(); +} + +void SavePlaylistQuery::DeserializeResult(const std::string& data) { + auto input = nlohmann::json::parse(data); + this->SetStatus(input["result"].get() == true + ? IQuery::Finished : IQuery::Failed); +} + +std::shared_ptr SavePlaylistQuery::DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data) +{ + auto options = nlohmann::json::parse(data)["options"]; + auto output = std::shared_ptr(new SavePlaylistQuery(library)); + output->op = options["op"].get(); + output->playlistName = options["playlistName"].get(); + output->categoryType = options["categoryType"].get(); + output->playlistId = options["playlistId"].get(); + output->categoryId = options["categoryId"].get(); + output->tracks.sharedTracks = std::make_shared(library); + TrackListFromJson(options["tracks"], *output->tracks.sharedTracks, library, true); + return output; +} \ No newline at end of file diff --git a/src/core/library/query/SavePlaylistQuery.h b/src/core/library/query/SavePlaylistQuery.h index 13784a15b..e9b507d96 100644 --- a/src/core/library/query/SavePlaylistQuery.h +++ b/src/core/library/query/SavePlaylistQuery.h @@ -44,6 +44,8 @@ namespace musik { namespace core { namespace library { namespace query { class SavePlaylistQuery : public musik::core::library::query::QueryBase { public: + static const std::string kQueryName; + static std::shared_ptr Save( musik::core::ILibraryPtr library, const std::string& playlistName, @@ -86,12 +88,19 @@ namespace musik { namespace core { namespace library { namespace query { const std::string& categoryType, int64_t categoryId); - virtual std::string Name() { return "SavePlaylistQuery"; } + virtual std::string Name() { return kQueryName; } virtual ~SavePlaylistQuery(); int64_t GetPlaylistId() const; + /* ISerializableQuery */ + virtual std::string SerializeQuery(); + virtual std::string SerializeResult(); + virtual void DeserializeResult(const std::string& data); + static std::shared_ptr DeserializeQuery( + musik::core::ILibraryPtr library, const std::string& data); + protected: virtual bool OnRun(musik::core::db::Connection &db); @@ -133,6 +142,8 @@ namespace musik { namespace core { namespace library { namespace query { const int64_t playlistId, const std::string& newName); + SavePlaylistQuery(musik::core::ILibraryPtr library); /* for query (de)serialization */ + struct TrackListWrapper { TrackListWrapper(); TrackListWrapper(std::shared_ptr shared); @@ -140,12 +151,18 @@ namespace musik { namespace core { namespace library { namespace query { bool Exists(); size_t Count(); TrackPtr Get(musik::core::ILibraryPtr library, size_t index); + musik::core::sdk::ITrackList* Get(); std::shared_ptr sharedTracks; musik::core::sdk::ITrackList* rawTracks; }; - enum Operation { CreateOp, RenameOp, ReplaceOp, AppendOp }; + enum class Operation: int { + Create = 1, + Rename = 2, + Replace = 3, + Append = 4 + }; bool CreatePlaylist(musik::core::db::Connection &db); bool RenamePlaylist(musik::core::db::Connection &db); @@ -159,6 +176,7 @@ namespace musik { namespace core { namespace library { namespace query { int64_t playlistId, TrackListWrapper& tracks); + bool result{ false }; Operation op; musik::core::ILibraryPtr library; std::string playlistName, categoryType; diff --git a/src/core/library/query/SearchTrackListQuery.cpp b/src/core/library/query/SearchTrackListQuery.cpp index f6a4fe3a9..42b06fc44 100755 --- a/src/core/library/query/SearchTrackListQuery.cpp +++ b/src/core/library/query/SearchTrackListQuery.cpp @@ -176,32 +176,26 @@ std::string SearchTrackListQuery::SerializeQuery() { { "sortType", sortType} }} }; - return output.dump(); + return FinalizeSerializedQueryWithLimitAndOffset(output); } std::string SearchTrackListQuery::SerializeResult() { - nlohmann::json output = { - { "result", { - { "headers", *this->headers }, - { "trackList", TrackListToJson(*this->result, true) } - }} - }; - return output.dump(); + return InitializeSerializedResultWithHeadersAndTrackList().dump(); } void SearchTrackListQuery::DeserializeResult(const std::string& data) { this->SetStatus(IQuery::Failed); nlohmann::json result = nlohmann::json::parse(data)["result"]; - this->result = std::make_shared(this->library); - TrackListFromJson(result["trackList"], *this->result, this->library, true); - JsonArrayToSet, size_t>(result["headers"], *this->headers); + this->DeserializeTrackListAndHeaders(result, this->library, this->result, this->headers); this->SetStatus(IQuery::Finished); } std::shared_ptr SearchTrackListQuery::DeserializeQuery(musik::core::ILibraryPtr library, const std::string& data) { auto options = nlohmann::json::parse(data)["options"]; - return std::make_shared( + auto result = std::make_shared( library, options["filter"].get(), options["sortType"].get()); + result->ExtractLimitAndOffsetFromDeserializedQuery(options); + return result; } diff --git a/src/core/library/query/SetTrackRatingQuery.cpp b/src/core/library/query/SetTrackRatingQuery.cpp index b444ac15d..43a84f4a0 100644 --- a/src/core/library/query/SetTrackRatingQuery.cpp +++ b/src/core/library/query/SetTrackRatingQuery.cpp @@ -54,13 +54,12 @@ bool SetTrackRatingQuery::OnRun(musik::core::db::Connection &db) { Statement stmt("UPDATE tracks SET rating=? WHERE id=?", db); stmt.BindInt32(0, this->rating); stmt.BindInt64(1, this->trackId); - if (stmt.Step() == db::Done) { - return true; - } - return false; + this->result = stmt.Step() == db::Done; + return this->result; } /* ISerializableQuery */ + std::string SetTrackRatingQuery::SerializeQuery() { nlohmann::json output = { { "name", kQueryName }, @@ -73,7 +72,7 @@ std::string SetTrackRatingQuery::SerializeQuery() { } std::string SetTrackRatingQuery::SerializeResult() { - nlohmann::json output = { { "result", true } }; + nlohmann::json output = { { "result", this->result } }; return output.dump(); } diff --git a/src/core/library/query/SetTrackRatingQuery.h b/src/core/library/query/SetTrackRatingQuery.h index 5f8d05279..bf0584c48 100644 --- a/src/core/library/query/SetTrackRatingQuery.h +++ b/src/core/library/query/SetTrackRatingQuery.h @@ -57,6 +57,7 @@ namespace musik { namespace core { namespace library { namespace query { int64_t trackId; int rating; + bool result{ false }; }; } } } } diff --git a/src/core/library/query/TrackListQueryBase.h b/src/core/library/query/TrackListQueryBase.h index 3e12b503c..d92a51b22 100755 --- a/src/core/library/query/TrackListQueryBase.h +++ b/src/core/library/query/TrackListQueryBase.h @@ -38,6 +38,9 @@ #include #include #include +#include + +#include namespace musik { namespace core { namespace library { namespace query { @@ -67,6 +70,9 @@ namespace musik { namespace core { namespace library { namespace query { } protected: + + /* for IMetadataProxy */ + std::string GetLimitAndOffset() { if (this->limit > 0 && this->offset >= 0) { return u8fmt("LIMIT %d OFFSET %d", this->limit, this->offset); @@ -74,6 +80,40 @@ namespace musik { namespace core { namespace library { namespace query { return ""; } + /* for ISerialization */ + + const std::string FinalizeSerializedQueryWithLimitAndOffset(nlohmann::json &output) { + auto& options = output["options"]; + options["limit"] = this->limit; + options["offset"] = this->offset; + return output.dump(); + } + + void ExtractLimitAndOffsetFromDeserializedQuery(nlohmann::json& options) { + this->limit = options.value("limit", -1); + this->offset = options.value("offset", 0); + } + + nlohmann::json InitializeSerializedResultWithHeadersAndTrackList() { + nlohmann::json output = { + { "result", { + { "headers", *this->GetHeaders() }, + { "trackList", serialization::TrackListToJson(*this->GetResult(), true) } + }} + }; + return output; + } + + void DeserializeTrackListAndHeaders( + nlohmann::json &result, + ILibraryPtr library, + Result tracks, + Headers headers) + { + serialization::TrackListFromJson(result["trackList"], *tracks, library, true); + serialization::JsonArrayToSet, size_t>(result["headers"], *headers); + } + private: int limit, offset; diff --git a/src/core/library/query/util/Serialization.cpp b/src/core/library/query/util/Serialization.cpp index 7458338ae..6e0117ee3 100644 --- a/src/core/library/query/util/Serialization.cpp +++ b/src/core/library/query/util/Serialization.cpp @@ -231,6 +231,14 @@ namespace musik { namespace core { namespace library { namespace query { } } + nlohmann::json ITrackListToJsonIdList(const ITrackList& input) { + nlohmann::json output; + for (size_t i = 0; i < input.Count(); i++) { + output.push_back(input.GetId(i)); + } + return output; + } + } } } } } diff --git a/src/core/library/query/util/Serialization.h b/src/core/library/query/util/Serialization.h index bfd92c2ea..c4bfead63 100644 --- a/src/core/library/query/util/Serialization.h +++ b/src/core/library/query/util/Serialization.h @@ -86,6 +86,9 @@ namespace musik { namespace core { namespace library { namespace query { musik::core::ILibraryPtr library, bool onlyIds); + nlohmann::json ITrackListToJsonIdList( + const musik::core::sdk::ITrackList& input); + template void JsonArrayToSet(const nlohmann::json& input, SetType& output) { for (auto& value : input) {