Finished initial round of query serialization.

This commit is contained in:
casey langen 2020-10-05 18:44:16 -07:00
parent 9af8844a29
commit fc8279968e
25 changed files with 428 additions and 97 deletions

View File

@ -37,16 +37,17 @@
#include "QueryRegistry.h"
#include <core/library/query/AlbumListQuery.h>
#include <core/library/query/AllCategoriesQuery.h>
//#include <core/library/query/AppendPlaylistQuery.h>
#include <core/library/query/AppendPlaylistQuery.h>
#include <core/library/query/GetPlaylistQuery.h>
#include <core/library/query/CategoryListQuery.h>
#include <core/library/query/CategoryTrackListQuery.h>
//#include <core/library/query/DeletePlaylistQuery.h>
//#include <core/library/query/DirectoryTrackListQuery.h>
#include <core/library/query/DeletePlaylistQuery.h>
#include <core/library/query/DirectoryTrackListQuery.h>
#include <core/library/query/LyricsQuery.h>
// #include <core/library/query/MarkTrackPlayedQuery.h>
// #include <core/library/query/NowPlayingTrackListQuery.h>
// #include <core/library/query/SavePlaylistQuery.h>
#include <core/library/query/MarkTrackPlayedQuery.h>
#include <core/library/query/NowPlayingTrackListQuery.h>
#include <core/library/query/PersistedPlayQueueQuery.h>
#include <core/library/query/SavePlaylistQuery.h>
#include <core/library/query/SearchTrackListQuery.h>
#include <core/library/query/SetTrackRatingQuery.h>
#include <core/library/query/TrackMetadataQuery.h>
@ -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<ISerializableQuery>();
}
bool IsLocalOnlyQuery(const std::string& queryName) {
static const std::set<std::string> sLocalOnlyQuerys = {
NowPlayingTrackListQuery::kQueryName,
PersistedPlayQueueQuery::kQueryName
};
return sLocalOnlyQuerys.find(queryName) != sLocalOnlyQuerys.end();
}
}
} } }

View File

@ -44,6 +44,8 @@ namespace musik { namespace core { namespace library {
namespace QueryRegistry {
std::shared_ptr<musik::core::db::ISerializableQuery> CreateLocalQueryFor(
const std::string& name, const std::string& data, musik::core::ILibraryPtr library);
bool IsLocalOnlyQuery(const std::string& queryName);
}
} } }

View File

@ -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<ISerializableQuery>(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);
}
};

View File

@ -36,10 +36,12 @@
#include "AppendPlaylistQuery.h"
#include <core/library/track/LibraryTrack.h>
#include <core/library/query/TrackMetadataQuery.h>
#include <core/library/query/util/Serialization.h>
#include <core/library/LocalLibraryConstants.h>
#include <core/runtime/Message.h>
#include <core/support/Messages.h>
#include <core/db/Statement.h>
#include <json.hpp>
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<bool>() == true
? IQuery::Finished : IQuery::Failed);
}
std::shared_ptr<AppendPlaylistQuery> AppendPlaylistQuery::DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data)
{
auto options = nlohmann::json::parse(data)["options"];
auto trackList = std::make_shared<TrackList>(library);
TrackListFromJson(options["tracks"], *trackList, library, true);
return std::make_shared<AppendPlaylistQuery>(
library,
options["playlistId"].get<int64_t>(),
trackList,
options["offset"].get<int>());
}

View File

@ -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<AppendPlaylistQuery> 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<musik::core::TrackList> sharedTracks;
musik::core::sdk::ITrackList* rawTracks;
int64_t playlistId;
int offset;
bool result{ false };
};
} } } }

View File

@ -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<TrackList>(this->library);
TrackListFromJson(result["trackList"], *this->result, this->library, true);
JsonArrayToSet<std::set<size_t>, 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> CategoryTrackListQuery::DeserializeQuery
library,
options["filter"].get<std::string>(),
options["sortType"].get<TrackSortType>());
result->ExtractLimitAndOffsetFromDeserializedQuery(options);
PredicateListFromJson(options["regularPredicateList"], result->regular);
PredicateListFromJson(options["extendedPredicateList"], result->extended);
result->ScanPredicateListsForQueryType();

View File

@ -40,11 +40,15 @@
#include <core/support/Messages.h>
#include <core/runtime/Message.h>
#include <json.hpp>
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<bool>() == true
? IQuery::Finished : IQuery::Failed);
}
std::shared_ptr<DeletePlaylistQuery> DeletePlaylistQuery::DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data)
{
auto options = nlohmann::json::parse(data)["options"];
return std::make_shared<DeletePlaylistQuery>(library, options["playlistId"].get<int64_t>());
}

View File

@ -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<DeletePlaylistQuery> 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 };
};
} } } }

View File

