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 GENERIC_KVDB_H
17 #define GENERIC_KVDB_H
18 
19 #include <cstdint>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 
24 #include "store_types.h"
25 #include "version.h"
26 #include "ikvdb.h"
27 #include "generic_kvdb_connection.h"
28 #include "performance_analysis.h"
29 #include "kvdb_conflict_entry.h"
30 #include "db_types.h"
31 
32 namespace DistributedDB {
33 class KvDBCommitNotifyFilterAbleData;
34 
35 struct ImportFileInfo {
36     std::string backupDir; // the directory of the current database backup
37     std::string unpackedDir; // the directory of the unpacked import file
38     std::string currentDir; // the directory of the current database
39     std::string curValidFile; // the file imply that the current directory is valid
40     std::string backValidFile; // the file imply that the backup directory is valid
41 };
42 
43 enum class RegisterFuncType {
44     OBSERVER_SINGLE_VERSION_NS_PUT_EVENT = 0,
45     OBSERVER_SINGLE_VERSION_NS_SYNC_EVENT,
46     OBSERVER_SINGLE_VERSION_NS_LOCAL_EVENT,
47     OBSERVER_SINGLE_VERSION_NS_CONFLICT_EVENT,
48     OBSERVER_MULTI_VERSION_NS_COMMIT_EVENT,
49     CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY,
50     CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG,
51     CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL,
52     REGISTER_FUNC_TYPE_MAX
53 };
54 
55 class GenericKvDB : public IKvDB {
56 public:
57     GenericKvDB();
58     ~GenericKvDB() override;
59 
60     DISABLE_COPY_ASSIGN_MOVE(GenericKvDB);
61 
62     // Get properties of this database.
63     const KvDBProperties &GetMyProperties() const override;
64 
65     // Create a db connection.
66     IKvDBConnection *GetDBConnection(int &errCode) final;
67 
68     // Called when all connections of this database closed.
69     void OnClose(const std::function<void(void)> &notifier) final;
70 
71     // Publish event when a commit action happened.
72     virtual void CommitNotify(int notifyEvent, KvDBCommitNotifyFilterAbleData *data);
73 
74     // Invoked automatically when connection count is zero
75     virtual void Close() = 0;
76 
77     virtual int TryToDisableConnection(OperatePerm perm);
78 
79     virtual void ReEnableConnection(OperatePerm perm);
80 
81     virtual int Rekey(const CipherPassword &passwd) = 0;
82 
83     // Empty passwords represent non-encrypted files.
84     // Export existing database files to a specified database file in the specified directory.
85     virtual int Export(const std::string &filePath, const CipherPassword &passwd) = 0;
86 
87     // Import the existing database files to the specified database file in the specified directory.
88     virtual int Import(const std::string &filePath, const CipherPassword &passwd) = 0;
89 
90     // Release a db connection.
91     void ReleaseDBConnection(GenericKvDBConnection *connection);
92 
93     // Register an event listener.
94     NotificationChain::Listener *RegisterEventListener(EventType type,
95         const NotificationChain::Listener::OnEvent &onEvent,
96         const NotificationChain::Listener::OnFinalize &onFinalize, int &errCode);
97 
98     // Get event notify counter.
99     uint64_t GetEventNotifyCounter() const;
100 
WakeUpSyncer()101     void WakeUpSyncer() override {};
102 
EnableAutonomicUpgrade()103     void EnableAutonomicUpgrade() override {};
104 
105     void SetCorruptHandler(const DatabaseCorruptHandler &handler) override;
106 
107     int RegisterFunction(RegisterFuncType type);
108 
109     int UnregisterFunction(RegisterFuncType type);
110 
111     uint32_t GetRegisterFunctionCount(RegisterFuncType type) const;
112 
113     virtual int TransObserverTypeToRegisterFunctionType(int observerType, RegisterFuncType &type) const;
114 
115     virtual int TransConflictTypeToRegisterFunctionType(int conflictType, RegisterFuncType &type) const;
116 
117     virtual int CheckDataStatus(const Key &key, const Value &value, bool isDeleted) const;
118 
119     virtual bool CheckWritePermission() const;
120 
121     virtual bool IsDataMigrating() const;
122 
123     virtual void SetConnectionFlag(bool isExisted) const;
124 
125     int CheckIntegrity() const override;
126 
127     std::string GetStorePath() const override;
128 
129     void Dump(int fd) override;
130 
131     virtual void ResetSyncStatus();
132 
133     void MarkRebuild() override;
134 protected:
135     // Create a connection object, no DB ref increased.
136     virtual GenericKvDBConnection *NewConnection(int &errCode) = 0;
137 
138     // Delete a connection object.
139     virtual void DelConnection(GenericKvDBConnection *connection);
140 
141     // Called when a new connection created.
142     void IncreaseConnectionCounter();
143 
144     // Called when a connection released.
145     void DecreaseConnectionCounter();
146 
147     // Register a new notification event type.
148     int RegisterNotificationEventType(int eventType);
149 
150     // Unregister a notification event type.
151     void UnRegisterNotificationEventType(int eventType);
152 
153     // Access 'properties_' for derived class.
154     const KvDBProperties &MyProp() const;
155     KvDBProperties &MyProp();
156 
157 #ifndef OMIT_MULTI_VER
158     static int GetWorkDir(const KvDBProperties &kvDBProp, std::string &workDir);
159 #endif
160 
161     void CorruptNotify() const;
162 
163     std::string GetStoreIdOnlyIdentifier(const KvDBProperties &properties) const;
164 
165     void GetStoreDirectory(const KvDBProperties &properties, int dbType,
166         std::string &storeDir, std::string &storeOnlyDir) const;
167 
168     PerformanceAnalysis *performance_;
169     DatabaseCorruptHandler corruptHandler_;
170     DeviceID devId_;
171 
172 private:
173     // Do commit notify in task pool.
174     void CommitNotifyAsync(int notifyEvent, KvDBCommitNotifyFilterAbleData *data);
175 
176     void CorruptNotifyAsync() const;
177 
178     // Get the ID of this kvdb.
179     std::string GetStoreId() const;
180 
181     DECLARE_OBJECT_TAG(GenericKvDB);
182 
183     // Databasse event notify counter.
184     std::atomic<uint64_t> eventNotifyCounter_;
185 
186     // Fields for tracking the connection count and invoking callbacks.
187     std::atomic<int> connectionCount_;
188     std::vector<std::function<void(void)>> closeNotifiers_;
189     NotificationChain *notificationChain_;
190     KvDBProperties properties_;
191     std::mutex connectMutex_;
192     mutable std::mutex corruptMutex_;
193     OperatePerm operatePerm_;
194     mutable std::mutex regFuncCountMutex_;
195     std::vector<uint32_t> registerFunctionCount_;
196     std::atomic<bool> isRebuild_;
197 };
198 } // namespace DistributedDB
199 
200 #endif // GENERIC_KVDB_H
201