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 GetCursorUpgradeSql(const std::string &tableName); 108 static std::string GetUpdateUploadFinishedSql(const std::string &tableName); 109 110 static bool IsSharedTable(const TableSchema &tableSchema); 111 static bool ChkFillCloudAssetParam(const CloudSyncBatch &data, int errCode); 112 static void GetToBeRemoveAssets(const VBucket &vBucket, const AssetOperationUtils::RecordAssetOpType &assetOpType, 113 std::vector<Asset> &removeAssets); 114 static std::pair<int, std::vector<uint8_t>> GetHashValueWithPrimaryKeyMap(const VBucket &vBucket, 115 const TableSchema &tableSchema, const TableInfo &localTable, const std::map<std::string, Field> &pkMap, 116 bool allowEmpty); 117 static std::string GetUpdateRecordFlagSql(const std::string &tableName, bool recordConflict, 118 const LogInfo &logInfo, const VBucket &uploadExtend = {}, const CloudWaterType &type = CloudWaterType::BUTT); 119 static int BindStepConsistentFlagStmt(sqlite3_stmt *stmt, const VBucket &data, 120 const std::set<std::string> &gidFilters); 121 static bool IsCloudGidMismatch(const std::string &downloadGid, const std::string &curGid); 122 123 template<typename T> GetValueFromOneField(Type & cloudValue,T & outVal)124 static int GetValueFromOneField(Type &cloudValue, T &outVal) 125 { 126 T *value = std::get_if<T>(&cloudValue); 127 if (value == nullptr) { 128 LOGE("Get cloud data fail because type mismatch."); 129 return -E_CLOUD_ERROR; 130 } 131 outVal = *value; 132 return E_OK; 133 } 134 135 template<typename T> GetValueFromVBucket(const std::string & fieldName,const VBucket & vBucket,T & outVal)136 static int GetValueFromVBucket(const std::string &fieldName, const VBucket &vBucket, T &outVal) 137 { 138 Type cloudValue; 139 bool isExisted = GetTypeCaseInsensitive(fieldName, vBucket, cloudValue); 140 if (!isExisted) { 141 return -E_NOT_FOUND; 142 } 143 return GetValueFromOneField(cloudValue, outVal); 144 } 145 146 template<typename T> GetValueFromType(Type & cloudValue,T & outVal)147 static int GetValueFromType(Type &cloudValue, T &outVal) 148 { 149 T *value = std::get_if<T>(&cloudValue); 150 if (value == nullptr) { 151 return -E_CLOUD_ERROR; 152 } 153 outVal = *value; 154 return E_OK; 155 } 156 157 static int CalculateHashKeyForOneField(const Field &field, const VBucket &vBucket, bool allowEmpty, 158 CollateType collateType, std::vector<uint8_t> &hashValue); 159 160 static bool CheckCloudSchemaFields(const TableSchema &tableSchema, const TableSchema &oldSchema); 161 162 static void TransferFieldToLower(VBucket &vBucket); 163 164 static bool GetTypeCaseInsensitive(const std::string &fieldName, const VBucket &vBucket, Type &data); 165 166 static int BindUpdateLogStmtFromVBucket(const VBucket &vBucket, const TableSchema &tableSchema, 167 const std::vector<std::string> &colNames, sqlite3_stmt *updateLogStmt); 168 169 static bool IsGetCloudDataContinue(uint32_t curNum, uint32_t curSize, uint32_t maxSize, uint32_t maxCount); 170 171 static int IdentifyCloudType(const CloudUploadRecorder &recorder, CloudSyncData &cloudSyncData, VBucket &data, 172 VBucket &log, VBucket &flags); 173 174 static bool IsAbnormalData(const VBucket &data); 175 176 static std::pair<int, DataItem> GetDataItemFromCloudData(VBucket &data); 177 178 static int GetBytesFromCloudData(const std::string &field, VBucket &data, Bytes &bytes); 179 180 static int GetStringFromCloudData(const std::string &field, VBucket &data, std::string &str); 181 182 static int GetUInt64FromCloudData(const std::string &field, VBucket &data, uint64_t &number); 183 184 static bool IsDataLocked(uint32_t status); 185 186 static std::pair<int, DataItem> GetDataItemFromCloudVersionData(VBucket &data); 187 188 static std::pair<int, DataItem> GetSystemRecordFromCloudData(VBucket &data); 189 190 static bool IsSystemRecord(const Key &key); 191 192 static int GetSyncQueryByPk(const std::string &tableName, const std::vector<VBucket> &data, bool isKv, 193 QuerySyncObject &querySyncObject); 194 private: 195 static int IdentifyCloudTypeInner(CloudSyncData &cloudSyncData, VBucket &data, VBucket &log, VBucket &flags); 196 }; 197 } 198 #endif // CLOUD_STORAGE_UTILS_H 199