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 ¬ifier)
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 ¬ifier) 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