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