1 /* 2 * Copyright (c) 2021 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 KV_DB_MANAGER_H 17 #define KV_DB_MANAGER_H 18 19 #include <string> 20 #include <map> 21 #include <mutex> 22 #include <set> 23 #include <condition_variable> 24 25 #include "db_errno.h" 26 #include "ikvdb.h" 27 #include "ikvdb_factory.h" 28 #include "platform_specific.h" 29 30 namespace DistributedDB { 31 class KvDBManager final { 32 public: 33 // used to generate process label 34 static const std::string PROCESS_LABEL_CONNECTOR; 35 36 // used to open a kvdb with the given property 37 static IKvDB *OpenDatabase(const KvDBProperties &property, int &errCode); 38 39 // used to open a kvdb with the given property 40 static IKvDBConnection *GetDatabaseConnection(const KvDBProperties &property, int &errCode, 41 bool isNeedIfOpened = true); 42 43 // used to close the connection. 44 static int ReleaseDatabaseConnection(IKvDBConnection *connection); 45 46 // used to delete a kvdb with the given property. 47 static int RemoveDatabase(const KvDBProperties &property); 48 49 // Used to set the process userid and appid 50 static int SetProcessLabel(const std::string &appId, const std::string &userId); 51 52 static int CalculateKvStoreSize(const KvDBProperties &property, uint64_t &size); 53 54 // used to restore the sync module of the store. 55 static void RestoreSyncableKvStore(); 56 57 // used to set the corruption handler. 58 static void SetDatabaseCorruptionHandler(const KvStoreCorruptionHandler &handler); 59 60 // Attention. After call FindKvDB and kvdb is not null, you need to call DecObjRef. 61 IKvDB* FindKvDB(const std::string &identifier) const; 62 63 // Get a KvDBManager instance, Singleton mode 64 static KvDBManager *GetInstance(); 65 private: 66 // Generate a KvDB unique Identifier 67 static std::string GenerateKvDBIdentifier(const KvDBProperties &property); 68 69 // used to judge Db opened, can not remove Db file 70 static int CheckDatabaseFileStatus(const KvDBProperties &properties); 71 72 IKvDB *OpenNewDatabase(const KvDBProperties &property, int &errCode); 73 74 // Save to IKvDB to the global map 75 IKvDB *SaveKvDBToCache(IKvDB *kvDB); 76 77 // Get IKvdb From global map 78 IKvDB *FindAndGetKvDBFromCache(const KvDBProperties &property, int &errCode) const; 79 80 // Get IKvdb From global map 81 void RemoveKvDBFromCache(const IKvDB *kvDB); 82 83 // Find a IKvdb From the given cache. the IKvDB will IncObjRef if found. 84 IKvDB *FindKvDBFromCache(const KvDBProperties &property, 85 const std::map<std::string, IKvDB *> &cache, bool isNeedCheckPasswd, int &errCode) const; 86 87 bool IsOpenMemoryDb(const KvDBProperties &properties, const std::map<std::string, IKvDB *> &cache) const; 88 89 void RestoreSyncerOfAllKvStore(); 90 91 void SetAllDatabaseCorruptionHander(const KvStoreCorruptionHandler &handler); 92 93 IKvDB *CreateDataBase(const KvDBProperties &property, int &errCode); 94 95 IKvDB *GetDataBase(const KvDBProperties &property, int &errCode, bool isNeedIfOpened); 96 97 void DataBaseCorruptNotify(const std::string &appId, const std::string &userId, const std::string &storeId); 98 99 void DataBaseCorruptNotifyAsync(const std::string &appId, const std::string &userId, const std::string &storeId); 100 101 void EnterDBOpenCloseProcess(const std::string &identifier); 102 103 void ExitDBOpenCloseProcess(const std::string &identifier); 104 105 void SetCorruptHandlerForDatabases(const std::map<std::string, IKvDB *> &kvDBMap); 106 107 // Compare two schema objects and return true if both are empty, 108 // or both are not empty and the schemas are equal, otherwise return false. 109 static bool CompareSchemaObject(const SchemaObject &newSchema, const SchemaObject &oldSchema); 110 111 // check schema is valid 112 static int CheckSchema(const IKvDB *kvDB, const KvDBProperties &properties); 113 114 static int ExecuteRemoveDatabase(const KvDBProperties &properties); 115 116 static void RemoveDBDirectory(const KvDBProperties &properties); 117 118 int CheckKvDBProperties(const IKvDB *kvDB, const KvDBProperties &properties, 119 bool isNeedCheckPasswd) const; 120 121 IKvDB *GetKvDBFromCacheByIdentify(const std::string &identifier, const std::map<std::string, IKvDB *> &cache) const; 122 123 static int CheckRemoveStateAndRetry(const KvDBProperties &property); 124 125 static int TryLockDB(const KvDBProperties &kvDBProp, int retryTimes); 126 static int UnlockDB(const KvDBProperties &kvDBProp); 127 128 static std::atomic<KvDBManager *> instance_; 129 static std::mutex kvDBLock_; 130 static std::mutex instanceLock_; 131 static std::map<std::string, OS::FileHandle> locks_; 132 133 std::map<std::string, IKvDB *> localKvDBs_; 134 std::map<std::string, IKvDB *> multiVerNaturalStores_; 135 std::map<std::string, IKvDB *> singleVerNaturalStores_; 136 137 std::mutex corruptMutex_; 138 std::mutex kvDBOpenMutex_; 139 std::condition_variable kvDBOpenCondition_; 140 std::set<std::string> kvDBOpenSet_; 141 KvStoreCorruptionHandler corruptHandler_; 142 }; 143 } // namespace DistributedDB 144 145 #endif // KV_DB_MANAGER_H 146