• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 "storage_engine_manager.h"
36 #include "sqlite_single_ver_natural_store_connection.h"
37 #include "value_hash_calc.h"
38 
39 namespace DistributedDB {
40 namespace {
41     constexpr int WAIT_DELEGATE_CALLBACK_TIME = 100;
42 
43     constexpr int DEVICE_ID_LEN = 32;
44     const std::string CREATE_DB_TIME = "createDBTime";
45 
46     // Called when get multiple dev data.
47     // deviceID is the device which currently being getting. When getting one dev data, deviceID is "".
48     // dataItems is the DataItems which already be get from DB sorted by timestamp.
49     // token must not be null.
ProcessContinueToken(const DeviceID & deviceID,const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)50     void ProcessContinueToken(const DeviceID &deviceID, const std::vector<DataItem> &dataItems, int &errCode,
51         SQLiteSingleVerContinueToken *&token)
52     {
53         if (errCode != -E_UNFINISHED) { // Error happened or get data finished. Token should be cleared.
54             delete token;
55             token = nullptr;
56             return;
57         }
58 
59         if (dataItems.empty()) {
60             errCode = -E_INTERNAL_ERROR;
61             LOGE("Get data unfinished but dataitems is empty.");
62             delete token;
63             token = nullptr;
64             return;
65         }
66 
67         Timestamp nextBeginTime = dataItems.back().timestamp + 1;
68         if (nextBeginTime > INT64_MAX) {
69             nextBeginTime = INT64_MAX;
70         }
71         token->SetNextBeginTime(deviceID, nextBeginTime);
72         return;
73     }
74 
75     // Called when get one dev data.
ProcessContinueToken(const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)76     void ProcessContinueToken(const std::vector<DataItem> &dataItems, int &errCode,
77         SQLiteSingleVerContinueToken *&token)
78     {
79         ProcessContinueToken("", dataItems, errCode, token);
80     }
81 
82     // Called when get query sync data.
83     // dataItems is the DataItems which already be get from DB sorted by timestamp.
84     // token must not be null.
ProcessContinueTokenForQuerySync(const std::vector<DataItem> & dataItems,int & errCode,SQLiteSingleVerContinueToken * & token)85     void ProcessContinueTokenForQuerySync(const std::vector<DataItem> &dataItems, int &errCode,
86         SQLiteSingleVerContinueToken *&token)
87     {
88         if (errCode != -E_UNFINISHED) { // Error happened or get data finished. Token should be cleared.
89             delete token;
90             token = nullptr;
91             return;
92         }
93 
94         if (dataItems.empty()) {
95             errCode = -E_INTERNAL_ERROR;
96             LOGE("Get data unfinished but dataitems is empty.");
97             delete token;
98             token = nullptr;
99             return;
100         }
101 
102         Timestamp nextBeginTime = dataItems.back().timestamp + 1;
103         if (nextBeginTime > INT64_MAX) {
104             nextBeginTime = INT64_MAX;
105         }
106         bool getDeleteData = ((dataItems.back().flag & DataItem::DELETE_FLAG) != 0);
107         if (getDeleteData) {
108             token->FinishGetQueryData();
109             token->SetDeletedNextBeginTime("", nextBeginTime);
110         } else {
111             token->SetNextBeginTime("", nextBeginTime);
112         }
113         return;
114     }
115 
UpdateSecProperties(KvDBProperties & properties,bool isReadOnly,const SchemaObject & savedSchemaObj,const SQLiteSingleVerStorageEngine * engine)116     void UpdateSecProperties(KvDBProperties &properties, bool isReadOnly, const SchemaObject &savedSchemaObj,
117         const SQLiteSingleVerStorageEngine *engine)
118     {
119         if (isReadOnly) {
120             properties.SetSchema(savedSchemaObj);
121             properties.SetBoolProp(KvDBProperties::FIRST_OPEN_IS_READ_ONLY, true);
122         }
123         // Update the security option from the storage engine for that
124         // we will not update the security label and flag for the existed database.
125         // So the security label and flag are from the existed database.
126         if (engine == nullptr) {
127             return;
128         }
129         properties.SetIntProp(KvDBProperties::SECURITY_LABEL, engine->GetSecurityOption().securityLabel);
130         properties.SetIntProp(KvDBProperties::SECURITY_FLAG, engine->GetSecurityOption().securityFlag);
131     }
132 
GetKvEntriesByDataItems(std::vector<SingleVerKvEntry * > & entries,std::vector<DataItem> & dataItems)133     int GetKvEntriesByDataItems(std::vector<SingleVerKvEntry *> &entries, std::vector<DataItem> &dataItems)
134     {
135         int errCode = E_OK;
136         for (auto &item : dataItems) {
137             auto entry = new (std::nothrow) GenericSingleVerKvEntry();
138             if (entry == nullptr) {
139                 errCode = -E_OUT_OF_MEMORY;
140                 LOGE("GetKvEntries failed, errCode:%d", errCode);
141                 SingleVerKvEntry::Release(entries);
142                 break;
143             }
144             entry->SetEntryData(std::move(item));
145             entries.push_back(entry);
146         }
147         return errCode;
148     }
149 
CanHoldDeletedData(const std::vector<DataItem> & dataItems,const DataSizeSpecInfo & dataSizeInfo,size_t appendLen)150     bool CanHoldDeletedData(const std::vector<DataItem> &dataItems, const DataSizeSpecInfo &dataSizeInfo,
151         size_t appendLen)
152     {
153         bool reachThreshold = false;
154         size_t blockSize = 0;
155         for (size_t i = 0; !reachThreshold && i < dataItems.size(); i++) {
156             blockSize += SQLiteSingleVerStorageExecutor::GetDataItemSerialSize(dataItems[i], appendLen);
157             reachThreshold = (blockSize >= dataSizeInfo.blockSize * DBConstant::QUERY_SYNC_THRESHOLD);
158         }
159         return !reachThreshold;
160     }
161 }
162 
SQLiteSingleVerNaturalStore()163 SQLiteSingleVerNaturalStore::SQLiteSingleVerNaturalStore()
164     : currentMaxTimestamp_(0),
165       migrateCount_(0),
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       dataInterceptor_(nullptr),
176       maxLogSize_(DBConstant::MAX_LOG_SIZE_DEFAULT),
177       abortPerm_(OperatePerm::NORMAL_PERM)
178 {}
179 
~SQLiteSingleVerNaturalStore()180 SQLiteSingleVerNaturalStore::~SQLiteSingleVerNaturalStore()
181 {
182     ReleaseResources();
183 }
184 
GetDatabasePath(const KvDBProperties & kvDBProp)185 std::string SQLiteSingleVerNaturalStore::GetDatabasePath(const KvDBProperties &kvDBProp)
186 {
187     return GetSubDirPath(kvDBProp) + "/" + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
188         DBConstant::SQLITE_DB_EXTENSION;
189 }
190 
GetSubDirPath(const KvDBProperties & kvDBProp)191 std::string SQLiteSingleVerNaturalStore::GetSubDirPath(const KvDBProperties &kvDBProp)
192 {
193     std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
194     std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
195     return dataDir + "/" + identifierDir + "/" + DBConstant::SINGLE_SUB_DIR;
196 }
197 
SetUserVer(const KvDBProperties & kvDBProp,int version)198 int SQLiteSingleVerNaturalStore::SetUserVer(const KvDBProperties &kvDBProp, int version)
199 {
200     OpenDbProperties properties;
201     properties.uri = GetDatabasePath(kvDBProp);
202     bool isEncryptedDb = kvDBProp.GetBoolProp(KvDBProperties::ENCRYPTED_MODE, false);
203     if (isEncryptedDb) {
204         kvDBProp.GetPassword(properties.cipherType, properties.passwd);
205     }
206 
207     int errCode = SQLiteUtils::SetUserVer(properties, version);
208     if (errCode != E_OK) {
209         LOGE("Recover for open db failed in single version:%d", errCode);
210     }
211     return errCode;
212 }
213 
InitDatabaseContext(const KvDBProperties & kvDBProp,bool isNeedUpdateSecOpt)214 int SQLiteSingleVerNaturalStore::InitDatabaseContext(const KvDBProperties &kvDBProp, bool isNeedUpdateSecOpt)
215 {
216     int errCode = InitStorageEngine(kvDBProp, isNeedUpdateSecOpt);
217     if (errCode != E_OK) {
218         return errCode;
219     }
220     InitCurrentMaxStamp();
221     return errCode;
222 }
223 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)224 int SQLiteSingleVerNaturalStore::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
225 {
226     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
227     int errCode;
228     if (!notifier) {
229         if (lifeTimerId_ == 0) {
230             return E_OK;
231         }
232         errCode = StopLifeCycleTimer();
233         if (errCode != E_OK) {
234             LOGE("Stop the life cycle timer failed:%d", errCode);
235         }
236         return E_OK;
237     }
238 
239     if (lifeTimerId_ != 0) {
240         errCode = StopLifeCycleTimer();
241         if (errCode != E_OK) {
242             LOGE("Stop the life cycle timer failed:%d", errCode);
243         }
244     }
245     errCode = StartLifeCycleTimer(notifier);
246     if (errCode != E_OK) {
247         LOGE("Register life cycle timer failed:%d", errCode);
248     }
249     return errCode;
250 }
251 
SetAutoLifeCycleTime(uint32_t time)252 int SQLiteSingleVerNaturalStore::SetAutoLifeCycleTime(uint32_t time)
253 {
254     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
255     if (lifeTimerId_ == 0) {
256         autoLifeTime_ = time;
257     } else {
258         auto runtimeCxt = RuntimeContext::GetInstance();
259         if (runtimeCxt == nullptr) {
260             return -E_INVALID_ARGS;
261         }
262         LOGI("[SingleVer] Set life cycle to %u", time);
263         int errCode = runtimeCxt->ModifyTimer(lifeTimerId_, time);
264         if (errCode != E_OK) {
265             return errCode;
266         }
267         autoLifeTime_ = time;
268     }
269     return E_OK;
270 }
271 
GetSecurityOption(SecurityOption & option) const272 int SQLiteSingleVerNaturalStore::GetSecurityOption(SecurityOption &option) const
273 {
274     bool isMemDb = GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false);
275     if (isMemDb) {
276         LOGI("[GetSecurityOption] MemDb, no need to get security option");
277         option = SecurityOption();
278         return -E_NOT_SUPPORT;
279     }
280 
281     option.securityLabel = GetDbProperties().GetSecLabel();
282     option.securityFlag = GetDbProperties().GetSecFlag();
283 
284     return E_OK;
285 }
286 
287 namespace {
OriValueCanBeUse(int errCode)288 inline bool OriValueCanBeUse(int errCode)
289 {
290     return (errCode == -E_VALUE_MATCH);
291 }
292 
AmendValueShouldBeUse(int errCode)293 inline bool AmendValueShouldBeUse(int errCode)
294 {
295     return (errCode == -E_VALUE_MATCH_AMENDED);
296 }
297 
IsValueMismatched(int errCode)298 inline bool IsValueMismatched(int errCode)
299 {
300     return (errCode == -E_VALUE_MISMATCH_FEILD_COUNT ||
301         errCode == -E_VALUE_MISMATCH_FEILD_TYPE ||
302         errCode == -E_VALUE_MISMATCH_CONSTRAINT);
303 }
304 }
305 
CheckValueAndAmendIfNeed(ValueSource sourceType,const Value & oriValue,Value & amendValue,bool & useAmendValue) const306 int SQLiteSingleVerNaturalStore::CheckValueAndAmendIfNeed(ValueSource sourceType, const Value &oriValue,
307     Value &amendValue, bool &useAmendValue) const
308 {
309     // oriValue size may already be checked previously, but check here const little
310     if (oriValue.size() > DBConstant::MAX_VALUE_SIZE) {
311         return -E_INVALID_ARGS;
312     }
313     const SchemaObject &schemaObjRef = MyProp().GetSchemaConstRef();
314     if (!schemaObjRef.IsSchemaValid()) {
315         // Not a schema database, do not need to check more
316         return E_OK;
317     }
318     if (schemaObjRef.GetSchemaType() == SchemaType::JSON) {
319         ValueObject valueObj;
320         int errCode = valueObj.Parse(oriValue.data(), oriValue.data() + oriValue.size(), schemaObjRef.GetSkipSize());
321         if (errCode != E_OK) {
322             return -E_INVALID_FORMAT;
323         }
324         errCode = schemaObjRef.CheckValueAndAmendIfNeed(sourceType, valueObj);
325         if (OriValueCanBeUse(errCode)) {
326             useAmendValue = false;
327             return E_OK;
328         }
329         if (AmendValueShouldBeUse(errCode)) {
330             std::string amended = valueObj.ToString();
331             if (amended.size() > DBConstant::MAX_VALUE_SIZE) {
332                 LOGE("[SqlSinStore][CheckAmendValue] ValueSize=%zu exceed limit after amend.", amended.size());
333                 return -E_INVALID_FORMAT;
334             }
335             amendValue.clear();
336             amendValue.assign(amended.begin(), amended.end());
337             useAmendValue = true;
338             return E_OK;
339         }
340         if (IsValueMismatched(errCode)) {
341             return errCode;
342         }
343     } else {
344         int errCode = schemaObjRef.VerifyValue(sourceType, oriValue);
345         if (errCode == E_OK) {
346             useAmendValue = false;
347             return E_OK;
348         }
349     }
350     // Any unexpected wrong
351     return -E_INVALID_FORMAT;
352 }
353 
ClearIncompleteDatabase(const KvDBProperties & kvDBPro) const354 int SQLiteSingleVerNaturalStore::ClearIncompleteDatabase(const KvDBProperties &kvDBPro) const
355 {
356     std::string dbSubDir = SQLiteSingleVerNaturalStore::GetSubDirPath(kvDBPro);
357     if (OS::CheckPathExistence(dbSubDir + DBConstant::PATH_POSTFIX_DB_INCOMPLETE)) {
358         int errCode = DBCommon::RemoveAllFilesOfDirectory(dbSubDir);
359         if (errCode != E_OK) {
360             LOGE("Remove the incomplete database dir failed!");
361             return -E_REMOVE_FILE;
362         }
363     }
364     return E_OK;
365 }
366 
CheckDatabaseRecovery(const KvDBProperties & kvDBProp)367 int SQLiteSingleVerNaturalStore::CheckDatabaseRecovery(const KvDBProperties &kvDBProp)
368 {
369     if (kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false)) { // memory status not need recovery
370         return E_OK;
371     }
372     std::unique_ptr<SingleVerDatabaseOper> operation = std::make_unique<SingleVerDatabaseOper>(this, nullptr);
373     (void)operation->ClearExportedTempFiles(kvDBProp);
374     int errCode = operation->RekeyRecover(kvDBProp);
375     if (errCode != E_OK) {
376         LOGE("Recover from rekey failed in single version:%d", errCode);
377         return errCode;
378     }
379 
380     errCode = operation->ClearImportTempFile(kvDBProp);
381     if (errCode != E_OK) {
382         LOGE("Clear imported temp db failed in single version:%d", errCode);
383         return errCode;
384     }
385 
386     // Currently, Design for the consistency of directory and file setting secOption
387     errCode = ClearIncompleteDatabase(kvDBProp);
388     if (errCode != E_OK) {
389         LOGE("Clear incomplete database failed in single version:%d", errCode);
390         return errCode;
391     }
392     const std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
393     const std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
394     bool isCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
395     bool isMemoryDb = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
396     if (!isMemoryDb) {
397         errCode = DBCommon::CreateStoreDirectory(dataDir, identifierDir, DBConstant::SINGLE_SUB_DIR, isCreate);
398         if (errCode != E_OK) {
399             LOGE("Create single version natural store directory failed:%d", errCode);
400         }
401     }
402     return errCode;
403 }
404 
GetAndInitStorageEngine(const KvDBProperties & kvDBProp)405 int SQLiteSingleVerNaturalStore::GetAndInitStorageEngine(const KvDBProperties &kvDBProp)
406 {
407     int errCode = E_OK;
408     {
409         std::unique_lock<std::shared_mutex> lock(engineMutex_);
410         storageEngine_ =
411             static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(kvDBProp, errCode));
412         if (storageEngine_ == nullptr) {
413             return errCode;
414         }
415     }
416 
417     if (storageEngine_->IsEngineCorrupted()) {
418         LOGE("[SqlSinStore][GetAndInitStorageEngine] database engine is corrupted or invalid passwd, stop open!");
419         return -E_INVALID_PASSWD_OR_CORRUPTED_DB;
420     }
421 
422     errCode = InitDatabaseContext(kvDBProp);
423     if (errCode != E_OK) {
424         LOGE("[SqlSinStore][GetAndInitStorageEngine] Init database context fail! errCode = [%d]", errCode);
425     }
426     return errCode;
427 }
428 
Open(const KvDBProperties & kvDBProp)429 int SQLiteSingleVerNaturalStore::Open(const KvDBProperties &kvDBProp)
430 {
431     std::lock_guard<std::mutex> lock(initialMutex_);
432     if (isInitialized_) {
433         return E_OK; // avoid the reopen operation.
434     }
435 
436     int errCode = CheckDatabaseRecovery(kvDBProp);
437     if (errCode != E_OK) {
438         return errCode;
439     }
440 
441     bool isReadOnly = false;
442     SchemaObject savedSchemaObj;
443 
444     errCode = GetAndInitStorageEngine(kvDBProp);
445     if (errCode != E_OK) {
446         goto ERROR;
447     }
448 
449     errCode = RegisterNotification();
450     if (errCode != E_OK) {
451         LOGE("Register notification failed:%d", errCode);
452         goto ERROR;
453     }
454 
455     errCode = RemoveAllSubscribe();
456     if (errCode != E_OK) {
457         LOGE("[SqlSinStore][Open] remove subscribe fail! errCode = [%d]", errCode);
458         goto ERROR;
459     }
460 
461     // Here, the dbfile is created or opened, and upgrade of table structure has done.
462     // More, Upgrade of schema is also done in upgrader call in InitDatabaseContext, schema in dbfile updated if need.
463     // If inputSchema is empty, upgrader do nothing of schema, isReadOnly will be true if dbfile contain schema before.
464     // In this case, we should load the savedSchema for checking value from sync which not restricted by readOnly.
465     // If inputSchema not empty, isReadOnly will not be true, we should do nothing more.
466     errCode = DecideReadOnlyBaseOnSchema(kvDBProp, isReadOnly, savedSchemaObj);
467     if (errCode != E_OK) {
468         LOGE("[SqlSinStore][Open] DecideReadOnlyBaseOnSchema failed=%d", errCode);
469         goto ERROR;
470     }
471     // Set KvDBProperties and set Schema
472     MyProp() = kvDBProp;
473     UpdateSecProperties(MyProp(), isReadOnly, savedSchemaObj, storageEngine_);
474 
475     StartSyncer();
476     OnKill([this]() { ReleaseResources(); });
477 
478     errCode = SaveCreateDBTimeIfNotExisted();
479     if (errCode != E_OK) {
480         goto ERROR;
481     }
482 
483     InitialLocalDataTimestamp();
484     isInitialized_ = true;
485     isReadOnly_ = isReadOnly;
486     return E_OK;
487 ERROR:
488     ReleaseResources();
489     return errCode;
490 }
491 
Close()492 void SQLiteSingleVerNaturalStore::Close()
493 {
494     ReleaseResources();
495 }
496 
NewConnection(int & errCode)497 GenericKvDBConnection *SQLiteSingleVerNaturalStore::NewConnection(int &errCode)
498 {
499     SQLiteSingleVerNaturalStoreConnection *connection = new (std::nothrow) SQLiteSingleVerNaturalStoreConnection(this);
500     if (connection == nullptr) {
501         errCode = -E_OUT_OF_MEMORY;
502         return nullptr;
503     }
504     errCode = E_OK;
505     return connection;
506 }
507 
508 // Get interface type of this kvdb.
GetInterfaceType() const509 int SQLiteSingleVerNaturalStore::GetInterfaceType() const
510 {
511     return SYNC_SVD;
512 }
513 
514 // Get the interface ref-count, in order to access asynchronously.
IncRefCount()515 void SQLiteSingleVerNaturalStore::IncRefCount()
516 {
517     IncObjRef(this);
518 }
519 
520 // Drop the interface ref-count.
DecRefCount()521 void SQLiteSingleVerNaturalStore::DecRefCount()
522 {
523     DecObjRef(this);
524 }
525 
526 // Get the identifier of this kvdb.
GetIdentifier() const527 std::vector<uint8_t> SQLiteSingleVerNaturalStore::GetIdentifier() const
528 {
529     std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
530     std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
531     return identifierVect;
532 }
533 
GetDualTupleIdentifier() const534 std::vector<uint8_t> SQLiteSingleVerNaturalStore::GetDualTupleIdentifier() const
535 {
536     std::string identifier = MyProp().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
537     std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
538     return identifierVect;
539 }
540 
541 // Get interface for syncer.
GetSyncInterface()542 IKvDBSyncInterface *SQLiteSingleVerNaturalStore::GetSyncInterface()
543 {
544     return this;
545 }
546 
GetMetaData(const Key & key,Value & value) const547 int SQLiteSingleVerNaturalStore::GetMetaData(const Key &key, Value &value) const
548 {
549     if (storageEngine_ == nullptr) {
550         return -E_INVALID_DB;
551     }
552     if (key.size() > DBConstant::MAX_KEY_SIZE) {
553         return -E_INVALID_ARGS;
554     }
555 
556     int errCode = E_OK;
557     auto handle = GetHandle(true, errCode);
558     if (handle == nullptr) {
559         return errCode;
560     }
561 
562     Timestamp timestamp;
563     errCode = handle->GetKvData(SingleVerDataType::META_TYPE, key, value, timestamp);
564     ReleaseHandle(handle);
565     HeartBeatForLifeCycle();
566     return errCode;
567 }
568 
PutMetaData(const Key & key,const Value & value)569 int SQLiteSingleVerNaturalStore::PutMetaData(const Key &key, const Value &value)
570 {
571     int errCode = SQLiteSingleVerNaturalStore::CheckDataStatus(key, value, false);
572     if (errCode != E_OK) {
573         return errCode;
574     }
575 
576     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
577     if (handle == nullptr) {
578         return errCode;
579     }
580 
581     errCode = handle->PutKvData(SingleVerDataType::META_TYPE, key, value, 0, nullptr); // meta doesn't need time.
582     if (errCode != E_OK) {
583         LOGE("Put kv data err:%d", errCode);
584     }
585 
586     HeartBeatForLifeCycle();
587     ReleaseHandle(handle);
588     return errCode;
589 }
590 
591 // Delete multiple meta data records in a transaction.
DeleteMetaData(const std::vector<Key> & keys)592 int SQLiteSingleVerNaturalStore::DeleteMetaData(const std::vector<Key> &keys)
593 {
594     for (const auto &key : keys) {
595         if (key.empty() || key.size() > DBConstant::MAX_KEY_SIZE) {
596             return -E_INVALID_ARGS;
597         }
598     }
599     int errCode = E_OK;
600     auto handle = GetHandle(true, errCode);
601     if (handle == nullptr) {
602         return errCode;
603     }
604 
605     handle->StartTransaction(TransactType::IMMEDIATE);
606     errCode = handle->DeleteMetaData(keys);
607     if (errCode != E_OK) {
608         handle->Rollback();
609         LOGE("[SinStore] DeleteMetaData failed, errCode = %d", errCode);
610     } else {
611         handle->Commit();
612     }
613 
614     ReleaseHandle(handle);
615     HeartBeatForLifeCycle();
616     return errCode;
617 }
618 
GetAllMetaKeys(std::vector<Key> & keys) const619 int SQLiteSingleVerNaturalStore::GetAllMetaKeys(std::vector<Key> &keys) const
620 {
621     if (storageEngine_ == nullptr) {
622         return -E_INVALID_DB;
623     }
624     int errCode = E_OK;
625     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
626     if (handle == nullptr) {
627         return errCode;
628     }
629 
630     errCode = handle->GetAllMetaKeys(keys);
631     ReleaseHandle(handle);
632     return errCode;
633 }
634 
CommitAndReleaseNotifyData(SingleVerNaturalStoreCommitNotifyData * & committedData,bool isNeedCommit,int eventType)635 void SQLiteSingleVerNaturalStore::CommitAndReleaseNotifyData(SingleVerNaturalStoreCommitNotifyData *&committedData,
636     bool isNeedCommit, int eventType)
637 {
638     if (isNeedCommit) {
639         if (committedData != nullptr) {
640             if (!committedData->IsChangedDataEmpty()) {
641                 CommitNotify(eventType, committedData);
642             }
643             if (!committedData->IsConflictedDataEmpty()) {
644                 CommitNotify(static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
645                     committedData);
646             }
647         }
648     }
649 
650     if (committedData != nullptr) {
651         committedData->DecObjRef(committedData);
652         committedData = nullptr;
653     }
654 }
655 
GetSyncData(Timestamp begin,Timestamp end,std::vector<SingleVerKvEntry * > & entries,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const656 int SQLiteSingleVerNaturalStore::GetSyncData(Timestamp begin, Timestamp end, std::vector<SingleVerKvEntry *> &entries,
657     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
658 {
659     int errCode = CheckReadDataControlled();
660     if (errCode != E_OK) {
661         LOGE("[GetSyncData] Existed cache database can not read data, errCode = [%d]!", errCode);
662         return errCode;
663     }
664 
665     std::vector<DataItem> dataItems;
666     errCode = GetSyncData(begin, end, dataItems, continueStmtToken, dataSizeInfo);
667     if (errCode != E_OK && errCode != -E_UNFINISHED) {
668         LOGE("GetSyncData errCode:%d", errCode);
669         goto ERROR;
670     }
671 
672     for (auto &item : dataItems) {
673         GenericSingleVerKvEntry *entry = new (std::nothrow) GenericSingleVerKvEntry();
674         if (entry == nullptr) {
675             errCode = -E_OUT_OF_MEMORY;
676             LOGE("GetSyncData errCode:%d", errCode);
677             goto ERROR;
678         }
679         entry->SetEntryData(std::move(item));
680         entries.push_back(entry);
681     }
682 
683 ERROR:
684     if (errCode != E_OK && errCode != -E_UNFINISHED) {
685         SingleVerKvEntry::Release(entries);
686     }
687     HeartBeatForLifeCycle();
688     return errCode;
689 }
690 
GetSyncData(Timestamp begin,Timestamp end,std::vector<DataItem> & dataItems,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const691 int SQLiteSingleVerNaturalStore::GetSyncData(Timestamp begin, Timestamp end, std::vector<DataItem> &dataItems,
692     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
693 {
694     if (begin >= end || dataSizeInfo.blockSize > DBConstant::MAX_SYNC_BLOCK_SIZE) {
695         return -E_INVALID_ARGS;
696     }
697 
698     auto token = new (std::nothrow) SQLiteSingleVerContinueToken(begin, end);
699     if (token == nullptr) {
700         LOGE("[SQLiteSingleVerNaturalStore][NewToken] Bad alloc.");
701         return -E_OUT_OF_MEMORY;
702     }
703 
704     int errCode = E_OK;
705     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
706     if (handle == nullptr) {
707         goto ERROR;
708     }
709 
710     errCode = handle->GetSyncDataByTimestamp(dataItems, GetAppendedLen(), begin, end, dataSizeInfo);
711     if (errCode == -E_FINISHED) {
712         errCode = E_OK;
713     }
714 
715 ERROR:
716     if (errCode != -E_UNFINISHED  && errCode != E_OK) {
717         dataItems.clear();
718     }
719     ProcessContinueToken(dataItems, errCode, token);
720     continueStmtToken = static_cast<ContinueToken>(token);
721 
722     ReleaseHandle(handle);
723     return errCode;
724 }
725 
GetSyncData(QueryObject & query,const SyncTimeRange & timeRange,const DataSizeSpecInfo & dataSizeInfo,ContinueToken & continueStmtToken,std::vector<SingleVerKvEntry * > & entries) const726 int SQLiteSingleVerNaturalStore::GetSyncData(QueryObject &query, const SyncTimeRange &timeRange,
727     const DataSizeSpecInfo &dataSizeInfo, ContinueToken &continueStmtToken,
728     std::vector<SingleVerKvEntry *> &entries) const
729 {
730     if (!timeRange.IsValid()) {
731         return -E_INVALID_ARGS;
732     }
733     int errCode = CheckReadDataControlled();
734     if (errCode != E_OK) {
735         LOGE("[GetEntries] Existed cache prevents the reading from query sync[%d]!", errCode);
736         return errCode;
737     }
738 
739     query.SetSchema(GetSchemaObject());
740     auto token = new (std::nothrow) SQLiteSingleVerContinueToken(timeRange, query);
741     if (token == nullptr) {
742         LOGE("[SingleVerNStore] Allocate continue token failed.");
743         return -E_OUT_OF_MEMORY;
744     }
745 
746     int innerCode;
747     std::vector<DataItem> dataItems;
748     errCode = GetSyncDataForQuerySync(dataItems, token, dataSizeInfo);
749     if (errCode != E_OK && errCode != -E_UNFINISHED) { // The code need be sent to outside except new error happened.
750         goto ERROR;
751     }
752 
753     innerCode = GetKvEntriesByDataItems(entries, dataItems);
754     if (innerCode != E_OK) {
755         errCode = innerCode;
756         delete token;
757         token = nullptr;
758     }
759 
760 ERROR:
761     continueStmtToken = static_cast<ContinueToken>(token);
762     return errCode;
763 }
764 
765 /**
766  * Caller must ensure that parameter continueStmtToken is valid.
767  * If error happened, token will be deleted here.
768  */
GetSyncDataForQuerySync(std::vector<DataItem> & dataItems,SQLiteSingleVerContinueToken * & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const769 int SQLiteSingleVerNaturalStore::GetSyncDataForQuerySync(std::vector<DataItem> &dataItems,
770     SQLiteSingleVerContinueToken *&continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
771 {
772     int errCode = E_OK;
773     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
774     if (handle == nullptr) {
775         goto ERROR;
776     }
777 
778     errCode = handle->StartTransaction(TransactType::DEFERRED);
779     if (errCode != E_OK) {
780         LOGE("[SingleVerNStore] Start transaction for get sync data failed. err=%d", errCode);
781         goto ERROR;
782     }
783 
784     // Get query data.
785     if (!continueStmtToken->IsGetQueryDataFinished()) {
786         LOGD("[SingleVerNStore] Get query data between %" PRIu64 " and %" PRIu64 ".",
787             continueStmtToken->GetQueryBeginTime(), continueStmtToken->GetQueryEndTime());
788         errCode = handle->GetSyncDataWithQuery(continueStmtToken->GetQuery(), GetAppendedLen(), dataSizeInfo,
789             std::make_pair(continueStmtToken->GetQueryBeginTime(), continueStmtToken->GetQueryEndTime()), dataItems);
790     }
791 
792     // Get query data finished.
793     if (errCode == E_OK || errCode == -E_FINISHED) {
794         // Clear query timeRange.
795         continueStmtToken->FinishGetQueryData();
796         if (!continueStmtToken->IsGetDeletedDataFinished()) {
797             errCode = -E_UNFINISHED;
798             // Get delete time next.
799             if (CanHoldDeletedData(dataItems, dataSizeInfo, GetAppendedLen())) {
800                 LOGD("[SingleVerNStore] Get deleted data between %" PRIu64 " and %" PRIu64 ".",
801                     continueStmtToken->GetDeletedBeginTime(), continueStmtToken->GetDeletedEndTime());
802                 errCode = handle->GetDeletedSyncDataByTimestamp(dataItems, GetAppendedLen(),
803                     continueStmtToken->GetDeletedBeginTime(), continueStmtToken->GetDeletedEndTime(), dataSizeInfo);
804             }
805         }
806     }
807 
808     (void)handle->Rollback(); // roll back query statement
809     if (errCode == -E_FINISHED) {
810         errCode = E_OK;
811     }
812 
813 ERROR:
814     if (errCode != -E_UNFINISHED && errCode != E_OK) { // Error happened.
815         dataItems.clear();
816     }
817     ProcessContinueTokenForQuerySync(dataItems, errCode, continueStmtToken);
818     ReleaseHandle(handle);
819     return errCode;
820 }
821 
GetSyncDataNext(std::vector<SingleVerKvEntry * > & entries,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const822 int SQLiteSingleVerNaturalStore::GetSyncDataNext(std::vector<SingleVerKvEntry *> &entries,
823     ContinueToken &continueStmtToken, const DataSizeSpecInfo &dataSizeInfo) const
824 {
825     int errCode = CheckReadDataControlled();
826     if (errCode != E_OK) {
827         LOGE("[GetSyncDataNext] Existed cache database can not read data, errCode = [%d]!", errCode);
828         return errCode;
829     }
830 
831     std::vector<DataItem> dataItems;
832     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
833     if (token->IsQuerySync()) {
834         errCode = GetSyncDataForQuerySync(dataItems, token, dataSizeInfo);
835         continueStmtToken = static_cast<ContinueToken>(token);
836     } else {
837         errCode = GetSyncDataNext(dataItems, continueStmtToken, dataSizeInfo);
838     }
839 
840     if (errCode != E_OK && errCode != -E_UNFINISHED) {
841         LOGE("GetSyncDataNext errCode:%d", errCode);
842         return errCode;
843     }
844 
845     int innerErrCode = GetKvEntriesByDataItems(entries, dataItems);
846     if (innerErrCode != E_OK) {
847         errCode = innerErrCode;
848         ReleaseContinueToken(continueStmtToken);
849     }
850     return errCode;
851 }
852 
GetSyncDataNext(std::vector<DataItem> & dataItems,ContinueToken & continueStmtToken,const DataSizeSpecInfo & dataSizeInfo) const853 int SQLiteSingleVerNaturalStore::GetSyncDataNext(std::vector<DataItem> &dataItems, ContinueToken &continueStmtToken,
854     const DataSizeSpecInfo &dataSizeInfo) const
855 {
856     if (dataSizeInfo.blockSize > DBConstant::MAX_SYNC_BLOCK_SIZE) {
857         return -E_INVALID_ARGS;
858     }
859 
860     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
861     if (token == nullptr || !(token->CheckValid())) {
862         LOGE("[SingleVerNaturalStore][GetSyncDataNext] invalid continue token.");
863         return -E_INVALID_ARGS;
864     }
865 
866     int errCode = E_OK;
867     SQLiteSingleVerStorageExecutor *handle = GetHandle(false, errCode);
868     if (handle == nullptr) {
869         ReleaseContinueToken(continueStmtToken);
870         return errCode;
871     }
872 
873     errCode = handle->GetSyncDataByTimestamp(dataItems, GetAppendedLen(), token->GetQueryBeginTime(),
874         token->GetQueryEndTime(), dataSizeInfo);
875     if (errCode == -E_FINISHED) {
876         errCode = E_OK;
877     }
878 
879     ProcessContinueToken(dataItems, errCode, token);
880     continueStmtToken = static_cast<ContinueToken>(token);
881 
882     ReleaseHandle(handle);
883     return errCode;
884 }
885 
ReleaseContinueToken(ContinueToken & continueStmtToken) const886 void SQLiteSingleVerNaturalStore::ReleaseContinueToken(ContinueToken &continueStmtToken) const
887 {
888     auto token = static_cast<SQLiteSingleVerContinueToken *>(continueStmtToken);
889     if (token == nullptr || !(token->CheckValid())) {
890         LOGE("[SQLiteSingleVerNaturalStore][ReleaseContinueToken] Input is not a continue token.");
891         return;
892     }
893     delete token;
894     continueStmtToken = nullptr;
895 }
896 
PutSyncDataWithQuery(const QueryObject & query,const std::vector<SingleVerKvEntry * > & entries,const std::string & deviceName)897 int SQLiteSingleVerNaturalStore::PutSyncDataWithQuery(const QueryObject &query,
898     const std::vector<SingleVerKvEntry *> &entries, const std::string &deviceName)
899 {
900     if (deviceName.length() > DBConstant::MAX_DEV_LENGTH) {
901         LOGW("Device length is invalid for sync put");
902         return -E_INVALID_ARGS;
903     }
904     HeartBeatForLifeCycle();
905     DeviceInfo deviceInfo = {false, deviceName};
906     if (deviceName.empty()) {
907         deviceInfo.deviceName = "Unknown";
908     }
909 
910     std::vector<DataItem> dataItems;
911     for (const auto itemEntry : entries) {
912         auto *entry = static_cast<GenericSingleVerKvEntry *>(itemEntry);
913         if (entry != nullptr) {
914             DataItem item;
915             item.origDev = entry->GetOrigDevice();
916             item.flag = entry->GetFlag();
917             item.timestamp = entry->GetTimestamp();
918             item.writeTimestamp = entry->GetWriteTimestamp();
919             entry->GetKey(item.key);
920             entry->GetValue(item.value);
921             dataItems.push_back(item);
922         }
923     }
924 
925     int errCode = SaveSyncDataItems(query, dataItems, deviceInfo, true); // Current is true to check value content
926     if (errCode != E_OK) {
927         LOGE("PutSyncData failed:%d", errCode);
928     }
929 
930     return errCode;
931 }
932 
GetMaxTimestamp(Timestamp & stamp) const933 void SQLiteSingleVerNaturalStore::GetMaxTimestamp(Timestamp &stamp) const
934 {
935     std::lock_guard<std::mutex> lock(maxTimestampMutex_);
936     stamp = currentMaxTimestamp_;
937 }
938 
SetMaxTimestamp(Timestamp timestamp)939 void SQLiteSingleVerNaturalStore::SetMaxTimestamp(Timestamp timestamp)
940 {
941     std::lock_guard<std::mutex> lock(maxTimestampMutex_);
942     if (timestamp > currentMaxTimestamp_) {
943         currentMaxTimestamp_ = timestamp;
944     }
945 }
946 
947 // In sync procedure, call this function
RemoveDeviceData(const std::string & deviceName,bool isNeedNotify)948 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, bool isNeedNotify)
949 {
950     if (deviceName.empty() || deviceName.length() > DBConstant::MAX_DEV_LENGTH) {
951         return -E_INVALID_ARGS;
952     }
953     LOGI("[RemoveDeviceData] %s{private} rebuild, clear history data", deviceName.c_str());
954     return RemoveDeviceData(deviceName, isNeedNotify, true);
955 }
956 
GetExistsDeviceList(std::set<std::string> & devices) const957 int SQLiteSingleVerNaturalStore::GetExistsDeviceList(std::set<std::string> &devices) const
958 {
959     int errCode = E_OK;
960     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
961     if (handle == nullptr) {
962         LOGE("[SingleVerNStore] GetExistsDeviceList get handle failed:%d", errCode);
963         return errCode;
964     }
965     errCode = handle->GetExistsDevicesFromMeta(devices);
966     if (errCode != E_OK) {
967         LOGE("[SingleVerNStore] Get remove device list from meta failed. err=%d", errCode);
968     }
969     ReleaseHandle(handle);
970     return errCode;
971 }
972 
973 // In local procedure, call this function
RemoveDeviceData(const std::string & deviceName,bool isNeedNotify,bool isInSync)974 int SQLiteSingleVerNaturalStore::RemoveDeviceData(const std::string &deviceName, bool isNeedNotify, bool isInSync)
975 {
976     if (!isInSync && !CheckWritePermission()) {
977         return -E_NOT_PERMIT;
978     }
979     std::string hashDeviceId;
980     bool hash = false;
981     do {
982         if (!deviceName.empty() && !isInSync) {
983             int errCode = GetHashDeviceId(deviceName, hashDeviceId);
984             if (errCode == -E_NOT_SUPPORT) {
985                 break;
986             }
987             if (errCode != E_OK) {
988                 return errCode;
989             }
990             hash = true;
991         }
992     } while (false);
993     if (!hash) {
994         hashDeviceId = DBCommon::TransferHashString(deviceName);
995     }
996 
997     return RemoveDeviceDataInner(hashDeviceId, isNeedNotify);
998 }
999 
RemoveDeviceDataInCacheMode(const std::string & hashDev,bool isNeedNotify) const1000 int SQLiteSingleVerNaturalStore::RemoveDeviceDataInCacheMode(const std::string &hashDev, bool isNeedNotify) const
1001 {
1002     int errCode = E_OK;
1003     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1004     if (handle == nullptr) {
1005         LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode);
1006         return errCode;
1007     }
1008     uint64_t recordVersion = GetAndIncreaseCacheRecordVersion();
1009     LOGI("Remove device data in cache mode isNeedNotify:%d, recordVersion:%" PRIu64, isNeedNotify, recordVersion);
1010     errCode = handle->RemoveDeviceDataInCacheMode(hashDev, isNeedNotify, recordVersion);
1011     if (errCode != E_OK) {
1012         LOGE("[SingleVerNStore] RemoveDeviceDataInCacheMode failed:%d", errCode);
1013     }
1014     ReleaseHandle(handle);
1015     return errCode;
1016 }
1017 
RemoveDeviceDataNormally(const std::string & hashDev,bool isNeedNotify)1018 int SQLiteSingleVerNaturalStore::RemoveDeviceDataNormally(const std::string &hashDev, bool isNeedNotify)
1019 {
1020     int errCode = E_OK;
1021     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1022     if (handle == nullptr) {
1023         LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode);
1024         return errCode;
1025     }
1026 
1027     std::vector<Entry> entries;
1028     if (isNeedNotify) {
1029         handle->GetAllSyncedEntries(hashDev, entries);
1030     }
1031 
1032     LOGI("Remove device data:%d", isNeedNotify);
1033     errCode = handle->RemoveDeviceData(hashDev);
1034     ReleaseHandle(handle);
1035     if (errCode == E_OK && isNeedNotify) {
1036         NotifyRemovedData(entries);
1037     }
1038     return errCode;
1039 }
1040 
NotifyRemovedData(std::vector<Entry> & entries)1041 void SQLiteSingleVerNaturalStore::NotifyRemovedData(std::vector<Entry> &entries)
1042 {
1043     if (entries.empty() || entries.size() > MAX_TOTAL_NOTIFY_ITEM_SIZE) {
1044         return;
1045     }
1046 
1047     size_t index = 0;
1048     size_t totalSize = 0;
1049     SingleVerNaturalStoreCommitNotifyData *notifyData = nullptr;
1050     while (index < entries.size()) {
1051         if (notifyData == nullptr) {
1052             notifyData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1053             if (notifyData == nullptr) {
1054                 LOGE("Failed to do commit sync removing because of OOM");
1055                 break;
1056             }
1057         }
1058 
1059         // ignore the invalid key.
1060         if (entries[index].key.size() > DBConstant::MAX_KEY_SIZE ||
1061             entries[index].value.size() > DBConstant::MAX_VALUE_SIZE) {
1062             index++;
1063             continue;
1064         }
1065 
1066         if ((entries[index].key.size() + entries[index].value.size() + totalSize) > MAX_TOTAL_NOTIFY_DATA_SIZE) {
1067             CommitAndReleaseNotifyData(notifyData, true,
1068                 static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1069             totalSize = 0;
1070             notifyData = nullptr;
1071             continue;
1072         }
1073 
1074         totalSize += (entries[index].key.size() + entries[index].value.size());
1075         notifyData->InsertCommittedData(std::move(entries[index]), DataType::DELETE, false);
1076         index++;
1077     }
1078     if (notifyData != nullptr) {
1079         CommitAndReleaseNotifyData(notifyData, true,
1080             static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1081     }
1082 }
1083 
GetHandle(bool isWrite,int & errCode,OperatePerm perm) const1084 SQLiteSingleVerStorageExecutor *SQLiteSingleVerNaturalStore::GetHandle(bool isWrite, int &errCode,
1085     OperatePerm perm) const
1086 {
1087     engineMutex_.lock_shared();
1088     if (storageEngine_ == nullptr) {
1089         errCode = -E_INVALID_DB;
1090         engineMutex_.unlock_shared(); // unlock when get handle failed.
1091         return nullptr;
1092     }
1093     // Use for check database corrupted in Asynchronous task, like cache data migrate to main database
1094     if (storageEngine_->IsEngineCorrupted()) {
1095         CorruptNotify();
1096         errCode = -E_INVALID_PASSWD_OR_CORRUPTED_DB;
1097         engineMutex_.unlock_shared(); // unlock when get handle failed.
1098         LOGI("Handle is corrupted or invalid passwd, can not to get! errCode = [%d]", errCode);
1099         return nullptr;
1100     }
1101 
1102     auto handle = storageEngine_->FindExecutor(isWrite, perm, errCode);
1103     if (handle == nullptr) {
1104         engineMutex_.unlock_shared(); // unlock when get handle failed.
1105     }
1106     return static_cast<SQLiteSingleVerStorageExecutor *>(handle);
1107 }
1108 
ReleaseHandle(SQLiteSingleVerStorageExecutor * & handle) const1109 void SQLiteSingleVerNaturalStore::ReleaseHandle(SQLiteSingleVerStorageExecutor *&handle) const
1110 {
1111     if (handle == nullptr) {
1112         return;
1113     }
1114 
1115     if (storageEngine_ != nullptr) {
1116         bool isCorrupted = handle->GetCorruptedStatus();
1117         StorageExecutor *databaseHandle = handle;
1118         storageEngine_->Recycle(databaseHandle);
1119         handle = nullptr;
1120         if (isCorrupted) {
1121             CorruptNotify();
1122         }
1123     }
1124     engineMutex_.unlock_shared(); // unlock after handle used up
1125 }
1126 
RegisterNotification()1127 int SQLiteSingleVerNaturalStore::RegisterNotification()
1128 {
1129     static const std::vector<int> events {
1130         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT),
1131         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT),
1132         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT),
1133         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
1134     };
1135 
1136     for (auto event = events.begin(); event != events.end(); ++event) {
1137         int errCode = RegisterNotificationEventType(*event);
1138         if (errCode == E_OK) {
1139             continue;
1140         }
1141         LOGE("Register single version event %d failed:%d!", *event, errCode);
1142         for (auto iter = events.begin(); iter != event; ++iter) {
1143             UnRegisterNotificationEventType(*iter);
1144         }
1145         return errCode;
1146     }
1147 
1148     notificationEventsRegistered_ = true;
1149     notificationConflictEventsRegistered_ = true;
1150     return E_OK;
1151 }
1152 
ReleaseResources()1153 void SQLiteSingleVerNaturalStore::ReleaseResources()
1154 {
1155     SyncAbleKvDB::Close();
1156     if (notificationEventsRegistered_) {
1157         UnRegisterNotificationEventType(
1158             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1159         UnRegisterNotificationEventType(
1160             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT));
1161         UnRegisterNotificationEventType(
1162             static_cast<EventType>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT));
1163         notificationEventsRegistered_ = false;
1164     }
1165 
1166     if (notificationConflictEventsRegistered_) {
1167         UnRegisterNotificationEventType(static_cast<EventType>(
1168             SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT));
1169         notificationConflictEventsRegistered_ = false;
1170     }
1171 
1172     {
1173         std::unique_lock<std::mutex> migrateLock(migrateMutex_);
1174         migrateCv_.wait(migrateLock, [this] {
1175             return migrateCount_ <= 0;
1176         });
1177     }
1178 
1179     {
1180         std::unique_lock<std::shared_mutex> lock(engineMutex_);
1181         if (storageEngine_ != nullptr) {
1182             storageEngine_->ClearEnginePasswd();
1183             (void)StorageEngineManager::ReleaseStorageEngine(storageEngine_);
1184             storageEngine_ = nullptr;
1185         }
1186     }
1187 
1188     isInitialized_ = false;
1189 }
1190 
InitCurrentMaxStamp()1191 void SQLiteSingleVerNaturalStore::InitCurrentMaxStamp()
1192 {
1193     if (storageEngine_ == nullptr) {
1194         return;
1195     }
1196     int errCode = E_OK;
1197     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1198     if (handle == nullptr) {
1199         return;
1200     }
1201 
1202     handle->InitCurrentMaxStamp(currentMaxTimestamp_);
1203     LOGD("Init max timestamp:%" PRIu64, currentMaxTimestamp_);
1204     ReleaseHandle(handle);
1205 }
1206 
InitConflictNotifiedFlag(SingleVerNaturalStoreCommitNotifyData * committedData)1207 void SQLiteSingleVerNaturalStore::InitConflictNotifiedFlag(SingleVerNaturalStoreCommitNotifyData *committedData)
1208 {
1209     unsigned int conflictFlag = 0;
1210     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY) != 0) {
1211         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY);
1212     }
1213     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG) != 0) {
1214         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG);
1215     }
1216     if (GetRegisterFunctionCount(RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL) != 0) {
1217         conflictFlag |= static_cast<unsigned>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL);
1218     }
1219     committedData->SetConflictedNotifiedFlag(static_cast<int>(conflictFlag));
1220 }
1221 
1222 // Currently this function only suitable to be call from sync in insert_record_from_sync procedure
1223 // 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)1224 int SQLiteSingleVerNaturalStore::SaveSyncDataItems(const QueryObject &query, std::vector<DataItem> &dataItems,
1225     const DeviceInfo &deviceInfo, bool checkValueContent)
1226 {
1227     // Sync procedure does not care readOnly Flag
1228     if (storageEngine_ == nullptr) {
1229         return -E_INVALID_DB;
1230     }
1231     int errCode = E_OK;
1232     for (const auto &item : dataItems) {
1233         // Check only the key and value size
1234         errCode = CheckDataStatus(item.key, item.value, (item.flag & DataItem::DELETE_FLAG) != 0);
1235         if (errCode != E_OK) {
1236             return errCode;
1237         }
1238     }
1239     if (checkValueContent) {
1240         CheckAmendValueContentForSyncProcedure(dataItems);
1241     }
1242     QueryObject queryInner = query;
1243     queryInner.SetSchema(GetSchemaObjectConstRef());
1244     if (IsExtendedCacheDBMode()) {
1245         errCode = SaveSyncDataToCacheDB(queryInner, dataItems, deviceInfo);
1246     } else {
1247         errCode = SaveSyncDataToMain(queryInner, dataItems, deviceInfo);
1248     }
1249     if (errCode != E_OK) {
1250         LOGE("[SingleVerNStore] SaveSyncDataItems failed:%d", errCode);
1251     }
1252     return errCode;
1253 }
1254 
SaveSyncDataToMain(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo)1255 int SQLiteSingleVerNaturalStore::SaveSyncDataToMain(const QueryObject &query, std::vector<DataItem> &dataItems,
1256     const DeviceInfo &deviceInfo)
1257 {
1258     auto *committedData = new (std::nothrow) SingleVerNaturalStoreCommitNotifyData;
1259     if (committedData == nullptr) {
1260         LOGE("[SingleVerNStore] Failed to alloc single version notify data");
1261         return -E_OUT_OF_MEMORY;
1262     }
1263     InitConflictNotifiedFlag(committedData);
1264     Timestamp maxTimestamp = 0;
1265     bool isNeedCommit = false;
1266     int errCode = SaveSyncItems(query, dataItems, deviceInfo, maxTimestamp, committedData);
1267     if (errCode == E_OK) {
1268         isNeedCommit = true;
1269         SetMaxTimestamp(maxTimestamp);
1270     }
1271 
1272     CommitAndReleaseNotifyData(committedData, isNeedCommit,
1273         static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT));
1274     return errCode;
1275 }
1276 
1277 // Currently, this function only suitable to be call from sync in insert_record_from_sync procedure
1278 // 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) const1279 int SQLiteSingleVerNaturalStore::SaveSyncItems(const QueryObject &query, std::vector<DataItem> &dataItems,
1280     const DeviceInfo &deviceInfo, Timestamp &maxTimestamp, SingleVerNaturalStoreCommitNotifyData *commitData) const
1281 {
1282     int errCode = E_OK;
1283     int innerCode = E_OK;
1284     LOGD("[SQLiteSingleVerNaturalStore::SaveSyncData] Get write handle.");
1285     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1286     if (handle == nullptr) {
1287         return errCode;
1288     }
1289     DBDfxAdapter::StartTraceSQL();
1290     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
1291     if (errCode != E_OK) {
1292         ReleaseHandle(handle);
1293         DBDfxAdapter::FinishTraceSQL();
1294         return errCode;
1295     }
1296     bool isPermitForceWrite = !(GetDbProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false));
1297     errCode = handle->CheckDataWithQuery(query, dataItems, deviceInfo);
1298     if (errCode != E_OK) {
1299         goto END;
1300     }
1301     errCode = handle->PrepareForSavingData(SingleVerDataType::SYNC_TYPE);
1302     if (errCode != E_OK) {
1303         goto END;
1304     }
1305     for (auto &item: dataItems) {
1306         if (item.neglect) { // Do not save this record if it is neglected
1307             continue;
1308         }
1309         errCode = handle->SaveSyncDataItem(item, deviceInfo, maxTimestamp, commitData, isPermitForceWrite);
1310         if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1311             break;
1312         }
1313     }
1314     if (errCode == -E_NOT_FOUND) {
1315         errCode = E_OK;
1316     }
1317     innerCode = handle->ResetForSavingData(SingleVerDataType::SYNC_TYPE);
1318     if (innerCode != E_OK) {
1319         errCode = innerCode;
1320     }
1321 END:
1322     if (errCode == E_OK) {
1323         errCode = handle->Commit();
1324     } else {
1325         (void)handle->Rollback(); // Keep the error code of the first scene
1326     }
1327     DBDfxAdapter::FinishTraceSQL();
1328     ReleaseHandle(handle);
1329     return errCode;
1330 }
1331 
SaveSyncDataToCacheDB(const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo)1332 int SQLiteSingleVerNaturalStore::SaveSyncDataToCacheDB(const QueryObject &query, std::vector<DataItem> &dataItems,
1333     const DeviceInfo &deviceInfo)
1334 {
1335     int errCode = E_OK;
1336     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
1337     if (handle == nullptr) {
1338         return errCode;
1339     }
1340 
1341     Timestamp maxTimestamp = 0;
1342     DBDfxAdapter::StartTraceSQL();
1343     errCode = SaveSyncItemsInCacheMode(handle, query, dataItems, deviceInfo, maxTimestamp);
1344     if (errCode != E_OK) {
1345         LOGE("[SingleVerNStore] Failed to save sync data in cache mode, err : %d", errCode);
1346     } else {
1347         SetMaxTimestamp(maxTimestamp);
1348     }
1349     DBDfxAdapter::FinishTraceSQL();
1350     ReleaseHandle(handle);
1351     return errCode;
1352 }
1353 
GetCurrentTimestamp()1354 Timestamp SQLiteSingleVerNaturalStore::GetCurrentTimestamp()
1355 {
1356     return GetTimestamp();
1357 }
1358 
InitStorageEngine(const KvDBProperties & kvDBProp,bool isNeedUpdateSecOpt)1359 int SQLiteSingleVerNaturalStore::InitStorageEngine(const KvDBProperties &kvDBProp, bool isNeedUpdateSecOpt)
1360 {
1361     OpenDbProperties option;
1362     InitDataBaseOption(kvDBProp, option);
1363 
1364     bool isMemoryMode = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
1365     StorageEngineAttr poolSize = {1, 1, 1, 16}; // at most 1 write 16 read.
1366     if (isMemoryMode) {
1367         poolSize.minWriteNum = 1; // keep at least one connection.
1368     }
1369 
1370     storageEngine_->SetNotifiedCallback(
1371         [&](int eventType, KvDBCommitNotifyFilterAbleData *committedData) {
1372             if (eventType == static_cast<int>(
1373                 SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_FINISH_MIGRATE_EVENT)) {
1374                 return this->TriggerSync(eventType);
1375             }
1376             auto commitData = static_cast<SingleVerNaturalStoreCommitNotifyData *>(committedData);
1377             this->CommitAndReleaseNotifyData(commitData, true, eventType);
1378         }
1379     );
1380 
1381     std::string identifier = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
1382     storageEngine_->SetNeedUpdateSecOption(isNeedUpdateSecOpt);
1383     int errCode = storageEngine_->InitSQLiteStorageEngine(poolSize, option, identifier);
1384     if (errCode != E_OK) {
1385         LOGE("Init the sqlite storage engine failed:%d", errCode);
1386     }
1387     return errCode;
1388 }
1389 
Rekey(const CipherPassword & passwd)1390 int SQLiteSingleVerNaturalStore::Rekey(const CipherPassword &passwd)
1391 {
1392     // Check the storage engine and try to disable the engine.
1393     if (storageEngine_ == nullptr) {
1394         return -E_INVALID_DB;
1395     }
1396 
1397     std::unique_ptr<SingleVerDatabaseOper> operation;
1398 
1399     // stop the syncer
1400     int errCode = storageEngine_->TryToDisable(false, OperatePerm::REKEY_MONOPOLIZE_PERM);
1401     if (errCode != E_OK) {
1402         return errCode;
1403     }
1404 
1405     LOGI("Stop the syncer for rekey");
1406     StopSyncer(true);
1407     std::this_thread::sleep_for(std::chrono::milliseconds(5));  // wait for 5 ms
1408     errCode = storageEngine_->TryToDisable(true, OperatePerm::REKEY_MONOPOLIZE_PERM);
1409     if (errCode != E_OK) {
1410         LOGE("[Rekey] Failed to disable the database: %d", errCode);
1411         goto END;
1412     }
1413 
1414     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1415         LOGE("Rekey is not supported while cache exists! state = [%d]", storageEngine_->GetEngineState());
1416         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1417         goto END;
1418     }
1419 
1420     operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1421     LOGI("Operation rekey");
1422     errCode = operation->Rekey(passwd);
1423 END:
1424     // Only maindb state have existed handle, if rekey fail other state will create error cache db
1425     // Abort can forbid get new handle, requesting handle will return BUSY and nullptr handle
1426     AbortHandle();
1427     if (errCode != -E_FORBID_CACHEDB) {
1428         storageEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
1429     } else {
1430         storageEngine_->Abort(OperatePerm::REKEY_MONOPOLIZE_PERM);
1431         errCode = E_OK;
1432     }
1433     storageEngine_->WaitWriteHandleIdle();
1434     StartSyncer();
1435     EnableHandle();
1436     return errCode;
1437 }
1438 
Export(const std::string & filePath,const CipherPassword & passwd)1439 int SQLiteSingleVerNaturalStore::Export(const std::string &filePath, const CipherPassword &passwd)
1440 {
1441     if (storageEngine_ == nullptr) {
1442         return -E_INVALID_DB;
1443     }
1444     if (MyProp().GetBoolProp(KvDBProperties::MEMORY_MODE, false)) {
1445         return -E_NOT_SUPPORT;
1446     }
1447 
1448     // Exclusively write resources
1449     std::string localDev;
1450     int errCode = GetAndResizeLocalIdentity(localDev);
1451 
1452     // The write handle is applied to prevent writing data during the export process.
1453     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode, OperatePerm::NORMAL_PERM);
1454     if (handle == nullptr) {
1455         return errCode;
1456     }
1457 
1458     // forbid migrate by hold write handle not release
1459     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1460         LOGE("Not support export when cacheDB existed! state = [%d]", storageEngine_->GetEngineState());
1461         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1462         ReleaseHandle(handle);
1463         return errCode;
1464     }
1465 
1466     std::unique_ptr<SingleVerDatabaseOper> operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1467     operation->SetLocalDevId(localDev);
1468     errCode = TryToDisableConnection(OperatePerm::NORMAL_WRITE);
1469     if (errCode != E_OK) {
1470         LOGE("disable connection failed! errCode %d", errCode);
1471         ReleaseHandle(handle);
1472         return errCode;
1473     }
1474     LOGI("Begin export the kv store");
1475     errCode = operation->Export(filePath, passwd);
1476 
1477     ReEnableConnection(OperatePerm::NORMAL_WRITE);
1478     ReleaseHandle(handle);
1479     return errCode;
1480 }
1481 
Import(const std::string & filePath,const CipherPassword & passwd)1482 int SQLiteSingleVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd)
1483 {
1484     if (storageEngine_ == nullptr) {
1485         return -E_INVALID_DB;
1486     }
1487     if (MyProp().GetBoolProp(KvDBProperties::MEMORY_MODE, false)) {
1488         return -E_NOT_SUPPORT;
1489     }
1490 
1491     std::string localDev;
1492     int errCode = GetLocalIdentity(localDev);
1493     if (errCode == -E_NOT_INIT) {
1494         localDev.resize(DEVICE_ID_LEN);
1495     } else if (errCode != E_OK) {
1496         LOGE("Failed to GetLocalIdentity!");
1497         localDev.resize(0);
1498     }
1499 
1500     // stop the syncer
1501     errCode = storageEngine_->TryToDisable(false, OperatePerm::IMPORT_MONOPOLIZE_PERM);
1502     if (errCode != E_OK) {
1503         return errCode;
1504     }
1505     StopSyncer(true);
1506     std::this_thread::sleep_for(std::chrono::milliseconds(5)); // wait for 5 ms
1507     std::unique_ptr<SingleVerDatabaseOper> operation;
1508 
1509     errCode = storageEngine_->TryToDisable(true, OperatePerm::IMPORT_MONOPOLIZE_PERM);
1510     if (errCode != E_OK) {
1511         LOGE("[Import] Failed to disable the database: %d", errCode);
1512         goto END;
1513     }
1514 
1515     if (storageEngine_->GetEngineState() != EngineState::MAINDB) {
1516         LOGE("Not support import when cacheDB existed! state = [%d]", storageEngine_->GetEngineState());
1517         errCode = (storageEngine_->GetEngineState() == EngineState::CACHEDB) ? -E_NOT_SUPPORT : -E_BUSY;
1518         goto END;
1519     }
1520 
1521     operation = std::make_unique<SingleVerDatabaseOper>(this, storageEngine_);
1522     operation->SetLocalDevId(localDev);
1523     errCode = operation->Import(filePath, passwd);
1524     if (errCode != E_OK) {
1525         goto END;
1526     }
1527 
1528     // Save create db time.
1529     storageEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
1530 
1531     // Get current max timestamp after import and before start syncer, reflash local time offset
1532     InitCurrentMaxStamp();
1533     errCode = SaveCreateDBTime(); // This step will start syncer
1534 
1535 END:
1536     // restore the storage engine and the syncer.
1537     AbortHandle();
1538     storageEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
1539     storageEngine_->WaitWriteHandleIdle();
1540     StartSyncer();
1541     EnableHandle();
1542     return errCode;
1543 }
1544 
CheckWritePermission() const1545 bool SQLiteSingleVerNaturalStore::CheckWritePermission() const
1546 {
1547     return !isReadOnly_;
1548 }
1549 
GetSchemaInfo() const1550 SchemaObject SQLiteSingleVerNaturalStore::GetSchemaInfo() const
1551 {
1552     return MyProp().GetSchemaConstRef();
1553 }
1554 
GetSchemaObject() const1555 SchemaObject SQLiteSingleVerNaturalStore::GetSchemaObject() const
1556 {
1557     return MyProp().GetSchema();
1558 }
1559 
GetSchemaObjectConstRef() const1560 const SchemaObject &SQLiteSingleVerNaturalStore::GetSchemaObjectConstRef() const
1561 {
1562     return MyProp().GetSchemaConstRef();
1563 }
1564 
CheckCompatible(const std::string & schema,uint8_t type) const1565 bool SQLiteSingleVerNaturalStore::CheckCompatible(const std::string &schema, uint8_t type) const
1566 {
1567     const SchemaObject &localSchema = MyProp().GetSchemaConstRef();
1568     if (!localSchema.IsSchemaValid() || schema.empty() || ReadSchemaType(type) == SchemaType::NONE) {
1569         // If at least one of local or remote is normal-kvdb, then allow sync
1570         LOGI("IsLocalSchemaDb=%d, IsRemoteSchemaDb=%d.", localSchema.IsSchemaValid(), !schema.empty());
1571         return true;
1572     }
1573     // Here both are schema-db, check their compatibility mutually
1574     SchemaObject remoteSchema;
1575     int errCode = remoteSchema.ParseFromSchemaString(schema);
1576     if (errCode != E_OK) {
1577         // Consider: if the parse errCode is SchemaVersionNotSupport, we can consider allow sync if schemaType equal.
1578         LOGE("Parse remote schema fail, errCode=%d.", errCode);
1579         return false;
1580     }
1581     // First, Compare remoteSchema based on localSchema
1582     errCode = localSchema.CompareAgainstSchemaObject(remoteSchema);
1583     if (errCode != -E_SCHEMA_UNEQUAL_INCOMPATIBLE) {
1584         LOGI("Remote(Maybe newer) compatible based on local, result=%d.", errCode);
1585         return true;
1586     }
1587     // Second, Compare localSchema based on remoteSchema
1588     errCode = remoteSchema.CompareAgainstSchemaObject(localSchema);
1589     if (errCode != -E_SCHEMA_UNEQUAL_INCOMPATIBLE) {
1590         LOGI("Local(Newer) compatible based on remote, result=%d.", errCode);
1591         return true;
1592     }
1593     LOGE("Local incompatible with remote mutually.");
1594     return false;
1595 }
1596 
InitDataBaseOption(const KvDBProperties & kvDBProp,OpenDbProperties & option)1597 void SQLiteSingleVerNaturalStore::InitDataBaseOption(const KvDBProperties &kvDBProp, OpenDbProperties &option)
1598 {
1599     std::string uri = GetDatabasePath(kvDBProp);
1600     bool isMemoryDb = kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
1601     if (isMemoryDb) {
1602         std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
1603         uri = identifierDir + DBConstant::SQLITE_MEMDB_IDENTIFY;
1604         LOGD("Begin create memory natural store database");
1605     }
1606     std::string subDir = GetSubDirPath(kvDBProp);
1607     CipherType cipherType;
1608     CipherPassword passwd;
1609     kvDBProp.GetPassword(cipherType, passwd);
1610     std::string schemaStr = kvDBProp.GetSchema().ToSchemaString();
1611 
1612     bool isCreateNecessary = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
1613     std::vector<std::string> createTableSqls;
1614 
1615     SecurityOption securityOpt;
1616     if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) {
1617         securityOpt.securityLabel = kvDBProp.GetSecLabel();
1618         securityOpt.securityFlag = kvDBProp.GetSecFlag();
1619     }
1620 
1621     option = {uri, isCreateNecessary, isMemoryDb, createTableSqls, cipherType, passwd, schemaStr, subDir, securityOpt};
1622     option.conflictReslovePolicy = kvDBProp.GetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, DEFAULT_LAST_WIN);
1623     option.createDirByStoreIdOnly = kvDBProp.GetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, false);
1624 }
1625 
TransObserverTypeToRegisterFunctionType(int observerType,RegisterFuncType & type) const1626 int SQLiteSingleVerNaturalStore::TransObserverTypeToRegisterFunctionType(
1627     int observerType, RegisterFuncType &type) const
1628 {
1629     static constexpr TransPair transMap[] = {
1630         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_PUT_EVENT),
1631             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_PUT_EVENT },
1632         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_SYNC_EVENT),
1633             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_SYNC_EVENT },
1634         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_NS_LOCAL_PUT_EVENT),
1635             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_LOCAL_EVENT },
1636         { static_cast<int>(SQLiteGeneralNSNotificationEventType::SQLITE_GENERAL_CONFLICT_EVENT),
1637             RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_CONFLICT_EVENT },
1638     };
1639     auto funcType = GetFuncType(observerType, transMap, sizeof(transMap) / sizeof(TransPair));
1640     if (funcType == RegisterFuncType::REGISTER_FUNC_TYPE_MAX) {
1641         return -E_NOT_SUPPORT;
1642     }
1643     type = funcType;
1644     return E_OK;
1645 }
1646 
TransConflictTypeToRegisterFunctionType(int conflictType,RegisterFuncType & type) const1647 int SQLiteSingleVerNaturalStore::TransConflictTypeToRegisterFunctionType(
1648     int conflictType, RegisterFuncType &type) const
1649 {
1650     static constexpr TransPair transMap[] = {
1651         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ONLY),
1652             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ONLY },
1653         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_FOREIGN_KEY_ORIG),
1654             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_FOREIGN_KEY_ORIG },
1655         { static_cast<int>(SQLiteGeneralNSConflictType::SQLITE_GENERAL_NS_NATIVE_ALL),
1656             RegisterFuncType::CONFLICT_SINGLE_VERSION_NS_NATIVE_ALL },
1657     };
1658     auto funcType = GetFuncType(conflictType, transMap, sizeof(transMap) / sizeof(TransPair));
1659     if (funcType == RegisterFuncType::REGISTER_FUNC_TYPE_MAX) {
1660         return -E_NOT_SUPPORT;
1661     }
1662     type = funcType;
1663     return E_OK;
1664 }
1665 
GetFuncType(int index,const TransPair * transMap,int32_t len)1666 RegisterFuncType SQLiteSingleVerNaturalStore::GetFuncType(int index, const TransPair *transMap, int32_t len)
1667 {
1668     int32_t head = 0;
1669     int32_t end = len - 1;
1670     while (head <= end) {
1671         int32_t mid = (head + end) / 2;
1672         if (transMap[mid].index < index) {
1673             head = mid + 1;
1674             continue;
1675         }
1676         if (transMap[mid].index > index) {
1677             end = mid - 1;
1678             continue;
1679         }
1680         return transMap[mid].funcType;
1681     }
1682     return RegisterFuncType::REGISTER_FUNC_TYPE_MAX;
1683 }
1684 
GetSchema(SchemaObject & schema) const1685 int SQLiteSingleVerNaturalStore::GetSchema(SchemaObject &schema) const
1686 {
1687     int errCode = E_OK;
1688     auto handle = GetHandle(true, errCode); // Only open kvdb use, no competition for write handle
1689     if (handle == nullptr) {
1690         return errCode;
1691     }
1692 
1693     Timestamp timestamp;
1694     std::string schemaKey = DBConstant::SCHEMA_KEY;
1695     Key key(schemaKey.begin(), schemaKey.end());
1696     Value value;
1697     errCode = handle->GetKvData(SingleVerDataType::META_TYPE, key, value, timestamp);
1698     if (errCode == E_OK) {
1699         std::string schemaValue(value.begin(), value.end());
1700         errCode = schema.ParseFromSchemaString(schemaValue);
1701     } else {
1702         LOGI("[SqlSinStore] Get schema error:%d.", errCode);
1703     }
1704     ReleaseHandle(handle);
1705     return errCode;
1706 }
1707 
DecideReadOnlyBaseOnSchema(const KvDBProperties & kvDBProp,bool & isReadOnly,SchemaObject & savedSchemaObj) const1708 int SQLiteSingleVerNaturalStore::DecideReadOnlyBaseOnSchema(const KvDBProperties &kvDBProp, bool &isReadOnly,
1709     SchemaObject &savedSchemaObj) const
1710 {
1711     // Check whether it is a memory db
1712     if (kvDBProp.GetBoolProp(KvDBProperties::MEMORY_MODE, false)) {
1713         isReadOnly = false;
1714         return E_OK;
1715     }
1716     SchemaObject inputSchemaObj = kvDBProp.GetSchema();
1717     if (!inputSchemaObj.IsSchemaValid()) {
1718         int errCode = GetSchema(savedSchemaObj);
1719         if (errCode != E_OK && errCode != -E_NOT_FOUND) {
1720             LOGE("[SqlSinStore][DecideReadOnly] GetSchema fail=%d.", errCode);
1721             return errCode;
1722         }
1723         if (savedSchemaObj.IsSchemaValid()) {
1724             isReadOnly = true;
1725             return E_OK;
1726         }
1727     }
1728     // An valid schema will not lead to readonly
1729     isReadOnly = false;
1730     return E_OK;
1731 }
1732 
InitialLocalDataTimestamp()1733 void SQLiteSingleVerNaturalStore::InitialLocalDataTimestamp()
1734 {
1735     Timestamp timestamp = GetCurrentTimestamp();
1736 
1737     int errCode = E_OK;
1738     auto handle = GetHandle(true, errCode);
1739     if (handle == nullptr) {
1740         return;
1741     }
1742 
1743     errCode = handle->UpdateLocalDataTimestamp(timestamp);
1744     if (errCode != E_OK) {
1745         LOGE("Update the timestamp for local data failed:%d", errCode);
1746     }
1747     ReleaseHandle(handle);
1748 }
1749 
GetDbProperties() const1750 const KvDBProperties &SQLiteSingleVerNaturalStore::GetDbProperties() const
1751 {
1752     return GetMyProperties();
1753 }
1754 
RemoveKvDB(const KvDBProperties & properties)1755 int SQLiteSingleVerNaturalStore::RemoveKvDB(const KvDBProperties &properties)
1756 {
1757     // To avoid leakage, the engine resources are forced to be released
1758     const std::string identifier = properties.GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
1759     (void)StorageEngineManager::ForceReleaseStorageEngine(identifier);
1760 
1761     // Only care the data directory and the db name.
1762     std::string storeOnlyDir;
1763     std::string storeDir;
1764     GenericKvDB::GetStoreDirectory(properties, KvDBProperties::SINGLE_VER_TYPE, storeDir, storeOnlyDir);
1765 
1766     const std::vector<std::pair<const std::string &, const std::string &>> dbDir {
1767         {DBConstant::MAINDB_DIR, DBConstant::SINGLE_VER_DATA_STORE},
1768         {DBConstant::METADB_DIR, DBConstant::SINGLE_VER_META_STORE},
1769         {DBConstant::CACHEDB_DIR, DBConstant::SINGLE_VER_CACHE_STORE}};
1770 
1771     bool isAllNotFound = true;
1772     for (const auto &item : dbDir) {
1773         std::string currentDir = storeDir + item.first + "/";
1774         std::string currentOnlyDir = storeOnlyDir + item.first + "/";
1775         int errCode = KvDBUtils::RemoveKvDB(currentDir, currentOnlyDir, item.second);
1776         if (errCode != -E_NOT_FOUND) {
1777             if (errCode != E_OK) {
1778                 return errCode;
1779             }
1780             isAllNotFound = false;
1781         }
1782     };
1783     if (isAllNotFound) {
1784         return -E_NOT_FOUND;
1785     }
1786 
1787     int errCode = DBCommon::RemoveAllFilesOfDirectory(storeDir, true);
1788     if (errCode != E_OK) {
1789         return errCode;
1790     }
1791     return DBCommon::RemoveAllFilesOfDirectory(storeOnlyDir, true);
1792 }
1793 
GetKvDBSize(const KvDBProperties & properties,uint64_t & size) const1794 int SQLiteSingleVerNaturalStore::GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const
1795 {
1796     std::string storeOnlyIdentDir;
1797     std::string storeIdentDir;
1798     GenericKvDB::GetStoreDirectory(properties, KvDBProperties::SINGLE_VER_TYPE, storeIdentDir, storeOnlyIdentDir);
1799     const std::vector<std::pair<const std::string &, const std::string &>> dbDir {
1800         {DBConstant::MAINDB_DIR, DBConstant::SINGLE_VER_DATA_STORE},
1801         {DBConstant::METADB_DIR, DBConstant::SINGLE_VER_META_STORE},
1802         {DBConstant::CACHEDB_DIR, DBConstant::SINGLE_VER_CACHE_STORE}};
1803     int errCode = -E_NOT_FOUND;
1804     for (const auto &item : dbDir) {
1805         std::string storeDir = storeIdentDir + item.first;
1806         std::string storeOnlyDir = storeOnlyIdentDir + item.first;
1807         int err = KvDBUtils::GetKvDbSize(storeDir, storeOnlyDir, item.second, size);
1808         if (err != -E_NOT_FOUND && err != E_OK) {
1809             return err;
1810         }
1811         if (err == E_OK) {
1812             errCode = E_OK;
1813         }
1814     }
1815     return errCode;
1816 }
1817 
GetDbPropertyForUpdate()1818 KvDBProperties &SQLiteSingleVerNaturalStore::GetDbPropertyForUpdate()
1819 {
1820     return MyProp();
1821 }
1822 
HeartBeatForLifeCycle() const1823 void SQLiteSingleVerNaturalStore::HeartBeatForLifeCycle() const
1824 {
1825     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
1826     int errCode = ResetLifeCycleTimer();
1827     if (errCode != E_OK) {
1828         LOGE("Heart beat for life cycle failed:%d", errCode);
1829     }
1830 }
1831 
StartLifeCycleTimer(const DatabaseLifeCycleNotifier & notifier) const1832 int SQLiteSingleVerNaturalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier &notifier) const
1833 {
1834     auto runtimeCxt = RuntimeContext::GetInstance();
1835     if (runtimeCxt == nullptr) {
1836         return -E_INVALID_ARGS;
1837     }
1838     RefObject::IncObjRef(this);
1839     TimerId timerId = 0;
1840     int errCode = runtimeCxt->SetTimer(autoLifeTime_,
1841         [this](TimerId id) -> int {
1842             std::lock_guard<std::mutex> lock(lifeCycleMutex_);
1843             if (lifeCycleNotifier_) {
1844                 std::string identifier;
1845                 if (GetMyProperties().GetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false)) {
1846                     identifier = GetMyProperties().GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
1847                 } else {
1848                     identifier = GetMyProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
1849                 }
1850                 auto userId = GetMyProperties().GetStringProp(DBProperties::USER_ID, "");
1851                 lifeCycleNotifier_(identifier, userId);
1852             }
1853             return 0;
1854         },
1855         [this]() {
1856             int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() {
1857                 RefObject::DecObjRef(this);
1858             });
1859             if (ret != E_OK) {
1860                 LOGE("SQLiteSingleVerNaturalStore timer finalizer ScheduleTask, errCode %d", ret);
1861             }
1862         },
1863         timerId);
1864     if (errCode != E_OK) {
1865         lifeTimerId_ = 0;
1866         LOGE("SetTimer failed:%d", errCode);
1867         RefObject::DecObjRef(this);
1868         return errCode;
1869     }
1870 
1871     lifeCycleNotifier_ = notifier;
1872     lifeTimerId_ = timerId;
1873     return E_OK;
1874 }
1875 
ResetLifeCycleTimer() const1876 int SQLiteSingleVerNaturalStore::ResetLifeCycleTimer() const
1877 {
1878     if (lifeTimerId_ == 0) {
1879         return E_OK;
1880     }
1881     auto lifeNotifier = lifeCycleNotifier_;
1882     lifeCycleNotifier_ = nullptr;
1883     int errCode = StopLifeCycleTimer();
1884     if (errCode != E_OK) {
1885         LOGE("[Reset timer]Stop the life cycle timer failed:%d", errCode);
1886     }
1887     return StartLifeCycleTimer(lifeNotifier);
1888 }
1889 
StopLifeCycleTimer() const1890 int SQLiteSingleVerNaturalStore::StopLifeCycleTimer() const
1891 {
1892     auto runtimeCxt = RuntimeContext::GetInstance();
1893     if (runtimeCxt == nullptr) {
1894         return -E_INVALID_ARGS;
1895     }
1896     if (lifeTimerId_ != 0) {
1897         TimerId timerId = lifeTimerId_;
1898         lifeTimerId_ = 0;
1899         runtimeCxt->RemoveTimer(timerId, false);
1900     }
1901     return E_OK;
1902 }
1903 
IsDataMigrating() const1904 bool SQLiteSingleVerNaturalStore::IsDataMigrating() const
1905 {
1906     if (storageEngine_ == nullptr) {
1907         return false;
1908     }
1909 
1910     if (storageEngine_->IsMigrating()) {
1911         LOGD("Migrating now.");
1912         return true;
1913     }
1914     return false;
1915 }
1916 
SetConnectionFlag(bool isExisted) const1917 void SQLiteSingleVerNaturalStore::SetConnectionFlag(bool isExisted) const
1918 {
1919     if (storageEngine_ != nullptr) {
1920         storageEngine_->SetConnectionFlag(isExisted);
1921     }
1922 }
1923 
TriggerToMigrateData() const1924 int SQLiteSingleVerNaturalStore::TriggerToMigrateData() const
1925 {
1926     RefObject::IncObjRef(this);
1927     {
1928         std::unique_lock<std::mutex> lock(migrateMutex_);
1929         migrateCount_++;
1930     }
1931     int errCode = RuntimeContext::GetInstance()->ScheduleTask(
1932         std::bind(&SQLiteSingleVerNaturalStore::AsyncDataMigration, this));
1933     if (errCode != E_OK) {
1934         {
1935             std::unique_lock<std::mutex> lock(migrateMutex_);
1936             migrateCount_--;
1937         }
1938         migrateCv_.notify_all();
1939         RefObject::DecObjRef(this);
1940         LOGE("[SingleVerNStore] Trigger to migrate data failed : %d.", errCode);
1941     }
1942     return errCode;
1943 }
1944 
IsCacheDBMode() const1945 bool SQLiteSingleVerNaturalStore::IsCacheDBMode() const
1946 {
1947     if (storageEngine_ == nullptr) {
1948         LOGE("[SingleVerNStore] IsCacheDBMode storage engine is invalid.");
1949         return false;
1950     }
1951     EngineState engineState = storageEngine_->GetEngineState();
1952     return (engineState == EngineState::CACHEDB);
1953 }
1954 
IsExtendedCacheDBMode() const1955 bool SQLiteSingleVerNaturalStore::IsExtendedCacheDBMode() const
1956 {
1957     if (storageEngine_ == nullptr) {
1958         LOGE("[SingleVerNStore] storage engine is invalid.");
1959         return false;
1960     }
1961     EngineState engineState = storageEngine_->GetEngineState();
1962     return (engineState == EngineState::CACHEDB || engineState == EngineState::MIGRATING ||
1963         engineState == EngineState::ATTACHING);
1964 }
1965 
CheckReadDataControlled() const1966 int SQLiteSingleVerNaturalStore::CheckReadDataControlled() const
1967 {
1968     if (IsExtendedCacheDBMode()) {
1969         int err = IsCacheDBMode() ? -E_EKEYREVOKED : -E_BUSY;
1970         LOGE("Existed cache database can not read data, errCode = [%d]!", err);
1971         return err;
1972     }
1973     return E_OK;
1974 }
1975 
IncreaseCacheRecordVersion() const1976 void SQLiteSingleVerNaturalStore::IncreaseCacheRecordVersion() const
1977 {
1978     if (storageEngine_ == nullptr) {
1979         LOGE("[SingleVerNStore] Increase cache version storage engine is invalid.");
1980         return;
1981     }
1982     storageEngine_->IncreaseCacheRecordVersion();
1983 }
1984 
GetCacheRecordVersion() const1985 uint64_t SQLiteSingleVerNaturalStore::GetCacheRecordVersion() const
1986 {
1987     if (storageEngine_ == nullptr) {
1988         LOGE("[SingleVerNStore] Get cache version storage engine is invalid.");
1989         return 0;
1990     }
1991     return storageEngine_->GetCacheRecordVersion();
1992 }
1993 
GetAndIncreaseCacheRecordVersion() const1994 uint64_t SQLiteSingleVerNaturalStore::GetAndIncreaseCacheRecordVersion() const
1995 {
1996     if (storageEngine_ == nullptr) {
1997         LOGE("[SingleVerNStore] Get cache version storage engine is invalid.");
1998         return 0;
1999     }
2000     return storageEngine_->GetAndIncreaseCacheRecordVersion();
2001 }
2002 
AsyncDataMigration() const2003 void SQLiteSingleVerNaturalStore::AsyncDataMigration() const
2004 {
2005     // Delay a little time to ensure the completion of the delegate callback
2006     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_DELEGATE_CALLBACK_TIME));
2007     bool isLocked = RuntimeContext::GetInstance()->IsAccessControlled();
2008     if (!isLocked) {
2009         LOGI("Begin to migrate cache data to manDb asynchronously!");
2010         // we can't use engineMutex_ here, because ExecuteMigration will call GetHandle, it will lead to crash at
2011         // engineMutex_.lock_shared
2012         (void)StorageEngineManager::ExecuteMigration(storageEngine_);
2013     }
2014 
2015     {
2016         std::unique_lock<std::mutex> lock(migrateMutex_);
2017         migrateCount_--;
2018     }
2019     migrateCv_.notify_all();
2020 
2021     RefObject::DecObjRef(this);
2022 }
2023 
CheckAmendValueContentForSyncProcedure(std::vector<DataItem> & dataItems) const2024 void SQLiteSingleVerNaturalStore::CheckAmendValueContentForSyncProcedure(std::vector<DataItem> &dataItems) const
2025 {
2026     const SchemaObject &schemaObjRef = MyProp().GetSchemaConstRef();
2027     if (!schemaObjRef.IsSchemaValid()) {
2028         // Not a schema database, do not need to check more
2029         return;
2030     }
2031     uint32_t deleteCount = 0;
2032     uint32_t amendCount = 0;
2033     uint32_t neglectCount = 0;
2034     for (auto &eachItem : dataItems) {
2035         if ((eachItem.flag & DataItem::DELETE_FLAG) == DataItem::DELETE_FLAG ||
2036             (eachItem.flag & DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) == DataItem::REMOTE_DEVICE_DATA_MISS_QUERY) {
2037             // Delete record not concerned
2038             deleteCount++;
2039             continue;
2040         }
2041         bool useAmendValue = false;
2042         int errCode = CheckValueAndAmendIfNeed(ValueSource::FROM_SYNC, eachItem.value, eachItem.value, useAmendValue);
2043         if (errCode != E_OK) {
2044             eachItem.neglect = true;
2045             neglectCount++;
2046             continue;
2047         }
2048         if (useAmendValue) {
2049             amendCount++;
2050         }
2051     }
2052     LOGI("[SqlSinStore][CheckAmendForSync] OriCount=%zu, DeleteCount=%u, AmendCount=%u, NeglectCount=%u",
2053         dataItems.size(), deleteCount, amendCount, neglectCount);
2054 }
2055 
SaveSyncItemsInCacheMode(SQLiteSingleVerStorageExecutor * handle,const QueryObject & query,std::vector<DataItem> & dataItems,const DeviceInfo & deviceInfo,Timestamp & maxTimestamp) const2056 int SQLiteSingleVerNaturalStore::SaveSyncItemsInCacheMode(SQLiteSingleVerStorageExecutor *handle,
2057     const QueryObject &query, std::vector<DataItem> &dataItems, const DeviceInfo &deviceInfo,
2058     Timestamp &maxTimestamp) const
2059 {
2060     int errCode = handle->StartTransaction(TransactType::IMMEDIATE);
2061     if (errCode != E_OK) {
2062         return errCode;
2063     }
2064 
2065     int innerCode;
2066     const uint64_t recordVersion = GetCacheRecordVersion();
2067     errCode = handle->PrepareForSavingCacheData(SingleVerDataType::SYNC_TYPE);
2068     if (errCode != E_OK) {
2069         goto END;
2070     }
2071 
2072     for (auto &item : dataItems) {
2073         errCode = handle->SaveSyncDataItemInCacheMode(item, deviceInfo, maxTimestamp, recordVersion, query);
2074         if (errCode != E_OK && errCode != -E_NOT_FOUND) {
2075             break;
2076         }
2077     }
2078 
2079     if (errCode == -E_NOT_FOUND) {
2080         errCode = E_OK;
2081     }
2082 
2083     innerCode = handle->ResetForSavingCacheData(SingleVerDataType::SYNC_TYPE);
2084     if (innerCode != E_OK) {
2085         errCode = innerCode;
2086     }
2087 END:
2088     if (errCode == E_OK) {
2089         storageEngine_->IncreaseCacheRecordVersion(); // use engine wihtin shard lock by handle
2090         errCode = handle->Commit();
2091     } else {
2092         (void)handle->Rollback(); // Keep the error code of the first scene
2093     }
2094     return errCode;
2095 }
2096 
NotifyRemotePushFinished(const std::string & targetId) const2097 void SQLiteSingleVerNaturalStore::NotifyRemotePushFinished(const std::string &targetId) const
2098 {
2099     std::string identifier = DBCommon::VectorToHexString(GetIdentifier());
2100     LOGI("label:%.6s sourceTarget: %s{private} push finished", identifier.c_str(), targetId.c_str());
2101     NotifyRemotePushFinishedInner(targetId);
2102 }
2103 
GetDatabaseCreateTimestamp(Timestamp & outTime) const2104 int SQLiteSingleVerNaturalStore::GetDatabaseCreateTimestamp(Timestamp &outTime) const
2105 {
2106     // Found in memory.
2107     {
2108         std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
2109         if (createDBTime_ != 0) {
2110             outTime = createDBTime_;
2111             return E_OK;
2112         }
2113     }
2114 
2115     const Key key(CREATE_DB_TIME.begin(), CREATE_DB_TIME.end());
2116     Value value;
2117     int errCode = GetMetaData(key, value);
2118     if (errCode != E_OK) {
2119         LOGD("GetDatabaseCreateTimestamp failed, errCode = %d.", errCode);
2120         return errCode;
2121     }
2122 
2123     Timestamp createDBTime = 0;
2124     Parcel parcel(value.data(), value.size());
2125     (void)parcel.ReadUInt64(createDBTime);
2126     if (parcel.IsError()) {
2127         return -E_INVALID_ARGS;
2128     }
2129     outTime = createDBTime;
2130     std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
2131     createDBTime_ = createDBTime;
2132     return E_OK;
2133 }
2134 
CheckIntegrity() const2135 int SQLiteSingleVerNaturalStore::CheckIntegrity() const
2136 {
2137     int errCode = E_OK;
2138     auto handle = GetHandle(true, errCode);
2139     if (handle == nullptr) {
2140         return errCode;
2141     }
2142 
2143     errCode = handle->CheckIntegrity();
2144     ReleaseHandle(handle);
2145     return errCode;
2146 }
2147 
SaveCreateDBTime()2148 int SQLiteSingleVerNaturalStore::SaveCreateDBTime()
2149 {
2150     Timestamp createDBTime = GetCurrentTimestamp();
2151     const Key key(CREATE_DB_TIME.begin(), CREATE_DB_TIME.end());
2152     Value value(Parcel::GetUInt64Len());
2153     Parcel parcel(value.data(), Parcel::GetUInt64Len());
2154     (void)parcel.WriteUInt64(createDBTime);
2155     if (parcel.IsError()) {
2156         LOGE("SaveCreateDBTime failed, something wrong in parcel.");
2157         return -E_PARSE_FAIL;
2158     }
2159 
2160     int errCode = PutMetaData(key, value);
2161     if (errCode != E_OK) {
2162         LOGE("SaveCreateDBTime failed, errCode = %d", errCode);
2163         return errCode;
2164     }
2165 
2166     // save in memory.
2167     std::lock_guard<std::mutex> autoLock(createDBTimeMutex_);
2168     createDBTime_ = createDBTime;
2169     return errCode;
2170 }
2171 
SaveCreateDBTimeIfNotExisted()2172 int SQLiteSingleVerNaturalStore::SaveCreateDBTimeIfNotExisted()
2173 {
2174     Timestamp createDBTime = 0;
2175     int errCode = GetDatabaseCreateTimestamp(createDBTime);
2176     if (errCode == -E_NOT_FOUND) {
2177         errCode = SaveCreateDBTime();
2178     }
2179     if (errCode != E_OK) {
2180         LOGE("SaveCreateDBTimeIfNotExisted failed, errCode=%d.", errCode);
2181     }
2182     return errCode;
2183 }
2184 
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const2185 int SQLiteSingleVerNaturalStore::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
2186 {
2187     if (keyPrefix.empty() || keyPrefix.size() > DBConstant::MAX_KEY_SIZE) {
2188         return -E_INVALID_ARGS;
2189     }
2190 
2191     int errCode = E_OK;
2192     auto handle = GetHandle(true, errCode);
2193     if (handle == nullptr) {
2194         return errCode;
2195     }
2196 
2197     errCode = handle->DeleteMetaDataByPrefixKey(keyPrefix);
2198     if (errCode != E_OK) {
2199         LOGE("[SinStore] DeleteMetaData by prefix key failed, errCode = %d", errCode);
2200     }
2201 
2202     ReleaseHandle(handle);
2203     HeartBeatForLifeCycle();
2204     return errCode;
2205 }
2206 
GetCompressionOption(bool & needCompressOnSync,uint8_t & compressionRate) const2207 int SQLiteSingleVerNaturalStore::GetCompressionOption(bool &needCompressOnSync, uint8_t &compressionRate) const
2208 {
2209     needCompressOnSync = GetDbProperties().GetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, false);
2210     compressionRate = GetDbProperties().GetIntProp(KvDBProperties::COMPRESSION_RATE,
2211         DBConstant::DEFAULT_COMPTRESS_RATE);
2212     return E_OK;
2213 }
2214 
GetCompressionAlgo(std::set<CompressAlgorithm> & algorithmSet) const2215 int SQLiteSingleVerNaturalStore::GetCompressionAlgo(std::set<CompressAlgorithm> &algorithmSet) const
2216 {
2217     algorithmSet.clear();
2218     DataCompression::GetCompressionAlgo(algorithmSet);
2219     return E_OK;
2220 }
2221 
CheckAndInitQueryCondition(QueryObject & query) const2222 int SQLiteSingleVerNaturalStore::CheckAndInitQueryCondition(QueryObject &query) const
2223 {
2224     const SchemaObject &localSchema = MyProp().GetSchemaConstRef();
2225     if (localSchema.GetSchemaType() != SchemaType::NONE && localSchema.GetSchemaType() != SchemaType::JSON) {
2226         // Flatbuffer schema is not support subscribe
2227         return -E_NOT_SUPPORT;
2228     }
2229     query.SetSchema(localSchema);
2230 
2231     int errCode = E_OK;
2232     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
2233     if (handle == nullptr) {
2234         return errCode;
2235     }
2236 
2237     errCode = handle->CheckQueryObjectLegal(query);
2238     if (errCode != E_OK) {
2239         LOGE("Check query condition failed [%d]!", errCode);
2240     }
2241     ReleaseHandle(handle);
2242     return errCode;
2243 }
2244 
SetDataInterceptor(const PushDataInterceptor & interceptor)2245 void SQLiteSingleVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor)
2246 {
2247     std::unique_lock<std::shared_mutex> lock(dataInterceptorMutex_);
2248     dataInterceptor_ = interceptor;
2249 }
2250 
InterceptData(std::vector<SingleVerKvEntry * > & entries,const std::string & sourceID,const std::string & targetID) const2251 int SQLiteSingleVerNaturalStore::InterceptData(std::vector<SingleVerKvEntry *> &entries, const std::string &sourceID,
2252     const std::string &targetID) const
2253 {
2254     PushDataInterceptor interceptor = nullptr;
2255     {
2256         std::shared_lock<std::shared_mutex> lock(dataInterceptorMutex_);
2257         if (dataInterceptor_ == nullptr) {
2258             return E_OK;
2259         }
2260         interceptor = dataInterceptor_;
2261     }
2262 
2263     InterceptedDataImpl data(entries, [this](const Value &newValue) -> int {
2264             bool useAmendValue = false;
2265             Value amendValue = newValue;
2266             return this->CheckValueAndAmendIfNeed(ValueSource::FROM_LOCAL, newValue, amendValue, useAmendValue);
2267         }
2268     );
2269 
2270     int errCode = interceptor(data, sourceID, targetID);
2271     if (data.IsError()) {
2272         SingleVerKvEntry::Release(entries);
2273         LOGE("Intercept data failed:%d.", errCode);
2274         return -E_INTERCEPT_DATA_FAIL;
2275     }
2276     return E_OK;
2277 }
2278 
AddSubscribe(const std::string & subscribeId,const QueryObject & query,bool needCacheSubscribe)2279 int SQLiteSingleVerNaturalStore::AddSubscribe(const std::string &subscribeId, const QueryObject &query,
2280     bool needCacheSubscribe)
2281 {
2282     if (IsSupportSubscribe() != E_OK) {
2283         return -E_NOT_SUPPORT;
2284     }
2285     const SchemaObject &localSchema = MyProp().GetSchemaConstRef();
2286     QueryObject queryInner = query;
2287     queryInner.SetSchema(localSchema);
2288     if (IsExtendedCacheDBMode() && needCacheSubscribe) { // cache auto subscribe when engine state is in CACHEDB mode
2289         LOGI("Cache subscribe query and return ok when in cacheDB.");
2290         storageEngine_->CacheSubscribe(subscribeId, queryInner);
2291         return E_OK;
2292     }
2293 
2294     int errCode = E_OK;
2295     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
2296     if (handle == nullptr) {
2297         return errCode;
2298     }
2299 
2300     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
2301     if (errCode != E_OK) {
2302         ReleaseHandle(handle);
2303         return errCode;
2304     }
2305 
2306     errCode = handle->AddSubscribeTrigger(queryInner, subscribeId);
2307     if (errCode != E_OK) {
2308         LOGE("Add subscribe trigger failed: %d", errCode);
2309         (void)handle->Rollback();
2310     } else {
2311         errCode = handle->Commit();
2312     }
2313     ReleaseHandle(handle);
2314     return errCode;
2315 }
2316 
RemoveSubscribe(const std::vector<std::string> & subscribeIds)2317 int SQLiteSingleVerNaturalStore::RemoveSubscribe(const std::vector<std::string> &subscribeIds)
2318 {
2319     int errCode = E_OK;
2320     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
2321     if (handle == nullptr) {
2322         return errCode;
2323     }
2324 
2325     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
2326     if (errCode != E_OK) {
2327         ReleaseHandle(handle);
2328         return errCode;
2329     }
2330     errCode = handle->RemoveSubscribeTrigger(subscribeIds);
2331     if (errCode != E_OK) {
2332         LOGE("Remove subscribe trigger failed: %d", errCode);
2333         goto ERR;
2334     }
2335     errCode = handle->RemoveSubscribeTriggerWaterMark(subscribeIds);
2336     if (errCode != E_OK) {
2337         LOGE("Remove subscribe data water mark failed: %d", errCode);
2338     }
2339 ERR:
2340     if (errCode == E_OK) {
2341         errCode = handle->Commit();
2342     } else {
2343         (void)handle->Rollback();
2344     }
2345     ReleaseHandle(handle);
2346     return errCode;
2347 }
2348 
RemoveSubscribe(const std::string & subscribeId)2349 int SQLiteSingleVerNaturalStore::RemoveSubscribe(const std::string &subscribeId)
2350 {
2351     return RemoveSubscribe(std::vector<std::string> {subscribeId});
2352 }
2353 
SetMaxLogSize(uint64_t limit)2354 int SQLiteSingleVerNaturalStore::SetMaxLogSize(uint64_t limit)
2355 {
2356     LOGI("Set the max log size to %" PRIu64, limit);
2357     maxLogSize_.store(limit);
2358     return E_OK;
2359 }
GetMaxLogSize() const2360 uint64_t SQLiteSingleVerNaturalStore::GetMaxLogSize() const
2361 {
2362     return maxLogSize_.load();
2363 }
2364 
RemoveAllSubscribe()2365 int SQLiteSingleVerNaturalStore::RemoveAllSubscribe()
2366 {
2367     int errCode = E_OK;
2368     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
2369     if (handle == nullptr) {
2370         return errCode;
2371     }
2372     std::vector<std::string> triggers;
2373     errCode = handle->GetTriggers(DBConstant::SUBSCRIBE_QUERY_PREFIX, triggers);
2374     if (errCode != E_OK) {
2375         LOGE("Get all subscribe triggers failed. %d", errCode);
2376         ReleaseHandle(handle);
2377         return errCode;
2378     }
2379 
2380     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
2381     if (errCode != E_OK) {
2382         ReleaseHandle(handle);
2383         return errCode;
2384     }
2385 
2386     Key prefixKey;
2387     errCode = handle->RemoveTrigger(triggers);
2388     if (errCode != E_OK) {
2389         LOGE("remove all subscribe triggers failed. %d", errCode);
2390         goto END;
2391     }
2392 
2393     DBCommon::StringToVector(DBConstant::SUBSCRIBE_QUERY_PREFIX, prefixKey);
2394     errCode = handle->DeleteMetaDataByPrefixKey(prefixKey);
2395     if (errCode != E_OK) {
2396         LOGE("remove all subscribe water mark failed. %d", errCode);
2397     }
2398 END:
2399     if (errCode == E_OK) {
2400         errCode = handle->Commit();
2401     } else {
2402         (void)handle->Rollback();
2403     }
2404     ReleaseHandle(handle);
2405     return errCode;
2406 }
2407 
Dump(int fd)2408 void SQLiteSingleVerNaturalStore::Dump(int fd)
2409 {
2410     std::string userId = MyProp().GetStringProp(DBProperties::USER_ID, "");
2411     std::string appId = MyProp().GetStringProp(DBProperties::APP_ID, "");
2412     std::string storeId = MyProp().GetStringProp(DBProperties::STORE_ID, "");
2413     std::string label = MyProp().GetStringProp(DBProperties::IDENTIFIER_DATA, "");
2414     label = DBCommon::TransferStringToHex(label);
2415     DBDumpHelper::Dump(fd, "\tdb userId = %s, appId = %s, storeId = %s, label = %s\n",
2416         userId.c_str(), appId.c_str(), storeId.c_str(), label.c_str());
2417     SyncAbleKvDB::Dump(fd);
2418 }
2419 
IsSupportSubscribe() const2420 int SQLiteSingleVerNaturalStore::IsSupportSubscribe() const
2421 {
2422     const SchemaObject &localSchema = MyProp().GetSchemaConstRef();
2423     if (localSchema.GetSchemaType() != SchemaType::NONE && localSchema.GetSchemaType() != SchemaType::JSON) {
2424         // Flatbuffer schema is not support subscribe
2425         return -E_NOT_SUPPORT;
2426     }
2427     return E_OK;
2428 }
2429 
RemoveDeviceDataInner(const std::string & hashDev,bool isNeedNotify)2430 int SQLiteSingleVerNaturalStore::RemoveDeviceDataInner(const std::string &hashDev, bool isNeedNotify)
2431 {
2432     int errCode = E_OK;
2433     SQLiteSingleVerStorageExecutor *handle = GetHandle(true, errCode);
2434     if (handle == nullptr) {
2435         LOGE("[SingleVerNStore] RemoveDeviceData get handle failed:%d", errCode);
2436         return errCode;
2437     }
2438     uint64_t logFileSize = handle->GetLogFileSize();
2439     ReleaseHandle(handle);
2440     if (logFileSize > GetMaxLogSize()) {
2441         LOGW("[SingleVerNStore] RmDevData log size[%" PRIu64 "] over the limit", logFileSize);
2442         return -E_LOG_OVER_LIMITS;
2443     }
2444 
2445     std::set<std::string> removeDevices;
2446     if (hashDev.empty()) {
2447         errCode = GetExistsDeviceList(removeDevices);
2448         if (errCode != E_OK) {
2449             LOGE("[SingleVerNStore] get remove device list failed:%d", errCode);
2450             return errCode;
2451         }
2452     } else {
2453         removeDevices.insert(hashDev);
2454     }
2455 
2456     LOGD("[SingleVerNStore] remove device data, size=%zu", removeDevices.size());
2457     for (const auto &iterDevice : removeDevices) {
2458         // Call the syncer module to erase the water mark.
2459         errCode = EraseDeviceWaterMark(iterDevice, false);
2460         if (errCode != E_OK) {
2461             LOGE("[SingleVerNStore] erase water mark failed:%d", errCode);
2462             return errCode;
2463         }
2464     }
2465 
2466     if (IsExtendedCacheDBMode()) {
2467         errCode = RemoveDeviceDataInCacheMode(hashDev, isNeedNotify);
2468     } else {
2469         errCode = RemoveDeviceDataNormally(hashDev, isNeedNotify);
2470     }
2471     if (errCode != E_OK) {
2472         LOGE("[SingleVerNStore] RemoveDeviceData failed:%d", errCode);
2473     }
2474 
2475     return errCode;
2476 }
2477 
AbortHandle()2478 void SQLiteSingleVerNaturalStore::AbortHandle()
2479 {
2480     std::unique_lock<std::shared_mutex> lock(abortHandleMutex_);
2481     abortPerm_ = OperatePerm::RESTART_SYNC_PERM;
2482 }
2483 
EnableHandle()2484 void SQLiteSingleVerNaturalStore::EnableHandle()
2485 {
2486     std::unique_lock<std::shared_mutex> lock(abortHandleMutex_);
2487     abortPerm_ = OperatePerm::NORMAL_PERM;
2488 }
2489 
TryHandle() const2490 int SQLiteSingleVerNaturalStore::TryHandle() const
2491 {
2492     std::unique_lock<std::shared_mutex> lock(abortHandleMutex_);
2493     if (abortPerm_ == OperatePerm::RESTART_SYNC_PERM) {
2494         LOGW("[SingleVerNStore] Restarting sync, handle id[%s] is busy",
2495             DBCommon::TransferStringToHex(storageEngine_->GetIdentifier()).c_str());
2496         return -E_BUSY;
2497     }
2498     return E_OK;
2499 }
2500 
GetAndResizeLocalIdentity(std::string & outTarget) const2501 int SQLiteSingleVerNaturalStore::GetAndResizeLocalIdentity(std::string &outTarget) const
2502 {
2503     int errCode = GetLocalIdentity(outTarget);
2504     if (errCode == -E_NOT_INIT) {
2505         outTarget.resize(DEVICE_ID_LEN);
2506     } else if (errCode != E_OK) {
2507         LOGE("Get local dev id err:%d", errCode);
2508         outTarget.resize(0);
2509     }
2510     return errCode;
2511 }
2512 DEFINE_OBJECT_TAG_FACILITIES(SQLiteSingleVerNaturalStore)
2513 }
2514