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 CLOUD_STORAGE_UTILS_H
17 #define CLOUD_STORAGE_UTILS_H
18 
19 #include "cloud/asset_operation_utils.h"
20 #include "cloud/cloud_store_types.h"
21 #include "cloud/cloud_upload_recorder.h"
22 #include "icloud_sync_storage_interface.h"
23 #include "sqlite_utils.h"
24 
25 namespace DistributedDB {
26 class CloudStorageUtils final {
27 public:
28     static int BindInt64(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
29     static int BindBool(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
30     static int BindDouble(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
31     static int BindText(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
32     static int BindBlob(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
33     static int BindAsset(int index, const VBucket &vBucket, const Field &field, sqlite3_stmt *upsertStmt);
34 
IsFieldValid(const Field & field,int errCode)35     static inline bool IsFieldValid(const Field &field, int errCode)
36     {
37         return (errCode == E_OK || (field.nullable && errCode == -E_NOT_FOUND));
38     }
39 
40     static int Int64ToVector(const VBucket &vBucket, const Field &field, CollateType collateType,
41         std::vector<uint8_t> &value);
42     static int BoolToVector(const VBucket &vBucket, const Field &field, CollateType collateType,
43         std::vector<uint8_t> &value);
44     static int DoubleToVector(const VBucket &vBucket, const Field &field, CollateType collateType,
45         std::vector<uint8_t> &value);
46     static int TextToVector(const VBucket &vBucket, const Field &field, CollateType collateType,
47         std::vector<uint8_t> &value);
48     static int BlobToVector(const VBucket &vBucket, const Field &field, CollateType collateType,
49         std::vector<uint8_t> &value);
50 
51     static std::set<std::string> GetCloudPrimaryKey(const TableSchema &tableSchema);
52     static std::vector<Field> GetCloudPrimaryKeyField(const TableSchema &tableSchema, bool sortByName = false);
53     static std::map<std::string, Field> GetCloudPrimaryKeyFieldMap(const TableSchema &tableSchema,
54         bool sortByUpper = false);
55     static bool IsContainsPrimaryKey(const TableSchema &tableSchema);
56     static std::vector<Field> GetCloudAsset(const TableSchema &tableSchema);
57     static int GetAssetFieldsFromSchema(const TableSchema &tableSchema, const VBucket &vBucket,
58         std::vector<Field> &fields);
59     static void ObtainAssetFromVBucket(const VBucket &vBucket, VBucket &asset);
60     static AssetOpType StatusToFlag(AssetStatus status);
61     static AssetStatus FlagToStatus(AssetOpType opType);
62     static void ChangeAssetsOnVBucketToAsset(VBucket &vBucket, std::vector<Field> &fields);
63     static Type GetAssetFromAssets(Type &value);
64     static int FillAssetBeforeDownload(Asset &asset);
65     static int FillAssetAfterDownloadFail(Asset &asset, Asset &dbAsset, AssetOperationUtils::AssetOpType assetOpType);
66     static void FillAssetsAfterDownloadFail(Assets &assets, Assets &dbAssets,
67         const std::map<std::string, AssetOperationUtils::AssetOpType> &assetOpTypeMap);
68     static void MergeAssetWithFillFunc(Assets &assets, Assets &dbAssets, const std::map<std::string,
69         AssetOperationUtils::AssetOpType> &assetOpTypeMap,
70         std::function<int(Asset &, Asset &, AssetOperationUtils::AssetOpType)> fillAsset);
71     static int FillAssetAfterDownload(Asset &asset, Asset &dbAsset, AssetOperationUtils::AssetOpType assetOpType);
72     static void FillAssetsAfterDownload(Assets &assets, Assets &dbAssets,
73         const std::map<std::string, AssetOperationUtils::AssetOpType> &assetOpTypeMap);
74     static int FillAssetBeforeUpload(Asset &asset, Asset &dbAsset, AssetOperationUtils::AssetOpType assetOpType);
75     static void FillAssetsBeforeUpload(Assets &assets, Assets &dbAssets,
76         const std::map<std::string, AssetOperationUtils::AssetOpType> &assetOpTypeMap);
77     static int FillAssetForUpload(Asset &asset, Asset &dbAsset, AssetOperationUtils::AssetOpType assetOpType);
78     static void FillAssetsForUpload(Assets &assets, Assets &dbAssets,
79         const std::map<std::string, AssetOperationUtils::AssetOpType> &assetOpTypeMap);
80     static int FillAssetForUploadFailed(Asset &asset, Asset &dbAsset, AssetOperationUtils::AssetOpType assetOpType);
81     static void FillAssetsForUploadFailed(Assets &assets, Assets &dbAssets,
82         const std::map<std::string, AssetOperationUtils::AssetOpType> &assetOpTypeMap);
83     static void PrepareToFillAssetFromVBucket(VBucket &vBucket, std::function<int(Asset &)> fillAsset);
84     static void FillAssetFromVBucketFinish(const AssetOperationUtils::RecordAssetOpType &assetOpType, VBucket &vBucket,
85         VBucket &dbAssets, std::function<int(Asset &, Asset &, AssetOperationUtils::AssetOpType)> fillAsset,
86         std::function<void(Assets &, Assets &,
87         const std::map<std::string, AssetOperationUtils::AssetOpType> &)> fillAssets);
88     static bool IsAsset(const Type &type);
89     static bool IsAssets(const Type &type);
90     static bool IsAssetsContainDuplicateAsset(Assets &assets);
91     static void EraseNoChangeAsset(std::map<std::string, Assets> &assetsMap);
92     static void MergeDownloadAsset(std::map<std::string, Assets> &downloadAssets,
93         std::map<std::string, Assets> &mergeAssets);
94     static std::map<std::string, size_t> GenAssetsIndexMap(Assets &assets);
95     static bool IsVbucketContainsAllPK(const VBucket &vBucket, const std::set<std::string> &pkSet);
96     static bool CheckAssetStatus(const Assets &assets);
97 
98     static int ConstraintsCheckForCloud(const TableInfo &table, const std::string &trimmedSql);
99     static std::string GetTableRefUpdateSql(const TableInfo &table, OpType opType);
100     static std::string GetLeftJoinLogSql(const std::string &tableName, bool logAsTableA = true);
101     static std::string GetUpdateLockChangedSql();
102     static std::string GetDeleteLockChangedSql();
103     static void AddUpdateColForShare(const TableSchema &tableSchema, std::string &updateLogSql,
104         std::vector<std::string> &updateColName);
105     static std::string GetSelectIncCursorSql(const std::string &tableName);
106     static std::string GetCursorIncSql(const std::string &tableName);
107     static std::string GetCursorIncSqlWhenAllow(const std::string &tableName);
108     static std::string GetCursorUpgradeSql(const std::string &tableName);
109     static std::string GetUpdateUploadFinishedSql(const std::string &tableName);
110 
111     static bool IsSharedTable(const TableSchema &tableSchema);
112     static bool ChkFillCloudAssetParam(const CloudSyncBatch &data, int errCode);
113     static void GetToBeRemoveAssets(const VBucket &vBucket, const AssetOperationUtils::RecordAssetOpType &assetOpType,
114         std::vector<Asset> &removeAssets);
115     static std::pair<int, std::vector<uint8_t>> GetHashValueWithPrimaryKeyMap(const VBucket &vBucket,
116         const TableSchema &tableSchema, const TableInfo &localTable, const std::map<std::string, Field> &pkMap,
117         bool allowEmpty);
118     static std::string GetUpdateRecordFlagSql(const std::string &tableName, bool recordConflict,
119         const LogInfo &logInfo, const VBucket &uploadExtend = {}, const CloudWaterType &type = CloudWaterType::BUTT);
120     static std::string GetUpdateRecordFlagSqlUpload(const std::string &tableName, bool recordConflict,
121         const LogInfo &logInfo, const VBucket &uploadExtend = {}, const CloudWaterType &type = CloudWaterType::BUTT);
122     static int BindStepConsistentFlagStmt(sqlite3_stmt *stmt, const VBucket &data,
123         const std::set<std::string> &gidFilters);
124     static bool IsCloudGidMismatch(const std::string &downloadGid, const std::string &curGid);
125 
126     template<typename T>
GetValueFromOneField(Type & cloudValue,T & outVal)127     static int GetValueFromOneField(Type &cloudValue, T &outVal)
128     {
129         T *value = std::get_if<T>(&cloudValue);
130         if (value == nullptr) {
131             LOGE("Get cloud data fail because type mismatch.");
132             return -E_CLOUD_ERROR;
133         }
134         outVal = *value;
135         return E_OK;
136     }
137 
138     template<typename T>
GetValueFromVBucket(const std::string & fieldName,const VBucket & vBucket,T & outVal)139     static int GetValueFromVBucket(const std::string &fieldName, const VBucket &vBucket, T &outVal)
140     {
141         Type cloudValue;
142         bool isExisted = GetTypeCaseInsensitive(fieldName, vBucket, cloudValue);
143         if (!isExisted) {
144             return -E_NOT_FOUND;
145         }
146         return GetValueFromOneField(cloudValue, outVal);
147     }
148 
149     template<typename T>
GetValueFromType(Type & cloudValue,T & outVal)150     static int GetValueFromType(Type &cloudValue, T &outVal)
151     {
152         T *value = std::get_if<T>(&cloudValue);
153         if (value == nullptr) {
154             return -E_CLOUD_ERROR;
155         }
156         outVal = *value;
157         return E_OK;
158     }
159 
160     static int CalculateHashKeyForOneField(const Field &field, const VBucket &vBucket, bool allowEmpty,
161         CollateType collateType, std::vector<uint8_t> &hashValue);
162 
163     static bool CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema);
164 
165     static void TransferFieldToLower(VBucket &vBucket);
166 
167     static bool GetTypeCaseInsensitive(const std::string &fieldName, const VBucket &vBucket, Type &data);
168 
169     static int BindUpdateLogStmtFromVBucket(const VBucket &vBucket, const TableSchema &tableSchema,
170         const std::vector<std::string> &colNames, sqlite3_stmt *updateLogStmt);
171 
172     static bool IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize, uint32_t maxCount);
173 
174     static int IdentifyCloudType(const CloudUploadRecorder &recorder, CloudSyncData &cloudSyncData, VBucket &data,
175         VBucket &log, VBucket &flags);
176 
177     static bool IsAbnormalData(const VBucket &data);
178 
179     static std::pair<int, DataItem> GetDataItemFromCloudData(VBucket &data);
180 
181     static int GetBytesFromCloudData(const std::string &field, VBucket &data, Bytes &bytes);
182 
183     static int GetStringFromCloudData(const std::string &field, VBucket &data, std::string &str);
184 
185     static int GetUInt64FromCloudData(const std::string &field, VBucket &data, uint64_t &number);
186 
187     static bool IsDataLocked(uint32_t status);
188 
189     static std::pair<int, DataItem> GetDataItemFromCloudVersionData(VBucket &data);
190 
191     static std::pair<int, DataItem> GetSystemRecordFromCloudData(VBucket &data);
192 
193     static bool IsSystemRecord(const Key &key);
194 
195     static int GetSyncQueryByPk(const std::string &tableName, const std::vector<VBucket> &data, bool isKv,
196         QuerySyncObject &querySyncObject);
197 private:
198     static int IdentifyCloudTypeInner(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, VBucket &flags);
199 };
200 }
201 #endif // CLOUD_STORAGE_UTILS_H
202