153c3577eSopenharmony_ci/*
253c3577eSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
353c3577eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
453c3577eSopenharmony_ci * you may not use this file except in compliance with the License.
553c3577eSopenharmony_ci * You may obtain a copy of the License at
653c3577eSopenharmony_ci *
753c3577eSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
853c3577eSopenharmony_ci *
953c3577eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1053c3577eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1153c3577eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1253c3577eSopenharmony_ci * See the License for the specific language governing permissions and
1353c3577eSopenharmony_ci * limitations under the License.
1453c3577eSopenharmony_ci */
1553c3577eSopenharmony_ci
1653c3577eSopenharmony_ci#ifndef OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_VALUE_PROXY_H
1753c3577eSopenharmony_ci#define OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_VALUE_PROXY_H
1853c3577eSopenharmony_ci#include "asset_value.h"
1953c3577eSopenharmony_ci#include "cloud/cloud_store_types.h"
2053c3577eSopenharmony_ci#include "distributeddb/result_set.h"
2153c3577eSopenharmony_ci#include "store/general_value.h"
2253c3577eSopenharmony_ci#include "value_object.h"
2353c3577eSopenharmony_ci#include "values_bucket.h"
2453c3577eSopenharmony_ci#include "common_types.h"
2553c3577eSopenharmony_ci
2653c3577eSopenharmony_cinamespace OHOS::DistributedData {
2753c3577eSopenharmony_ciclass ValueProxy final {
2853c3577eSopenharmony_cipublic:
2953c3577eSopenharmony_ci    template<class T>
3053c3577eSopenharmony_ci    static inline constexpr uint32_t INDEX = DistributedData::TYPE_INDEX<T>;
3153c3577eSopenharmony_ci    static inline constexpr uint32_t MAX = DistributedData::TYPE_MAX;
3253c3577eSopenharmony_ci
3353c3577eSopenharmony_ci    template<typename T, typename... Types>
3453c3577eSopenharmony_ci    struct variant_cvt_of {
3553c3577eSopenharmony_ci        static constexpr size_t value = std::is_class_v<T> ? Traits::convertible_index_of_v<T, Types...>
3653c3577eSopenharmony_ci                                                           : Traits::same_index_of_v<T, Types...>;
3753c3577eSopenharmony_ci    };
3853c3577eSopenharmony_ci
3953c3577eSopenharmony_ci    template<typename T, typename... Types>
4053c3577eSopenharmony_ci    static variant_cvt_of<T, Types...> variant_cvt_test(const T &, const std::variant<Types...> &);
4153c3577eSopenharmony_ci
4253c3577eSopenharmony_ci    template<class T, class V>
4353c3577eSopenharmony_ci    static inline constexpr uint32_t CVT_INDEX =
4453c3577eSopenharmony_ci        decltype(variant_cvt_test(std::declval<T>(), std::declval<V>()))::value;
4553c3577eSopenharmony_ci
4653c3577eSopenharmony_ci    using Bytes = DistributedData::Bytes;
4753c3577eSopenharmony_ci    class Asset {
4853c3577eSopenharmony_ci    public:
4953c3577eSopenharmony_ci        Asset() = default;
5053c3577eSopenharmony_ci        Asset(Asset &&proxy) noexcept
5153c3577eSopenharmony_ci        {
5253c3577eSopenharmony_ci            *this = std::move(proxy);
5353c3577eSopenharmony_ci        };
5453c3577eSopenharmony_ci        Asset(const Asset &proxy)
5553c3577eSopenharmony_ci        {
5653c3577eSopenharmony_ci            *this = proxy;
5753c3577eSopenharmony_ci        };
5853c3577eSopenharmony_ci        Asset(DistributedData::Asset asset);
5953c3577eSopenharmony_ci        Asset(CommonType::AssetValue asset);
6053c3577eSopenharmony_ci        Asset(NativeRdb::AssetValue asset);
6153c3577eSopenharmony_ci        Asset(DistributedDB::Asset asset);
6253c3577eSopenharmony_ci        Asset &operator=(const Asset &proxy);
6353c3577eSopenharmony_ci        Asset &operator=(Asset &&proxy) noexcept;
6453c3577eSopenharmony_ci        operator CommonType::AssetValue();
6553c3577eSopenharmony_ci        operator NativeRdb::AssetValue();
6653c3577eSopenharmony_ci        operator DistributedData::Asset();
6753c3577eSopenharmony_ci        operator DistributedDB::Asset();
6853c3577eSopenharmony_ci        static uint32_t ConvertToDataStatus(const DistributedDB::Asset &asset);
6953c3577eSopenharmony_ci        static uint32_t ConvertToDBStatus(const uint32_t &status);
7053c3577eSopenharmony_ci
7153c3577eSopenharmony_ci    private:
7253c3577eSopenharmony_ci        DistributedData::Asset asset_;
7353c3577eSopenharmony_ci    };
7453c3577eSopenharmony_ci
7553c3577eSopenharmony_ci    class TempAsset {
7653c3577eSopenharmony_ci    public:
7753c3577eSopenharmony_ci        explicit TempAsset(DistributedDB::Asset asset);
7853c3577eSopenharmony_ci        operator NativeRdb::AssetValue();
7953c3577eSopenharmony_ci
8053c3577eSopenharmony_ci    private:
8153c3577eSopenharmony_ci        static uint32_t ConvertToDataStatus(const uint32_t &status);
8253c3577eSopenharmony_ci        DistributedData::Asset asset_;
8353c3577eSopenharmony_ci    };
8453c3577eSopenharmony_ci
8553c3577eSopenharmony_ci    class Assets {
8653c3577eSopenharmony_ci    public:
8753c3577eSopenharmony_ci        Assets() = default;
8853c3577eSopenharmony_ci        Assets(Assets &&proxy) noexcept
8953c3577eSopenharmony_ci        {
9053c3577eSopenharmony_ci            *this = std::move(proxy);
9153c3577eSopenharmony_ci        };
9253c3577eSopenharmony_ci        Assets(const Assets &proxy)
9353c3577eSopenharmony_ci        {
9453c3577eSopenharmony_ci            *this = proxy;
9553c3577eSopenharmony_ci        };
9653c3577eSopenharmony_ci        Assets(DistributedData::Assets assets);
9753c3577eSopenharmony_ci        Assets(CommonType::Assets assets);
9853c3577eSopenharmony_ci        Assets(NativeRdb::ValueObject::Assets assets);
9953c3577eSopenharmony_ci        Assets(DistributedDB::Assets assets);
10053c3577eSopenharmony_ci        Assets &operator=(const Assets &proxy);
10153c3577eSopenharmony_ci        Assets &operator=(Assets &&proxy) noexcept;
10253c3577eSopenharmony_ci        operator CommonType::Assets();
10353c3577eSopenharmony_ci        operator NativeRdb::ValueObject::Assets();
10453c3577eSopenharmony_ci        operator DistributedData::Assets();
10553c3577eSopenharmony_ci        operator DistributedDB::Assets();
10653c3577eSopenharmony_ci
10753c3577eSopenharmony_ci    private:
10853c3577eSopenharmony_ci        std::vector<Asset> assets_;
10953c3577eSopenharmony_ci    };
11053c3577eSopenharmony_ci    using Relations = std::map<std::string, std::string>;
11153c3577eSopenharmony_ci    using Proxy = std::variant<std::monostate, int64_t, double, std::string, bool, Bytes, Asset, Assets, Relations>;
11253c3577eSopenharmony_ci
11353c3577eSopenharmony_ci    class Value {
11453c3577eSopenharmony_ci    public:
11553c3577eSopenharmony_ci        Value() = default;
11653c3577eSopenharmony_ci        Value(Value &&value) noexcept
11753c3577eSopenharmony_ci        {
11853c3577eSopenharmony_ci            *this = std::move(value);
11953c3577eSopenharmony_ci        };
12053c3577eSopenharmony_ci        Value &operator=(Value &&value) noexcept;
12153c3577eSopenharmony_ci        operator NativeRdb::ValueObject();
12253c3577eSopenharmony_ci        operator CommonType::Value();
12353c3577eSopenharmony_ci        operator DistributedData::Value();
12453c3577eSopenharmony_ci        operator DistributedDB::Type();
12553c3577eSopenharmony_ci
12653c3577eSopenharmony_ci        template<typename T>
12753c3577eSopenharmony_ci        operator T() noexcept
12853c3577eSopenharmony_ci        {
12953c3577eSopenharmony_ci            auto val = Traits::get_if<T>(&value_);
13053c3577eSopenharmony_ci            if (val != nullptr) {
13153c3577eSopenharmony_ci                return T(std::move(*val));
13253c3577eSopenharmony_ci            }
13353c3577eSopenharmony_ci            return T();
13453c3577eSopenharmony_ci        };
13553c3577eSopenharmony_ci
13653c3577eSopenharmony_ci    private:
13753c3577eSopenharmony_ci        friend ValueProxy;
13853c3577eSopenharmony_ci        Proxy value_;
13953c3577eSopenharmony_ci    };
14053c3577eSopenharmony_ci    class Values {
14153c3577eSopenharmony_ci    public:
14253c3577eSopenharmony_ci        Values() = default;
14353c3577eSopenharmony_ci        Values(Values &&values) noexcept
14453c3577eSopenharmony_ci        {
14553c3577eSopenharmony_ci            *this = std::move(values);
14653c3577eSopenharmony_ci        };
14753c3577eSopenharmony_ci        Values &operator=(Values &&values) noexcept;
14853c3577eSopenharmony_ci        template<typename T>
14953c3577eSopenharmony_ci        operator std::vector<T>()
15053c3577eSopenharmony_ci        {
15153c3577eSopenharmony_ci            std::vector<T> objects;
15253c3577eSopenharmony_ci            objects.reserve(value_.size());
15353c3577eSopenharmony_ci            for (auto &proxy : value_) {
15453c3577eSopenharmony_ci                objects.emplace_back(std::move(proxy));
15553c3577eSopenharmony_ci            }
15653c3577eSopenharmony_ci            value_.clear();
15753c3577eSopenharmony_ci            return objects;
15853c3577eSopenharmony_ci        }
15953c3577eSopenharmony_ci
16053c3577eSopenharmony_ci    private:
16153c3577eSopenharmony_ci        friend ValueProxy;
16253c3577eSopenharmony_ci        std::vector<Value> value_;
16353c3577eSopenharmony_ci    };
16453c3577eSopenharmony_ci    class Bucket {
16553c3577eSopenharmony_ci    public:
16653c3577eSopenharmony_ci        Bucket() = default;
16753c3577eSopenharmony_ci        Bucket(Bucket &&bucket) noexcept
16853c3577eSopenharmony_ci        {
16953c3577eSopenharmony_ci            *this = std::move(bucket);
17053c3577eSopenharmony_ci        };
17153c3577eSopenharmony_ci        Bucket &operator=(Bucket &&bucket) noexcept;
17253c3577eSopenharmony_ci        template<typename T>
17353c3577eSopenharmony_ci        operator std::map<std::string, T>()
17453c3577eSopenharmony_ci        {
17553c3577eSopenharmony_ci            std::map<std::string, T> bucket;
17653c3577eSopenharmony_ci            for (auto &[key, value] : value_) {
17753c3577eSopenharmony_ci                bucket.insert_or_assign(key, std::move(static_cast<T>(value)));
17853c3577eSopenharmony_ci            }
17953c3577eSopenharmony_ci            value_.clear();
18053c3577eSopenharmony_ci            return bucket;
18153c3577eSopenharmony_ci        }
18253c3577eSopenharmony_ci        operator NativeRdb::ValuesBucket();
18353c3577eSopenharmony_ci        operator CommonType::ValuesBucket();
18453c3577eSopenharmony_ci
18553c3577eSopenharmony_ci    private:
18653c3577eSopenharmony_ci        friend ValueProxy;
18753c3577eSopenharmony_ci        std::map<std::string, Value> value_;
18853c3577eSopenharmony_ci    };
18953c3577eSopenharmony_ci    class Buckets {
19053c3577eSopenharmony_ci    public:
19153c3577eSopenharmony_ci        Buckets() = default;
19253c3577eSopenharmony_ci        Buckets(Buckets &&buckets) noexcept
19353c3577eSopenharmony_ci        {
19453c3577eSopenharmony_ci            *this = std::move(buckets);
19553c3577eSopenharmony_ci        };
19653c3577eSopenharmony_ci        Buckets &operator=(Buckets &&buckets) noexcept;
19753c3577eSopenharmony_ci        template<typename T>
19853c3577eSopenharmony_ci        operator std::vector<T>()
19953c3577eSopenharmony_ci        {
20053c3577eSopenharmony_ci            std::vector<T> buckets;
20153c3577eSopenharmony_ci            buckets.reserve(value_.size());
20253c3577eSopenharmony_ci            for (auto &bucket : value_) {
20353c3577eSopenharmony_ci                buckets.emplace_back(std::move(bucket));
20453c3577eSopenharmony_ci            }
20553c3577eSopenharmony_ci            value_.clear();
20653c3577eSopenharmony_ci            return buckets;
20753c3577eSopenharmony_ci        }
20853c3577eSopenharmony_ci
20953c3577eSopenharmony_ci    private:
21053c3577eSopenharmony_ci        friend ValueProxy;
21153c3577eSopenharmony_ci        std::vector<Bucket> value_;
21253c3577eSopenharmony_ci    };
21353c3577eSopenharmony_ci
21453c3577eSopenharmony_ci    static Value Convert(DistributedData::Value &&value);
21553c3577eSopenharmony_ci    static Value Convert(CommonType::Value &&value);
21653c3577eSopenharmony_ci    static Value Convert(NativeRdb::ValueObject &&value);
21753c3577eSopenharmony_ci    static Value Convert(DistributedDB::Type &&value);
21853c3577eSopenharmony_ci    static Values Convert(DistributedData::Values &&values);
21953c3577eSopenharmony_ci    static Values Convert(std::vector<CommonType::Value> &&values);
22053c3577eSopenharmony_ci    static Values Convert(std::vector<NativeRdb::ValueObject> &&values);
22153c3577eSopenharmony_ci    static Values Convert(std::vector<DistributedDB::Type> &&values);
22253c3577eSopenharmony_ci    static Bucket Convert(DistributedData::VBucket &&bucket);
22353c3577eSopenharmony_ci    static Bucket Convert(NativeRdb::ValuesBucket &&bucket);
22453c3577eSopenharmony_ci    static Bucket Convert(CommonType::ValuesBucket &&bucket);
22553c3577eSopenharmony_ci    static Bucket Convert(DistributedDB::VBucket &&bucket);
22653c3577eSopenharmony_ci    static Buckets Convert(DistributedData::VBuckets &&buckets);
22753c3577eSopenharmony_ci    static Buckets Convert(std::vector<NativeRdb::ValuesBucket> &&buckets);
22853c3577eSopenharmony_ci    static Buckets Convert(std::vector<CommonType::ValuesBucket> &&buckets);
22953c3577eSopenharmony_ci    static Buckets Convert(std::vector<DistributedDB::VBucket> &&buckets);
23053c3577eSopenharmony_ci
23153c3577eSopenharmony_ci    static Value Convert(DistributedDB::VariantData &&value);
23253c3577eSopenharmony_ci    static Bucket Convert(std::map<std::string, DistributedDB::VariantData> &&value);
23353c3577eSopenharmony_ci
23453c3577eSopenharmony_ci    template<typename T>
23553c3577eSopenharmony_ci    static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Bucket>
23653c3577eSopenharmony_ci    Convert(const std::map<std::string, T> &values)
23753c3577eSopenharmony_ci    {
23853c3577eSopenharmony_ci        Bucket bucket;
23953c3577eSopenharmony_ci        for (auto &[key, value] : values) {
24053c3577eSopenharmony_ci            bucket.value_[key].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(value);
24153c3577eSopenharmony_ci        }
24253c3577eSopenharmony_ci        return bucket;
24353c3577eSopenharmony_ci    }
24453c3577eSopenharmony_ci
24553c3577eSopenharmony_ci    template<typename T>
24653c3577eSopenharmony_ci    static std::enable_if_t < CVT_INDEX<T, Proxy><MAX, Values>
24753c3577eSopenharmony_ci    Convert(const std::vector<T> &values)
24853c3577eSopenharmony_ci    {
24953c3577eSopenharmony_ci        Values proxy;
25053c3577eSopenharmony_ci        proxy.value_.resize(values.size());
25153c3577eSopenharmony_ci        for (size_t i = 0; i < values.size(); i++) {
25253c3577eSopenharmony_ci            proxy.value_[i].value_ = static_cast<std::variant_alternative_t<CVT_INDEX<T, Proxy>, Proxy>>(values[i]);
25353c3577eSopenharmony_ci        }
25453c3577eSopenharmony_ci        return proxy;
25553c3577eSopenharmony_ci    }
25653c3577eSopenharmony_ci
25753c3577eSopenharmony_ciprivate:
25853c3577eSopenharmony_ci    ValueProxy() = delete;
25953c3577eSopenharmony_ci    ~ValueProxy() = delete;
26053c3577eSopenharmony_ci    static inline uint32_t GetHighStatus(uint32_t status)
26153c3577eSopenharmony_ci    {
26253c3577eSopenharmony_ci        return status & 0xF0000000;
26353c3577eSopenharmony_ci    }
26453c3577eSopenharmony_ci
26553c3577eSopenharmony_ci    static inline uint32_t GetLowStatus(uint32_t status)
26653c3577eSopenharmony_ci    {
26753c3577eSopenharmony_ci        return status & ~0xF0000000;
26853c3577eSopenharmony_ci    }
26953c3577eSopenharmony_ci};
27053c3577eSopenharmony_ci} // namespace OHOS::DistributedRdb
27153c3577eSopenharmony_ci#endif // OHOS_DISTRIBUTED_DATA_DATAMGR_SERVICE_COMMON_VALUE_PROXY_H
272