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 #include "generic_kvdb_connection.h"
17 
18 #include <algorithm>
19 
20 #include "log_print.h"
21 #include "db_constant.h"
22 #include "db_errno.h"
23 #include "generic_kvdb.h"
24 #include "kvdb_observer_handle.h"
25 #include "kvdb_commit_notify_filterable_data.h"
26 
27 namespace DistributedDB {
GenericKvDBConnection(GenericKvDB * kvDB)28 GenericKvDBConnection::GenericKvDBConnection(GenericKvDB *kvDB)
29     : kvDB_(kvDB),
30       isExclusive_(false),
31       isSafeDeleted_(false),
32       isRebuild_(false)
33 {
34 }
35 
~GenericKvDBConnection()36 GenericKvDBConnection::~GenericKvDBConnection()
37 {
38     if (!isSafeDeleted_) {
39         LOGF("The connection is deleted directly by user.");
40     }
41 
42     for (auto &observer : observerList_) {
43         delete observer;
44         observer = nullptr;
45     }
46 }
47 
RegisterObserverForOneType(int type,const Key & key,const KvDBObserverAction & action,NotificationChain::Listener * & listener)48 int GenericKvDBConnection::RegisterObserverForOneType(int type, const Key &key, const KvDBObserverAction &action,
49     NotificationChain::Listener *&listener)
50 {
51     if (kvDB_ == nullptr) {
52         return -E_INVALID_CONNECTION;
53     }
54     RegisterFuncType funcType = RegisterFuncType::REGISTER_FUNC_TYPE_MAX;
55     int errCode = kvDB_->TransObserverTypeToRegisterFunctionType(type, funcType);
56     if (errCode != E_OK) {
57         return errCode;
58     }
59     errCode = kvDB_->RegisterFunction(funcType);
60     if (errCode != E_OK) {
61         return errCode;
62     }
63     listener = RegisterSpecialListener(type, key, action, false, errCode);
64     if (listener == nullptr) {
65         (void)(kvDB_->UnregisterFunction(funcType));
66         return errCode;
67     }
68     return E_OK;
69 }
70 
RegisterObserver(unsigned mode,const Key & key,const KvDBObserverAction & action,int & errCode)71 KvDBObserverHandle *GenericKvDBConnection::RegisterObserver(unsigned mode,
72     const Key &key, const KvDBObserverAction &action, int &errCode)
73 {
74     if (!action || key.size() > DBConstant::MAX_KEY_SIZE) {
75         errCode = -E_INVALID_ARGS;
76         return nullptr;
77     }
78     std::list<int> eventTypes;
79     errCode = GetEventType(mode, eventTypes);
80     if (errCode != E_OK) {
81         return nullptr;
82     }
83 
84     std::lock_guard<std::mutex> lockGuard(observerListLock_);
85     if (observerList_.size() >= DBConstant::MAX_OBSERVER_COUNT) {
86         errCode = -E_MAX_LIMITS;
87         LOGE("The number of observers has been larger than 'MAX_OBSERVER_COUNT'!");
88         return nullptr;
89     }
90     if (isExclusive_.load()) {
91         errCode = -E_BUSY;
92         LOGE("Observer is exclusived %d", errCode);
93         return nullptr;
94     }
95     auto observerHandle = new (std::nothrow) KvDBObserverHandle(mode);
96     if (observerHandle == nullptr) {
97         errCode = -E_OUT_OF_MEMORY;
98         return nullptr;
99     }
100 
101     std::list<NotificationChain::Listener *> listenerList;
102     for (const auto &type : eventTypes) {
103         NotificationChain::Listener *listenerObj = nullptr;
104         // Register function count in db is also protected by observer list lock.
105         errCode = RegisterObserverForOneType(type, key, action, listenerObj);
106         if (errCode != E_OK) {
107             for (auto &listener : listenerList) {
108                 listener->Drop();
109             }
110             LOGE("Register observer failed, register listener failed, err:'%d'.", errCode);
111             delete observerHandle;
112             observerHandle = nullptr;
113             return nullptr;
114         }
115         listenerList.push_back(listenerObj);
116     }
117 
118     for (auto &listener : listenerList) {
119         observerHandle->InsertListener(listener);
120     }
121     observerList_.push_back(observerHandle);
122     errCode = E_OK;
123     return observerHandle;
124 }
125 
UnRegisterObserver(const KvDBObserverHandle * observerHandle)126 int GenericKvDBConnection::UnRegisterObserver(const KvDBObserverHandle *observerHandle)
127 {
128     if (observerHandle == nullptr) {
129         return -E_INVALID_ARGS;
130     }
131 
132     if (kvDB_ == nullptr) {
133         return -E_INVALID_CONNECTION;
134     }
135 
136     std::list<int> eventTypes;
137     int errCode = GetEventType(observerHandle->GetObserverMode(), eventTypes);
138     if (errCode != E_OK) {
139         return errCode;
140     }
141 
142     {
143         std::lock_guard<std::mutex> lockGuard(observerListLock_);
144         auto observerIter = std::find(observerList_.begin(), observerList_.end(), observerHandle);
145         if (observerIter == observerList_.end()) {
146             LOGE("Unregister observer failed, no such entry.");
147             return -E_NO_SUCH_ENTRY;
148         }
149         observerList_.erase(observerIter);
150         // Register function count in db is also protected by observer list lock.
151         RegisterFuncType funcType = RegisterFuncType::REGISTER_FUNC_TYPE_MAX;
152         for (auto type : eventTypes) {
153             errCode = kvDB_->TransObserverTypeToRegisterFunctionType(type, funcType);
154             if (errCode != E_OK) {
155                 LOGE("Get register function type failed, err:'%d'.", errCode);
156                 continue;
157             }
158             errCode = kvDB_->UnregisterFunction(funcType);
159             if (errCode != E_OK) {
160                 LOGE("Unregister function failed, err:'%d'.", errCode);
161                 continue;
162             }
163         }
164     }
165 
166     delete observerHandle;
167     observerHandle = nullptr;
168     return E_OK;
169 }
170 
SetConflictNotifier(int conflictType,const KvDBConflictAction & action)171 int GenericKvDBConnection::SetConflictNotifier(int conflictType, const KvDBConflictAction &action)
172 {
173     (void)conflictType;
174     (void)action;
175     return -E_NOT_SUPPORT;
176 }
177 
Close()178 int GenericKvDBConnection::Close()
179 {
180     if (kvDB_ == nullptr) {
181         return -E_INVALID_CONNECTION;
182     }
183 
184     if (isExclusive_.load()) {
185         LOGE("Current connection is occupied by other connection");
186         return -E_BUSY;
187     }
188     if (kvDB_->IsDataMigrating()) {
189         LOGE("Data is migrating");
190         return -E_BUSY;
191     }
192 
193     int errCode = PreClose();
194     if (errCode != E_OK) {
195         LOGE("Close connection  failed, err:'%d'.", errCode);
196         return errCode;
197     }
198     kvDB_->ReleaseDBConnection(this);
199     return E_OK;
200 }
201 
GetIdentifier() const202 std::string GenericKvDBConnection::GetIdentifier() const
203 {
204     if (kvDB_ == nullptr) {
205         return "";
206     }
207     return kvDB_->GetMyProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
208 }
209 
Pragma(int cmd,void * parameter)210 int GenericKvDBConnection::Pragma(int cmd, void *parameter)
211 {
212     (void)cmd;
213     (void)parameter;
214     return -E_NOT_SUPPORT;
215 }
216 
PreClose()217 int GenericKvDBConnection::PreClose()
218 {
219     return E_OK;
220 }
221 
SetSafeDeleted()222 void GenericKvDBConnection::SetSafeDeleted()
223 {
224     isSafeDeleted_ = true;
225 }
226 
GetEntries(const IOption & option,const Key & keyPrefix,std::vector<Entry> & entries) const227 int GenericKvDBConnection::GetEntries(const IOption &option, const Key &keyPrefix, std::vector<Entry> &entries) const
228 {
229     (void)option;
230     (void)keyPrefix;
231     (void)entries;
232     return -E_NOT_SUPPORT;
233 }
234 
GetEntries(const IOption & option,const Query & query,std::vector<Entry> & entries) const235 int GenericKvDBConnection::GetEntries(const IOption &option, const Query &query, std::vector<Entry> &entries) const
236 {
237     (void)option;
238     (void)query;
239     (void)entries;
240     return -E_NOT_SUPPORT;
241 }
242 
GetResultSet(const IOption & option,const Key & keyPrefix,IKvDBResultSet * & resultSet) const243 int GenericKvDBConnection::GetResultSet(const IOption &option, const Key &keyPrefix, IKvDBResultSet *&resultSet) const
244 {
245     (void)option;
246     (void)keyPrefix;
247     (void)resultSet;
248     return -E_NOT_SUPPORT;
249 }
250 
GetResultSet(const IOption & option,const Query & query,IKvDBResultSet * & resultSet) const251 int GenericKvDBConnection::GetResultSet(const IOption &option, const Query &query, IKvDBResultSet *&resultSet) const
252 {
253     (void)option;
254     (void)query;
255     (void)resultSet;
256     return -E_NOT_SUPPORT;
257 }
258 
GetCount(const IOption & option,const Query & query,int & count) const259 int GenericKvDBConnection::GetCount(const IOption &option, const Query &query, int &count) const
260 {
261     (void)option;
262     (void)query;
263     (void)count;
264     return -E_NOT_SUPPORT;
265 }
266 
ReleaseResultSet(IKvDBResultSet * & resultSet)267 void GenericKvDBConnection::ReleaseResultSet(IKvDBResultSet *&resultSet)
268 {
269     (void)resultSet;
270     return;
271 }
272 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)273 int GenericKvDBConnection::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
274 {
275     (void)notifier;
276     return -E_NOT_SUPPORT;
277 }
278 
GetSecurityOption(int & securityLabel,int & securityFlag) const279 int GenericKvDBConnection::GetSecurityOption(int &securityLabel, int &securityFlag) const
280 {
281     if (kvDB_ == nullptr) {
282         return -E_INVALID_CONNECTION;
283     }
284     securityLabel = kvDB_->GetMyProperties().GetIntProp(KvDBProperties::SECURITY_LABEL, 0);
285     securityFlag = kvDB_->GetMyProperties().GetIntProp(KvDBProperties::SECURITY_FLAG, 0);
286     return E_OK;
287 }
288 
RegisterSpecialListener(int type,const Key & key,const KvDBObserverAction & action,bool conflict,int & errCode)289 NotificationChain::Listener *GenericKvDBConnection::RegisterSpecialListener(int type,
290     const Key &key, const KvDBObserverAction &action, bool conflict, int &errCode)
291 {
292     if (!action) {
293         errCode = -E_INVALID_ARGS;
294         return nullptr;
295     }
296 
297     if (kvDB_ == nullptr) {
298         errCode = -E_INVALID_CONNECTION;
299         return nullptr;
300     }
301 
302     uint64_t notifyBarrier = kvDB_->GetEventNotifyCounter();
303     return kvDB_->RegisterEventListener(static_cast<EventType>(type),
304         [key, action, conflict, notifyBarrier](void *ptr) {
305             if (ptr == nullptr) {
306                 return;
307             }
308             KvDBCommitNotifyFilterAbleData *data = static_cast<KvDBCommitNotifyFilterAbleData *>(ptr);
309             if (data->GetNotifyID() <= notifyBarrier) {
310                 return;
311             }
312             data->SetFilterKey(key);
313             if (conflict) {
314                 if (!data->IsConflictedDataEmpty()) {
315                     action(*data);
316                 }
317             } else {
318                 if (!data->IsChangedDataEmpty()) {
319                     action(*data);
320                 }
321             }
322         }, nullptr, errCode);
323 }
324 
PreCheckExclusiveStatus()325 int GenericKvDBConnection::PreCheckExclusiveStatus()
326 {
327     std::lock_guard<std::mutex> lockGuard(observerListLock_);
328     if (observerList_.empty()) {
329         isExclusive_.store(true);
330         return E_OK;
331     }
332     return -E_BUSY;
333 }
334 
ResetExclusiveStatus()335 void GenericKvDBConnection::ResetExclusiveStatus()
336 {
337     isExclusive_.store(false);
338 }
339 
GetEventType(unsigned mode,std::list<int> & eventTypes) const340 int GenericKvDBConnection::GetEventType(unsigned mode, std::list<int> &eventTypes) const
341 {
342     if (kvDB_ == nullptr) {
343         return -E_INVALID_CONNECTION;
344     }
345 
346     return TranslateObserverModeToEventTypes(mode, eventTypes);
347 }
348 
CheckIntegrity() const349 int GenericKvDBConnection::CheckIntegrity() const
350 {
351     return E_OK;
352 }
353 
GetKeys(const IOption & option,const Key & keyPrefix,std::vector<Key> & keys) const354 int GenericKvDBConnection::GetKeys(const IOption &option, const Key &keyPrefix, std::vector<Key> &keys) const
355 {
356     return -E_NOT_SUPPORT;
357 }
358 
GetSyncDataSize(const std::string & device,size_t & size) const359 int GenericKvDBConnection::GetSyncDataSize(const std::string &device, size_t &size) const
360 {
361     return -E_NOT_SUPPORT;
362 }
363 
UpdateKey(const UpdateKeyCallback & callback)364 int GenericKvDBConnection::UpdateKey(const UpdateKeyCallback &callback)
365 {
366     return -E_NOT_SUPPORT;
367 }
368 
369 int GenericKvDBConnection::GetWatermarkInfo([[gnu::unused]] const std::string &device,
370     [[gnu::unused]] WatermarkInfo &info)
371 {
372     return -E_NOT_SUPPORT;
373 }
374 
IsObserverEmpty()375 bool GenericKvDBConnection::IsObserverEmpty()
376 {
377     std::lock_guard<std::mutex> lockGuard(observerListLock_);
378     return observerList_.empty();
379 }
380 
381 int GenericKvDBConnection::Sync([[gnu::unused]] const CloudSyncOption &option,
382     [[gnu::unused]] const SyncProcessCallback &onProcess)
383 {
384     return -E_NOT_SUPPORT;
385 }
386 
387 int GenericKvDBConnection::SetCloudDB([[gnu::unused]] const std::map<std::string, std::shared_ptr<ICloudDb>> &cloudDBs)
388 {
389     return -E_NOT_SUPPORT;
390 }
391 
392 int GenericKvDBConnection::SetCloudDbSchema([[gnu::unused]] const std::map<std::string, DataBaseSchema> &schema)
393 {
394     return -E_NOT_SUPPORT;
395 }
396 
397 int GenericKvDBConnection::RemoveDeviceData([[gnu::unused]] const std::string &device, [[gnu::unused]] ClearMode mode)
398 {
399     return -E_NOT_SUPPORT;
400 }
401 
402 int GenericKvDBConnection::RemoveDeviceData([[gnu::unused]] const std::string &device,
403     [[gnu::unused]] const std::string &user, [[gnu::unused]] ClearMode mode)\
404 {
405     return -E_NOT_SUPPORT;
406 }
407 
GetTaskCount()408 int32_t GenericKvDBConnection::GetTaskCount()
409 {
410     return 0;
411 }
412 
413 int GenericKvDBConnection::RegisterObserverAction([[gnu::unused]] const KvStoreObserver *observer,
414     [[gnu::unused]] const ObserverAction &action)
415 {
416     return E_OK;
417 }
418 
419 int GenericKvDBConnection::UnRegisterObserverAction([[gnu::unused]] const KvStoreObserver *observer)
420 {
421     return E_OK;
422 }
423 
SetGenCloudVersionCallback(const GenerateCloudVersionCallback & callback)424 void GenericKvDBConnection::SetGenCloudVersionCallback(const GenerateCloudVersionCallback &callback)
425 {
426     (void)callback;
427     return;
428 }
429 
GetCloudVersion(const std::string & device,std::map<std::string,std::string> & versionMap)430 int GenericKvDBConnection::GetCloudVersion(const std::string &device, std::map<std::string, std::string> &versionMap)
431 {
432     return -E_NOT_SUPPORT;
433 }
434 
SetReceiveDataInterceptor(const DataInterceptor & interceptor)435 int GenericKvDBConnection::SetReceiveDataInterceptor(const DataInterceptor &interceptor)
436 {
437     return -E_NOT_SUPPORT;
438 }
439 
SetCloudSyncConfig(const CloudSyncConfig & config)440 int GenericKvDBConnection::SetCloudSyncConfig(const CloudSyncConfig &config)
441 {
442     return -E_NOT_SUPPORT;
443 }
444 
GetEntries(const std::string & device,std::vector<Entry> & entries) const445 int GenericKvDBConnection::GetEntries(const std::string &device, std::vector<Entry> &entries) const
446 {
447     return -E_NOT_SUPPORT;
448 }
449 
MarkRebuild()450 void GenericKvDBConnection::MarkRebuild()
451 {
452     isRebuild_ = true;
453 }
454 
IsRebuild() const455 bool GenericKvDBConnection::IsRebuild() const
456 {
457     return isRebuild_;
458 }
459 }