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 "sqlite_single_ver_natural_store_connection.h"
17 #include <algorithm>
18 
19 #include "db_common.h"
20 #include "db_constant.h"
21 #include "db_dfx_adapter.h"
22 #include "db_errno.h"
23 #include "kvdb_observer_handle.h"
24 #include "kvdb_pragma.h"
25 #include "log_print.h"
26 #include "single_ver_natural_store_connection.h"
27 #include "sqlite_single_ver_natural_store.h"
28 #include "sqlite_single_ver_result_set.h"
29 #include "store_types.h"
30 #include "time_helper.h"
31 
32 namespace DistributedDB {
33 namespace {
34     enum class LocalOperType {
35         LOCAL_OPR_NONE = 0,
36         LOCAL_OPR_DEL = 1,
37         LOCAL_OPR_PUT = 2
38     };
39     const uint32_t MAX_AUTO_LIFE_CYCLE = 1800000; // half an hour.
40     const uint32_t MIN_AUTO_LIFE_CYCLE = 5000; // 5s.
41 }
42 
SQLiteSingleVerNaturalStoreConnection(SQLiteSingleVerNaturalStore * kvDB)43 SQLiteSingleVerNaturalStoreConnection::SQLiteSingleVerNaturalStoreConnection(SQLiteSingleVerNaturalStore *kvDB)
44     : SingleVerNaturalStoreConnection(kvDB),
45       cacheMaxSizeForNewResultSet_(DEFAULT_RESULT_SET_CACHE_MAX_SIZE),
46       conflictType_(0),
47       transactionEntryLen_(0),
48       currentMaxTimestamp_(0),
49       committedData_(nullptr),
50       localCommittedData_(nullptr),
51       transactionExeFlag_(false),
52       conflictListener_(nullptr),
53       writeHandle_(nullptr)
54 {}
55 
~SQLiteSingleVerNaturalStoreConnection()56 SQLiteSingleVerNaturalStoreConnection::~SQLiteSingleVerNaturalStoreConnection()
57 {
58     if (conflictListener_ != nullptr) {
59         conflictListener_->Drop(true);
60         conflictListener_ = nullptr;
61     }
62 }
63 
IsFileAccessControlled() const64 inline bool SQLiteSingleVerNaturalStoreConnection::IsFileAccessControlled() const
65 {
66     return RuntimeContext::GetInstance()->IsAccessControlled() &&
67         kvDB_->GetMyProperties().GetSecLabel() > SecurityLabel::S2;
68 }
69 
CheckReadDataControlled() const70 int SQLiteSingleVerNaturalStoreConnection::CheckReadDataControlled() const
71 {
72     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
73     if (naturalStore == nullptr) {
74         LOGE("[SingleVerConnection] natural store is nullptr in CheckReadDataControlled.");
75         return E_OK;
76     }
77     return naturalStore->CheckReadDataControlled();
78 }
79 
Get(const IOption & option,const Key & key,Value & value) const80 int SQLiteSingleVerNaturalStoreConnection::Get(const IOption &option, const Key &key, Value &value) const
81 {
82     if (key.size() > DBConstant::MAX_KEY_SIZE || key.empty()) {
83         return -E_INVALID_ARGS;
84     }
85 
86     SingleVerDataType dataType;
87     if (option.dataType == IOption::LOCAL_DATA) {
88         dataType = SingleVerDataType::LOCAL_TYPE_SQLITE;
89     } else if (option.dataType == IOption::SYNC_DATA) {
90         dataType = SingleVerDataType::SYNC_TYPE;
91     } else {
92         return -E_NOT_SUPPORT;
93     }
94 
95     int errCode = CheckReadDataControlled();
96     if (errCode != E_OK) {
97         LOGE("[Get] Existed cache database can not read data, errCode = [%d]!", errCode);
98         return errCode;
99     }
100 
101     DBDfxAdapter::StartTracing();
102     {
103         // need to check if the transaction started
104         std::lock_guard<std::mutex> lock(transactionMutex_);
105         if (writeHandle_ != nullptr) {
106             LOGD("Transaction started already.");
107             Timestamp recordTimestamp;
108             errCode = writeHandle_->GetKvData(dataType, key, value, recordTimestamp);
109             DBDfxAdapter::FinishTracing();
110             return errCode;
111         }
112     }
113 
114     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
115     if (handle == nullptr) {
116         DBDfxAdapter::FinishTracing();
117         return errCode;
118     }
119 
120     Timestamp timestamp;
121     errCode = handle->GetKvData(dataType, key, value, timestamp);
122     ReleaseExecutor(handle);
123     DBDfxAdapter::FinishTracing();
124     return errCode;
125 }
126 
Clear(const IOption & option)127 int SQLiteSingleVerNaturalStoreConnection::Clear(const IOption &option)
128 {
129     return -E_NOT_SUPPORT;
130 }
131 
GetEntries(const IOption & option,const Key & keyPrefix,std::vector<Entry> & entries) const132 int SQLiteSingleVerNaturalStoreConnection::GetEntries(const IOption &option, const Key &keyPrefix,
133     std::vector<Entry> &entries) const
134 {
135     return GetEntriesInner(true, option, keyPrefix, entries);
136 }
137 
GetEntries(const IOption & option,const Query & query,std::vector<Entry> & entries) const138 int SQLiteSingleVerNaturalStoreConnection::GetEntries(const IOption &option, const Query &query,
139     std::vector<Entry> &entries) const
140 {
141     if (option.dataType != IOption::SYNC_DATA) {
142         return -E_NOT_SUPPORT;
143     }
144     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
145     if (naturalStore == nullptr) {
146         return -E_INVALID_DB;
147     }
148     int errCode = CheckReadDataControlled();
149     if (errCode != E_OK) {
150         LOGE("[GetEntries] Existed cache database can not read data, errCode = [%d]!", errCode);
151         return errCode;
152     }
153     QueryObject queryObj(query);
154     if (((queryObj.GetSortType() != SortType::NONE) && !queryObj.IsQueryOnlyByKey())
155         || queryObj.IsQueryByRange()) {
156         LOGE("[GetEntries][query] timestamp sort only support prefixKey and not support Range search");
157         return -E_NOT_SUPPORT;
158     }
159 
160     // In readOnly mode, forbidden all schema related query
161     if (CheckWritePermission() == E_OK) {
162         const SchemaObject &schemaObjRef = naturalStore->GetSchemaObjectConstRef();
163         queryObj.SetSchema(schemaObjRef);
164     }
165     DBDfxAdapter::StartTracing();
166     {
167         std::lock_guard<std::mutex> lock(transactionMutex_);
168         if (writeHandle_ != nullptr) {
169             LOGD("Transaction started already.");
170             errCode = writeHandle_->GetEntries(queryObj, entries);
171             DBDfxAdapter::FinishTracing();
172             return errCode;
173         }
174     }
175 
176     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
177     if (handle == nullptr) {
178         DBDfxAdapter::FinishTracing();
179         return errCode;
180     }
181 
182     errCode = handle->GetEntries(queryObj, entries);
183     ReleaseExecutor(handle);
184     DBDfxAdapter::FinishTracing();
185     return errCode;
186 }
187 
GetCount(const IOption & option,const Query & query,int & count) const188 int SQLiteSingleVerNaturalStoreConnection::GetCount(const IOption &option, const Query &query, int &count) const
189 {
190     if (option.dataType != IOption::SYNC_DATA) {
191         return -E_NOT_SUPPORT;
192     }
193     int errCode = CheckReadDataControlled();
194     if (errCode != E_OK) {
195         LOGE("[GetCount] Existed cache database can not read data, errCode = [%d]!", errCode);
196         return errCode;
197     }
198 
199     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
200     if (naturalStore == nullptr) {
201         return -E_INVALID_DB;
202     }
203     QueryObject queryObj(query);
204     if (((queryObj.GetSortType() != SortType::NONE) && !queryObj.IsQueryOnlyByKey())
205         || queryObj.IsQueryByRange()) {
206         LOGE("[GetCount] get count query invalid");
207         return -E_NOT_SUPPORT;
208     }
209     // In readOnly mode, forbidden all schema related query
210     if (CheckWritePermission() == E_OK) {
211         const SchemaObject &schemaObjRef = naturalStore->GetSchemaObjectConstRef();
212         queryObj.SetSchema(schemaObjRef);
213     }
214     DBDfxAdapter::StartTracing();
215     {
216         std::lock_guard<std::mutex> lock(transactionMutex_);
217         if (writeHandle_ != nullptr) {
218             LOGD("Transaction started already.");
219             errCode = writeHandle_->GetCount(queryObj, count);
220             DBDfxAdapter::FinishTracing();
221             return errCode;
222         }
223     }
224 
225     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
226     if (handle == nullptr) {
227         DBDfxAdapter::FinishTracing();
228         return errCode;
229     }
230     errCode = handle->GetCount(queryObj, count);
231     ReleaseExecutor(handle);
232     DBDfxAdapter::FinishTracing();
233     return errCode;
234 }
235 
PutBatch(const IOption & option,const std::vector<Entry> & entries)236 int SQLiteSingleVerNaturalStoreConnection::PutBatch(const IOption &option, const std::vector<Entry> &entries)
237 {
238     LOGD("[PutBatch] entries size is : %zu, dataType : %d", entries.size(), option.dataType);
239     if (option.dataType == IOption::LOCAL_DATA) {
240         int retCode = CheckLocalEntriesValid(entries);
241         if (retCode != E_OK) {
242             return retCode;
243         }
244         return PutBatchInner(option, entries);
245     }
246 
247     return SingleVerNaturalStoreConnection::PutBatch(option, entries);
248 }
249 
DeleteBatch(const IOption & option,const std::vector<Key> & keys)250 int SQLiteSingleVerNaturalStoreConnection::DeleteBatch(const IOption &option, const std::vector<Key> &keys)
251 {
252     if (option.dataType == IOption::LOCAL_DATA) {
253         LOGD("[DeleteBatch] keys size is : %zu, dataType : %d", keys.size(), option.dataType);
254         int retCode = CheckLocalKeysValid(keys);
255         if (retCode != E_OK) {
256             return retCode;
257         }
258         return DeleteBatchInner(option, keys);
259     }
260 
261     return SingleVerNaturalStoreConnection::DeleteBatch(option, keys);
262 }
263 
GetSnapshot(IKvDBSnapshot * & snapshot) const264 int SQLiteSingleVerNaturalStoreConnection::GetSnapshot(IKvDBSnapshot *&snapshot) const
265 {
266     return -E_NOT_SUPPORT;
267 }
268 
ReleaseSnapshot(IKvDBSnapshot * & snapshot)269 void SQLiteSingleVerNaturalStoreConnection::ReleaseSnapshot(IKvDBSnapshot *&snapshot)
270 {}
271 
StartTransaction()272 int SQLiteSingleVerNaturalStoreConnection::StartTransaction()
273 {
274     std::lock_guard<std::mutex> lock(transactionMutex_);
275     if (writeHandle_ != nullptr) {
276         LOGD("Transaction started already.");
277         return -E_TRANSACT_STATE;
278     }
279 
280     int errCode = StartTransactionInner();
281     if (errCode == E_OK) {
282         transactionExeFlag_.store(true);
283     }
284     return errCode;
285 }
286 
Commit()287 int SQLiteSingleVerNaturalStoreConnection::Commit()
288 {
289     std::lock_guard<std::mutex> lock(transactionMutex_);
290     if (writeHandle_ == nullptr) {
291         LOGE("single version database is null or the transaction has not been started");
292         return -E_INVALID_DB;
293     }
294 
295     int errCode = CommitInner();
296     if (errCode == E_OK) {
297         transactionExeFlag_.store(false);
298     }
299     return errCode;
300 }
301 
RollBack()302 int SQLiteSingleVerNaturalStoreConnection::RollBack()
303 {
304     std::lock_guard<std::mutex> lock(transactionMutex_);
305     if (writeHandle_ == nullptr) {
306         LOGE("Invalid handle for rollback or the transaction has not been started.");
307         return -E_INVALID_DB;
308     }
309 
310     int errCode = RollbackInner();
311     if (errCode == E_OK) {
312         transactionExeFlag_.store(false);
313     }
314     return errCode;
315 }
316 
IsTransactionStarted() const317 bool SQLiteSingleVerNaturalStoreConnection::IsTransactionStarted() const
318 {
319     return transactionExeFlag_.load();
320 }
321 
Pragma(int cmd,void * parameter)322 int SQLiteSingleVerNaturalStoreConnection::Pragma(int cmd, void *parameter)
323 {
324     int errCode = E_OK;
325     switch (cmd) {
326         case PRAGMA_RM_DEVICE_DATA: {
327             SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
328             if (naturalStore == nullptr) {
329                 return -E_INVALID_DB;
330             }
331             auto deviceName = static_cast<std::string *>(parameter);
332             errCode = naturalStore->RemoveDeviceData(*deviceName, false, false);
333             break;
334         }
335         case PRAGMA_GET_IDENTIFIER_OF_DEVICE: {
336             if (parameter == nullptr) {
337                 return -E_INVALID_ARGS;
338             }
339             return CalcHashDevID(*(static_cast<PragmaDeviceIdentifier *>(parameter)));
340         }
341         case PRAGMA_GET_DEVICE_IDENTIFIER_OF_ENTRY:
342             return GetDeviceIdentifier(static_cast<PragmaEntryDeviceIdentifier *>(parameter));
343         case PRAGMA_PUBLISH_LOCAL:
344             return PragmaPublish(parameter);
345         case PRAGMA_UNPUBLISH_SYNC:
346             errCode = PragmaUnpublish(parameter);
347             break;
348         case PRAGMA_SET_AUTO_LIFE_CYCLE:
349             return PragmaSetAutoLifeCycle(static_cast<uint32_t *>(parameter));
350         case PRAGMA_RESULT_SET_CACHE_MODE:
351             return PragmaResultSetCacheMode(parameter);
352         case PRAGMA_RESULT_SET_CACHE_MAX_SIZE:
353             return PragmaResultSetCacheMaxSize(parameter);
354         case PRAGMA_TRIGGER_TO_MIGRATE_DATA:
355             return PragmaTriggerToMigrateData(*static_cast<SecurityOption *>(parameter));
356         case PRAGMA_SET_MAX_LOG_LIMIT:
357             return PragmaSetMaxLogSize(static_cast<uint64_t *>(parameter));
358         case PRAGMA_EXEC_CHECKPOINT:
359             return ForceCheckPoint();
360         default:
361             // Call Pragma() of super class.
362             errCode = SyncAbleKvDBConnection::Pragma(cmd, parameter);
363             break;
364     }
365 
366     return errCode;
367 }
368 
TranslateObserverModeToEventTypes(unsigned mode,std::list<int> & eventTypes) const369 int SQLiteSingleVerNaturalStoreConnection::TranslateObserverModeToEventTypes(unsigned mode,
370     std::list<int> &eventTypes) const
371 {
372     int errCode = E_OK;
373     switch (mode) {
374         case static_cast<unsigned>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT):
375             eventTypes.push_back(static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT));
376             break;
377         case static_cast<unsigned>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT):
378             eventTypes.push_back(static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
379             break;
380         case (static_cast<unsigned>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT) |
381             static_cast<unsigned>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT)):
382             eventTypes.push_back(static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT));
383             eventTypes.push_back(static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
384             break;
385         case static_cast<unsigned>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT):
386             eventTypes.push_back(
387                 static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
388             break;
389         default:
390             errCode = -E_NOT_SUPPORT;
391             break;
392     }
393     return errCode;
394 }
395 
ClearConflictNotifierCount()396 void SQLiteSingleVerNaturalStoreConnection::ClearConflictNotifierCount()
397 {
398     uint32_t conflictType = static_cast<unsigned>(conflictType_);
399     if ((conflictType & static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY)) != 0) {
400         (void)kvDB_->UnregisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY);
401     }
402     if ((conflictType & static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG)) != 0) {
403         (void)kvDB_->UnregisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG);
404     }
405     if ((conflictType & static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL)) != 0) {
406         (void)kvDB_->UnregisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL);
407     }
408     return;
409 }
410 
ResetConflictNotifierCount(int target)411 void SQLiteSingleVerNaturalStoreConnection::ResetConflictNotifierCount(int target)
412 {
413     // Clear the old conflict type function.
414     ClearConflictNotifierCount();
415 
416     LOGD("Conflict type:%d to %d", conflictType_, target);
417     // Add the new conflict type function.
418     AddConflictNotifierCount(target);
419     conflictType_ = target;
420 }
421 
AddConflictNotifierCount(int target)422 void SQLiteSingleVerNaturalStoreConnection::AddConflictNotifierCount(int target)
423 {
424     LOGD("Conflict type:%u vs %u", conflictType_, target);
425     // Add the new conflict type function.
426     uint32_t targetTemp = static_cast<uint32_t>(target);
427     if ((targetTemp & static_cast<uint32_t>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY)) != 0) {
428         (void)kvDB_->RegisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY);
429     }
430     if ((targetTemp & static_cast<uint32_t>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG)) != 0) {
431         (void)kvDB_->RegisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG);
432     }
433     if ((targetTemp & static_cast<uint32_t>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL)) != 0) {
434         (void)kvDB_->RegisterFunction(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL);
435     }
436 }
437 
SetConflictNotifier(int conflictType,const KvDBConflictAction & action)438 int SQLiteSingleVerNaturalStoreConnection::SetConflictNotifier(int conflictType,
439     const KvDBConflictAction &action)
440 {
441     std::lock_guard<std::mutex> lock(conflictMutex_);
442     if (!action && conflictListener_ == nullptr) {
443         return -E_INVALID_ARGS;
444     }
445     if (kvDB_ == nullptr) {
446         return -E_INVALID_DB;
447     }
448 
449     // prevent the rekey operation.
450     if (isExclusive_.load()) {
451         return -E_BUSY;
452     }
453 
454     int targetType = 0;
455     NotificationChain::Listener *listener = nullptr;
456     if (action) {
457         int errCode = E_OK;
458         Key key;
459         listener = RegisterSpecialListener(
460             static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT), key, action, true,
461             errCode);
462         if (listener == nullptr) {
463             LOGE("Register Conflict listener failed:'%d'.", errCode);
464             return errCode;
465         }
466         targetType = conflictType;
467     }
468 
469     ResetConflictNotifierCount(targetType);
470     // drop the old listener.
471     if (conflictListener_ != nullptr) {
472         conflictListener_->Drop(true);
473     }
474     conflictListener_ = listener;
475     return E_OK;
476 }
477 
Rekey(const CipherPassword & passwd)478 int SQLiteSingleVerNaturalStoreConnection::Rekey(const CipherPassword &passwd)
479 {
480     if (IsFileAccessControlled()) {
481         LOGE("Forbid Rekey when screen locked and security label [%d]!", kvDB_->GetMyProperties().GetSecLabel());
482         return -E_NOT_SUPPORT;
483     }
484     std::lock_guard<std::mutex> lock(rekeyMutex_);
485     int errCode = CheckMonoStatus(OperatePerm::REKEY_MONOPOLIZE_PERM);
486     if (errCode != E_OK) {
487         return errCode;
488     }
489     LOGI("Begin rekey operation");
490     errCode = kvDB_->Rekey(passwd);
491     GenericKvDBConnection::ResetExclusiveStatus();
492     kvDB_->ReEnableConnection(OperatePerm::REKEY_MONOPOLIZE_PERM);
493     EnableManualSync();
494     LOGI("End rekey operation errCode = [%d]", errCode);
495     return errCode;
496 }
497 
Export(const std::string & filePath,const CipherPassword & passwd)498 int SQLiteSingleVerNaturalStoreConnection::Export(const std::string &filePath, const CipherPassword &passwd)
499 {
500     if (kvDB_ == nullptr) {
501         return -E_INVALID_DB;
502     }
503 
504     if (IsFileAccessControlled()) {
505         LOGE("Forbid Export when screen locked and security label [%d] file lock state [%d]",
506             kvDB_->GetMyProperties().GetSecLabel(), RuntimeContext::GetInstance()->IsAccessControlled());
507         return -E_NOT_SUPPORT;
508     } // Avoid abnormal branch handling without affecting the business
509     return kvDB_->Export(filePath, passwd);
510 }
511 
Import(const std::string & filePath,const CipherPassword & passwd)512 int SQLiteSingleVerNaturalStoreConnection::Import(const std::string &filePath, const CipherPassword &passwd)
513 {
514     if (IsFileAccessControlled()) {
515         LOGE("Forbid Import when screen locked and security label [%d]!", kvDB_->GetMyProperties().GetSecLabel());
516         return -E_NOT_SUPPORT;
517     }
518 
519     std::lock_guard<std::mutex> lock(importMutex_);
520     int errCode = CheckMonoStatus(OperatePerm::IMPORT_MONOPOLIZE_PERM);
521     if (errCode != E_OK) {
522         return errCode;
523     }
524     errCode = kvDB_->Import(filePath, passwd);
525     GenericKvDBConnection::ResetExclusiveStatus();
526     kvDB_->ReEnableConnection(OperatePerm::IMPORT_MONOPOLIZE_PERM);
527     EnableManualSync();
528     if (errCode == E_OK) {
529         kvDB_->ResetSyncStatus();
530     }
531     return errCode;
532 }
533 
GetResultSet(const IOption & option,const Key & keyPrefix,IKvDBResultSet * & resultSet) const534 int SQLiteSingleVerNaturalStoreConnection::GetResultSet(const IOption &option, const Key &keyPrefix,
535     IKvDBResultSet *&resultSet) const
536 {
537     // need to check if the transaction started
538     if (transactionExeFlag_.load()) {
539         LOGD("Transaction started already.");
540         return -E_BUSY;
541     }
542 
543     // maximum of result set size is 4
544     std::lock_guard<std::mutex> lock(kvDbResultSetsMutex_);
545     if (kvDbResultSets_.size() >= MAX_RESULT_SET_SIZE) {
546         LOGE("Over max result set size");
547         return -E_MAX_LIMITS;
548     }
549 
550     int errCode = CheckReadDataControlled();
551     if (errCode != E_OK) {
552         LOGE("[GetResultSet][keyPrefix] Existed cache database can not read data, errCode = [%d]!", errCode);
553         return errCode;
554     }
555 
556     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
557     if (naturalStore == nullptr) {
558         return -E_INVALID_DB;
559     }
560     bool isMemDb = naturalStore->GetMyProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false);
561     resultSet = new (std::nothrow) SQLiteSingleVerResultSet(naturalStore, keyPrefix,
562         SQLiteSingleVerResultSet::Option{cacheModeForNewResultSet_.load(), cacheMaxSizeForNewResultSet_.load()});
563     if (resultSet == nullptr) {
564         LOGE("Create single version result set failed.");
565         return -E_OUT_OF_MEMORY;
566     }
567     errCode = resultSet->Open(isMemDb);
568     if (errCode != E_OK) {
569         delete resultSet;
570         resultSet = nullptr;
571         LOGE("Open result set failed.");
572         return errCode;
573     }
574     kvDbResultSets_.insert(resultSet);
575     return E_OK;
576 }
577 
GetResultSet(const IOption & option,const Query & query,IKvDBResultSet * & resultSet) const578 int SQLiteSingleVerNaturalStoreConnection::GetResultSet(const IOption &option, const Query &query,
579     IKvDBResultSet *&resultSet) const
580 {
581     // need to check if the transaction started
582     if (transactionExeFlag_.load()) {
583         LOGD("Transaction started already.");
584         return -E_BUSY;
585     }
586 
587     // maximum of result set size is 4
588     std::lock_guard<std::mutex> lock(kvDbResultSetsMutex_);
589     if (kvDbResultSets_.size() >= MAX_RESULT_SET_SIZE) {
590         LOGE("Over max result set size");
591         return -E_MAX_LIMITS;
592     }
593 
594     int errCode = CheckReadDataControlled();
595     if (errCode != E_OK) {
596         LOGE("[GetResultSet][query] Existed cache database can not read data, errCode = [%d]!", errCode);
597         return errCode;
598     }
599 
600     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>(); // Guarantee not nullptr
601     QueryObject queryObj(query);
602     // In readOnly mode, forbidden all schema related query
603     if (CheckWritePermission() == E_OK) {
604         const SchemaObject &schemaObjRef = naturalStore->GetSchemaObjectConstRef();
605         queryObj.SetSchema(schemaObjRef);
606     }
607     if (((queryObj.GetSortType() != SortType::NONE) && !queryObj.IsQueryOnlyByKey())
608         || queryObj.IsQueryByRange()) {
609         LOGE("[GetResultSet][query] timestamp sort only support prefixKey and not support range search");
610         return -E_NOT_SUPPORT;
611     }
612     bool isMemDb = naturalStore->GetMyProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false);
613     resultSet = new (std::nothrow) SQLiteSingleVerResultSet(naturalStore, queryObj,
614         SQLiteSingleVerResultSet::Option{cacheModeForNewResultSet_.load(), cacheMaxSizeForNewResultSet_.load()});
615     if (resultSet == nullptr) {
616         LOGE("Create single version result set failed.");
617         return -E_OUT_OF_MEMORY;
618     }
619     errCode = resultSet->Open(isMemDb);
620     if (errCode != E_OK) {
621         delete resultSet;
622         resultSet = nullptr;
623         LOGE("Open result set failed.");
624         return errCode;
625     }
626     kvDbResultSets_.insert(resultSet);
627     return E_OK;
628 }
629 
ReleaseResultSet(IKvDBResultSet * & resultSet)630 void SQLiteSingleVerNaturalStoreConnection::ReleaseResultSet(IKvDBResultSet *&resultSet)
631 {
632     std::lock_guard<std::mutex> lock(kvDbResultSetsMutex_);
633     if (resultSet == nullptr) {
634         return;
635     }
636     resultSet->Close();
637     kvDbResultSets_.erase(resultSet);
638     delete resultSet;
639     resultSet = nullptr;
640     return;
641 }
642 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)643 int SQLiteSingleVerNaturalStoreConnection::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
644 {
645     if (kvDB_ == nullptr) {
646         return -E_INVALID_DB;
647     }
648     return static_cast<SQLiteSingleVerNaturalStore *>(kvDB_)->RegisterLifeCycleCallback(notifier);
649 }
650 
PreClose()651 int SQLiteSingleVerNaturalStoreConnection::PreClose()
652 {
653     // check if result set closed
654     {
655         std::lock_guard<std::mutex> kvDbResultLock(kvDbResultSetsMutex_);
656         if (kvDbResultSets_.size() > 0) {
657             LOGE("The connection have [%zu] active result set, can not close.", kvDbResultSets_.size());
658             return -E_BUSY;
659         }
660     }
661 
662     // check if transaction closed
663     {
664         std::lock_guard<std::mutex> transactionLock(transactionMutex_);
665         if (writeHandle_ != nullptr) {
666             LOGW("Transaction started, need to rollback before close.");
667             int errCode = RollbackInner();
668             if (errCode != E_OK) {
669                 LOGE("Rollback transaction failed, %d.", errCode);
670             }
671             ReleaseExecutor(writeHandle_);
672         }
673     }
674 
675     // Clear the conflict type function.
676     {
677         std::lock_guard<std::mutex> lock(conflictMutex_);
678         ClearConflictNotifierCount();
679         conflictType_ = 0;
680     }
681     return E_OK;
682 }
683 
CheckIntegrity() const684 int SQLiteSingleVerNaturalStoreConnection::CheckIntegrity() const
685 {
686     int errCode = E_OK;
687     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
688     if (handle == nullptr) {
689         LOGW("Failed to get the executor for the integrity check.");
690         return errCode;
691     }
692 
693     errCode = handle->CheckIntegrity();
694     ReleaseExecutor(handle);
695     return errCode;
696 }
697 
PragmaSetMaxLogSize(uint64_t * limit)698 int SQLiteSingleVerNaturalStoreConnection::PragmaSetMaxLogSize(uint64_t *limit)
699 {
700     if (limit == nullptr) {
701         return -E_INVALID_ARGS;
702     }
703     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
704     if (naturalStore == nullptr) {
705         LOGE("[SingleVerConnection] db is nullptr for max log limit set.");
706         return -E_INVALID_DB;
707     }
708     if (*limit > DBConstant::MAX_LOG_SIZE_HIGH || *limit < DBConstant::MAX_LOG_SIZE_LOW) {
709         return -E_INVALID_ARGS;
710     }
711     return naturalStore->SetMaxLogSize(*limit);
712 }
713 
ForceCheckPoint() const714 int SQLiteSingleVerNaturalStoreConnection::ForceCheckPoint() const
715 {
716     int errCode = E_OK;
717     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
718     if (handle == nullptr) {
719         LOGW("Failed to get the executor for the checkpoint.");
720         return errCode;
721     }
722 
723     errCode = handle->ForceCheckPoint();
724     ReleaseExecutor(handle);
725     return errCode;
726 }
727 
CheckMonoStatus(OperatePerm perm)728 int SQLiteSingleVerNaturalStoreConnection::CheckMonoStatus(OperatePerm perm)
729 {
730     // 1. Get the connection number
731     if (kvDB_ == nullptr) {
732         return -E_INVALID_DB;
733     }
734     int errCode = DisableManualSync();
735     if (errCode != E_OK) {
736         LOGE("In manual sync");
737         return -E_BUSY;
738     }
739 
740     // 2. check the result set number
741     {
742         std::lock_guard<std::mutex> kvDbResultLock(kvDbResultSetsMutex_);
743         if (kvDbResultSets_.size() > 0) {
744             LOGE("Active result set exist.");
745             EnableManualSync();
746             return -E_BUSY;
747         }
748     }
749     // 1. Get the connection number, and get the right to do the rekey operation.
750     errCode = kvDB_->TryToDisableConnection(perm);
751     if (errCode != E_OK) {
752         // If precheck failed, it means that there are more than one connection.
753         // No need reset the condition for the scene.
754         LOGE("More than one connection");
755         EnableManualSync();
756         return errCode;
757     }
758     // 2. Check the observer list.
759     errCode = GenericKvDBConnection::PreCheckExclusiveStatus();
760     if (errCode != E_OK) {
761         kvDB_->ReEnableConnection(perm);
762         LOGE("Observer prevents.");
763         EnableManualSync();
764         return errCode;
765     }
766 
767     // 3. Check the conflict notifier.
768     {
769         std::lock_guard<std::mutex> conflictLock(conflictMutex_);
770         if (conflictListener_ != nullptr) {
771             errCode = -E_BUSY;
772             GenericKvDBConnection::ResetExclusiveStatus();
773             kvDB_->ReEnableConnection(perm);
774             LOGE("Conflict notifier prevents");
775             EnableManualSync();
776             return errCode;
777         }
778     }
779     return E_OK;
780 }
781 
GetDeviceIdentifier(PragmaEntryDeviceIdentifier * identifier)782 int SQLiteSingleVerNaturalStoreConnection::GetDeviceIdentifier(PragmaEntryDeviceIdentifier *identifier)
783 {
784     if (identifier == nullptr) {
785         return -E_INVALID_ARGS;
786     }
787 
788     if (identifier->key.empty() || identifier->key.size() > DBConstant::MAX_VALUE_SIZE) {
789         return -E_INVALID_ARGS;
790     }
791 
792     int errCode = E_OK;
793     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
794     if (handle == nullptr) {
795         return errCode;
796     }
797 
798     errCode = handle->GetDeviceIdentifier(identifier);
799     ReleaseExecutor(handle);
800     return errCode;
801 }
802 
PutBatchInner(const IOption & option,const std::vector<Entry> & entries)803 int SQLiteSingleVerNaturalStoreConnection::PutBatchInner(const IOption &option, const std::vector<Entry> &entries)
804 {
805     DBDfxAdapter::StartTracing();
806     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
807     if (naturalStore == nullptr) {
808         return -E_INVALID_DB;
809     }
810     // check whether sync started to get SystemTime
811     naturalStore->WakeUpSyncer();
812     std::lock_guard<std::mutex> lock(transactionMutex_);
813     bool isAuto = false;
814     int errCode = E_OK;
815     if (writeHandle_ == nullptr) {
816         isAuto = true;
817         errCode = StartTransactionInner(TransactType::IMMEDIATE);
818         if (errCode != E_OK) {
819             DBDfxAdapter::FinishTracing();
820             return errCode;
821         }
822     }
823     uint32_t len = 0;
824     if (!CheckAndGetEntryLen(entries, (DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS - transactionEntryLen_), len)) {
825         DBDfxAdapter::FinishTracing();
826         return -E_MAX_LIMITS;
827     }
828 
829     if (option.dataType == IOption::SYNC_DATA) {
830         errCode = SaveSyncEntries(entries);
831     } else {
832         errCode = SaveLocalEntries(entries);
833     }
834     if (errCode == E_OK) {
835         transactionEntryLen_ += len;
836     }
837 
838     if (isAuto) {
839         if (errCode == E_OK) {
840             errCode = CommitInner();
841         } else {
842             int innerCode = RollbackInner();
843             errCode = (innerCode != E_OK) ? innerCode : errCode;
844         }
845     }
846     DBDfxAdapter::FinishTracing();
847     return errCode;
848 }
849 
DeleteBatchInner(const IOption & option,const std::vector<Key> & keys)850 int SQLiteSingleVerNaturalStoreConnection::DeleteBatchInner(const IOption &option, const std::vector<Key> &keys)
851 {
852     DBDfxAdapter::StartTracing();
853     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
854     if (naturalStore == nullptr) {
855         return -E_INVALID_DB;
856     }
857     // check whether sync started to get SystemTime
858     naturalStore->WakeUpSyncer();
859     std::lock_guard<std::mutex> lock(transactionMutex_);
860     bool isAuto = false;
861     int errCode = E_OK;
862 
863     if (writeHandle_ == nullptr) {
864         isAuto = true;
865         errCode = StartTransactionInner(TransactType::IMMEDIATE);
866         if (errCode != E_OK) {
867             DBDfxAdapter::FinishTracing();
868             return errCode;
869         }
870     }
871     uint32_t len = 0;
872     if (!CheckAndGetKeyLen(keys, (DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS - transactionEntryLen_), len)) {
873         DBDfxAdapter::FinishTracing();
874         return -E_MAX_LIMITS;
875     }
876 
877     if (option.dataType == IOption::SYNC_DATA) {
878         errCode = DeleteSyncEntries(keys);
879     } else {
880         errCode = DeleteLocalEntries(keys);
881     }
882     if (errCode == E_OK) {
883         transactionEntryLen_ += len;
884     }
885 
886     if (isAuto) {
887         if (errCode == E_OK) {
888             errCode = CommitInner();
889         } else {
890             int innerCode = RollbackInner();
891             errCode = (innerCode != E_OK) ? innerCode : errCode;
892         }
893     }
894     DBDfxAdapter::FinishTracing();
895     return errCode;
896 }
897 
SaveSyncEntries(const std::vector<Entry> & entries)898 int SQLiteSingleVerNaturalStoreConnection::SaveSyncEntries(const std::vector<Entry> &entries)
899 {
900     int errCode = E_OK;
901     for (const auto &entry : entries) {
902         errCode = SaveEntry(entry, false);
903         if (errCode != E_OK) {
904             break;
905         }
906     }
907     return errCode;
908 }
909 
SaveLocalEntries(const std::vector<Entry> & entries)910 int SQLiteSingleVerNaturalStoreConnection::SaveLocalEntries(const std::vector<Entry> &entries)
911 {
912     int errCode = E_OK;
913     for (const auto &entry : entries) {
914         errCode = SaveLocalEntry(entry, false);
915         if (errCode != E_OK) {
916             break;
917         }
918     }
919     return errCode;
920 }
921 
DeleteSyncEntries(const std::vector<Key> & keys)922 int SQLiteSingleVerNaturalStoreConnection::DeleteSyncEntries(const std::vector<Key> &keys)
923 {
924     int errCode = E_OK;
925     for (const auto &key : keys) {
926         Entry entry;
927         DBCommon::CalcValueHash(key, entry.key);
928         errCode = SaveEntry(entry, true);
929         if ((errCode != E_OK) && (errCode != -E_NOT_FOUND)) {
930             LOGE("[DeleteSyncEntries] Delete data err:%d", errCode);
931             break;
932         }
933     }
934     return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
935 }
936 
DeleteLocalEntries(const std::vector<Key> & keys)937 int SQLiteSingleVerNaturalStoreConnection::DeleteLocalEntries(const std::vector<Key> &keys)
938 {
939     int errCode = E_OK;
940     for (const auto &key : keys) {
941         Entry entry = {key, Value()};
942         errCode = SaveLocalEntry(entry, true);
943         if ((errCode != E_OK) && (errCode != -E_NOT_FOUND)) {
944             LOGE("[DeleteLocalEntries] Delete data err:%d", errCode);
945             break;
946         }
947     }
948     return (errCode == -E_NOT_FOUND) ? E_OK : errCode;
949 }
950 
951 // This function currently only be called in local procedure to change sync_data table, do not use in sync procedure.
952 // It will check and amend value when need if it is a schema database. return error if some value disagree with the
953 // schema. But in sync procedure, we just neglect the value that disagree with schema.
SaveEntry(const Entry & entry,bool isDelete,Timestamp timestamp)954 int SQLiteSingleVerNaturalStoreConnection::SaveEntry(const Entry &entry, bool isDelete, Timestamp timestamp)
955 {
956     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
957     if (naturalStore == nullptr) {
958         return -E_INVALID_DB;
959     }
960 
961     DataItem dataItem;
962     dataItem.key = entry.key;
963     dataItem.value = entry.value;
964     dataItem.flag = DataItem::LOCAL_FLAG;
965     if (isDelete) {
966         dataItem.flag |= DataItem::DELETE_FLAG;
967     } else {
968         int errCode = CheckAmendValueContentForLocalProcedure(dataItem.value, dataItem.value);
969         if (errCode != E_OK) {
970             LOGE("[SqlSinCon][SaveEntry] CheckAmendValue fail, errCode=%d.", errCode);
971             return errCode;
972         }
973     }
974     RecordTimeIntoDataItem(timestamp, dataItem, *naturalStore);
975     if (IsExtendedCacheDBMode()) {
976         uint64_t recordVersion = naturalStore->GetCacheRecordVersion();
977         return SaveEntryInCacheMode(dataItem, recordVersion);
978     } else {
979         return SaveEntryNormally(dataItem);
980     }
981 }
982 
SaveLocalEntry(const Entry & entry,bool isDelete)983 int SQLiteSingleVerNaturalStoreConnection::SaveLocalEntry(const Entry &entry, bool isDelete)
984 {
985     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
986     if (naturalStore == nullptr) {
987         return -E_INVALID_DB;
988     }
989 
990     LocalDataItem dataItem;
991     dataItem.key = entry.key;
992     dataItem.value = entry.value;
993     (void)DBCommon::CalcValueHash(entry.key, dataItem.hashKey);
994     if (isDelete) {
995         dataItem.flag = DataItem::DELETE_FLAG;
996     }
997     dataItem.timestamp = naturalStore->GetCurrentTimestamp();
998     LOGD("Timestamp is %" PRIu64, dataItem.timestamp);
999 
1000     if (IsCacheDBMode()) {
1001         return SaveLocalItemInCacheMode(dataItem);
1002     } else {
1003         return SaveLocalItem(dataItem);
1004     }
1005 }
1006 
SaveLocalItem(const LocalDataItem & dataItem) const1007 int SQLiteSingleVerNaturalStoreConnection::SaveLocalItem(const LocalDataItem &dataItem) const
1008 {
1009     int errCode = E_OK;
1010     if ((dataItem.flag & DataItem::DELETE_FLAG) == 0) {
1011         errCode = writeHandle_->PutKvData(SingleVerDataType::LOCAL_TYPE_SQLITE, dataItem.key, dataItem.value,
1012             dataItem.timestamp, localCommittedData_);
1013     } else {
1014         Value value;
1015         Timestamp localTimestamp = 0;
1016         errCode = writeHandle_->DeleteLocalKvData(dataItem.key, localCommittedData_, value, localTimestamp);
1017     }
1018     return errCode;
1019 }
1020 
SaveLocalItemInCacheMode(const LocalDataItem & dataItem) const1021 int SQLiteSingleVerNaturalStoreConnection::SaveLocalItemInCacheMode(const LocalDataItem &dataItem) const
1022 {
1023     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1024     if (naturalStore == nullptr) {
1025         return -E_INVALID_DB;
1026     }
1027 
1028     int errCode = writeHandle_->PutLocalDataToCacheDB(dataItem);
1029     if (errCode != E_OK) {
1030         LOGE("[PutLocalEntries] Put local data to cacheDB err:%d", errCode);
1031     }
1032     return errCode;
1033 }
1034 
SaveEntryNormally(DataItem & dataItem)1035 int SQLiteSingleVerNaturalStoreConnection::SaveEntryNormally(DataItem &dataItem)
1036 {
1037     int errCode = writeHandle_->PrepareForSavingData(SingleVerDataType::SYNC_TYPE);
1038     if (errCode != E_OK) {
1039         LOGE("Prepare the saving sync data failed:%d", errCode);
1040         return errCode;
1041     }
1042 
1043     Timestamp maxTimestamp = 0;
1044     DeviceInfo deviceInfo = {true, ""};
1045     errCode = writeHandle_->SaveSyncDataItem(dataItem, deviceInfo, maxTimestamp, committedData_);
1046     if (errCode == E_OK) {
1047         if (maxTimestamp > currentMaxTimestamp_) {
1048             currentMaxTimestamp_ = maxTimestamp;
1049         }
1050     } else {
1051         LOGE("Save entry failed, err:%d", errCode);
1052     }
1053     return errCode;
1054 }
1055 
SaveEntryInCacheMode(DataItem & dataItem,uint64_t recordVersion)1056 int SQLiteSingleVerNaturalStoreConnection::SaveEntryInCacheMode(DataItem &dataItem, uint64_t recordVersion)
1057 {
1058     int errCode = writeHandle_->PrepareForSavingCacheData(SingleVerDataType::SYNC_TYPE);
1059     if (errCode != E_OK) {
1060         LOGE("Prepare the saving sync data failed:%d", errCode);
1061         return errCode;
1062     }
1063 
1064     Timestamp maxTimestamp = 0;
1065     DeviceInfo deviceInfo = {true, ""};
1066     QueryObject query(Query::Select());
1067     errCode = writeHandle_->SaveSyncDataItemInCacheMode(dataItem, deviceInfo, maxTimestamp, recordVersion, query);
1068     if (errCode == E_OK) {
1069         if (maxTimestamp > currentMaxTimestamp_) {
1070             currentMaxTimestamp_ = maxTimestamp;
1071         }
1072     } else {
1073         LOGE("Save entry failed, err:%d", errCode);
1074     }
1075     return errCode;
1076 }
1077 
CheckDataStatus(const Key & key,const Value & value,bool isDelete) const1078 int SQLiteSingleVerNaturalStoreConnection::CheckDataStatus(const Key &key, const Value &value, bool isDelete) const
1079 {
1080     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1081     if (naturalStore == nullptr) {
1082         return -E_INVALID_DB;
1083     }
1084 
1085     return naturalStore->CheckDataStatus(key, value, isDelete);
1086 }
1087 
CheckWritePermission() const1088 int SQLiteSingleVerNaturalStoreConnection::CheckWritePermission() const
1089 {
1090     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1091     if (naturalStore == nullptr) {
1092         return -E_INVALID_DB;
1093     }
1094 
1095     if (!naturalStore->CheckWritePermission()) {
1096         return -E_READ_ONLY;
1097     }
1098     return E_OK;
1099 }
1100 
CheckSyncEntriesValid(const std::vector<Entry> & entries) const1101 int SQLiteSingleVerNaturalStoreConnection::CheckSyncEntriesValid(const std::vector<Entry> &entries) const
1102 {
1103     uint32_t len = 0;
1104     if (!CheckAndGetEntryLen(entries, DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS, len)) {
1105         return -E_INVALID_ARGS;
1106     }
1107 
1108     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1109     if (naturalStore == nullptr) {
1110         return -E_INVALID_DB;
1111     }
1112 
1113     if (!naturalStore->CheckWritePermission()) {
1114         return -E_READ_ONLY;
1115     }
1116 
1117     for (const auto &entry : entries) {
1118         int errCode = naturalStore->CheckDataStatus(entry.key, entry.value, false);
1119         if (errCode != E_OK) {
1120             return errCode;
1121         }
1122     }
1123     return E_OK;
1124 }
1125 
CheckSyncKeysValid(const std::vector<Key> & keys) const1126 int SQLiteSingleVerNaturalStoreConnection::CheckSyncKeysValid(const std::vector<Key> &keys) const
1127 {
1128     uint32_t len = 0;
1129     if (!CheckAndGetKeyLen(keys, DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS, len)) {
1130         return -E_INVALID_ARGS;
1131     }
1132     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1133     if (naturalStore == nullptr) {
1134         return -E_INVALID_DB;
1135     }
1136 
1137     if (!naturalStore->CheckWritePermission()) {
1138         return -E_READ_ONLY;
1139     }
1140 
1141     for (const auto &key : keys) {
1142         int errCode = naturalStore->CheckDataStatus(key, {}, true);
1143         if (errCode != E_OK) {
1144             return errCode;
1145         }
1146     }
1147     return E_OK;
1148 }
1149 
CheckLocalEntriesValid(const std::vector<Entry> & entries) const1150 int SQLiteSingleVerNaturalStoreConnection::CheckLocalEntriesValid(const std::vector<Entry> &entries) const
1151 {
1152     uint32_t len = 0;
1153     if (!CheckAndGetEntryLen(entries, DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS, len)) {
1154         return -E_INVALID_ARGS;
1155     }
1156 
1157     GenericKvDB *naturalStore = GetDB<GenericKvDB>();
1158     if (naturalStore == nullptr) {
1159         return -E_INVALID_DB;
1160     }
1161 
1162     if (!naturalStore->GenericKvDB::CheckWritePermission()) {
1163         return -E_READ_ONLY;
1164     }
1165 
1166     for (const auto &entry : entries) {
1167         int errCode = naturalStore->GenericKvDB::CheckDataStatus(entry.key, entry.value, false);
1168         if (errCode != E_OK) {
1169             return errCode;
1170         }
1171     }
1172     return E_OK;
1173 }
1174 
CheckLocalKeysValid(const std::vector<Key> & keys) const1175 int SQLiteSingleVerNaturalStoreConnection::CheckLocalKeysValid(const std::vector<Key> &keys) const
1176 {
1177     uint32_t len = 0;
1178     if (!CheckAndGetKeyLen(keys, DBConstant::MAX_TRANSACTION_KEY_VALUE_LENS, len)) {
1179         return -E_INVALID_ARGS;
1180     }
1181     GenericKvDB *naturalStore = GetDB<GenericKvDB>();
1182     if (naturalStore == nullptr) {
1183         return -E_INVALID_DB;
1184     }
1185 
1186     if (!naturalStore->GenericKvDB::CheckWritePermission()) {
1187         return -E_READ_ONLY;
1188     }
1189 
1190     for (const auto &key : keys) {
1191         int errCode = naturalStore->GenericKvDB::CheckDataStatus(key, {}, true);
1192         if (errCode != E_OK) {
1193             return errCode;
1194         }
1195     }
1196     return E_OK;
1197 }
1198 
CommitAndReleaseNotifyData(SingleVerNaturalStoreCommitNotifyData * & committedData,bool isNeedCommit,int eventType)1199 void SQLiteSingleVerNaturalStoreConnection::CommitAndReleaseNotifyData(
1200     SingleVerNaturalStoreCommitNotifyData *&committedData, bool isNeedCommit, int eventType)
1201 {
1202     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1203     if ((naturalStore != nullptr) && (committedData != nullptr)) {
1204         if (isNeedCommit) {
1205             if (!committedData->IsChangedDataEmpty()) {
1206                 naturalStore->CommitNotify(eventType, committedData);
1207             }
1208             if (!committedData->IsConflictedDataEmpty()) {
1209                 naturalStore->CommitNotify(
1210                     static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
1211                     committedData);
1212             }
1213         }
1214     }
1215     ReleaseCommitData(committedData);
1216 }
1217 
StartTransactionInner(TransactType transType)1218 int SQLiteSingleVerNaturalStoreConnection::StartTransactionInner(TransactType transType)
1219 {
1220     if (IsExtendedCacheDBMode()) {
1221         return StartTransactionInCacheMode(transType);
1222     } else {
1223         return StartTransactionNormally(transType);
1224     }
1225 }
1226 
StartTransactionInCacheMode(TransactType transType)1227 int SQLiteSingleVerNaturalStoreConnection::StartTransactionInCacheMode(TransactType transType)
1228 {
1229     int errCode = E_OK;
1230     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
1231     if (handle == nullptr) {
1232         return errCode;
1233     }
1234     if (CheckLogOverLimit(handle)) {
1235         LOGW("Over the log limit");
1236         ReleaseExecutor(handle);
1237         return -E_LOG_OVER_LIMITS;
1238     }
1239     errCode = handle->StartTransaction(transType);
1240     if (errCode != E_OK) {
1241         ReleaseExecutor(handle);
1242         return errCode;
1243     }
1244 
1245     writeHandle_ = handle;
1246     transactionEntryLen_ = 0;
1247     return E_OK;
1248 }
1249 
StartTransactionNormally(TransactType transType)1250 int SQLiteSingleVerNaturalStoreConnection::StartTransactionNormally(TransactType transType)
1251 {
1252     int errCode = E_OK;
1253     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
1254     if (handle == nullptr) {
1255         return errCode;
1256     }
1257 
1258     errCode = kvDB_->TryToDisableConnection(OperatePerm::NORMAL_WRITE);
1259     if (errCode != E_OK) { // on operate rekey or import
1260         ReleaseExecutor(handle);
1261         LOGE("Start transaction failed, %d perm not normal", errCode);
1262         return errCode;
1263     }
1264 
1265     if (CheckLogOverLimit(handle)) {
1266         LOGW("Over the log limit");
1267         ReleaseExecutor(handle);
1268         return -E_LOG_OVER_LIMITS;
1269     }
1270 
1271     if (committedData_ == nullptr) {
1272         committedData_ = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1273         if (committedData_ == nullptr) {
1274             ReleaseExecutor(handle);
1275             return -E_OUT_OF_MEMORY;
1276         }
1277         InitConflictNotifiedFlag();
1278     }
1279     if (localCommittedData_ == nullptr) {
1280         localCommittedData_ = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1281         if (localCommittedData_ == nullptr) {
1282             ReleaseExecutor(handle);
1283             ReleaseCommitData(committedData_);
1284             return -E_OUT_OF_MEMORY;
1285         }
1286     }
1287     errCode = handle->StartTransaction(transType);
1288     if (errCode != E_OK) {
1289         ReleaseExecutor(handle);
1290         ReleaseCommitData(committedData_);
1291         ReleaseCommitData(localCommittedData_);
1292         return errCode;
1293     }
1294 
1295     writeHandle_ = handle;
1296     transactionEntryLen_ = 0;
1297     return E_OK;
1298 }
1299 
InitConflictNotifiedFlag()1300 void SQLiteSingleVerNaturalStoreConnection::InitConflictNotifiedFlag()
1301 {
1302     unsigned int conflictFlag = 0;
1303     if (kvDB_->GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY) != 0) {
1304         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY);
1305     }
1306     if (kvDB_->GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG) != 0) {
1307         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG);
1308     }
1309     if (kvDB_->GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL) != 0) {
1310         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL);
1311     }
1312 
1313     committedData_->SetConflictedNotifiedFlag(static_cast<int>(conflictFlag));
1314 }
1315 
CommitInner()1316 int SQLiteSingleVerNaturalStoreConnection::CommitInner()
1317 {
1318     bool isCacheOrMigrating = IsExtendedCacheDBMode();
1319 
1320     int errCode = writeHandle_->Commit();
1321     ReleaseExecutor(writeHandle_);
1322     transactionEntryLen_ = 0;
1323 
1324     if (!isCacheOrMigrating) {
1325         CommitAndReleaseNotifyData(committedData_, true,
1326             static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT));
1327         CommitAndReleaseNotifyData(localCommittedData_, true,
1328             static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
1329     }
1330     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1331     if (naturalStore == nullptr) {
1332         return -E_INVALID_DB;
1333     }
1334 
1335     if (isCacheOrMigrating) {
1336         naturalStore->IncreaseCacheRecordVersion();
1337     }
1338     return errCode;
1339 }
1340 
RollbackInner()1341 int SQLiteSingleVerNaturalStoreConnection::RollbackInner()
1342 {
1343     int errCode = writeHandle_->Rollback();
1344     transactionEntryLen_ = 0;
1345     currentMaxTimestamp_ = 0;
1346     if (!IsExtendedCacheDBMode()) {
1347         ReleaseCommitData(committedData_);
1348         ReleaseCommitData(localCommittedData_);
1349     }
1350     ReleaseExecutor(writeHandle_);
1351     return errCode;
1352 }
1353 
GetExecutor(bool isWrite,int & errCode) const1354 SQLiteSingleVerStorageExecutor *SQLiteSingleVerNaturalStoreConnection::GetExecutor(bool isWrite, int &errCode) const
1355 {
1356     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1357     if (naturalStore == nullptr) {
1358         errCode = -E_NOT_INIT;
1359         LOGE("[SingleVerConnection] the store is null");
1360         return nullptr;
1361     }
1362     errCode = naturalStore->TryHandle();
1363     if (errCode != E_OK) {
1364         return nullptr;
1365     }
1366     return naturalStore->GetHandle(isWrite, errCode);
1367 }
1368 
IsCacheDBMode() const1369 bool SQLiteSingleVerNaturalStoreConnection::IsCacheDBMode() const
1370 {
1371     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1372     if (naturalStore == nullptr) {
1373         LOGE("[SingleVerConnection] the store is null");
1374         return false;
1375     }
1376     return naturalStore->IsCacheDBMode();
1377 }
1378 
IsExtendedCacheDBMode() const1379 bool SQLiteSingleVerNaturalStoreConnection::IsExtendedCacheDBMode() const
1380 {
1381     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1382     if (naturalStore == nullptr) {
1383         LOGE("[SingleVerConnection] the store is null");
1384         return false;
1385     }
1386     return naturalStore->IsExtendedCacheDBMode();
1387 }
1388 
ReleaseExecutor(SQLiteSingleVerStorageExecutor * & executor) const1389 void SQLiteSingleVerNaturalStoreConnection::ReleaseExecutor(SQLiteSingleVerStorageExecutor *&executor) const
1390 {
1391     kvDB_->ReEnableConnection(OperatePerm::NORMAL_WRITE);
1392     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1393     if (naturalStore != nullptr) {
1394         naturalStore->ReleaseHandle(executor);
1395     }
1396 }
1397 
PublishLocal(const Key & key,bool deleteLocal,bool updateTimestamp,const KvStoreNbPublishAction & onConflict)1398 int SQLiteSingleVerNaturalStoreConnection::PublishLocal(const Key &key, bool deleteLocal, bool updateTimestamp,
1399     const KvStoreNbPublishAction &onConflict)
1400 {
1401     int errCode = CheckWritePermission();
1402     if (errCode != E_OK) {
1403         return errCode;
1404     }
1405 
1406     bool isNeedCallback = (onConflict != nullptr);
1407     SingleVerRecord localRecord;
1408     localRecord.key = key;
1409     SingleVerRecord syncRecord;
1410     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1411     if (naturalStore == nullptr) {
1412         return -E_INVALID_DB;
1413     }
1414     // check whether sync started to get SystemTime
1415     naturalStore->WakeUpSyncer();
1416     {
1417         if (IsTransactionStarted()) {
1418             return -E_NOT_SUPPORT;
1419         }
1420         std::lock_guard<std::mutex> lock(transactionMutex_);
1421         errCode = StartTransactionInner(TransactType::IMMEDIATE);
1422         if (errCode != E_OK) {
1423             return errCode;
1424         }
1425 
1426         SingleVerNaturalStoreCommitNotifyData *localCommittedData = nullptr;
1427         if (deleteLocal) {
1428             localCommittedData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1429             if (localCommittedData == nullptr) {
1430                 errCode = -E_OUT_OF_MEMORY;
1431             }
1432         }
1433         if (errCode == E_OK) {
1434             errCode = PublishInner(localCommittedData, updateTimestamp, localRecord, syncRecord, isNeedCallback);
1435         }
1436 
1437         if (errCode != E_OK || isNeedCallback) {
1438             int innerCode = RollbackInner();
1439             errCode = (innerCode != E_OK) ? innerCode : errCode;
1440         } else {
1441             errCode = CommitInner();
1442             if (errCode == E_OK) {
1443                 CommitAndReleaseNotifyData(localCommittedData, true,
1444                     static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
1445             }
1446         }
1447         ReleaseCommitData(localCommittedData);
1448     }
1449 
1450     // need to release the handle lock before callback invoked
1451     if (isNeedCallback) {
1452         return PublishLocalCallback(updateTimestamp, localRecord, syncRecord, onConflict);
1453     }
1454 
1455     return errCode;
1456 }
1457 
PublishLocalCallback(bool updateTimestamp,const SingleVerRecord & localRecord,const SingleVerRecord & syncRecord,const KvStoreNbPublishAction & onConflict)1458 int SQLiteSingleVerNaturalStoreConnection::PublishLocalCallback(bool updateTimestamp,
1459     const SingleVerRecord &localRecord, const SingleVerRecord &syncRecord, const KvStoreNbPublishAction &onConflict)
1460 {
1461     bool isLocalLastest = updateTimestamp ? true : (localRecord.timestamp > syncRecord.writeTimestamp);
1462     if ((syncRecord.flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG) {
1463         onConflict({localRecord.key, localRecord.value}, nullptr, isLocalLastest);
1464     } else {
1465         Entry syncEntry = {syncRecord.key, syncRecord.value};
1466         onConflict({localRecord.key, localRecord.value}, &syncEntry, isLocalLastest);
1467     }
1468     return E_OK;
1469 }
1470 
PublishInner(SingleVerNaturalStoreCommitNotifyData * committedData,bool updateTimestamp,SingleVerRecord & localRecord,SingleVerRecord & syncRecord,bool & isNeedCallback)1471 int SQLiteSingleVerNaturalStoreConnection::PublishInner(SingleVerNaturalStoreCommitNotifyData *committedData,
1472     bool updateTimestamp, SingleVerRecord &localRecord, SingleVerRecord &syncRecord, bool &isNeedCallback)
1473 {
1474     Key hashKey;
1475     int errCode = DBCommon::CalcValueHash(localRecord.key, hashKey);
1476     if (errCode != E_OK) {
1477         return errCode;
1478     }
1479 
1480     if (committedData != nullptr) {
1481         errCode = writeHandle_->DeleteLocalKvData(localRecord.key, committedData, localRecord.value,
1482             localRecord.timestamp);
1483         if (errCode != E_OK) {
1484             LOGE("Delete local kv data err:%d", errCode);
1485             return errCode;
1486         }
1487     } else {
1488         if (!writeHandle_->CheckIfKeyExisted(localRecord.key, true, localRecord.value, localRecord.timestamp)) {
1489             LOGE("Record not found.");
1490             return -E_NOT_FOUND;
1491         }
1492     }
1493 
1494     // begin to insert entry to sync table
1495     errCode = CheckDataStatus(localRecord.key, localRecord.value, false);
1496     if (errCode != E_OK) {
1497         return errCode;
1498     }
1499 
1500     errCode = writeHandle_->GetKvDataByHashKey(hashKey, syncRecord);
1501     if (errCode == E_OK) { // has conflict record
1502         if (isNeedCallback) {
1503             return errCode;
1504         }
1505         // fix conflict with LAST_WIN policy
1506         if (updateTimestamp) { // local win
1507             errCode = SaveEntry({localRecord.key, localRecord.value}, false);
1508         } else {
1509             if (localRecord.timestamp <= syncRecord.writeTimestamp) { // sync win
1510                 errCode = -E_STALE;
1511             } else {
1512                 errCode = SaveEntry({localRecord.key, localRecord.value}, false, localRecord.timestamp);
1513             }
1514         }
1515     } else {
1516         isNeedCallback = false;
1517         if (errCode == -E_NOT_FOUND) {
1518             errCode = SaveEntry({localRecord.key, localRecord.value}, false, localRecord.timestamp);
1519         }
1520     }
1521     return errCode;
1522 }
1523 
UnpublishToLocal(const Key & key,bool deletePublic,bool updateTimestamp)1524 int SQLiteSingleVerNaturalStoreConnection::UnpublishToLocal(const Key &key, bool deletePublic, bool updateTimestamp)
1525 {
1526     int errCode = CheckWritePermission();
1527     if (errCode != E_OK) {
1528         return errCode;
1529     }
1530 
1531     if (IsTransactionStarted()) {
1532         return -E_NOT_SUPPORT;
1533     }
1534     // check whether sync started to get SystemTime
1535     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1536     if (naturalStore != nullptr) {
1537         naturalStore->WakeUpSyncer();
1538     }
1539 
1540     std::lock_guard<std::mutex> lock(transactionMutex_);
1541 
1542     errCode = StartTransactionInner(TransactType::IMMEDIATE);
1543     if (errCode != E_OK) {
1544         return errCode;
1545     }
1546 
1547     Key hashKey;
1548     int innerErrCode = E_OK;
1549     SingleVerRecord syncRecord;
1550     std::pair<Key, Key> keyPair = { key, hashKey };
1551     SingleVerNaturalStoreCommitNotifyData *localCommittedData = nullptr;
1552     errCode = UnpublishInner(keyPair, localCommittedData, syncRecord, updateTimestamp, innerErrCode);
1553     if (errCode != E_OK) {
1554         goto END;
1555     }
1556 
1557     if (deletePublic && (syncRecord.flag & DataItem::DELETE_FLAG) != DataItem::DELETE_FLAG) {
1558         errCode = SaveEntry({keyPair.second, {}}, true);
1559     }
1560 
1561 END:
1562     // finalize
1563     if (errCode != E_OK) {
1564         int rollbackRet = RollbackInner();
1565         errCode = (rollbackRet != E_OK) ? rollbackRet : errCode;
1566     } else {
1567         errCode = CommitInner();
1568         if (errCode == E_OK) {
1569             CommitAndReleaseNotifyData(localCommittedData, true,
1570                 static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
1571         }
1572     }
1573     ReleaseCommitData(localCommittedData);
1574 
1575     return (errCode == E_OK) ? innerErrCode : errCode;
1576 }
1577 
UnpublishInner(std::pair<Key,Key> & keyPair,SingleVerNaturalStoreCommitNotifyData * & committedData,SingleVerRecord & syncRecord,bool updateTimestamp,int & innerErrCode)1578 int SQLiteSingleVerNaturalStoreConnection::UnpublishInner(std::pair<Key, Key> &keyPair,
1579     SingleVerNaturalStoreCommitNotifyData *&committedData, SingleVerRecord &syncRecord, bool updateTimestamp,
1580     int &innerErrCode)
1581 {
1582     int errCode = E_OK;
1583     auto &[key, hashKey] = keyPair;
1584     errCode = DBCommon::CalcValueHash(key, hashKey);
1585     if (errCode != E_OK) {
1586         return errCode;
1587     }
1588     errCode = writeHandle_->GetKvDataByHashKey(hashKey, syncRecord);
1589     if (errCode != E_OK) {
1590         return errCode;
1591     }
1592     syncRecord.key = key;
1593     int localOperation = static_cast<int>(LocalOperType::LOCAL_OPR_NONE);
1594     SingleVerRecord localRecord;
1595 
1596     innerErrCode = -E_LOCAL_DEFEAT;
1597     if (writeHandle_->CheckIfKeyExisted(syncRecord.key, true, localRecord.value, localRecord.timestamp)) {
1598         if ((syncRecord.flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG) {
1599             if (updateTimestamp || localRecord.timestamp <= syncRecord.writeTimestamp) { // sync win
1600                 innerErrCode = -E_LOCAL_DELETED;
1601                 localOperation = static_cast<int>(LocalOperType::LOCAL_OPR_DEL);
1602             }
1603         } else if (updateTimestamp || localRecord.timestamp <= syncRecord.writeTimestamp) { // sync win
1604             innerErrCode = -E_LOCAL_COVERED;
1605             localOperation = static_cast<int>(LocalOperType::LOCAL_OPR_PUT);
1606         }
1607     } else { // no conflict entry in local
1608         innerErrCode = E_OK;
1609         if ((syncRecord.flag & DataItem::DELETE_FLAG) != DataItem::DELETE_FLAG) {
1610             localOperation = static_cast<int>(LocalOperType::LOCAL_OPR_PUT);
1611         }
1612     }
1613 
1614     if (localOperation != static_cast<int>(LocalOperType::LOCAL_OPR_NONE)) {
1615         errCode = UnpublishOper(committedData, syncRecord, updateTimestamp, localOperation);
1616     }
1617 
1618     return errCode;
1619 }
1620 
UnpublishOper(SingleVerNaturalStoreCommitNotifyData * & committedData,const SingleVerRecord & syncRecord,bool updateTimestamp,int operType)1621 int SQLiteSingleVerNaturalStoreConnection::UnpublishOper(SingleVerNaturalStoreCommitNotifyData *&committedData,
1622     const SingleVerRecord &syncRecord, bool updateTimestamp, int operType)
1623 {
1624     committedData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1625     if (committedData == nullptr) {
1626         return -E_OUT_OF_MEMORY;
1627     }
1628 
1629     int errCode = E_OK;
1630     if (operType == static_cast<int>(LocalOperType::LOCAL_OPR_PUT)) {
1631         SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1632         if (naturalStore == nullptr) {
1633             return -E_INVALID_DB;
1634         }
1635 
1636         errCode = CheckDataStatus(syncRecord.key, syncRecord.value, false);
1637         if (errCode != E_OK) {
1638             return errCode;
1639         }
1640 
1641         Timestamp time = updateTimestamp ? naturalStore->GetCurrentTimestamp() : syncRecord.writeTimestamp;
1642         errCode = writeHandle_->PutKvData(SingleVerDataType::LOCAL_TYPE_SQLITE, syncRecord.key, syncRecord.value, time,
1643             committedData);
1644     } else if (operType == static_cast<int>(LocalOperType::LOCAL_OPR_DEL)) {
1645         Timestamp localTimestamp = 0;
1646         Value value;
1647         errCode = writeHandle_->DeleteLocalKvData(syncRecord.key, committedData, value, localTimestamp);
1648     }
1649 
1650     return errCode;
1651 }
1652 
ReleaseCommitData(SingleVerNaturalStoreCommitNotifyData * & committedData)1653 void SQLiteSingleVerNaturalStoreConnection::ReleaseCommitData(SingleVerNaturalStoreCommitNotifyData *&committedData)
1654 {
1655     if (committedData != nullptr) {
1656         committedData->DecObjRef(committedData);
1657         committedData = nullptr;
1658     }
1659 }
1660 
PragmaPublish(void * parameter)1661 int SQLiteSingleVerNaturalStoreConnection::PragmaPublish(void *parameter)
1662 {
1663     PragmaPublishInfo *info = static_cast<PragmaPublishInfo *>(parameter);
1664     if (info == nullptr) {
1665         return -E_INVALID_ARGS;
1666     }
1667     if (IsExtendedCacheDBMode()) {
1668         int err = IsCacheDBMode() ? -E_EKEYREVOKED : -E_BUSY;
1669         LOGE("[PragmaPublish]Existed cache database can not read data, errCode = [%d]!", err);
1670         return err;
1671     }
1672     return PublishLocal(info->key, info->deleteLocal, info->updateTimestamp, info->action);
1673 }
1674 
PragmaUnpublish(void * parameter)1675 int SQLiteSingleVerNaturalStoreConnection::PragmaUnpublish(void *parameter)
1676 {
1677     PragmaUnpublishInfo *info = static_cast<PragmaUnpublishInfo *>(parameter);
1678     if (info == nullptr) {
1679         return -E_INVALID_ARGS;
1680     }
1681     if (IsExtendedCacheDBMode()) {
1682         int err = IsCacheDBMode() ? -E_EKEYREVOKED : -E_BUSY;
1683         LOGE("[PragmaUnpublish]Existed cache database can not read data, errCode = [%d]!", err);
1684         return err;
1685     }
1686     return UnpublishToLocal(info->key, info->isDeleteSync, info->isUpdateTime);
1687 }
1688 
PragmaSetAutoLifeCycle(const uint32_t * lifeTime)1689 int SQLiteSingleVerNaturalStoreConnection::PragmaSetAutoLifeCycle(const uint32_t *lifeTime)
1690 {
1691     if (lifeTime == nullptr || *lifeTime > MAX_AUTO_LIFE_CYCLE || *lifeTime < MIN_AUTO_LIFE_CYCLE) {
1692         return -E_INVALID_ARGS;
1693     }
1694     if (kvDB_ == nullptr) {
1695         return -E_INVALID_DB;
1696     }
1697     return static_cast<SQLiteSingleVerNaturalStore *>(kvDB_)->SetAutoLifeCycleTime(*lifeTime);
1698 }
1699 
PragmaResultSetCacheMode(PragmaData inMode)1700 int SQLiteSingleVerNaturalStoreConnection::PragmaResultSetCacheMode(PragmaData inMode)
1701 {
1702     if (inMode == nullptr) {
1703         return -E_INVALID_ARGS;
1704     }
1705     auto mode = *(static_cast<ResultSetCacheMode *>(inMode));
1706     if (mode != ResultSetCacheMode::CACHE_FULL_ENTRY && mode != ResultSetCacheMode::CACHE_ENTRY_ID_ONLY) {
1707         return -E_INVALID_ARGS;
1708     }
1709     cacheModeForNewResultSet_.store(mode);
1710     return E_OK;
1711 }
1712 
PragmaResultSetCacheMaxSize(PragmaData inSize)1713 int SQLiteSingleVerNaturalStoreConnection::PragmaResultSetCacheMaxSize(PragmaData inSize)
1714 {
1715     if (inSize == nullptr) {
1716         return -E_INVALID_ARGS;
1717     }
1718     int size = *(static_cast<int *>(inSize));
1719     if (size < RESULT_SET_CACHE_MAX_SIZE_MIN || size > RESULT_SET_CACHE_MAX_SIZE_MAX) {
1720         return -E_INVALID_ARGS;
1721     }
1722     cacheMaxSizeForNewResultSet_.store(size);
1723     return E_OK;
1724 }
1725 
1726 // use for getkvstore migrating cache data
PragmaTriggerToMigrateData(const SecurityOption & secOption) const1727 int SQLiteSingleVerNaturalStoreConnection::PragmaTriggerToMigrateData(const SecurityOption &secOption) const
1728 {
1729     if ((secOption.securityLabel != S3) || (secOption.securityFlag != SECE)) {
1730         LOGD("Only S3 SECE data need migrate data!");
1731         return E_OK;
1732     }
1733 
1734     LOGI("Begin trigger the migration data while open the database!");
1735     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1736     if (naturalStore == nullptr) {
1737         return -E_INVALID_CONNECTION;
1738     }
1739     return naturalStore->TriggerToMigrateData();
1740 }
1741 
CheckAmendValueContentForLocalProcedure(const Value & oriValue,Value & amendValue) const1742 int SQLiteSingleVerNaturalStoreConnection::CheckAmendValueContentForLocalProcedure(const Value &oriValue,
1743     Value &amendValue) const
1744 {
1745     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1746     if (naturalStore == nullptr) { // Not Likely
1747         return -E_INVALID_DB;
1748     }
1749     bool useAmendValue = false;
1750     return naturalStore->CheckValueAndAmendIfNeed(ValueSource::FROM_LOCAL, oriValue, amendValue, useAmendValue);
1751 }
1752 
CheckLogOverLimit(SQLiteSingleVerStorageExecutor * executor) const1753 bool SQLiteSingleVerNaturalStoreConnection::CheckLogOverLimit(SQLiteSingleVerStorageExecutor *executor) const
1754 {
1755     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1756     if (naturalStore == nullptr || executor == nullptr) { // Not Likely
1757         return false;
1758     }
1759     uint64_t logFileSize = executor->GetLogFileSize();
1760     bool result = logFileSize > naturalStore->GetMaxLogSize();
1761     if (result) {
1762         LOGW("Log size[%" PRIu64 "] over the limit", logFileSize);
1763     }
1764     return result;
1765 }
1766 
CalcHashDevID(PragmaDeviceIdentifier & pragmaDev)1767 int SQLiteSingleVerNaturalStoreConnection::CalcHashDevID(PragmaDeviceIdentifier &pragmaDev)
1768 {
1769     if (pragmaDev.deviceID.empty()) {
1770         return -E_INVALID_ARGS;
1771     }
1772     pragmaDev.deviceIdentifier = DBCommon::TransferHashString(pragmaDev.deviceID);
1773     return E_OK;
1774 }
1775 
GetKeys(const IOption & option,const Key & keyPrefix,std::vector<Key> & keys) const1776 int SQLiteSingleVerNaturalStoreConnection::GetKeys(const IOption &option,
1777     const Key &keyPrefix, std::vector<Key> &keys) const
1778 {
1779     keys.clear();
1780     std::vector<Entry> entries;
1781     int errCode = GetEntriesInner(false, option, keyPrefix, entries);
1782     if (errCode == E_OK) {
1783         keys.resize(entries.size());
1784         std::transform(entries.begin(), entries.end(), keys.begin(), [](auto &entry) {
1785             return std::move(entry.key);
1786         });
1787     }
1788     keys.shrink_to_fit();
1789     return errCode;
1790 }
1791 
GetEntriesInner(bool isGetValue,const IOption & option,const Key & keyPrefix,std::vector<Entry> & entries) const1792 int SQLiteSingleVerNaturalStoreConnection::GetEntriesInner(bool isGetValue, const IOption &option,
1793     const Key &keyPrefix, std::vector<Entry> &entries) const
1794 {
1795     if (keyPrefix.size() > DBConstant::MAX_KEY_SIZE) {
1796         return -E_INVALID_ARGS;
1797     }
1798 
1799     SingleVerDataType type;
1800     if (option.dataType == IOption::LOCAL_DATA) {
1801         type = SingleVerDataType::LOCAL_TYPE_SQLITE;
1802     } else if (option.dataType == IOption::SYNC_DATA) {
1803         type = SingleVerDataType::SYNC_TYPE;
1804     } else {
1805         return -E_INVALID_ARGS;
1806     }
1807 
1808     int errCode = CheckReadDataControlled();
1809     if (errCode != E_OK) {
1810         LOGE("[GetEntries] Existed cache database can not read data, errCode = [%d]!", errCode);
1811         return errCode;
1812     }
1813 
1814     DBDfxAdapter::StartTracing();
1815     {
1816         std::lock_guard<std::mutex> lock(transactionMutex_);
1817         if (writeHandle_ != nullptr) {
1818             LOGD("[SQLiteSingleVerNaturalStoreConnection] Transaction started already.");
1819             errCode = writeHandle_->GetEntries(isGetValue, type, keyPrefix, entries);
1820             DBDfxAdapter::FinishTracing();
1821             return errCode;
1822         }
1823     }
1824 
1825     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
1826     if (handle == nullptr) {
1827         LOGE("[SQLiteSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode);
1828         DBDfxAdapter::FinishTracing();
1829         return errCode;
1830     }
1831 
1832     errCode = handle->GetEntries(isGetValue, type, keyPrefix, entries);
1833     ReleaseExecutor(handle);
1834     DBDfxAdapter::FinishTracing();
1835     return errCode;
1836 }
1837 
UpdateKey(const DistributedDB::UpdateKeyCallback & callback)1838 int SQLiteSingleVerNaturalStoreConnection::UpdateKey(const DistributedDB::UpdateKeyCallback &callback)
1839 {
1840     if (IsExtendedCacheDBMode()) {
1841         LOGE("[Connection] Not support update key in cache mode");
1842         return -E_NOT_SUPPORT;
1843     }
1844     int errCode = E_OK;
1845     {
1846         std::lock_guard<std::mutex> lock(transactionMutex_);
1847         if (writeHandle_ != nullptr) {
1848             LOGD("[Connection] Transaction started already.");
1849             errCode = writeHandle_->UpdateKey(callback);
1850             return errCode;
1851         }
1852     }
1853 
1854     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
1855     if (handle == nullptr) {
1856         LOGE("[Connection]::[UpdateKey] Get executor failed, errCode = [%d]", errCode);
1857         return errCode;
1858     }
1859 
1860     errCode = handle->UpdateKey(callback);
1861     ReleaseExecutor(handle);
1862     return errCode;
1863 }
1864 
SetCloudDbSchema(const std::map<std::string,DataBaseSchema> & schema)1865 int SQLiteSingleVerNaturalStoreConnection::SetCloudDbSchema(const std::map<std::string, DataBaseSchema> &schema)
1866 {
1867     int errCode = E_OK;
1868     SQLiteSingleVerStorageExecutor *handle = GetExecutor(true, errCode);
1869     if (handle == nullptr) {
1870         LOGE("[Connection]::[UpdateKey] Get executor failed, errCode = [%d]", errCode);
1871         return errCode;
1872     }
1873     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1874     if (errCode != E_OK) {
1875         ReleaseExecutor(handle);
1876         return errCode;
1877     }
1878     errCode = handle->CreateCloudLogTable();
1879     if (errCode != E_OK) {
1880         (void)handle->Rollback();
1881         ReleaseExecutor(handle);
1882         LOGE("[SingleVerConnection] create cloud log table failed, errCode = [%d]", errCode);
1883         return errCode;
1884     }
1885     errCode = handle->Commit();
1886     ReleaseExecutor(handle);
1887     if (errCode != E_OK) {
1888         LOGE("[SingleVerConnection] commit create cloud log table failed, errCode = [%d]", errCode);
1889         return errCode;
1890     }
1891 
1892     auto naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1893     if (naturalStore == nullptr) {
1894         LOGE("[SingleVerConnection] the store is null");
1895         return -E_NOT_INIT;
1896     }
1897     return naturalStore->SetCloudDbSchema(schema);
1898 }
1899 
RegisterObserverAction(const KvStoreObserver * observer,const ObserverAction & action)1900 int SQLiteSingleVerNaturalStoreConnection::RegisterObserverAction(const KvStoreObserver *observer,
1901     const ObserverAction &action)
1902 {
1903     auto naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1904     if (naturalStore == nullptr) {
1905         LOGE("[SingleVerConnection] the store is null");
1906         return -E_NOT_INIT;
1907     }
1908     return naturalStore->RegisterObserverAction(observer, action);
1909 }
1910 
UnRegisterObserverAction(const KvStoreObserver * observer)1911 int SQLiteSingleVerNaturalStoreConnection::UnRegisterObserverAction(const KvStoreObserver *observer)
1912 {
1913     auto naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1914     if (naturalStore == nullptr) {
1915         LOGW("[SingleVerConnection] unregister observer but store is null");
1916         return E_OK;
1917     }
1918     return naturalStore->UnRegisterObserverAction(observer);
1919 }
1920 
RemoveDeviceData(const std::string & device,ClearMode mode)1921 int SQLiteSingleVerNaturalStoreConnection::RemoveDeviceData(const std::string &device, ClearMode mode)
1922 {
1923     if (device.length() > DBConstant::MAX_DEV_LENGTH) {
1924         return -E_INVALID_ARGS;
1925     }
1926     if (mode == ClearMode::CLEAR_SHARED_TABLE) {
1927         return -E_NOT_SUPPORT;
1928     }
1929     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1930     if (naturalStore == nullptr) {
1931         return -E_INVALID_DB;
1932     }
1933     return naturalStore->RemoveDeviceData(device, mode);
1934 }
1935 
RemoveDeviceData(const std::string & device,const std::string & user,ClearMode mode)1936 int SQLiteSingleVerNaturalStoreConnection::RemoveDeviceData(const std::string &device, const std::string &user,
1937     ClearMode mode)
1938 {
1939     if (device.length() > DBConstant::MAX_DEV_LENGTH) {
1940         return -E_INVALID_ARGS;
1941     }
1942     if (mode == ClearMode::CLEAR_SHARED_TABLE) {
1943         return -E_NOT_SUPPORT;
1944     }
1945     SQLiteSingleVerNaturalStore *naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1946     if (naturalStore == nullptr) {
1947         return -E_INVALID_DB;
1948     }
1949     return naturalStore->RemoveDeviceData(device, user, mode);
1950 }
1951 
GetCloudVersion(const std::string & device,std::map<std::string,std::string> & versionMap)1952 int SQLiteSingleVerNaturalStoreConnection::GetCloudVersion(const std::string &device,
1953     std::map<std::string, std::string> &versionMap)
1954 {
1955     auto naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1956     if (naturalStore == nullptr) {
1957         return -E_INVALID_DB;
1958     }
1959     return naturalStore->GetCloudVersion(device, versionMap);
1960 }
1961 
SetCloudSyncConfig(const CloudSyncConfig & config)1962 int SQLiteSingleVerNaturalStoreConnection::SetCloudSyncConfig(const CloudSyncConfig &config)
1963 {
1964     auto naturalStore = GetDB<SQLiteSingleVerNaturalStore>();
1965     if (naturalStore == nullptr) {
1966         LOGE("[SingleVerConnection] DB is null when set config");
1967         return -E_INVALID_DB;
1968     }
1969     return naturalStore->SetCloudSyncConfig(config);
1970 }
1971 
RecordTimeIntoDataItem(Timestamp existCreateTime,DataItem & dataItem,SQLiteSingleVerNaturalStore & naturalStore)1972 void SQLiteSingleVerNaturalStoreConnection::RecordTimeIntoDataItem(Timestamp existCreateTime, DataItem &dataItem,
1973     SQLiteSingleVerNaturalStore &naturalStore)
1974 {
1975     dataItem.timestamp = naturalStore.GetCurrentTimestamp(false);
1976     if (currentMaxTimestamp_ > dataItem.timestamp) {
1977         dataItem.timestamp = currentMaxTimestamp_;
1978     }
1979 
1980     auto currentRawTime = TimeHelper::GetSysCurrentTime();
1981     if (existCreateTime != 0) {
1982         dataItem.writeTimestamp = existCreateTime;
1983     } else {
1984         dataItem.writeTimestamp = dataItem.timestamp;
1985     }
1986     dataItem.createTime = currentRawTime;
1987     dataItem.modifyTime = currentRawTime;
1988 }
1989 
GetEntries(const std::string & device,std::vector<Entry> & entries) const1990 int SQLiteSingleVerNaturalStoreConnection::GetEntries(const std::string &device, std::vector<Entry> &entries) const
1991 {
1992     int errCode = CheckReadDataControlled();
1993     if (errCode != E_OK) {
1994         LOGE("[GetEntries] Existed cache database can not read data, errCode = [%d]!", errCode);
1995         return errCode;
1996     }
1997     std::string localId;
1998     errCode = RuntimeContext::GetInstance()->GetLocalIdentity(localId);
1999     std::string getDevice;
2000     // if device is local, just search with empty string
2001     if (errCode != E_OK || localId != device) {
2002         getDevice = device;
2003     }
2004     {
2005         std::lock_guard<std::mutex> lock(transactionMutex_);
2006         if (writeHandle_ != nullptr) {
2007             LOGD("[SQLiteSingleVerNaturalStoreConnection] Transaction started already.");
2008             return writeHandle_->GetEntries(getDevice, entries);
2009         }
2010     }
2011 
2012     SQLiteSingleVerStorageExecutor *handle = GetExecutor(false, errCode);
2013     if (handle == nullptr) {
2014         LOGE("[SQLiteSingleVerNaturalStoreConnection]::[GetEntries] Get executor failed, errCode = [%d]", errCode);
2015         return errCode;
2016     }
2017 
2018     errCode = handle->GetEntries(getDevice, entries);
2019     ReleaseExecutor(handle);
2020     return errCode;
2021 }
2022 DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStoreConnection)
2023 }