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