1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2004-2021 musikcube team 4 // 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are met: 9 // 10 // * Redistributions of source code must retain the above copyright notice, 11 // this list of conditions and the following disclaimer. 12 // 13 // * Redistributions in binary form must reproduce the above copyright 14 // notice, this list of conditions and the following disclaimer in the 15 // documentation and/or other materials provided with the distribution. 16 // 17 // * Neither the name of the author nor the names of other contributors may 18 // be used to endorse or promote products derived from this software 19 // without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 // POSSIBILITY OF SUCH DAMAGE. 32 // 33 ////////////////////////////////////////////////////////////////////////////// 34 35 #pragma once 36 37 #include <musikcore/library/QueryBase.h> 38 #include <musikcore/db/Connection.h> 39 #include <musikcore/library/track/Track.h> 40 #include <musikcore/library/track/TrackList.h> 41 #include <musikcore/library/query/util/Serialization.h> 42 43 #pragma warning(push, 0) 44 #include <nlohmann/json.hpp> 45 #pragma warning(pop) 46 47 namespace musik { namespace core { namespace library { namespace query { 48 49 class TrackListQueryBase : public musik::core::library::query::QueryBase { 50 public: 51 typedef std::shared_ptr<musik::core::TrackList> Result; 52 typedef std::shared_ptr<std::set<size_t>> Headers; 53 typedef std::shared_ptr<std::map<size_t, size_t>> Durations; 54 55 DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(TrackListQueryBase) 56 TrackListQueryBase()57 TrackListQueryBase() { 58 this->limit = -1; 59 this->offset = 0; 60 } 61 62 /* virtual methods we define */ 63 virtual Result GetResult() = 0; 64 virtual Headers GetHeaders() = 0; 65 virtual Durations GetDurations() = 0; 66 virtual size_t GetQueryHash() = 0; 67 68 virtual void SetLimitAndOffset(int limit, int offset = 0) noexcept { 69 this->limit = limit; 70 this->offset = offset; 71 } 72 GetSdkResult()73 virtual musik::core::sdk::ITrackList* GetSdkResult() { 74 return new WrappedTrackList(GetResult()); 75 } 76 77 protected: 78 79 /* for IMetadataProxy */ 80 GetLimitAndOffset()81 std::string GetLimitAndOffset() { 82 if (this->limit > 0 && this->offset >= 0) { 83 return u8fmt("LIMIT %d OFFSET %d", this->limit, this->offset); 84 } 85 return ""; 86 } 87 88 /* for ISerialization */ 89 FinalizeSerializedQueryWithLimitAndOffset(nlohmann::json & output)90 const std::string FinalizeSerializedQueryWithLimitAndOffset(nlohmann::json &output) { 91 auto& options = output["options"]; 92 options["limit"] = this->limit; 93 options["offset"] = this->offset; 94 return output.dump(); 95 } 96 ExtractLimitAndOffsetFromDeserializedQuery(const nlohmann::json & options)97 void ExtractLimitAndOffsetFromDeserializedQuery(const nlohmann::json& options) { 98 this->limit = options.value("limit", -1); 99 this->offset = options.value("offset", 0); 100 } 101 InitializeSerializedResultWithHeadersAndTrackList()102 nlohmann::json InitializeSerializedResultWithHeadersAndTrackList() { 103 nlohmann::json output = { 104 { "result", { 105 { "headers", *this->GetHeaders() }, 106 { "durations", serialization::DurationMapToJsonMap(*this->GetDurations()) }, 107 { "trackList", serialization::TrackListToJson(*this->GetResult(), true) } 108 }} 109 }; 110 return output; 111 } 112 DeserializeTrackListAndHeaders(nlohmann::json & result,ILibraryPtr library,TrackListQueryBase * query)113 void DeserializeTrackListAndHeaders( 114 nlohmann::json& result, 115 ILibraryPtr library, 116 TrackListQueryBase* query) 117 { 118 serialization::JsonArrayToSet<std::set<size_t>, size_t>(result["headers"], *query->GetHeaders()); 119 serialization::JsonMapToDuration(result["durations"], *query->GetDurations()); 120 serialization::TrackListFromJson(result["trackList"], *query->GetResult(), library, true); 121 } 122 123 private: 124 int limit, offset; 125 126 class WrappedTrackList : public musik::core::sdk::ITrackList { 127 public: WrappedTrackList(Result wrapped)128 WrappedTrackList(Result wrapped) noexcept { 129 this->wrapped = wrapped; 130 } 131 ~WrappedTrackList()132 virtual ~WrappedTrackList() { 133 } 134 Release()135 void Release() noexcept override { 136 delete this; 137 } 138 Count()139 size_t Count() const override { 140 return this->wrapped->Count(); 141 } 142 GetId(size_t index)143 int64_t GetId(size_t index) const override { 144 return this->wrapped->GetId(index); 145 } 146 IndexOf(int64_t id)147 int IndexOf(int64_t id) const override { 148 return this->wrapped->IndexOf(id); 149 } 150 GetTrack(size_t index)151 musik::core::sdk::ITrack* GetTrack(size_t index) const override { 152 return this->wrapped->GetTrack(index); 153 } 154 155 private: 156 Result wrapped; 157 }; 158 }; 159 160 } } } } 161