1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H 17 #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H 18 #include "asset_value.h" 19 #include "cloud/cloud_store_types.h" 20 #include "store/general_value.h" 21 #include "value_object.h" 22 #include "values_bucket.h" 23 #include "distributeddb/result_set.h" 24 namespace OHOS::DistributedRdb { 25 class ValueProxy final { 26 public: 27 template<class T> 28 static inline constexpr uint32_t INDEX = DistributedData::TYPE_INDEX<T>; 29 static inline constexpr uint32_t MAX = DistributedData::TYPE_MAX; 30 31 template<typename T, typename... Types> 32 struct variant_cvt_of { 33 static constexpr size_t value = std::is_class_v<T> ? Traits::convertible_index_of_v<T, Types...> 34 : Traits::same_index_of_v<T, Types...>; 35 }; 36 37 template<typename T, typename... Types> 38 static variant_cvt_of<T, Types...> variant_cvt_test(const T &, const std::variant<Types...> &); 39 40 template<class T, class V> 41 static inline constexpr uint32_t CVT_INDEX = 42 decltype(variant_cvt_test(std::declval<T>(), std::declval<V>()))::value; 43 44 using Bytes = DistributedData::Bytes; 45 class Asset { 46 public: 47 Asset() = default; Asset(Asset && proxy)48 Asset(Asset &&proxy) noexcept 49 { 50 *this = std::move(proxy); 51 }; Asset(const Asset & proxy)52 Asset(const Asset &proxy) 53 { 54 *this = proxy; 55 }; 56 Asset(DistributedData::Asset asset); 57 Asset(NativeRdb::AssetValue asset); 58 Asset(DistributedDB::Asset asset); 59 Asset &operator=(const Asset &proxy); 60 Asset &operator=(Asset &&proxy) noexcept; 61 operator NativeRdb::AssetValue(); 62 operator DistributedData::Asset(); 63 operator DistributedDB::Asset(); 64 static uint32_t ConvertToDataStatus(const DistributedDB::Asset &asset); 65 static uint32_t ConvertToDBStatus(const DistributedData::Asset &asset); 66 67 private: 68 DistributedData::Asset asset_; 69 }; 70 71 class Assets { 72 public: 73 Assets() = default; Assets(Assets && proxy)74 Assets(Assets &&proxy) noexcept 75 { 76 *this = std::move(proxy); 77 }; Assets(const Assets & proxy)78 Assets(const Assets &proxy) 79 { 80 *this = proxy; 81 }; 82 Assets(DistributedData::Assets assets); 83 Assets(NativeRdb::ValueObject::Assets assets); 84 Assets(DistributedDB::Assets assets); 85 Assets &operator=(const Assets &proxy); 86 Assets &operator=(Assets &&proxy) noexcept; 87 operator NativeRdb::ValueObject::Assets(); 88 operator DistributedData::Assets(); 89 operator DistributedDB::Assets(); 90 91 private: 92 std::vector<Asset> assets_; 93 }; 94 using Proxy = std::variant<std::monostate, int64_t, double, std::string, bool, Bytes, Asset, Assets>; 95 96 class Value { 97 public: 98 Value() = default; Value(Value && value)99 Value(Value &&value) noexcept 100 { 101 *this = std::move(value); 102 }; 103 Value &operator=(Value &&value) noexcept; 104 operator NativeRdb::ValueObject(); 105 operator DistributedData::Value(); 106 operator DistributedDB::Type(); 107 108 template<typename T> T()109 operator T() noexcept 110 { 111 auto val = Traits::get_if<T>(&value_); 112 if (val != nullptr) { 113 return T(std::move(*val)); 114 } 115 return T(); 116 }; 117 118 private: 119 friend ValueProxy; 120 Proxy value_; 121 }; 122 class Values { 123 public: 124 Values() = default; Values(Values && values)125 Values(Values &&values) noexcept 126 { 127 *this = std::move(values); 128 }; 129 Values &operator=(Values &&values) noexcept; 130 template<typename T> 131 operator std::vector<T>() 132 { 133 std::vector<T> objects; 134 objects.reserve(value_.size()); 135 for (auto &proxy : value_) { 136 objects.emplace_back(std::move(proxy)); 137 } 138 value_.clear(); 139 return objects; 140 } 141 142 private: 143 friend ValueProxy; 144 std::vector<Value> value_; 145 }; 146 class Bucket { 147 public: 148 Bucket() = default; Bucket(Bucket && bucket)149 Bucket(Bucket &&bucket) noexcept 150 { 151 *this = std::move(bucket); 152 }; 153 Bucket &operator=(Bucket &&bucket) noexcept; 154 template<typename T> 155 operator std::map<std::string, T>() 156 { 157 std::map<std::string, T> bucket; 158 for (auto &[key, value] : value_) { 159 bucket.insert_or_assign(key, std::move(static_cast<T>(value))); 160 } 161 value_.clear(); 162 return bucket; 163 } 164 operator NativeRdb::ValuesBucket(); 165 166 private: 167 friend ValueProxy; 168 std::map<std::string, Value> value_; 169 }; 170 class Buckets { 171 public: 172 Buckets() = default; Buckets(Buckets && buckets)173 Buckets(Buckets &&buckets) noexcept 174 { 175 *this = std::move(buckets); 176 }; 177 Buckets &operator=(Buckets &&buckets) noexcept; 178 template<typename T> 179 operator std::vector<T>() 180 { 181 std::vector<T> buckets; 182 buckets.reserve(value_.size()); 183 for (auto &bucket : value_) { 184 buckets.emplace_back(std::move(bucket)); 185 } 186 value_.clear(); 187 return buckets; 188 } 189 190 private: 191 friend ValueProxy; 192 std::vector<Bucket> value_; 193 }; 194 195 static Value Convert(DistributedData::Value &&value); 196 static Value Convert(NativeRdb::ValueObject &&value); 197 static Value Convert(DistributedDB::Type &&value); 198 static Values Convert(DistributedData::Values &&values); 199 static Values Convert(std::vector<NativeRdb::ValueObject> &&values); 200 static Bucket Convert(DistributedData::VBucket &&bucket); 201 static Bucket Convert(NativeRdb::ValuesBucket &&bucket); 202 static Bucket Convert(DistributedDB::VBucket &&bucket); 203 static Buckets Convert(DistributedData::VBuckets &&buckets); 204 static Buckets Convert(std::vector<NativeRdb::ValuesBucket> &&buckets); 205 static Buckets Convert(std::vector<DistributedDB::VBucket> &&buckets); 206 207 static Value Convert(DistributedDB::VariantData &&value); 208 static Bucket Convert(std::map<std::string, DistributedDB::VariantData> &&value); 209 210 template<typename T> 211 static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Bucket> 212 Convert(const std::map<std::string, T> &values) 213 { 214 Bucket bucket; 215 for (auto &[key, value] : values) { 216 bucket.value_[key].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(value); 217 } 218 return bucket; 219 } 220 221 template<typename T> 222 static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Values> 223 Convert(const std::vector<T> &values) 224 { 225 Values proxy; 226 proxy.value_.resize(values.size()); 227 for (size_t i = 0; i < values.size(); i++) { 228 proxy.value_[i].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(values[i]); 229 } 230 return proxy; 231 } 232 233 private: 234 ValueProxy() = delete; 235 ~ValueProxy() = delete; 236 }; 237 } // namespace OHOS::DistributedRdb 238 #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_RDB_VALUE_PROXY_H 239