• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
33 }
34 
~GenericKvDBConnection()35 GenericKvDBConnection::~GenericKvDBConnection()
36 {
37     if (!isSafeDeleted_) {
38         LOGF("The connection is deleted directly by user.");
39     }
40 
41     for (auto &observer : observerList_) {
42         delete observer;
43         observer = nullptr;
44     }
45 }
46 
RegisterObserverForOneType(int type,const Key & key,const KvDBObserverAction & action,NotificationChain::Listener * & listener)47 int GenericKvDBConnection::RegisterObserverForOneType(int type, const Key &key, const KvDBObserverAction &action,
48     NotificationChain::Listener *&listener)
49 {
50     if (kvDB_ == nullptr) {
51         return -E_INVALID_CONNECTION;
52     }
53     RegisterFuncType funcType = REGISTER_FUNC_TYPE_MAX;
54     int errCode = kvDB_->TransObserverTypeToRegisterFunctionType(type, funcType);
55     if (errCode != E_OK) {
56         return errCode;
57     }
58     errCode = kvDB_->RegisterFunction(funcType);
59     if (errCode != E_OK) {
60         return errCode;
61     }
62     listener = RegisterSpecialListener(type, key, action, false, errCode);
63     if (listener == nullptr) {
64         (void)(kvDB_->UnregisterFunction(funcType));
65         return errCode;
66     }
67     return E_OK;
68 }
69 
RegisterObserver(unsigned mode,const Key & key,const KvDBObserverAction & action,int & errCode)70 KvDBObserverHandle *GenericKvDBConnection::RegisterObserver(unsigned mode,
71     const Key &key, const KvDBObserverAction &action, int &errCode)
72 {
73     if (!action || key.size() > DBConstant::MAX_KEY_SIZE) {
74         errCode = -E_INVALID_ARGS;
75         return nullptr;
76     }
77     std::list<int> eventTypes;
78     errCode = GetEventType(mode, eventTypes);
79     if (errCode != E_OK) {
80         return nullptr;
81     }
82 
83     std::lock_guard<std::mutex> lockGuard(observerListLock_);
84     if (observerList_.size() >= MAX_OBSERVER_COUNT) {
85         errCode = -E_MAX_LIMITS;
86         LOGE("The number of observers has been larger than 'MAX_OBSERVER_COUNT'!");
87         return nullptr;
88     }
89     if (isExclusive_.load()) {
90         errCode = -E_BUSY;
91         return nullptr;
92     }
93     auto observerHandle = new (std::nothrow) KvDBObserverHandle(mode);
94     if (observerHandle == nullptr) {
95         errCode = -E_OUT_OF_MEMORY;
96         return nullptr;
97     }
98 
99     std::list<NotificationChain::Listener *> listenerList;
100     for (const auto &type : eventTypes) {
101         NotificationChain::Listener *listenerObj = nullptr;
102         // Register function count in db is also protected by observer list lock.
103         errCode = RegisterObserverForOneType(type, key, action, listenerObj);
104         if (errCode != E_OK) {
105             for (auto &listener : listenerList) {
106                 listener->Drop();
107             }
108             LOGE("Register observer failed, register listener failed, err:'%d'.", errCode);
109             delete observerHandle;
110             observerHandle = nullptr;
111             return nullptr;
112         }
113         listenerList.push_back(listenerObj);
114     }
115 
116     for (auto &listener : listenerList) {
117         observerHandle->InsertListener(listener);
118     }
119     observerList_.push_back(observerHandle);
120     errCode = E_OK;
121     return observerHandle;
122 }
123 
UnRegisterObserver(const KvDBObserverHandle * observerHandle)124 int GenericKvDBConnection::UnRegisterObserver(const KvDBObserverHandle *observerHandle)
125 {
126     if (observerHandle == nullptr) {
127         return -E_INVALID_ARGS;
128     }
129 
130     if (kvDB_ == nullptr) {
131         return -E_INVALID_CONNECTION;
132     }
133 
134     std::list<int> eventTypes;
135     int errCode = GetEventType(observerHandle->GetObserverMode(), eventTypes);
136     if (errCode != E_OK) {
137         return errCode;
138     }
139 
140     {
141         std::lock_guard<std::mutex> lockGuard(observerListLock_);
142         auto observerIter = std::find(observerList_.begin(), observerList_.end(), observerHandle);
143         if (observerIter == observerList_.end()) {
144             LOGE("Unregister observer failed, no such entry.");
145             return -E_NO_SUCH_ENTRY;
146         }
147         observerList_.erase(observerIter);
148         // Register function count in db is also protected by observer list lock.
149         RegisterFuncType funcType = REGISTER_FUNC_TYPE_MAX;
150         for (auto type : eventTypes) {
151             errCode = kvDB_->TransObserverTypeToRegisterFunctionType(type, funcType);
152             if (errCode != E_OK) {
153                 LOGE("Get register function type failed, err:'%d'.", errCode);
154                 continue;
155             }
156             errCode = kvDB_->UnregisterFunction(funcType);
157             if (errCode != E_OK) {
158                 LOGE("Unregister function failed, err:'%d'.", errCode);
159                 continue;
160             }
161         }
162     }
163 
164     delete observerHandle;
165     observerHandle = nullptr;
166     return E_OK;
167 }
168 
SetConflictNotifier(int conflictType,const KvDBConflictAction & action)169 int GenericKvDBConnection::SetConflictNotifier(int conflictType, const KvDBConflictAction &action)
170 {
171     (void)conflictType;
172     (void)action;
173     return -E_NOT_SUPPORT;
174 }
175 
Close()176 int GenericKvDBConnection::Close()
177 {
178     if (kvDB_ == nullptr) {
179         return -E_INVALID_CONNECTION;
180     }
181 
182     if (isExclusive_.load()) {
183         return -E_BUSY;
184     }
185     if (kvDB_->IsDataMigrating()) {
186         return -E_BUSY;
187     }
188 
189     int errCode = PreClose();
190     if (errCode != E_OK) {
191         LOGE("Close connection  failed, err:'%d'.", errCode);
192         return errCode;
193     }
194     kvDB_->ReleaseDBConnection(this);
195     return E_OK;
196 }
197 
GetIdentifier() const198 std::string GenericKvDBConnection::GetIdentifier() const
199 {
200     if (kvDB_ == nullptr) {
201         return "";
202     }
203     return kvDB_->GetMyProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
204 }
205 
Pragma(int cmd,void * parameter)206 int GenericKvDBConnection::Pragma(int cmd, void *parameter)
207 {
208     (void)cmd;
209     (void)parameter;
210     return -E_NOT_SUPPORT;
211 }
212 
PreClose()213 int GenericKvDBConnection::PreClose()
214 {
215     return E_OK;
216 }
217 
SetSafeDeleted()218 void GenericKvDBConnection::SetSafeDeleted()
219 {
220     isSafeDeleted_ = true;
221 }
222 
GetEntries(const IOption & option,const Key & keyPrefix,std::vector<Entry> & entries) const223 int GenericKvDBConnection::GetEntries(const IOption &option, const Key &keyPrefix, std::vector<Entry> &entries) const
224 {
225     (void)option;
226     (void)keyPrefix;
227     (void)entries;
228     return -E_NOT_SUPPORT;
229 }
230 
GetEntries(const IOption & option,const Query & query,std::vector<Entry> & entries) const231 int GenericKvDBConnection::GetEntries(const IOption &option, const Query &query, std::vector<Entry> &entries) const
232 {
233     (void)option;
234     (void)query;
235     (void)entries;
236     return -E_NOT_SUPPORT;
237 }
238 
GetResultSet(const IOption & option,const Key & keyPrefix,IKvDBResultSet * & resultSet) const239 int GenericKvDBConnection::GetResultSet(const IOption &option, const Key &keyPrefix, IKvDBResultSet *&resultSet) const
240 {
241     (void)option;
242     (void)keyPrefix;
243     (void)resultSet;
244     return -E_NOT_SUPPORT;
245 }
246 
GetResultSet(const IOption & option,const Query & query,IKvDBResultSet * & resultSet) const247 int GenericKvDBConnection::GetResultSet(const IOption &option, const Query &query, IKvDBResultSet *&resultSet) const
248 {
249     (void)option;
250     (void)query;
251     (void)resultSet;
252     return -E_NOT_SUPPORT;
253 }
254 
GetCount(const IOption & option,const Query & query,int & count) const255 int GenericKvDBConnection::GetCount(const IOption &option, const Query &query, int &count) const
256 {
257     (void)option;
258     (void)query;
259     (void)count;
260     return -E_NOT_SUPPORT;
261 }
262 
ReleaseResultSet(IKvDBResultSet * & resultSet)263 void GenericKvDBConnection::ReleaseResultSet(IKvDBResultSet *&resultSet)
264 {
265     (void)resultSet;
266     return;
267 }
268 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)269 int GenericKvDBConnection::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
270 {
271     (void)notifier;
272     return -E_NOT_SUPPORT;
273 }
274 
GetSecurityOption(int & securityLabel,int & securityFlag) const275 int GenericKvDBConnection::GetSecurityOption(int &securityLabel, int &securityFlag) const
276 {
277     if (kvDB_ == nullptr) {
278         return -E_INVALID_CONNECTION;
279     }
280     securityLabel = kvDB_->GetMyProperties().GetIntProp(KvDBProperties::SECURITY_LABEL, 0);
281     securityFlag = kvDB_->GetMyProperties().GetIntProp(KvDBProperties::SECURITY_FLAG, 0);
282     return E_OK;
283 }
284 
RegisterSpecialListener(int type,const Key & key,const KvDBObserverAction & action,bool conflict,int & errCode)285 NotificationChain::Listener *GenericKvDBConnection::RegisterSpecialListener(int type,
286     const Key &key, const KvDBObserverAction &action, bool conflict, int &errCode)
287 {
288     if (!action) {
289         errCode = -E_INVALID_ARGS;
290         return nullptr;
291     }
292 
293     if (kvDB_ == nullptr) {
294         errCode = -E_INVALID_CONNECTION;
295         return nullptr;
296     }
297 
298     uint64_t notifyBarrier = kvDB_->GetEventNotifyCounter();
299     return kvDB_->RegisterEventListener(static_cast<EventType>(type),
300         [key, action, conflict, notifyBarrier](void *ptr) {
301             if (ptr == nullptr) {
302                 return;
303             }
304             KvDBCommitNotifyFilterAbleData *data = static_cast<KvDBCommitNotifyFilterAbleData *>(ptr);
305             if (data->GetNotifyID() <= notifyBarrier) {
306                 return;
307             }
308             data->SetFilterKey(key);
309             if (conflict) {
310                 if (!data->IsConflictedDataEmpty()) {
311                     action(*data);
312                 }
313             } else {
314                 if (!data->IsChangedDataEmpty()) {
315                     action(*data);
316                 }
317             }
318         }, nullptr, errCode);
319 }
320 
PreCheckExclusiveStatus()321 int GenericKvDBConnection::PreCheckExclusiveStatus()
322 {
323     std::lock_guard<std::mutex> lockGuard(observerListLock_);
324     if (observerList_.empty()) {
325         isExclusive_.store(true);
326         return E_OK;
327     }
328     return -E_BUSY;
329 }
330 
ResetExclusiveStatus()331 void GenericKvDBConnection::ResetExclusiveStatus()
332 {
333     isExclusive_.store(false);
334 }
335 
GetEventType(unsigned mode,std::list<int> & eventTypes) const336 int GenericKvDBConnection::GetEventType(unsigned mode, std::list<int> &eventTypes) const
337 {
338     if (kvDB_ == nullptr) {
339         return -E_INVALID_CONNECTION;
340     }
341 
342     return TranslateObserverModeToEventTypes(mode, eventTypes);
343 }
344 
CheckIntegrity() const345 int GenericKvDBConnection::CheckIntegrity() const
346 {
347     return E_OK;
348 }
349 }