@ -34,6 +34,7 @@
#include "pch.hpp"
#include <core/library/LocalLibraryConstants.h>
#include <core/library/query/util/Serialization.h>
#include <core/i18n/Locale.h>
#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> DirectoryTrackListQuery::DeserializeQuery(
ILibraryPtr library, const std::string& data)
{
auto options = nlohmann::json::parse(data)["options"];
auto result = std::make_shared<DirectoryTrackListQuery>(
library,
options["directory"].get<std::string>(),
options["filter"].get<std::string>());
result->ExtractLimitAndOffsetFromDeserializedQuery(options);
return result;
}

View File

@ -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<DirectoryTrackListQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);

View File

@ -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<TrackList>(this->library);
TrackListFromJson(result["trackList"], *this->result, this->library, true);
JsonArrayToSet<std::set<size_t>, 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> GetPlaylistQuery::DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data)
{
auto options = nlohmann::json::parse(data)["options"];
return std::make_shared<GetPlaylistQuery>(
auto result = std::make_shared<GetPlaylistQuery>(
library, options["playlistId"].get<int64_t>());
result->ExtractLimitAndOffsetFromDeserializedQuery(options);
return result;
}

View File

@ -34,11 +34,14 @@
#include "pch.hpp"
#include "MarkTrackPlayedQuery.h"
#include <json.hpp>
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<bool>() == true
? IQuery::Finished : IQuery::Failed);
}
std::shared_ptr<MarkTrackPlayedQuery> MarkTrackPlayedQuery::DeserializeQuery(const std::string& data) {
auto options = nlohmann::json::parse(data)["options"];
return std::make_shared<MarkTrackPlayedQuery>(options["trackId"].get<int64_t>());
}

View File

@ -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<MarkTrackPlayedQuery> DeserializeQuery(const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
int64_t trackId;
bool result{ false };
};
} } } }

View File

@ -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)

View File

@ -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();

View File

@ -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,

View File

@ -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);

View File

@ -38,18 +38,25 @@
#include <core/library/track/LibraryTrack.h>
#include <core/library/query/TrackMetadataQuery.h>
#include <core/library/query/util/Serialization.h>
#include <core/library/LocalLibraryConstants.h>
#include <core/db/ScopedTransaction.h>
#include <core/db/Statement.h>
#include <core/runtime/Message.h>
#include <core/support/Messages.h>
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> SavePlaylistQuery::Append(
auto result = std::shared_ptr<SavePlaylistQuery>(
new SavePlaylistQuery(library, playlistId, tracks));
result->op = AppendOp;
result->op = Operation::Append;
return result;
}
@ -146,7 +153,7 @@ std::shared_ptr<SavePlaylistQuery> SavePlaylistQuery::Append(
auto result = std::shared_ptr<SavePlaylistQuery>(
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<bool>() == true
? IQuery::Finished : IQuery::Failed);
}
std::shared_ptr<SavePlaylistQuery> SavePlaylistQuery::DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data)
{
auto options = nlohmann::json::parse(data)["options"];
auto output = std::shared_ptr<SavePlaylistQuery>(new SavePlaylistQuery(library));
output->op = options["op"].get<Operation>();
output->playlistName = options["playlistName"].get<std::string>();
output->categoryType = options["categoryType"].get<std::string>();
output->playlistId = options["playlistId"].get<int64_t>();
output->categoryId = options["categoryId"].get<int64_t>();
output->tracks.sharedTracks = std::make_shared<TrackList>(library);
TrackListFromJson(options["tracks"], *output->tracks.sharedTracks, library, true);
return output;
}

View File

@ -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<SavePlaylistQuery> 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<SavePlaylistQuery> 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<musik::core::TrackList> 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<musik::core::TrackList> 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;

View File

@ -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<TrackList>(this->library);
TrackListFromJson(result["trackList"], *this->result, this->library, true);
JsonArrayToSet<std::set<size_t>, size_t>(result["headers"], *this->headers);
this->DeserializeTrackListAndHeaders(result, this->library, this->result, this->headers);
this->SetStatus(IQuery::Finished);
}
std::shared_ptr<SearchTrackListQuery> SearchTrackListQuery::DeserializeQuery(musik::core::ILibraryPtr library, const std::string& data) {
auto options = nlohmann::json::parse(data)["options"];
return std::make_shared<SearchTrackListQuery>(
auto result = std::make_shared<SearchTrackListQuery>(
library,
options["filter"].get<std::string>(),
options["sortType"].get<TrackSortType>());
result->ExtractLimitAndOffsetFromDeserializedQuery(options);
return result;
}

View File

@ -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();
}

View File

@ -57,6 +57,7 @@ namespace musik { namespace core { namespace library { namespace query {
int64_t trackId;
int rating;
bool result{ false };
};
} } } }

View File

@ -38,6 +38,9 @@
#include <core/db/Connection.h>
#include <core/library/track/Track.h>
#include <core/library/track/TrackList.h>
#include <core/library/query/util/Serialization.h>
#include <json.hpp>
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<std::set<size_t>, size_t>(result["headers"], *headers);
}
private:
int limit, offset;

View File

@ -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;
}
}
} } } }

View File

@ -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 <typename SetType, typename DataType>
void JsonArrayToSet(const nlohmann::json& input, SetType& output) {
for (auto& value : input) {