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.h"
17 
18 #include <algorithm>
19 #include <thread>
20 #include <chrono>
21 
22 #include "data_compression.h"
23 #include "db_common.h"
24 #include "db_constant.h"
25 #include "db_dump_helper.h"
26 #include "db_dfx_adapter.h"
27 #include "db_errno.h"
28 #include "generic_single_ver_kv_entry.h"
29 #include "intercepted_data_impl.h"
30 #include "kvdb_utils.h"
31 #include "log_print.h"
32 #include "platform_specific.h"
33 #include "schema_object.h"
34 #include "single_ver_database_oper.h"
35 #include "single_ver_utils.h"
36 #include "storage_engine_manager.h"
37 #include "sqlite_single_ver_natural_store_connection.h"
38 #include "time_helper.h"
39 #include "value_hash_calc.h"
40 
41 namespace DistributedDB {
42 namespace {
43     constexpr int WAIT_DELEGATE_CALLBACK_TIME = 100;
44 
45     constexpr int DEVICE_ID_LEN = 32;
46     const std::string CREATE_DB_TIME = "createDBTime";
47 
48     // Called when get multiple dev data.
49     // deviceID is the device which currently being getting. When getting one dev data, deviceID is "".
50     // dataItems is the DataItems which already be get from DB sorted by timestamp.
51     // token must not be null.
ProcessContinueToken(const DeviceID & deviceID,const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)52     void ProcessContinueToken(const DeviceID &deviceID, const std::vector<DataItem> &dataItems, int &errCode,
53         SQLiteSingleVerContinueToken *&token)
54     {
55         if (errCode != -E_UNFINISHED) { // Error happened or get data finished. Token should be cleared.
56             delete token;
57             token = nullptr;
58             return;
59         }
60 
61         if (dataItems.empty()) {
62             errCode = -E_INTERNAL_ERROR;
63             LOGE("Get data unfinished but dataitems is empty.");
64             delete token;
65             token = nullptr;
66             return;
67         }
68 
69         Timestamp nextBeginTime = dataItems.back().timestamp + 1;
70         if (nextBeginTime > INT64_MAX) {
71             nextBeginTime = INT64_MAX;
72         }
73         token->SetNextBeginTime(deviceID, nextBeginTime);
74         return;
75     }
76 
77     // Called when get one dev data.
ProcessContinueToken(const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)78     void ProcessContinueToken(const std::vector<DataItem> &dataItems, int &errCode,
79         SQLiteSingleVerContinueToken *&token)
80     {
81         ProcessContinueToken("", dataItems, errCode, token);
82     }
83 
84     // Called when get query sync data.
85     // dataItems is the DataItems which already be get from DB sorted by timestamp.
86     // token must not be null.
ProcessContinueTokenForQuerySync(const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)87     void ProcessContinueTokenForQuerySync(const std::vector<DataItem> &dataItems, int &errCode,
88         SQLiteSingleVerContinueToken *&token)
89     {
90         if (errCode != -E_UNFINISHED) { // Error happened or get data finished. Token should be cleared.
91             delete token;
92             token = nullptr;
93             return;
94         }
95 
96         if (dataItems.empty()) {
97             errCode = -E_INTERNAL_ERROR;
98             LOGE("Get data unfinished but dataitems is empty.");
99             delete token;
100             token = nullptr;
101             return;
102         }
103 
104         Timestamp nextBeginTime = dataItems.back().timestamp + 1;
105         if (nextBeginTime > INT64_MAX) {
106             nextBeginTime = INT64_MAX;
107         }
108         bool getDeleteData = ((dataItems.back().flag & DataItem::DELETE_FLAG) != 0);
109         if (getDeleteData) {
110             token->FinishGetQueryData();
111             token->SetDeletedNextBeginTime("", nextBeginTime);
112         } else {
113             token->SetNextBeginTime("", nextBeginTime);
114         }
115         return;
116     }
117 
UpdateSecProperties(KvDBProperties & properties,bool isReadOnly,const SchemaObject & savedSchemaObj,const SQLiteSingleVerStorageEngine * engine)118     void UpdateSecProperties(KvDBProperties &properties, bool isReadOnly, const SchemaObject &savedSchemaObj,
119         const SQLiteSingleVerStorageEngine *engine)
120     {
121         if (isReadOnly) {
122             properties.SetSchema(savedSchemaObj);
123             properties.SetBoolProp(KvDBProperties::FIRST_OPEN_IS_READ_ONLY, true);
124         }
125         // Update the security option from the storage engine for that
126         // we will not update the security label and flag for the existed database.
127         // So the security label and flag are from the existed database.
128         if (engine == nullptr) {
129             return;
130         }
131         properties.SetIntProp(KvDBProperties::SECURITY_LABEL, engine->GetSecurityOption().securityLabel);
132         properties.SetIntProp(KvDBProperties::SECURITY_FLAG, engine->GetSecurityOption().securityFlag);
133     }
134 
GetKvEntriesByDataItems(std::vector<SingleVerKvEntry * > & entries,std::vector<DataItem> & dataItems)135     int GetKvEntriesByDataItems(std::vector<SingleVerKvEntry *> &entries, std::vector<DataItem> &dataItems)
136     {
137         int errCode = E_OK;
138         for (auto &item : dataItems) {
139             auto entry = new (std::nothrow) GenericSingleVerKvEntry();
140             if (entry == nullptr) {
141                 errCode = -E_OUT_OF_MEMORY;
142                 LOGE("GetKvEntries failed, errCode:%d", errCode);
143                 SingleVerKvEntry::Release(entries);
144                 break;
145             }
146             entry->SetEntryData(std::move(item));
147             entries.push_back(entry);
148         }
149         return errCode;
150     }
151 
CanHoldDeletedData(const std::vector<DataItem> & dataItems,const DataSizeSpecInfo & dataSizeInfo,size_t appendLen)152     bool CanHoldDeletedData(const std::vector<DataItem> &dataItems, const DataSizeSpecInfo &dataSizeInfo,
153         size_t appendLen)
154     {
155         bool reachThreshold = false;
156         size_t blockSize = 0;
157         for (size_t i = 0; !reachThreshold && i < dataItems.size(); i++) {
158             blockSize += SQLiteSingleVerStorageExecutor::GetDataItemSerialSize(dataItems[i], appendLen);
159             reachThreshold = (blockSize >= dataSizeInfo.blockSize * DBConstant::QUERY_SYNC_THRESHOLD);
160         }
161         return !reachThreshold;
162     }
163 }
164 
SQLiteSingleVerNaturalStore()165 SQLiteSingleVerNaturalStore::SQLiteSingleVerNaturalStore()
166     : storageEngine_(nullptr),
167       notificationEventsRegistered_(false),
168       notificationConflictEventsRegistered_(false),
169       isInitialized_(false),
170       isReadOnly_(false),
171       lifeCycleNotifier_(nullptr),
172       lifeTimerId_(0),
173       autoLifeTime_(DBConstant::DEF_LIFE_CYCLE_TIME),
174       createDBTime_(0),
175       pushDataInterceptor_(nullptr),
176       receiveDataInterceptor_(nullptr),
177       maxLogSize_(DBConstant::MAX_LOG_SIZE_DEFAULT),
178       abortPerm_(OperatePerm::NORMAL_PERM),
179       sqliteCloudKvStore_(nullptr)
180 {}
181 
~SQLiteSingleVerNaturalStore()182 SQLiteSingleVerNaturalStore::~SQLiteSingleVerNaturalStore()
183 {
184     ReleaseResources();
185 }
186 
SetUserVer(const KvDBProperties & kvDBProp,int version)187 int SQLiteSingleVerNaturalStore::SetUserVer(const KvDBProperties &kvDBProp, int version)
188 {
189     OpenDbProperties properties;
190     properties.uri = GetDatabasePath(kvDBProp);
191     bool isEncryptedDb = kvDBProp.GetBoolProp(KvDBProperties::ENCRYPTED_MODE, false);
192     if (isEncryptedDb) { // LCOV_EXCL_BR_LINE
193         kvDBProp.GetPassword(properties.cipherType, properties.passwd);
194     }
195 
196     int errCode = SQLiteUtils::SetUserVer(properties, version);
197     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
198         LOGE("Recover for open db failed in single version:%d", errCode);
199     }
200     return errCode;
201 }
202 
InitDatabaseContext(const KvDBProperties & kvDBProp,bool isNeedUpdateSecOpt)203 int SQLiteSingleVerNaturalStore::InitDatabaseContext(const KvDBProperties &kvDBProp, bool isNeedUpdateSecOpt)
204 {
205     int errCode = InitStorageEngine(kvDBProp, isNeedUpdateSecOpt);
206     if (errCode != E_OK) {
207         return errCode;
208     }
209     return errCode;
210 }
211 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)212 int SQLiteSingleVerNaturalStore::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
213 {
214     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
215     int errCode;
216     if (!notifier) {
217         if (lifeTimerId_ == 0) {
218             return E_OK;
219         }
220         errCode = StopLifeCycleTimer();
221         if (errCode != E_OK) {
222             LOGE("Stop the life cycle timer failed:%d", errCode);
223         }
224         return E_OK;
225     }
226 
227     if (lifeTimerId_ != 0) {
228         errCode = StopLifeCycleTimer();
229         if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
230             LOGE("Stop the life cycle timer failed:%d", errCode);
231         }
232     }
233     errCode = StartLifeCycleTimer(notifier);
234     if (errCode != E_OK) {
235         LOGE("Register life cycle timer failed:%d", errCode);
236     }
237     return errCode;
238 }
239 
SetAutoLifeCycleTime(uint32_t time)240 int SQLiteSingleVerNaturalStore::SetAutoLifeCycleTime(uint32_t time)
241 {
242     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
243     if (lifeTimerId_ == 0) {
244         autoLifeTime_ = time;
245     } else {
246         auto runtimeCxt = RuntimeContext::GetInstance();
247         if (runtimeCxt == nullptr) {
248             return -E_INVALID_ARGS;
249         }
250         LOGI("[SingleVer] Set life cycle to %u", time);
251         int errCode = runtimeCxt->ModifyTimer(lifeTimerId_, time);
252         if (errCode != E_OK) {
253             return errCode;
254         }
255         autoLifeTime_ = time;
256     }
257     return E_OK;
258 }
259 
GetSecurityOption(SecurityOption & option) const260 int SQLiteSingleVerNaturalStore::GetSecurityOption(SecurityOption &option) const
261 {
262     bool isMemDb = GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false);
263     if (isMemDb) { // LCOV_EXCL_BR_LINE
264         LOGI("[GetSecurityOption] MemDb, no need to get security option");
265         option = SecurityOption();
266         return -E_NOT_SUPPORT;
267     }
268     if (!RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) { // LCOV_EXCL_BR_LINE
269         LOGI("[GetSecurityOption] Not set api adapter");
270         return -E_NOT_SUPPORT;
271     }
272     option.securityLabel = GetDbProperties().GetSecLabel();
273     option.securityFlag = GetDbProperties().GetSecFlag();
274 
275     return E_OK;
276 }
277 
278 namespace {
OriValueCanBeUse(int errCode)279 inline bool OriValueCanBeUse(int errCode)
280 {
281     return (errCode == -E_VALUE_MATCH);
282 }
283 
AmendValueShouldBeUse(int errCode)284 inline bool AmendValueShouldBeUse(int errCode)
285 {
286     return (errCode == -E_VALUE_MATCH_AMENDED);
287 }
288 
IsValueMismatched(int errCode)289 inline bool IsValueMismatched(int errCode)
290 {
291     return (errCode == -E_VALUE_MISMATCH_FEILD_COUNT ||
292         errCode == -E_VALUE_MISMATCH_FEILD_TYPE ||
293         errCode == -E_VALUE_MISMATCH_CONSTRAINT);
294 }
295 }
296 
CheckValueAndAmendIfNeed(ValueSource sourceType,const Value & oriValue,Value & amendValue,bool & useAmendValue) const297 int SQLiteSingleVerNaturalStore::CheckValueAndAmendIfNeed(ValueSource sourceType, const Value &oriValue,
298     Value &amendValue, bool &useAmendValue) const
299 {
300     // oriValue size may already be checked previously, but check here const little
301     if (oriValue.size() > DBConstant::MAX_VALUE_SIZE) {
302         return -E_INVALID_ARGS;
303     }
304     const SchemaObject &schemaObjRef = MyProp().GetSchemaConstRef();
305     if (!schemaObjRef.IsSchemaValid()) {
306         // Not a schema database, do not need to check more
307         return E_OK;
308     }
309     if (schemaObjRef.GetSchemaType() == SchemaType::JSON) { // LCOV_EXCL_BR_LINE
310         ValueObject valueObj;
311         int errCode = valueObj.Parse(oriValue.data(), oriValue.data() + oriValue.size(), schemaObjRef.GetSkipSize());
312         if (errCode != E_OK) {
313             return -E_INVALID_FORMAT;
314         }
315         errCode = schemaObjRef.CheckValueAndAmendIfNeed(sourceType, valueObj);
316         if (OriValueCanBeUse(errCode)) {
317             useAmendValue = false;
318             return E_OK;
319         }
320         if (AmendValueShouldBeUse(errCode)) {
321             std::string amended = valueObj.ToString();
322             if (amended.size() > DBConstant::MAX_VALUE_SIZE) {
323                 LOGE("[SqlSinStore][CheckAmendValue] ValueSize=%zu exceed limit after amend.", amended.size());
324                 return -E_INVALID_FORMAT;
325             }
326             amendValue.clear();
327             amendValue.assign(amended.begin(), amended.end());
328             useAmendValue = true;
329             return E_OK;
330         }
331         if (IsValueMismatched(errCode)) {
332             return errCode;
333         }
334     } else {
335         int errCode = schemaObjRef.VerifyValue(sourceType, oriValue);
336         if (errCode == E_OK) { // LCOV_EXCL_BR_LINE
337             useAmendValue = false;
338             return E_OK;
339         }
340     }
341     // Any unexpected wrong
342     return -E_INVALID_FORMAT;
343 }
344 
CheckDatabaseRecovery(const KvDBProperties & kvDBProp)345 int SQLiteSingleVerNaturalStore::CheckDatabaseRecovery(const KvDBProperties &kvDBProp)
346 {
347     if (kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false)) { // memory status not need recovery
348         return E_OK;
349     }
350     std::unique_ptr<SingleVerDatabaseOper> operation = std::make_unique<SingleVerDatabaseOper>(this, nullptr);
351     (void)operation->ClearExportedTempFiles(kvDBProp);
352     int errCode = operation->RekeyRecover(kvDBProp);
353     if (errCode != E_OK) {
354         LOGE("Recover from rekey failed in single version:%d", errCode);
355         return errCode;
356     }
357 
358     errCode = operation->ClearImportTempFile(kvDBProp);
359     if (errCode != E_OK) {
360         LOGE("Clear imported temp db failed in single version:%d", errCode);
361         return errCode;
362     }
363 
364     // Currently, Design for the consistency of directory and file setting secOption
365     errCode = ClearIncompleteDatabase(kvDBProp);
366     if (errCode != E_OK) {
367         LOGE("Clear incomplete database failed in single version:%d", errCode);
368         return errCode;
369     }
370     const std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
371     const std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
372     bool isCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
373     bool isMemoryDb = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
374     if (!isMemoryDb) { // LCOV_EXCL_BR_LINE
375         errCode = DBCommon::CreateStoreDirectory(dataDir, identifierDir, DBConstant::SINGLE_SUB_DIR, isCreate);
376         if (errCode != E_OK) {
377             LOGE("Create single version natural store directory failed:%d", errCode);
378         }
379     }
380     return errCode;
381 }
382 
GetAndInitStorageEngine(const KvDBProperties & kvDBProp)383 int SQLiteSingleVerNaturalStore::GetAndInitStorageEngine(const KvDBProperties &kvDBProp)
384 {
385     int errCode = E_OK;
386     {
387         std::unique_lock<std::shared_mutex> lock(engineMutex_);
388         storageEngine_ =
389             static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(kvDBProp, errCode));
390         if (storageEngine_ == nullptr) {
391             return errCode;
392         }
393     }
394 
395     if (storageEngine_->IsEngineCorrupted()) { // LCOV_EXCL_BR_LINE
396         LOGE("[SqlSinStore][GetAndInitStorageEngine] database engine is corrupted or invalid key, stop open!");
397         return -E_INVALID_PASSWD_OR_CORRUPTED_DB;
398     }
399 
400     errCode = InitDatabaseContext(kvDBProp);
401     if (errCode != E_OK) {
402         LOGE("[SqlSinStore][GetAndInitStorageEngine] Init database context fail! errCode = [%d]", errCode);
403     }
404     return errCode;
405 }
406 
Open(const KvDBProperties & kvDBProp)407 int SQLiteSingleVerNaturalStore::Open(const KvDBProperties &kvDBProp)
408 {
409     std::lock_guard<std::mutex> lock(initialMutex_);
410     if (isInitialized_) { // LCOV_EXCL_BR_LINE
411         return E_OK; // avoid the reopen operation.
412     }
413 
414     int errCode = CheckDatabaseRecovery(kvDBProp);
415     if (errCode != E_OK) {
416         return errCode;
417     }
418 
419     bool isReadOnly = false;
420     SchemaObject savedSchemaObj;
421 
422     errCode = GetAndInitStorageEngine(kvDBProp);
423     if (errCode != E_OK) {
424         goto ERROR;
425     }
426 
427     errCode = RegisterNotification();
428     if (errCode != E_OK) {
429         LOGE("Register notification failed:%d", errCode);
430         goto ERROR;
431     }
432 
433     errCode = RemoveAllSubscribe();
434     if (errCode != E_OK) {
435         LOGE("[SqlSinStore][Open] remove subscribe fail! errCode = [%d]", errCode);
436         goto ERROR;
437     }
438 
439     // Here, the dbfile is created or opened, and upgrade of table structure has done.
440     // More, Upgrade of schema is also done in upgrader call in InitDatabaseContext, schema in dbfile updated if need.
441     // If inputSchema is empty, upgrader do nothing of schema, isReadOnly will be true if dbfile contain schema before.
442     // In this case, we should load the savedSchema for checking value from sync which not restricted by readOnly.
443     // If inputSchema not empty, isReadOnly will not be true, we should do nothing more.
444     errCode = DecideReadOnlyBaseOnSchema(kvDBProp, isReadOnly, savedSchemaObj);
445     if (errCode != E_OK) {
446         LOGE("[SqlSinStore][Open] DecideReadOnlyBaseOnSchema failed=%d", errCode);
447         goto ERROR;
448     }
449     // Set KvDBProperties and set Schema
450     MyProp() = kvDBProp;
451     UpdateSecProperties(MyProp(), isReadOnly, savedSchemaObj, storageEngine_);
452 
453     StartSyncer();
454     OnKill([this]() { ReleaseResources(); });
455 
456     errCode = SaveCreateDBTimeIfNotExisted();
457     if (errCode != E_OK) {
458         goto ERROR;
459     }
460 
461     InitialLocalDataTimestamp();
462     storageEngine_->UpgradeLocalMetaData();
463     isInitialized_ = true;
464     isReadOnly_ = isReadOnly;
465     return E_OK;
466 ERROR:
467     ReleaseResources();
468     return errCode;
469 }
470 
Close()471 void SQLiteSingleVerNaturalStore::Close()
472 {
473     ReleaseResources();
474 }
475 
NewConnection(int & errCode)476 GenericKvDBConnection *SQLiteSingleVerNaturalStore::NewConnection(int &errCode)
477 {
478     SQLiteSingleVerNaturalStoreConnection *connection = new (std::nothrow) SQLiteSingleVerNaturalStoreConnection(this);
479     if (connection == nullptr) {
480         errCode = -E_OUT_OF_MEMORY;
481         return nullptr;
482     }
483     errCode = E_OK;
484     return connection;
485 }
486 
487 // Get interface type of this kvdb.
GetInterfaceType() const488 int SQLiteSingleVerNaturalStore::GetInterfaceType() const
489 {
490     return SYNC_SVD;
491 }
492 
493 // Get the interface ref-count, in order to access asynchronously.
IncRefCount()494 void SQLiteSingleVerNaturalStore::IncRefCount()
495 {
496     IncObjRef(this);
497 }
498 
499 // Drop the interface ref-count.
DecRefCount()500 void SQLiteSingleVerNaturalStore::DecRefCount()
501 {
502     DecObjRef(this);
503 }
504 
505 // Get the identifier of this kvdb.
GetIdentifier() const506 std::vector<uint8_t> SQLiteSingleVerNaturalStore::GetIdentifier() const
507 {
508     std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
509     std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
510     return identifierVect;
511 }
512 
GetDualTupleIdentifier() const513 std::vector<uint8_t> SQLiteSingleVerNaturalStore::GetDualTupleIdentifier() const
514 {
515     std::string identifier = MyProp().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
516     std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
517     return identifierVect;
518 }
519 
520 // Get interface for syncer.
GetSyncInterface()521 IKvDBSyncInterface *SQLiteSingleVerNaturalStore::GetSyncInterface()
522 {
523     return this;
524 }
525 
GetMetaData(const Key & key,Value & value) const526 int SQLiteSingleVerNaturalStore::GetMetaData(const Key &key, Value &value) const
527 {
528     if (storageEngine_ == nullptr) {
529         return -E_INVALID_DB;
530     }
531     if (key.size() > DBConstant::MAX_KEY_SIZE) {
532         return -E_INVALID_ARGS;
533     }
534 
535     int errCode = E_OK;
536     SecurityOption option;
537     (void)GetSecurityOption(option);
538     bool isWrite = (option.securityLabel >= S3) && (option.securityFlag == SECE);
539     // meta in S3 SECE open meta.db, should use write handle
540     auto handle = GetHandle(isWrite, errCode);
541     if (handle == nullptr) {
542         return errCode;
543     }
544 
545     Timestamp timestamp;
546     errCode = handle->GetKvData(SingleVerDataType::META_TYPE, key, value, timestamp);
547     ReleaseHandle(handle);
548     HeartBeatForLifeCycle();
549     return errCode;
550 }
551 
PutMetaData(const Key & key,const Value & value,bool isInTransaction)552 int SQLiteSingleVerNaturalStore::PutMetaData(const Key &key, const Value &value, bool isInTransaction)
553 {
554     (void)isInTransaction;
555     int errCode = SQLiteSingleVerNaturalStore::CheckDataStatus(key, value, false);
556     if (errCode != E_OK) {
557         return errCode;
558     }
559 
560     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
561     if (handle == nullptr) {
562         return errCode;
563     }
564 
565     errCode = handle->PutKvData(SingleVerDataType::META_TYPE, key, value, 0, nullptr); // meta doesn't need time.
566     if (errCode != E_OK) {
567         LOGE("Put kv data err:%d", errCode);
568     }
569 
570     HeartBeatForLifeCycle();
571     ReleaseHandle(handle);
572     return errCode;
573 }
574 
575 // Delete multiple meta data records in a transaction.
DeleteMetaData(const std::vector<Key> & keys)576 int SQLiteSingleVerNaturalStore::DeleteMetaData(const std::vector<Key> &keys)
577 {
578     for (const auto &key : keys) {
579         if (key.empty() || key.size() > DBConstant::MAX_KEY_SIZE) {
580             return -E_INVALID_ARGS;
581         }
582     }
583     int errCode = E_OK;
584     auto handle = GetHandle(true, errCode);
585     if (handle == nullptr) {
586         return errCode;
587     }
588 
589     handle->StartTransaction(TransactType::IMMEDIATE);
590     errCode = handle->DeleteMetaData(keys);
591     if (errCode != E_OK) {
592         handle->Rollback();
593         LOGE("[SinStore] DeleteMetaData failed, errCode = %d", errCode);
594     } else {
595         handle->Commit();
596     }
597 
598     ReleaseHandle(handle);
599     HeartBeatForLifeCycle();
600     return errCode;
601 }
602 
GetAllMetaKeys(std::vector<Key> & keys) const603 int SQLiteSingleVerNaturalStore::GetAllMetaKeys(std::vector<Key> &keys) const
604 {
605     if (storageEngine_ == nullptr) {
606         return -E_INVALID_DB;
607     }
608     int errCode = E_OK;
609     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
610     if (handle == nullptr) {
611         return errCode;
612     }
613 
614     errCode = handle->GetAllMetaKeys(keys);
615     ReleaseHandle(handle);
616     return errCode;
617 }
618 
GetSyncData(Timestamp begin,Timestamp end,std::vector<SingleVerKvEntry * > & entries,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const619 int SQLiteSingleVerNaturalStore::GetSyncData(Timestamp begin, Timestamp end, std::vector<SingleVerKvEntry *> &entries,
620     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
621 {
622     int errCode = CheckReadDataControlled();
623     if (errCode != E_OK) {
624         LOGE("[GetSyncData] Existed cache database can not read data, errCode = [%d]!", errCode);
625         return errCode;
626     }
627 
628     std::vector<DataItem> dataItems;
629     errCode = GetSyncData(begin, end, dataItems, continueStmtToken, dataSizeInfo);
630     if (errCode != E_OK && errCode != -E_UNFINISHED) {
631         LOGE("GetSyncData errCode:%d", errCode);
632         goto ERROR;
633     }
634 
635     for (auto &item : dataItems) {
636         GenericSingleVerKvEntry *entry = new (std::nothrow) GenericSingleVerKvEntry();
637         if (entry == nullptr) {
638             errCode = -E_OUT_OF_MEMORY;
639             LOGE("GetSyncData errCode:%d", errCode);
640             goto ERROR;
641         }
642         entry->SetEntryData(std::move(item));
643         entries.push_back(entry);
644     }
645 
646 ERROR:
647     if (errCode != E_OK && errCode != -E_UNFINISHED) {
648         SingleVerKvEntry::Release(entries);
649     }
650     HeartBeatForLifeCycle();
651     return errCode;
652 }
653 
GetSyncData(Timestamp begin,Timestamp end,std::vector<DataItem> & dataItems,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const654 int SQLiteSingleVerNaturalStore::GetSyncData(Timestamp begin, Timestamp end, std::vector<DataItem> &dataItems,
655     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
656 {
657     if (begin >= end || dataSizeInfo.blockSize > DBConstant::MAX_SYNC_BLOCK_SIZE) {
658         return -E_INVALID_ARGS;
659     }
660 
661     auto token = new (std::nothrow) SQLiteSingleVerContinueToken(begin, end);
662     if (token == nullptr) {
663         LOGE("[SQLiteSingleVerNaturalStore][NewToken] Bad alloc.");
664         return -E_OUT_OF_MEMORY;
665     }
666 
667     int errCode = E_OK;
668     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
669     if (handle == nullptr) {
670         goto ERROR;
671     }
672 
673     errCode = handle->GetSyncDataByTimestamp(dataItems, GetAppendedLen(), begin, end, dataSizeInfo);
674     if (errCode == -E_FINISHED) {
675         errCode = E_OK;
676     }
677 
678 ERROR:
679     if (errCode != -E_UNFINISHED  && errCode != E_OK) {
680         dataItems.clear();
681     }
682     ProcessContinueToken(dataItems, errCode, token);
683     continueStmtToken = static_cast<ContinueToken>(token);
684 
685     ReleaseHandle(handle);
686     return errCode;
687 }
688 
GetSyncData(QueryObject & query,const SyncTimeRange & timeRange,const DataSizeSpecInfo & dataSizeInfo,ContinueToken & continueStmtToken,std::vector<SingleVerKvEntry * > & entries) const689 int SQLiteSingleVerNaturalStore::GetSyncData(QueryObject &query, const SyncTimeRange &timeRange,
690     const DataSizeSpecInfo &dataSizeInfo, ContinueToken &continueStmtToken,
691     std::vector<SingleVerKvEntry *> &entries) const
692 {
693     if (!timeRange.IsValid()) {
694         return -E_INVALID_ARGS;
695     }
696     int errCode = CheckReadDataControlled();
697     if (errCode != E_OK) {
698         LOGE("[GetEntries] Existed cache prevents the reading from query sync[%d]!", errCode);
699         return errCode;
700     }
701 
702     query.SetSchema(GetSchemaObject());
703     auto token = new (std::nothrow) SQLiteSingleVerContinueToken(timeRange, query);
704     if (token == nullptr) {
705         LOGE("[SingleVerNStore] Allocate continue token failed.");
706         return -E_OUT_OF_MEMORY;
707     }
708 
709     int innerCode;
710     std::vector<DataItem> dataItems;
711     errCode = GetSyncDataForQuerySync(dataItems, token, dataSizeInfo);
712     if (errCode != E_OK && errCode != -E_UNFINISHED) { // The code need be sent to outside except new error happened.
713         goto ERROR;
714     }
715 
716     innerCode = GetKvEntriesByDataItems(entries, dataItems);
717     if (innerCode != E_OK) {
718         errCode = innerCode;
719         delete token;
720         token = nullptr;
721     }
722 
723 ERROR:
724     continueStmtToken = static_cast<ContinueToken>(token);
725     return errCode;
726 }
727 
728 /**
729  * Caller must ensure that parameter continueStmtToken is valid.
730  * If error happened, token will be deleted here.
731  */
GetSyncDataForQuerySync(std::vector<DataItem> & dataItems,SQLiteSingleVerContinueToken * & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const732 int SQLiteSingleVerNaturalStore::GetSyncDataForQuerySync(std::vector<DataItem> &dataItems,
733     SQLiteSingleVerContinueToken *&continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
734 {
735     int errCode = E_OK;
736     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
737     if (handle == nullptr) {
738         goto ERROR;
739     }
740 
741     errCode = handle->StartTransaction(TransactType::DEFERRED);
742     if (errCode != E_OK) {
743         LOGE("[SingleVerNStore] Start transaction for get sync data failed. err=%d", errCode);
744         goto ERROR;
745     }
746 
747     // Get query data.
748     if (!continueStmtToken->IsGetQueryDataFinished()) {
749         LOGD("[SingleVerNStore] Get query data between %" PRIu64 " and %" PRIu64 ".",
750             continueStmtToken->GetQueryBeginTime(), continueStmtToken->GetQueryEndTime());
751         errCode = handle->GetSyncDataWithQuery(continueStmtToken->GetQuery(), GetAppendedLen(), dataSizeInfo,
752             std::make_pair(continueStmtToken->GetQueryBeginTime(), continueStmtToken->GetQueryEndTime()), dataItems);
753     }
754 
755     // Get query data finished.
756     if (errCode == E_OK || errCode == -E_FINISHED) {
757         // Clear query timeRange.
758         continueStmtToken->FinishGetQueryData();
759         if (!continueStmtToken->IsGetDeletedDataFinished()) {
760             errCode = -E_UNFINISHED;
761             // Get delete time next.
762             if (CanHoldDeletedData(dataItems, dataSizeInfo, GetAppendedLen())) {
763                 LOGD("[SingleVerNStore] Get deleted data between %" PRIu64 " and %" PRIu64 ".",
764                     continueStmtToken->GetDeletedBeginTime(), continueStmtToken->GetDeletedEndTime());
765                 errCode = handle->GetDeletedSyncDataByTimestamp(dataItems, GetAppendedLen(),
766                     continueStmtToken->GetDeletedBeginTime(), continueStmtToken->GetDeletedEndTime(), dataSizeInfo);
767             }
768         }
769     }
770 
771     (void)handle->Rollback(); // roll back query statement
772     if (errCode == -E_FINISHED) {
773         errCode = E_OK;
774     }
775 
776 ERROR:
777     if (errCode != -E_UNFINISHED && errCode != E_OK) { // Error happened.
778         dataItems.clear();
779     }
780     ProcessContinueTokenForQuerySync(dataItems, errCode, continueStmtToken);
781     ReleaseHandle(handle);
782     return errCode;
783 }
784 
GetSyncDataNext(std::vector<SingleVerKvEntry * > & entries,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const785 int SQLiteSingleVerNaturalStore::GetSyncDataNext(std::vector<SingleVerKvEntry *> &entries,
786     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
787 {
788     int errCode = CheckReadDataControlled();
789     if (errCode != E_OK) {
790         LOGE("[GetSyncDataNext] Existed cache database can not read data, errCode = [%d]!", errCode);
791         return errCode;
792     }
793 
794     std::vector<DataItem> dataItems;
795     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
796     if (token->IsQuerySync()) {
797         errCode = GetSyncDataForQuerySync(dataItems, token, dataSizeInfo);
798         continueStmtToken = static_cast<ContinueToken>(token);
799     } else {
800         errCode = GetSyncDataNext(dataItems, continueStmtToken, dataSizeInfo);
801     }
802 
803     if (errCode != E_OK && errCode != -E_UNFINISHED) {
804         LOGE("GetSyncDataNext errCode:%d", errCode);
805         return errCode;
806     }
807 
808     int innerErrCode = GetKvEntriesByDataItems(entries, dataItems);
809     if (innerErrCode != E_OK) {
810         errCode = innerErrCode;
811         ReleaseContinueToken(continueStmtToken);
812     }
813     return errCode;
814 }
815 
GetSyncDataNext(std::vector<DataItem> & dataItems,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const816 int SQLiteSingleVerNaturalStore::GetSyncDataNext(std::vector<DataItem> &dataItems, ContinueToken &continueStmtToken,
817     const DataSizeSpecInfo &dataSizeInfo) const
818 {
819     if (dataSizeInfo.blockSize > DBConstant::MAX_SYNC_BLOCK_SIZE) {
820         return -E_INVALID_ARGS;
821     }
822 
823     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
824     if (token == nullptr || !(token->CheckValid())) {
825         LOGE("[SingleVerNaturalStore][GetSyncDataNext] invalid continue token.");
826         return -E_INVALID_ARGS;
827     }
828 
829     int errCode = E_OK;
830     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
831     if (handle == nullptr) {
832         ReleaseContinueToken(continueStmtToken);
833         return errCode;
834     }
835 
836     errCode = handle->GetSyncDataByTimestamp(dataItems, GetAppendedLen(), token->GetQueryBeginTime(),
837         token->GetQueryEndTime(), dataSizeInfo);
838     if (errCode == -E_FINISHED) {
839         errCode = E_OK;
840     }
841 
842     ProcessContinueToken(dataItems, errCode, token);
843     continueStmtToken = static_cast<ContinueToken>(token);
844 
845     ReleaseHandle(handle);
846     return errCode;
847 }
848 
ReleaseContinueToken(ContinueToken & continueStmtToken) const849 void SQLiteSingleVerNaturalStore::ReleaseContinueToken(ContinueToken &continueStmtToken) const
850 {
851     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
852     if (token == nullptr || !(token->CheckValid())) {
853         LOGE("[SQLiteSingleVerNaturalStore][ReleaseContinueToken] Input is not a continue token.");
854         return;
855     }
856     delete token;
857     continueStmtToken = nullptr;
858 }
859 
PutSyncDataWithQuery(const QueryObject & query,const std::vector<SingleVerKvEntry * > & entries,const std::string & deviceName)860 int SQLiteSingleVerNaturalStore::PutSyncDataWithQuery(const QueryObject &query,
861     const std::vector<SingleVerKvEntry *> &entries, const std::string &deviceName)
862 {
863     if (deviceName.length() > DBConstant::MAX_DEV_LENGTH) {
864         LOGW("Device length is invalid for sync put");
865         return -E_INVALID_ARGS;
866     }
867     HeartBeatForLifeCycle();
868     DeviceInfo deviceInfo = {false, deviceName};
869     if (deviceName.empty()) {
870         deviceInfo.deviceName = "Unknown";
871     }
872 
873     std::vector<DataItem> dataItems;
874     for (const auto itemEntry : entries) {
875         auto *entry = static_cast<GenericSingleVerKvEntry *>(itemEntry);
876         if (entry != nullptr) {
877             DataItem item;
878             item.origDev = entry->GetOrigDevice();
879             item.flag = entry->GetFlag();
880             item.timestamp = entry->GetTimestamp();
881             item.writeTimestamp = entry->GetWriteTimestamp();
882             entry->GetKey(item.key);
883             entry->GetValue(item.value);
884             dataItems.push_back(item);
885         }
886     }
887 
888     int errCode = SaveSyncDataItems(query, dataItems, deviceInfo, true); // Current is true to check value content
889     if (errCode != E_OK) {
890         LOGE("PutSyncData failed:%d", errCode);
891     }
892 
893     return errCode;
894 }
895 
GetMaxTimestamp(Timestamp & stamp) const896 void SQLiteSingleVerNaturalStore::GetMaxTimestamp(Timestamp &stamp) const
897 {
898     if (storageEngine_ == nullptr) {
899         return;
900     }
901     int errCode = E_OK;
902     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
903     if (handle == nullptr) {
904         return;
905     }
906     handle->InitCurrentMaxStamp(stamp);
907     LOGD("Get max timestamp from db:%" PRIu64, stamp);
908     ReleaseHandle(handle);
909 }
910 
911 // In sync procedure, call this function
RemoveDeviceData(const std::string & deviceName,bool isNeedNotify)912 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, bool isNeedNotify)
913 {
914     if (deviceName.empty() || deviceName.length() > DBConstant::MAX_DEV_LENGTH) {
915         return -E_INVALID_ARGS;
916     }
917     LOGI("[RemoveDeviceData] %s{private} rebuild, clear history data", deviceName.c_str());
918     return RemoveDeviceData(deviceName, isNeedNotify, true);
919 }
920 
GetExistsDeviceList(std::set<std::string> & devices) const921 int SQLiteSingleVerNaturalStore::GetExistsDeviceList(std::set<std::string> &devices) const
922 {
923     int errCode = E_OK;
924     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
925     if (handle == nullptr) {
926         LOGE("[SingleVerNStore] GetExistsDeviceList get handle failed:%d", errCode);
927         return errCode;
928     }
929     errCode = handle->GetExistsDevicesFromMeta(devices);
930     if (errCode != E_OK) {
931         LOGE("[SingleVerNStore] Get remove device list from meta failed. err=%d", errCode);
932     }
933     ReleaseHandle(handle);
934     return errCode;
935 }
936 
937 // In local procedure, call this function
RemoveDeviceData(const std::string & deviceName,bool isNeedNotify,bool isInSync)938 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, bool isNeedNotify, bool isInSync)
939 {
940     if (!isInSync && !CheckWritePermission()) {
941         return -E_NOT_PERMIT;
942     }
943     std::string hashDeviceId;
944     bool hash = false;
945     do {
946         if (!deviceName.empty() && !isInSync) {
947             int errCode = GetHashDeviceId(deviceName, hashDeviceId);
948             if (errCode == -E_NOT_SUPPORT) {
949                 break;
950             }
951             if (errCode != E_OK) {
952                 return errCode;
953             }
954             hash = true;
955         }
956     } while (false);
957     if (!hash) { // LCOV_EXCL_BR_LINE
958         hashDeviceId = DBCommon::TransferHashString(deviceName);
959     }
960 
961     return RemoveDeviceDataInner(hashDeviceId, isNeedNotify);
962 }
963 
964 // In sync procedure, call this function
RemoveDeviceData(const std::string & deviceName,ClearMode mode)965 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, ClearMode mode)
966 {
967     CleanAllWaterMark();
968     return RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), mode);
969 }
970 
971 // In sync procedure, call this function
RemoveDeviceData(const std::string & deviceName,const std::string & user,ClearMode mode)972 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, const std::string &user,
973     ClearMode mode)
974 {
975     CleanAllWaterMark();
976     return RemoveDeviceDataInner(DBCommon::TransferHashString(deviceName), user, mode);
977 }
978 
RemoveDeviceDataInCacheMode(const std::string & hashDev,bool isNeedNotify) const979 int SQLiteSingleVerNaturalStore::RemoveDeviceDataInCacheMode(const std::string &hashDev, bool isNeedNotify) const
980 {
981     int errCode = E_OK;
982     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
983     if (handle == nullptr) {
984         LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode);
985         return errCode;
986     }
987     uint64_t recordVersion = GetAndIncreaseCacheRecordVersion();
988     LOGI("Remove device data in cache mode isNeedNotify:%d, recordVersion:%" PRIu64, isNeedNotify, recordVersion);
989     errCode = handle->RemoveDeviceDataInCacheMode(hashDev, isNeedNotify, recordVersion);
990     if (errCode != E_OK) {
991         LOGE("[SingleVerNStore] RemoveDeviceDataInCacheMode failed:%d", errCode);
992     }
993     ReleaseHandle(handle);
994     return errCode;
995 }
996 
RemoveDeviceDataNormally(const std::string & hashDev,bool isNeedNotify)997 int SQLiteSingleVerNaturalStore::RemoveDeviceDataNormally(const std::string &hashDev, bool isNeedNotify)
998 {
999     int errCode = E_OK;
1000     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1001     if (handle == nullptr) {
1002         LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode);
1003         return errCode;
1004     }
1005 
1006     std::vector<Entry> entries;
1007     if (isNeedNotify) {
1008         handle->GetAllSyncedEntries(hashDev, entries);
1009     }
1010 
1011     LOGI("Remove device data:%d", isNeedNotify);
1012     errCode = handle->RemoveDeviceData(hashDev);
1013     ReleaseHandle(handle);
1014     if (errCode == E_OK && isNeedNotify) {
1015         NotifyRemovedData(entries);
1016     }
1017     return errCode;
1018 }
1019 
NotifyRemovedData(std::vector<Entry> & entries)1020 void SQLiteSingleVerNaturalStore::NotifyRemovedData(std::vector<Entry> &entries)
1021 {
1022     if (entries.empty() || entries.size() > MAX_TOTAL_NOTIFY_ITEM_SIZE) {
1023         return;
1024     }
1025 
1026     size_t index = 0;
1027     size_t totalSize = 0;
1028     SingleVerNaturalStoreCommitNotifyData *notifyData = nullptr;
1029     while (index < entries.size()) {
1030         if (notifyData == nullptr) {
1031             notifyData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1032             if (notifyData == nullptr) {
1033                 LOGE("Failed to do commit sync removing because of OOM");
1034                 break;
1035             }
1036         }
1037 
1038         // ignore the invalid key.
1039         if (entries[index].key.size() > DBConstant::MAX_KEY_SIZE ||
1040             entries[index].value.size() > DBConstant::MAX_VALUE_SIZE) {
1041             index++;
1042             continue;
1043         }
1044 
1045         if ((entries[index].key.size() + entries[index].value.size() + totalSize) > MAX_TOTAL_NOTIFY_DATA_SIZE) {
1046             CommitAndReleaseNotifyData(notifyData, true,
1047                 static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1048             totalSize = 0;
1049             notifyData = nullptr;
1050             continue;
1051         }
1052 
1053         totalSize += (entries[index].key.size() + entries[index].value.size());
1054         notifyData->InsertCommittedData(std::move(entries[index]), DataType::DELETE, false);
1055         index++;
1056     }
1057     if (notifyData != nullptr) {
1058         CommitAndReleaseNotifyData(notifyData, true,
1059             static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1060     }
1061 }
1062 
GetHandle(bool isWrite,int & errCode,OperatePerm perm) const1063 SQLiteSingleVerStorageExecutor *SQLiteSingleVerNaturalStore::GetHandle(bool isWrite, int &errCode,
1064     OperatePerm perm) const
1065 {
1066     engineMutex_.lock_shared();
1067     if (storageEngine_ == nullptr) {
1068         errCode = -E_INVALID_DB;
1069         engineMutex_.unlock_shared(); // unlock when get handle failed.
1070         return nullptr;
1071     }
1072     // Use for check database corrupted in Asynchronous task, like cache data migrate to main database
1073     if (storageEngine_->IsEngineCorrupted()) { // LCOV_EXCL_BR_LINE
1074         CorruptNotify();
1075         errCode = -E_INVALID_PASSWD_OR_CORRUPTED_DB;
1076         engineMutex_.unlock_shared(); // unlock when get handle failed.
1077         LOGI("Handle is corrupted or invalid key, can not to get! errCode = [%d]", errCode);
1078         return nullptr;
1079     }
1080 
1081     auto handle = storageEngine_->FindExecutor(isWrite, perm, errCode);
1082     if (handle == nullptr) {
1083         engineMutex_.unlock_shared(); // unlock when get handle failed.
1084     }
1085     return static_cast<SQLiteSingleVerStorageExecutor *>(handle);
1086 }
1087 
ReleaseHandle(SQLiteSingleVerStorageExecutor * & handle) const1088 void SQLiteSingleVerNaturalStore::ReleaseHandle(SQLiteSingleVerStorageExecutor *&handle) const
1089 {
1090     if (handle == nullptr) {
1091         return;
1092     }
1093 
1094     if (storageEngine_ != nullptr) {
1095         bool isCorrupted = handle->GetCorruptedStatus();
1096         StorageExecutor *databaseHandle = handle;
1097         storageEngine_->Recycle(databaseHandle);
1098         handle = nullptr;
1099         if (isCorrupted) {
1100             CorruptNotify();
1101         }
1102     }
1103     engineMutex_.unlock_shared(); // unlock after handle used up
1104 }
1105 
RegisterNotification()1106 int SQLiteSingleVerNaturalStore::RegisterNotification()
1107 {
1108     static const std::vector<int> events {
1109         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT),
1110         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT),
1111         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT),
1112         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
1113     };
1114 
1115     for (auto event = events.begin(); event != events.end(); ++event) {
1116         int errCode = RegisterNotificationEventType(*event);
1117         if (errCode == E_OK) {
1118             continue;
1119         }
1120         LOGE("Register single version event %d failed:%d!", *event, errCode);
1121         for (auto iter = events.begin(); iter != event; ++iter) {
1122             UnRegisterNotificationEventType(*iter);
1123         }
1124         return errCode;
1125     }
1126 
1127     notificationEventsRegistered_ = true;
1128     notificationConflictEventsRegistered_ = true;
1129     return E_OK;
1130 }
1131 
ReleaseResources()1132 void SQLiteSingleVerNaturalStore::ReleaseResources()
1133 {
1134     SyncAbleKvDB::Close();
1135     if (notificationEventsRegistered_) {
1136         UnRegisterNotificationEventType(
1137             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1138         UnRegisterNotificationEventType(
1139             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT));
1140         UnRegisterNotificationEventType(
1141             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
1142         notificationEventsRegistered_ = false;
1143     }
1144 
1145     if (notificationConflictEventsRegistered_) {
1146         UnRegisterNotificationEventType(static_cast<EventType>(
1147             SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT));
1148         notificationConflictEventsRegistered_ = false;
1149     }
1150 
1151     {
1152         std::lock_guard<std::mutex> autoLock(cloudStoreMutex_);
1153         RefObject::KillAndDecObjRef(sqliteCloudKvStore_);
1154         sqliteCloudKvStore_ = nullptr;
1155     }
1156     {
1157         std::unique_lock<std::shared_mutex> lock(engineMutex_);
1158         if (storageEngine_ != nullptr) {
1159             storageEngine_->ClearEnginePasswd();
1160             (void)StorageEngineManager::ReleaseStorageEngine(storageEngine_);
1161             storageEngine_ = nullptr;
1162         }
1163     }
1164 
1165     isInitialized_ = false;
1166 }
1167 
InitConflictNotifiedFlag(SingleVerNaturalStoreCommitNotifyData * committedData)1168 void SQLiteSingleVerNaturalStore::InitConflictNotifiedFlag(SingleVerNaturalStoreCommitNotifyData *committedData)
1169 {
1170     unsigned int conflictFlag = 0;
1171     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY) != 0) {
1172         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY);
1173     }
1174     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG) != 0) {
1175         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG);
1176     }
1177     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL) != 0) {
1178         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL);
1179     }
1180     committedData->SetConflictedNotifiedFlag(static_cast<int>(conflictFlag));
1181 }
1182 
1183 // Currently this function only suitable to be call from sync in insert_record_from_sync procedure
1184 // Take attention if future coder attempt to call it in other situation procedure
SaveSyncDataItems(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo,bool checkValueContent)1185 int SQLiteSingleVerNaturalStore::SaveSyncDataItems(const QueryObject &query, std::vector<DataItem> &dataItems,
1186     const DeviceInfo &deviceInfo, bool checkValueContent)
1187 {
1188     // Sync procedure does not care readOnly Flag
1189     if (storageEngine_ == nullptr) {
1190         return -E_INVALID_DB;
1191     }
1192     int errCode = E_OK;
1193     auto offset = GetLocalTimeOffset();
1194     for (auto &item : dataItems) {
1195         // Check only the key and value size
1196         errCode = CheckDataStatus(item.key, item.value, (item.flag & DataItem::DELETE_FLAG) != 0);
1197         if (errCode != E_OK) {
1198             return errCode;
1199         }
1200         if (offset != 0) {
1201             item.modifyTime = static_cast<Timestamp>(static_cast<int64_t>(item.timestamp) - offset);
1202             item.createTime = static_cast<Timestamp>(static_cast<int64_t>(item.writeTimestamp) - offset);
1203         }
1204     }
1205     if (checkValueContent) { // LCOV_EXCL_BR_LINE
1206         CheckAmendValueContentForSyncProcedure(dataItems);
1207     }
1208     QueryObject queryInner = query;
1209     queryInner.SetSchema(GetSchemaObjectConstRef());
1210     if (IsExtendedCacheDBMode()) {
1211         errCode = SaveSyncDataToCacheDB(queryInner, dataItems, deviceInfo);
1212     } else {
1213         errCode = SaveSyncDataToMain(queryInner, dataItems, deviceInfo);
1214     }
1215     if (errCode != E_OK) {
1216         LOGE("[SingleVerNStore] SaveSyncDataItems failed:%d", errCode);
1217     }
1218     return errCode;
1219 }
1220 
SaveSyncDataToMain(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo)1221 int SQLiteSingleVerNaturalStore::SaveSyncDataToMain(const QueryObject &query, std::vector<DataItem> &dataItems,
1222     const DeviceInfo &deviceInfo)
1223 {
1224     auto *committedData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1225     if (committedData == nullptr) {
1226         LOGE("[SingleVerNStore] Failed to alloc single version notify data");
1227         return -E_OUT_OF_MEMORY;
1228     }
1229     InitConflictNotifiedFlag(committedData);
1230     Timestamp maxTimestamp = 0;
1231     bool isNeedCommit = false;
1232     int errCode = SaveSyncItems(query, dataItems, deviceInfo, maxTimestamp, committedData);
1233     if (errCode == E_OK) {
1234         isNeedCommit = true;
1235     }
1236 
1237     CommitAndReleaseNotifyData(committedData, isNeedCommit,
1238         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1239     return errCode;
1240 }
1241 
1242 // Currently, this function only suitable to be call from sync in insert_record_from_sync procedure
1243 // Take attention if future coder attempt to call it in other situation procedure
SaveSyncItems(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo,Timestamp & maxTimestamp,SingleVerNaturalStoreCommitNotifyData * commitData) const1244 int SQLiteSingleVerNaturalStore::SaveSyncItems(const QueryObject &query, std::vector<DataItem> &dataItems,
1245     const DeviceInfo &deviceInfo, Timestamp &maxTimestamp, SingleVerNaturalStoreCommitNotifyData *commitData) const
1246 {
1247     int errCode = E_OK;
1248     int innerCode = E_OK;
1249     LOGD("[SQLiteSingleVerNaturalStore::SaveSyncData] Get write handle.");
1250     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1251     if (handle == nullptr) {
1252         return errCode;
1253     }
1254     DBDfxAdapter::StartTracing();
1255     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1256     if (errCode != E_OK) {
1257         ReleaseHandle(handle);
1258         DBDfxAdapter::FinishTracing();
1259         return errCode;
1260     }
1261     errCode = handle->CheckDataWithQuery(query, dataItems, deviceInfo);
1262     if (errCode != E_OK) {
1263         goto END;
1264     }
1265     errCode = handle->PrepareForSavingData(SingleVerDataType::SYNC_TYPE);
1266     if (errCode != E_OK) {
1267         goto END;
1268     }
1269     for (auto &item: dataItems) {
1270         if (item.neglect) { // Do not save this record if it is neglected
1271             continue;
1272         }
1273         errCode = handle->SaveSyncDataItem(item, deviceInfo, maxTimestamp, commitData, true);
1274         if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1275             break;
1276         }
1277     }
1278     if (errCode == -E_NOT_FOUND) {
1279         errCode = E_OK;
1280     }
1281     innerCode = handle->ResetForSavingData(SingleVerDataType::SYNC_TYPE);
1282     if (innerCode != E_OK) {
1283         errCode = innerCode;
1284     }
1285 END:
1286     if (errCode == E_OK) {
1287         errCode = handle->Commit();
1288     } else {
1289         (void)handle->Rollback(); // Keep the error code of the first scene
1290     }
1291     DBDfxAdapter::FinishTracing();
1292     ReleaseHandle(handle);
1293     return errCode;
1294 }
1295 
SaveSyncDataToCacheDB(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo)1296 int SQLiteSingleVerNaturalStore::SaveSyncDataToCacheDB(const QueryObject &query, std::vector<DataItem> &dataItems,
1297     const DeviceInfo &deviceInfo)
1298 {
1299     int errCode = E_OK;
1300     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1301     if (handle == nullptr) {
1302         return errCode;
1303     }
1304 
1305     Timestamp maxTimestamp = 0;
1306     DBDfxAdapter::StartTracing();
1307     errCode = SaveSyncItemsInCacheMode(handle, query, dataItems, deviceInfo, maxTimestamp);
1308     if (errCode != E_OK) {
1309         LOGE("[SingleVerNStore] Failed to save sync data in cache mode, err : %d", errCode);
1310     }
1311     DBDfxAdapter::FinishTracing();
1312     ReleaseHandle(handle);
1313     return errCode;
1314 }
1315 
GetTimestampFromDB()1316 uint64_t SQLiteSingleVerNaturalStore::GetTimestampFromDB()
1317 {
1318     std::vector<uint8_t> key;
1319     std::vector<uint8_t> timeOffset;
1320     int64_t localTimeOffset = TimeHelper::BASE_OFFSET;
1321     DBCommon::StringToVector(std::string(DBConstant::LOCALTIME_OFFSET_KEY), key);
1322     int errCode = GetMetaData(key, timeOffset);
1323     if (errCode == E_OK) {
1324         std::string timeOffsetString(timeOffset.begin(), timeOffset.end());
1325         int64_t result = std::strtoll(timeOffsetString.c_str(), nullptr, DBConstant::STR_TO_LL_BY_DEVALUE);
1326         if (errno != ERANGE && result != LLONG_MIN && result != LLONG_MAX) {
1327             localTimeOffset = result;
1328         }
1329     } else {
1330         LOGW("GetTimestampFromDb::when sync not start get metadata from db failed,err=%d", errCode);
1331     }
1332     uint64_t currentSysTime = TimeHelper::GetSysCurrentTime();
1333     if (localTimeOffset < 0 && currentSysTime >= static_cast<uint64_t>(std::abs(localTimeOffset))) {
1334         return currentSysTime - static_cast<uint64_t>(std::abs(localTimeOffset));
1335     } else if (localTimeOffset >= 0 && (UINT64_MAX - currentSysTime >= static_cast<uint64_t>(localTimeOffset))) {
1336         return currentSysTime + static_cast<uint64_t>(localTimeOffset);
1337     } else {
1338         LOGW("[GetTimestampFromDB] localTimeOffset plus currentSysTime overflow");
1339         return currentSysTime;
1340     }
1341 }
1342 
GetCurrentTimestamp(bool needStartSync)1343 Timestamp SQLiteSingleVerNaturalStore::GetCurrentTimestamp(bool needStartSync)
1344 {
1345     return GetTimestamp(needStartSync);
1346 }
1347 
InitStorageEngine(const KvDBProperties & kvDBProp,bool isNeedUpdateSecOpt)1348 int SQLiteSingleVerNaturalStore::InitStorageEngine(const KvDBProperties &kvDBProp, bool isNeedUpdateSecOpt)
1349 {
1350     OpenDbProperties option;
1351     InitDataBaseOption(kvDBProp, option);
1352 
1353     bool isMemoryMode = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
1354     StorageEngineAttr poolSize = {1, 1, 1, 16}; // at most 1 write 16 read.
1355     if (isMemoryMode) {
1356         poolSize.minWriteNum = 1; // keep at least one connection.
1357     }
1358 
1359     storageEngine_->SetNotifiedCallback(
1360         [&](int eventType, KvDBCommitNotifyFilterAbleData *committedData) {
1361             if (eventType == static_cast<int>(
1362                 SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_FINISH_MIGRATE_EVENT)) {
1363                 return this->TriggerSync(eventType);
1364             }
1365             auto commitData = static_cast<SingleVerNaturalStoreCommitNotifyData *>(committedData);
1366             this->CommitAndReleaseNotifyData(commitData, true, eventType);
1367         }
1368     );
1369     storageEngine_->SetSchemaChangedCallback(
1370         [&]() {
1371             return this->UpgradeSchemaVerInMeta();
1372         }
1373     );
1374 
1375     std::string identifier = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
1376     storageEngine_->SetNeedUpdateSecOption(isNeedUpdateSecOpt);
1377     int errCode = storageEngine_->InitSQLiteStorageEngine(poolSize, option, identifier);
1378     if (errCode != E_OK) {
1379         LOGE("Init the sqlite storage engine failed:%d", errCode);
1380         return errCode;
1381     }
1382 
1383     std::lock_guard<std::mutex> autoLock(cloudStoreMutex_);
1384     if (sqliteCloudKvStore_ != nullptr) {
1385         return E_OK;
1386     }
1387     sqliteCloudKvStore_ = new(std::nothrow) SqliteCloudKvStore(this);
1388     if (sqliteCloudKvStore_ == nullptr) {
1389         return E_OUT_OF_MEMORY;
1390     }
1391     return E_OK;
1392 }
1393 
Rekey(const CipherPassword & passwd)1394 int SQLiteSingleVerNaturalStore::Rekey(const CipherPassword &passwd)
1395 {
1396     // Check the storage engine and try to disable the engine.
1397     if (storageEngine_ == nullptr) {
1398         return -E_INVALID_DB;
1399     }
1400 
1401     std::unique_ptr<SingleVerDatabaseOper> operation;
1402 
1403     // stop the syncer
1404     int errCode = storageEngine_->TryToDisable(false, OperatePerm::REKEY_MONOPOLIZE_PERM);
1405     if (errCode != E_OK) {
1406         return errCode;
1407     }
1408 
1409     LOGI("Stop the syncer for rekey");
1410     StopSyncer(true);
1411     std::this_thread::sleep_for(std::chrono::milliseconds(5));  // wait for 5 ms
1412     errCode = storageEngine_->TryToDisable(true, OperatePerm::REKEY_MONOPOLIZE_PERM);
1413     if (errCode != E_OK) {
1414         LOGE("[Rekey] Failed to disable the database: %d", errCode);
1415         goto END;
1416     }
1417 
1418     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1419         LOGE("Rekey is not supported while cache exists! state = [%d]", storageEngine_->GetEngineState());
1420         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1421         goto END;
1422     }
1423 
1424     operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1425     LOGI("Operation rekey");
1426     errCode = operation->Rekey(passwd);
1427 END:
1428     // Only maindb state have existed handle, if rekey fail other state will create error cache db
1429     // Abort can forbid get new handle, requesting handle will return BUSY and nullptr handle
1430     AbortHandle();
1431     if (errCode != -E_FORBID_CACHEDB) {
1432         storageEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
1433     } else {
1434         storageEngine_->Abort(OperatePerm::REKEY_MONOPOLIZE_PERM);
1435         errCode = E_OK;
1436     }
1437     storageEngine_->WaitWriteHandleIdle();
1438     StartSyncer();
1439     EnableHandle();
1440     return errCode;
1441 }
1442 
Export(const std::string & filePath,const CipherPassword & passwd)1443 int SQLiteSingleVerNaturalStore::Export(const std::string &filePath, const CipherPassword &passwd)
1444 {
1445     if (storageEngine_ == nullptr) {
1446         return -E_INVALID_DB;
1447     }
1448     if (MyProp().GetBoolProp(KvDBProperties::MEMORY_MODE, false)) { // LCOV_EXCL_BR_LINE
1449         return -E_NOT_SUPPORT;
1450     }
1451 
1452     // Exclusively write resources
1453     std::string localDev;
1454     GetAndResizeLocalIdentity(localDev);
1455 
1456     // The write handle is applied to prevent writing data during the export process.
1457     int errCode =  E_OK;
1458     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM);
1459     if (handle == nullptr) {
1460         return errCode;
1461     }
1462 
1463     // forbid migrate by hold write handle not release
1464     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1465         LOGE("Not support export when cacheDB existed! state = [%d]", storageEngine_->GetEngineState());
1466         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1467         ReleaseHandle(handle);
1468         return errCode;
1469     }
1470 
1471     std::unique_ptr<SingleVerDatabaseOper> operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1472     operation->SetLocalDevId(localDev);
1473     errCode = TryToDisableConnection(OperatePerm::NORMAL_WRITE);
1474     if (errCode != E_OK) {
1475         LOGE("disable connection failed! errCode %d", errCode);
1476         ReleaseHandle(handle);
1477         return errCode;
1478     }
1479     LOGD("Begin export the kv store");
1480     errCode = operation->Export(filePath, passwd);
1481 
1482     ReEnableConnection(OperatePerm::NORMAL_WRITE);
1483     ReleaseHandle(handle);
1484     return errCode;
1485 }
1486 
Import(const std::string & filePath,const CipherPassword & passwd)1487 int SQLiteSingleVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd)
1488 {
1489     if (storageEngine_ == nullptr) {
1490         return -E_INVALID_DB;
1491     }
1492     if (MyProp().GetBoolProp(KvDBProperties::MEMORY_MODE, false)) { // LCOV_EXCL_BR_LINE
1493         return -E_NOT_SUPPORT;
1494     }
1495 
1496     std::string localDev;
1497     int errCode = GetLocalIdentity(localDev);
1498     if (errCode == -E_NOT_INIT) {
1499         localDev.resize(DEVICE_ID_LEN);
1500     } else if (errCode != E_OK) {
1501         LOGE("Failed to GetLocalIdentity!");
1502         localDev.resize(0);
1503     }
1504 
1505     // stop the syncer
1506     errCode = storageEngine_->TryToDisable(false, OperatePerm::IMPORT_MONOPOLIZE_PERM);
1507     if (errCode != E_OK) {
1508         return errCode;
1509     }
1510     StopSyncer(true, true);
1511     std::this_thread::sleep_for(std::chrono::milliseconds(5)); // wait for 5 ms
1512     std::unique_ptr<SingleVerDatabaseOper> operation;
1513 
1514     errCode = storageEngine_->TryToDisable(true, OperatePerm::IMPORT_MONOPOLIZE_PERM);
1515     if (errCode != E_OK) {
1516         LOGE("[Import] Failed to disable the database: %d", errCode);
1517         goto END;
1518     }
1519 
1520     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1521         LOGE("Not support import when cacheDB existed! state = [%d]", storageEngine_->GetEngineState());
1522         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1523         goto END;
1524     }
1525 
1526     operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1527     operation->SetLocalDevId(localDev);
1528     errCode = operation->Import(filePath, passwd);
1529     if (errCode != E_OK) {
1530         goto END;
1531     }
1532 
1533     // Save create db time.
1534     storageEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
1535 
1536     errCode = SaveCreateDBTime(); // This step will start syncer
1537 
1538 END:
1539     // restore the storage engine and the syncer.
1540     AbortHandle();
1541     storageEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
1542     storageEngine_->WaitWriteHandleIdle();
1543     StartSyncer();
1544     EnableHandle();
1545     return errCode;
1546 }
1547 
CheckWritePermission() const1548 bool SQLiteSingleVerNaturalStore::CheckWritePermission() const
1549 {
1550     return !isReadOnly_;
1551 }
1552 
GetSchemaInfo() const1553 SchemaObject SQLiteSingleVerNaturalStore::GetSchemaInfo() const
1554 {
1555     return MyProp().GetSchemaConstRef();
1556 }
1557 
GetSchemaObject() const1558 SchemaObject SQLiteSingleVerNaturalStore::GetSchemaObject() const
1559 {
1560     return MyProp().GetSchema();
1561 }
1562 
GetSchemaObjectConstRef() const1563 const SchemaObject &SQLiteSingleVerNaturalStore::GetSchemaObjectConstRef() const
1564 {
1565     return MyProp().GetSchemaConstRef();
1566 }
1567 
CheckCompatible(const std::string & schema,uint8_t type) const1568 bool SQLiteSingleVerNaturalStore::CheckCompatible(const std::string &schema, uint8_t type) const
1569 {
1570     const SchemaObject &localSchema = MyProp().GetSchemaConstRef();
1571     if (!localSchema.IsSchemaValid() || schema.empty() || ReadSchemaType(type) == SchemaType::NONE) {
1572         // If at least one of local or remote is normal-kvdb, then allow sync
1573         LOGI("IsLocalSchemaDb=%d, IsRemoteSchemaDb=%d.", localSchema.IsSchemaValid(), !schema.empty());
1574         return true;
1575     }
1576     // Here both are schema-db, check their compatibility mutually
1577     SchemaObject remoteSchema;
1578     int errCode = remoteSchema.ParseFromSchemaString(schema);
1579     if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
1580         // Consider: if the parse errCode is SchemaVersionNotSupport, we can consider allow sync if schemaType equal.
1581         LOGE("Parse remote schema fail, errCode=%d.", errCode);
1582         return false;
1583     }
1584     // First, Compare remoteSchema based on localSchema
1585     errCode = localSchema.CompareAgainstSchemaObject(remoteSchema);
1586     if (errCode != -E_SCHEMA_UNEQUAL_INCOMPATIBLE) { // LCOV_EXCL_BR_LINE
1587         LOGI("Remote(Maybe newer) compatible based on local, result=%d.", errCode);
1588         return true;
1589     }
1590     // Second, Compare localSchema based on remoteSchema
1591     errCode = remoteSchema.CompareAgainstSchemaObject(localSchema);
1592     if (errCode != -E_SCHEMA_UNEQUAL_INCOMPATIBLE) { // LCOV_EXCL_BR_LINE
1593         LOGI("Local(Newer) compatible based on remote, result=%d.", errCode);
1594         return true;
1595     }
1596     LOGE("Local incompatible with remote mutually.");
1597     return false;
1598 }
1599 
InitDataBaseOption(const KvDBProperties & kvDBProp,OpenDbProperties & option)1600 void SQLiteSingleVerNaturalStore::InitDataBaseOption(const KvDBProperties &kvDBProp, OpenDbProperties &option)
1601 {
1602     std::string uri = GetDatabasePath(kvDBProp);
1603     bool isMemoryDb = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
1604     if (isMemoryDb) {
1605         std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
1606         uri = identifierDir + DBConstant::SQLITE_MEMDB_IDENTIFY;
1607         LOGD("Begin create memory natural store database");
1608     }
1609     std::string subDir = GetSubDirPath(kvDBProp);
1610     CipherType cipherType;
1611     CipherPassword passwd;
1612     kvDBProp.GetPassword(cipherType, passwd);
1613     std::string schemaStr = kvDBProp.GetSchema().ToSchemaString();
1614 
1615     bool isCreateNecessary = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
1616     std::vector<std::string> createTableSqls;
1617 
1618     SecurityOption securityOpt;
1619     if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) {
1620         securityOpt.securityLabel = kvDBProp.GetSecLabel();
1621         securityOpt.securityFlag = kvDBProp.GetSecFlag();
1622     }
1623 
1624     option = {uri, isCreateNecessary, isMemoryDb, createTableSqls, cipherType, passwd, schemaStr, subDir, securityOpt};
1625     option.conflictReslovePolicy = kvDBProp.GetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, DEFAULT_LAST_WIN);
1626     option.createDirByStoreIdOnly = kvDBProp.GetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, false);
1627 }
1628 
TransObserverTypeToRegisterFunctionType(int observerType,RegisterFuncType & type) const1629 int SQLiteSingleVerNaturalStore::TransObserverTypeToRegisterFunctionType(
1630     int observerType, RegisterFuncType &type) const
1631 {
1632     static constexpr TransPair transMap[] = {
1633         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT),
1634             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_PUT_EVENT },
1635         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT),
1636             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_SYNC_EVENT },
1637         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT),
1638             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_LOCAL_EVENT },
1639         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
1640             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_CONFLICT_EVENT },
1641     };
1642     auto funcType = GetFuncType(observerType, transMap, sizeof(transMap) / sizeof(TransPair));
1643     if (funcType == RegisterFuncType::REGISTER_FUNC_TYPE_MAX) {
1644         return -E_NOT_SUPPORT;
1645     }
1646     type = funcType;
1647     return E_OK;
1648 }
1649 
TransConflictTypeToRegisterFunctionType(int conflictType,RegisterFuncType & type) const1650 int SQLiteSingleVerNaturalStore::TransConflictTypeToRegisterFunctionType(
1651     int conflictType, RegisterFuncType &type) const
1652 {
1653     static constexpr TransPair transMap[] = {
1654         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY),
1655             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY },
1656         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG),
1657             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG },
1658         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL),
1659             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL },
1660     };
1661     auto funcType = GetFuncType(conflictType, transMap, sizeof(transMap) / sizeof(TransPair));
1662     if (funcType == RegisterFuncType::REGISTER_FUNC_TYPE_MAX) {
1663         return -E_NOT_SUPPORT;
1664     }
1665     type = funcType;
1666     return E_OK;
1667 }
1668 
GetSchema(SchemaObject & schema) const1669 int SQLiteSingleVerNaturalStore::GetSchema(SchemaObject &schema) const
1670 {
1671     int errCode = E_OK;
1672     auto handle = GetHandle(true, errCode); // Only open kvdb use, no competition for write handle
1673     if (handle == nullptr) {
1674         return errCode;
1675     }
1676 
1677     Timestamp timestamp;
1678     std::string schemaKey = DBConstant::SCHEMA_KEY;
1679     Key key(schemaKey.begin(), schemaKey.end());
1680     Value value;
1681     errCode = handle->GetKvData(SingleVerDataType::META_TYPE, key, value, timestamp);
1682     if (errCode == E_OK) {
1683         std::string schemaValue(value.begin(), value.end());
1684         errCode = schema.ParseFromSchemaString(schemaValue);
1685     } else {
1686         std::string label = MyProp().GetStringProp(DBProperties::IDENTIFIER_DATA, "");
1687         LOGI("[SqlSinStore] [%.3s] Get schema error:%d.", label.c_str(), errCode);
1688     }
1689     ReleaseHandle(handle);
1690     return errCode;
1691 }
1692 
DecideReadOnlyBaseOnSchema(const KvDBProperties & kvDBProp,bool & isReadOnly,SchemaObject & savedSchemaObj) const1693 int SQLiteSingleVerNaturalStore::DecideReadOnlyBaseOnSchema(const KvDBProperties &kvDBProp, bool &isReadOnly,
1694     SchemaObject &savedSchemaObj) const
1695 {
1696     // Check whether it is a memory db
1697     if (kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false)) {
1698         isReadOnly = false;
1699         return E_OK;
1700     }
1701     SchemaObject inputSchemaObj = kvDBProp.GetSchema();
1702     if (!inputSchemaObj.IsSchemaValid()) {
1703         int errCode = GetSchema(savedSchemaObj);
1704         if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1705             LOGE("[SqlSinStore][DecideReadOnly] GetSchema fail=%d.", errCode);
1706             return errCode;
1707         }
1708         if (savedSchemaObj.IsSchemaValid()) {
1709             isReadOnly = true;
1710             return E_OK;
1711         }
1712     }
1713     // An valid schema will not lead to readonly
1714     isReadOnly = false;
1715     return E_OK;
1716 }
1717 
InitialLocalDataTimestamp()1718 void SQLiteSingleVerNaturalStore::InitialLocalDataTimestamp()
1719 {
1720     Timestamp timestamp = GetCurrentTimestamp();
1721 
1722     int errCode = E_OK;
1723     auto handle = GetHandle(true, errCode);
1724     if (handle == nullptr) {
1725         return;
1726     }
1727 
1728     errCode = handle->UpdateLocalDataTimestamp(timestamp);
1729     if (errCode != E_OK) {
1730         LOGE("Update the timestamp for local data failed:%d", errCode);
1731     }
1732     ReleaseHandle(handle);
1733 }
1734 
GetDbProperties() const1735 const KvDBProperties &SQLiteSingleVerNaturalStore::GetDbProperties() const
1736 {
1737     return GetMyProperties();
1738 }
1739 
GetKvDBSize(const KvDBProperties & properties,uint64_t & size) const1740 int SQLiteSingleVerNaturalStore::GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const
1741 {
1742     std::string storeOnlyIdentDir;
1743     std::string storeIdentDir;
1744     GenericKvDB::GetStoreDirectory(properties, KvDBProperties::SINGLE_VER_TYPE_SQLITE, storeIdentDir,
1745         storeOnlyIdentDir);
1746     const std::vector<std::pair<const std::string &, const std::string &>> dbDir {
1747         {DBConstant::MAINDB_DIR, DBConstant::SINGLE_VER_DATA_STORE},
1748         {DBConstant::METADB_DIR, DBConstant::SINGLE_VER_META_STORE},
1749         {DBConstant::CACHEDB_DIR, DBConstant::SINGLE_VER_CACHE_STORE}};
1750     int errCode = -E_NOT_FOUND;
1751     for (const auto &item : dbDir) {
1752         std::string storeDir = storeIdentDir + item.first;
1753         std::string storeOnlyDir = storeOnlyIdentDir + item.first;
1754         int err = KvDBUtils::GetKvDbSize(storeDir, storeOnlyDir, item.second, size);
1755         if (err != -E_NOT_FOUND && err != E_OK) {
1756             return err;
1757         }
1758         if (err == E_OK) {
1759             errCode = E_OK;
1760         }
1761     }
1762     return errCode;
1763 }
1764 
AsyncDataMigration(SQLiteSingleVerStorageEngine * storageEngine) const1765 void SQLiteSingleVerNaturalStore::AsyncDataMigration(SQLiteSingleVerStorageEngine *storageEngine) const
1766 {
1767     // Delay a little time to ensure the completion of the delegate callback
1768     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_DELEGATE_CALLBACK_TIME));
1769     bool isLocked = RuntimeContext::GetInstance()->IsAccessControlled();
1770     if (!isLocked) {
1771         LOGI("Begin to migrate cache data to manDb asynchronously!");
1772         // we can't use engineMutex_ here, because ExecuteMigration will call GetHandle, it will lead to crash at
1773         // engineMutex_.lock_shared
1774         (void)StorageEngineManager::ExecuteMigration(storageEngine);
1775     }
1776 
1777     RefObject::DecObjRef(storageEngine);
1778     RefObject::DecObjRef(this);
1779 }
1780 
SaveSyncItemsInCacheMode(SQLiteSingleVerStorageExecutor * handle,const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo,Timestamp & maxTimestamp) const1781 int SQLiteSingleVerNaturalStore::SaveSyncItemsInCacheMode(SQLiteSingleVerStorageExecutor *handle,
1782     const QueryObject &query, std::vector<DataItem> &dataItems, const DeviceInfo &deviceInfo,
1783     Timestamp &maxTimestamp) const
1784 {
1785     int errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1786     if (errCode != E_OK) {
1787         return errCode;
1788     }
1789 
1790     int innerCode;
1791     const uint64_t recordVersion = GetCacheRecordVersion();
1792     errCode = handle->PrepareForSavingCacheData(SingleVerDataType::SYNC_TYPE);
1793     if (errCode != E_OK) {
1794         goto END;
1795     }
1796 
1797     for (auto &item : dataItems) {
1798         errCode = handle->SaveSyncDataItemInCacheMode(item, deviceInfo, maxTimestamp, recordVersion, query);
1799         if (errCode != E_OK && errCode != -E_NOT_FOUND) { // LCOV_EXCL_BR_LINE
1800             break;
1801         }
1802     }
1803 
1804     if (errCode == -E_NOT_FOUND) { // LCOV_EXCL_BR_LINE
1805         errCode = E_OK;
1806     }
1807 
1808     innerCode = handle->ResetForSavingCacheData(SingleVerDataType::SYNC_TYPE);
1809     if (innerCode != E_OK) { // LCOV_EXCL_BR_LINE
1810         errCode = innerCode;
1811     }
1812 END:
1813     if (errCode == E_OK) {
1814         storageEngine_->IncreaseCacheRecordVersion(); // use engine wihtin shard lock by handle
1815         errCode = handle->Commit();
1816     } else {
1817         (void)handle->Rollback(); // Keep the error code of the first scene
1818     }
1819     return errCode;
1820 }
1821 
GetDatabaseCreateTimestamp(Timestamp & outTime) const1822 int SQLiteSingleVerNaturalStore::GetDatabaseCreateTimestamp(Timestamp &outTime) const
1823 {
1824     // Found in memory.
1825     {
1826         std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
1827         if (createDBTime_ != 0) {
1828             outTime = createDBTime_;
1829             return E_OK;
1830         }
1831     }
1832 
1833     const Key key(CREATE_DB_TIME.begin(), CREATE_DB_TIME.end());
1834     Value value;
1835     int errCode = GetMetaData(key, value);
1836     if (errCode != E_OK) {
1837         LOGD("GetDatabaseCreateTimestamp failed, errCode = %d.", errCode);
1838         return errCode;
1839     }
1840 
1841     Timestamp createDBTime = 0;
1842     Parcel parcel(value.data(), value.size());
1843     (void)parcel.ReadUInt64(createDBTime);
1844     if (parcel.IsError()) {
1845         return -E_INVALID_ARGS;
1846     }
1847     outTime = createDBTime;
1848     std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
1849     createDBTime_ = createDBTime;
1850     return E_OK;
1851 }
1852 
SaveCreateDBTime()1853 int SQLiteSingleVerNaturalStore::SaveCreateDBTime()
1854 {
1855     Timestamp createDBTime = GetCurrentTimestamp();
1856     const Key key(CREATE_DB_TIME.begin(), CREATE_DB_TIME.end());
1857     Value value(Parcel::GetUInt64Len());
1858     Parcel parcel(value.data(), Parcel::GetUInt64Len());
1859     (void)parcel.WriteUInt64(createDBTime);
1860     if (parcel.IsError()) {
1861         LOGE("SaveCreateDBTime failed, something wrong in parcel.");
1862         return -E_PARSE_FAIL;
1863     }
1864 
1865     int errCode = PutMetaData(key, value, false);
1866     if (errCode != E_OK) {
1867         LOGE("SaveCreateDBTime failed, errCode = %d", errCode);
1868         return errCode;
1869     }
1870 
1871     // save in memory.
1872     std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
1873     createDBTime_ = createDBTime;
1874     return errCode;
1875 }
1876 
RemoveSubscribe(const std::vector<std::string> & subscribeIds)1877 int SQLiteSingleVerNaturalStore::RemoveSubscribe(const std::vector<std::string> &subscribeIds)
1878 {
1879     int errCode = E_OK;
1880     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1881     if (handle == nullptr) {
1882         return errCode;
1883     }
1884 
1885     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1886     if (errCode != E_OK) {
1887         ReleaseHandle(handle);
1888         return errCode;
1889     }
1890     errCode = handle->RemoveSubscribeTrigger(subscribeIds);
1891     if (errCode != E_OK) {
1892         LOGE("Remove subscribe trigger failed: %d", errCode);
1893         goto ERR;
1894     }
1895     errCode = handle->RemoveSubscribeTriggerWaterMark(subscribeIds);
1896     if (errCode != E_OK) {
1897         LOGE("Remove subscribe data water mark failed: %d", errCode);
1898     }
1899 ERR:
1900     if (errCode == E_OK) {
1901         errCode = handle->Commit();
1902     } else {
1903         (void)handle->Rollback();
1904     }
1905     ReleaseHandle(handle);
1906     return errCode;
1907 }
1908 
RemoveSubscribe(const std::string & subscribeId)1909 int SQLiteSingleVerNaturalStore::RemoveSubscribe(const std::string &subscribeId)
1910 {
1911     return RemoveSubscribe(std::vector<std::string> {subscribeId});
1912 }
1913 
RemoveAllSubscribe()1914 int SQLiteSingleVerNaturalStore::RemoveAllSubscribe()
1915 {
1916     int errCode = E_OK;
1917     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1918     if (handle == nullptr) {
1919         return errCode;
1920     }
1921     std::vector<std::string> triggers;
1922     errCode = handle->GetTriggers(DBConstant::SUBSCRIBE_QUERY_PREFIX, triggers);
1923     if (errCode != E_OK) {
1924         LOGE("Get all subscribe triggers failed. %d", errCode);
1925         ReleaseHandle(handle);
1926         return errCode;
1927     }
1928 
1929     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1930     if (errCode != E_OK) {
1931         ReleaseHandle(handle);
1932         return errCode;
1933     }
1934 
1935     Key prefixKey;
1936     errCode = handle->RemoveTrigger(triggers);
1937     if (errCode != E_OK) {
1938         LOGE("remove all subscribe triggers failed. %d", errCode);
1939         goto END;
1940     }
1941 
1942     DBCommon::StringToVector(DBConstant::SUBSCRIBE_QUERY_PREFIX, prefixKey);
1943     errCode = handle->DeleteMetaDataByPrefixKey(prefixKey);
1944     if (errCode != E_OK) {
1945         LOGE("remove all subscribe water mark failed. %d", errCode);
1946     }
1947 END:
1948     if (errCode == E_OK) {
1949         errCode = handle->Commit();
1950     } else {
1951         (void)handle->Rollback();
1952     }
1953     ReleaseHandle(handle);
1954     return errCode;
1955 }
1956 
GetAndResizeLocalIdentity(std::string & outTarget) const1957 void SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarget) const
1958 {
1959     int errCode = GetLocalIdentity(outTarget);
1960     if (errCode == -E_NOT_INIT) {
1961         outTarget.resize(DEVICE_ID_LEN);
1962     } else if (errCode != E_OK) {
1963         LOGE("Get local dev id err:%d", errCode);
1964         outTarget.resize(0);
1965     }
1966 }
1967 
GetICloudSyncInterface() const1968 ICloudSyncStorageInterface *SQLiteSingleVerNaturalStore::GetICloudSyncInterface() const
1969 {
1970     std::lock_guard<std::mutex> autoLock(cloudStoreMutex_);
1971     return sqliteCloudKvStore_;
1972 }
1973 
SetCloudDbSchema(const std::map<std::string,DataBaseSchema> & schema)1974 int SQLiteSingleVerNaturalStore::SetCloudDbSchema(const std::map<std::string, DataBaseSchema> &schema)
1975 {
1976     std::lock_guard<std::mutex> autoLock(cloudStoreMutex_);
1977     return sqliteCloudKvStore_->SetCloudDbSchema(schema);
1978 }
1979 
GetDataBaseSchemas()1980 std::map<std::string, DataBaseSchema> SQLiteSingleVerNaturalStore::GetDataBaseSchemas()
1981 {
1982     std::lock_guard<std::mutex> autoLock(cloudStoreMutex_);
1983     return sqliteCloudKvStore_->GetDataBaseSchemas();
1984 }
1985 
CheckSchemaSupportForCloudSync() const1986 bool SQLiteSingleVerNaturalStore::CheckSchemaSupportForCloudSync() const
1987 {
1988     auto schemaType = GetSchemaObject().GetSchemaType();
1989     if (schemaType != SchemaType::NONE) {
1990         LOGE("un support schema type %d for cloud sync", static_cast<int>(schemaType));
1991         return false;
1992     }
1993     return true;
1994 }
1995 DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStore)
1996 }
1997