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_COMMON_VALUE_PROXY_H
17 #define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_VALUE_PROXY_H
18 #include "asset_value.h"
19 #include "cloud/cloud_store_types.h"
20 #include "distributeddb/result_set.h"
21 #include "store/general_value.h"
22 #include "value_object.h"
23 #include "values_bucket.h"
24 #include "common_types.h"
25 
26 namespace OHOS::DistributedData {
27 class ValueProxy final {
28 public:
29     template<class T>
30     static inline constexpr uint32_t INDEX = DistributedData::TYPE_INDEX<T>;
31     static inline constexpr uint32_t MAX = DistributedData::TYPE_MAX;
32 
33     template<typename T, typename... Types>
34     struct variant_cvt_of {
35         static constexpr size_t value = std::is_class_v<T> ? Traits::convertible_index_of_v<T, Types...>
36                                                            : Traits::same_index_of_v<T, Types...>;
37     };
38 
39     template<typename T, typename... Types>
40     static variant_cvt_of<T, Types...> variant_cvt_test(const T &, const std::variant<Types...> &);
41 
42     template<class T, class V>
43     static inline constexpr uint32_t CVT_INDEX =
44         decltype(variant_cvt_test(std::declval<T>(), std::declval<V>()))::value;
45 
46     using Bytes = DistributedData::Bytes;
47     class Asset {
48     public:
49         Asset() = default;
Asset(Asset && proxy)50         Asset(Asset &&proxy) noexcept
51         {
52             *this = std::move(proxy);
53         };
Asset(const Asset & proxy)54         Asset(const Asset &proxy)
55         {
56             *this = proxy;
57         };
58         Asset(DistributedData::Asset asset);
59         Asset(CommonType::AssetValue asset);
60         Asset(NativeRdb::AssetValue asset);
61         Asset(DistributedDB::Asset asset);
62         Asset &operator=(const Asset &proxy);
63         Asset &operator=(Asset &&proxy) noexcept;
64         operator CommonType::AssetValue();
65         operator NativeRdb::AssetValue();
66         operator DistributedData::Asset();
67         operator DistributedDB::Asset();
68         static uint32_t ConvertToDataStatus(const DistributedDB::Asset &asset);
69         static uint32_t ConvertToDBStatus(const uint32_t &status);
70 
71     private:
72         DistributedData::Asset asset_;
73     };
74 
75     class TempAsset {
76     public:
77         explicit TempAsset(DistributedDB::Asset asset);
78         operator NativeRdb::AssetValue();
79 
80     private:
81         static uint32_t ConvertToDataStatus(const uint32_t &status);
82         DistributedData::Asset asset_;
83     };
84 
85     class Assets {
86     public:
87         Assets() = default;
Assets(Assets && proxy)88         Assets(Assets &&proxy) noexcept
89         {
90             *this = std::move(proxy);
91         };
Assets(const Assets & proxy)92         Assets(const Assets &proxy)
93         {
94             *this = proxy;
95         };
96         Assets(DistributedData::Assets assets);
97         Assets(CommonType::Assets assets);
98         Assets(NativeRdb::ValueObject::Assets assets);
99         Assets(DistributedDB::Assets assets);
100         Assets &operator=(const Assets &proxy);
101         Assets &operator=(Assets &&proxy) noexcept;
102         operator CommonType::Assets();
103         operator NativeRdb::ValueObject::Assets();
104         operator DistributedData::Assets();
105         operator DistributedDB::Assets();
106 
107     private:
108         std::vector<Asset> assets_;
109     };
110     using Relations = std::map<std::string, std::string>;
111     using Proxy = std::variant<std::monostate, int64_t, double, std::string, bool, Bytes, Asset, Assets, Relations>;
112 
113     class Value {
114     public:
115         Value() = default;
Value(Value && value)116         Value(Value &&value) noexcept
117         {
118             *this = std::move(value);
119         };
120         Value &operator=(Value &&value) noexcept;
121         operator NativeRdb::ValueObject();
122         operator CommonType::Value();
123         operator DistributedData::Value();
124         operator DistributedDB::Type();
125 
126         template<typename T>
T()127         operator T() noexcept
128         {
129             auto val = Traits::get_if<T>(&value_);
130             if (val != nullptr) {
131                 return T(std::move(*val));
132             }
133             return T();
134         };
135 
136     private:
137         friend ValueProxy;
138         Proxy value_;
139     };
140     class Values {
141     public:
142         Values() = default;
Values(Values && values)143         Values(Values &&values) noexcept
144         {
145             *this = std::move(values);
146         };
147         Values &operator=(Values &&values) noexcept;
148         template<typename T>
vector()149         operator std::vector<T>()
150         {
151             std::vector<T> objects;
152             objects.reserve(value_.size());
153             for (auto &proxy : value_) {
154                 objects.emplace_back(std::move(proxy));
155             }
156             value_.clear();
157             return objects;
158         }
159 
160     private:
161         friend ValueProxy;
162         std::vector<Value> value_;
163     };
164     class Bucket {
165     public:
166         Bucket() = default;
Bucket(Bucket && bucket)167         Bucket(Bucket &&bucket) noexcept
168         {
169             *this = std::move(bucket);
170         };
171         Bucket &operator=(Bucket &&bucket) noexcept;
172         template<typename T>
map()173         operator std::map<std::string, T>()
174         {
175             std::map<std::string, T> bucket;
176             for (auto &[key, value] : value_) {
177                 bucket.insert_or_assign(key, std::move(static_cast<T>(value)));
178             }
179             value_.clear();
180             return bucket;
181         }
182         operator NativeRdb::ValuesBucket();
183         operator CommonType::ValuesBucket();
184 
185     private:
186         friend ValueProxy;
187         std::map<std::string, Value> value_;
188     };
189     class Buckets {
190     public:
191         Buckets() = default;
Buckets(Buckets && buckets)192         Buckets(Buckets &&buckets) noexcept
193         {
194             *this = std::move(buckets);
195         };
196         Buckets &operator=(Buckets &&buckets) noexcept;
197         template<typename T>
vector()198         operator std::vector<T>()
199         {
200             std::vector<T> buckets;
201             buckets.reserve(value_.size());
202             for (auto &bucket : value_) {
203                 buckets.emplace_back(std::move(bucket));
204             }
205             value_.clear();
206             return buckets;
207         }
208 
209     private:
210         friend ValueProxy;
211         std::vector<Bucket> value_;
212     };
213 
214     static Value Convert(DistributedData::Value &&value);
215     static Value Convert(CommonType::Value &&value);
216     static Value Convert(NativeRdb::ValueObject &&value);
217     static Value Convert(DistributedDB::Type &&value);
218     static Values Convert(DistributedData::Values &&values);
219     static Values Convert(std::vector<CommonType::Value> &&values);
220     static Values Convert(std::vector<NativeRdb::ValueObject> &&values);
221     static Values Convert(std::vector<DistributedDB::Type> &&values);
222     static Bucket Convert(DistributedData::VBucket &&bucket);
223     static Bucket Convert(NativeRdb::ValuesBucket &&bucket);
224     static Bucket Convert(CommonType::ValuesBucket &&bucket);
225     static Bucket Convert(DistributedDB::VBucket &&bucket);
226     static Buckets Convert(DistributedData::VBuckets &&buckets);
227     static Buckets Convert(std::vector<NativeRdb::ValuesBucket> &&buckets);
228     static Buckets Convert(std::vector<CommonType::ValuesBucket> &&buckets);
229     static Buckets Convert(std::vector<DistributedDB::VBucket> &&buckets);
230 
231     static Value Convert(DistributedDB::VariantData &&value);
232     static Bucket Convert(std::map<std::string, DistributedDB::VariantData> &&value);
233 
234     template<typename T>
235     static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Bucket>
236     Convert(const std::map<std::string, T> &values)
237     {
238         Bucket bucket;
239         for (auto &[key, value] : values) {
240             bucket.value_[key].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(value);
241         }
242         return bucket;
243     }
244 
245     template<typename T>
246     static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Values>
247     Convert(const std::vector<T> &values)
248     {
249         Values proxy;
250         proxy.value_.resize(values.size());
251         for (size_t i = 0; i < values.size(); i++) {
252             proxy.value_[i].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(values[i]);
253         }
254         return proxy;
255     }
256 
257 private:
258     ValueProxy() = delete;
259     ~ValueProxy() = delete;
GetHighStatus(uint32_t status)260     static inline uint32_t GetHighStatus(uint32_t status)
261     {
262         return status & 0xF0000000;
263     }
264 
GetLowStatus(uint32_t status)265     static inline uint32_t GetLowStatus(uint32_t status)
266     {
267         return status & ~0xF0000000;
268     }
269 };
270 } // namespace OHOS::DistributedRdb
271 #endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_VALUE_PROXY_H
272