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 #ifndef OMIT_MULTI_VER
17 #include "multi_ver_natural_store.h"
18
19 #include <cstdio>
20 #include <openssl/rand.h>
21
22 #include "securec.h"
23
24 #include "db_constant.h"
25 #include "ikvdb_factory.h"
26 #include "db_common.h"
27 #include "endian_convert.h"
28 #include "log_print.h"
29 #include "db_errno.h"
30 #include "multi_ver_storage_engine.h"
31 #include "multi_ver_natural_store_connection.h"
32 #include "generic_multi_ver_kv_entry.h"
33 #include "sqlite_multi_ver_data_storage.h"
34 #include "multi_ver_natural_store_commit_storage.h"
35 #include "multi_ver_vacuum_executor_impl.h"
36 #include "kvdb_utils.h"
37 #include "sqlite_utils.h"
38 #include "platform_specific.h"
39 #include "package_file.h"
40 #include "multi_ver_database_oper.h"
41
42 namespace DistributedDB {
43 namespace {
44 // file block doesn't support the atomic of the upgrade temporarily.
45 struct VersionFileBlock {
46 static const uint64_t MAGIC_NUMBER = 0x37F8C35AULL;
47 uint64_t magic = MAGIC_NUMBER; // magic number.
48 uint32_t fileVersion = VERSION_FILE_VERSION_CURRENT; // file format version.
49 uint32_t version = 0U; // version of the database.
50 uint8_t tag[MULTI_VER_TAG_SIZE] = {0}; // tag of the multi ver branch.
51 uint8_t reserved[72] = {0}; // reserved data.
52 uint8_t checkSum[32] = {0}; // check sum
53 };
54
TransferHostFileBlockToNet(VersionFileBlock & block)55 void TransferHostFileBlockToNet(VersionFileBlock &block)
56 {
57 block.magic = HostToNet(block.magic);
58 block.fileVersion = HostToNet(block.fileVersion);
59 block.version = HostToNet(block.version);
60 }
61
TransferNetFileBlockToHost(VersionFileBlock & block)62 void TransferNetFileBlockToHost(VersionFileBlock &block)
63 {
64 block.magic = NetToHost(block.magic);
65 block.fileVersion = NetToHost(block.fileVersion);
66 block.version = NetToHost(block.version);
67 }
68
CalcFileBlockCheckSum(VersionFileBlock & block)69 int CalcFileBlockCheckSum(VersionFileBlock &block)
70 {
71 std::vector<uint8_t> vect(reinterpret_cast<uint8_t *>(&block),
72 reinterpret_cast<uint8_t *>(&block) + sizeof(block) - sizeof(block.checkSum));
73 std::vector<uint8_t> hashVect;
74 int errCode = DBCommon::CalcValueHash(vect, hashVect);
75 if (errCode != E_OK) {
76 return errCode;
77 }
78 errCode = memcpy_s(block.checkSum, sizeof(block.checkSum), hashVect.data(), hashVect.size());
79 if (errCode != EOK) {
80 return -E_SECUREC_ERROR;
81 }
82 return E_OK;
83 }
84
CheckFileBlock(VersionFileBlock & block)85 int CheckFileBlock(VersionFileBlock &block)
86 {
87 uint64_t readMagic = NetToHost(block.magic);
88 if (readMagic != block.MAGIC_NUMBER) {
89 LOGE("Invalid file head");
90 return -E_UNEXPECTED_DATA;
91 }
92
93 std::vector<uint8_t> vect(reinterpret_cast<uint8_t *>(&block),
94 reinterpret_cast<uint8_t *>(&block) + sizeof(block) - sizeof(block.checkSum));
95 std::vector<uint8_t> hashVect;
96 int errCode = DBCommon::CalcValueHash(vect, hashVect);
97 if (errCode != E_OK) {
98 return errCode;
99 }
100 if (memcmp(hashVect.data(), block.checkSum, sizeof(block.checkSum)) != 0) {
101 LOGE("Check block error");
102 return -E_UNEXPECTED_DATA;
103 }
104
105 return E_OK;
106 }
107
CreateNewVersionFile(const std::string & versionFileDir,uint32_t version,std::vector<uint8_t> & tag)108 int CreateNewVersionFile(const std::string &versionFileDir, uint32_t version, std::vector<uint8_t> &tag)
109 {
110 VersionFileBlock block;
111 block.version = version;
112 #ifdef SQLITE_HAS_CODEC
113 RAND_bytes(block.tag, sizeof(block.tag));
114 #endif
115 int errCode = memset_s(block.reserved, sizeof(block.reserved), 0, sizeof(block.reserved));
116 if (errCode != EOK) {
117 return -E_SECUREC_ERROR;
118 }
119
120 TransferHostFileBlockToNet(block);
121 errCode = CalcFileBlockCheckSum(block);
122 if (errCode != E_OK) {
123 return errCode;
124 }
125 FILE *versionFile = fopen(versionFileDir.c_str(), "wb+");
126 if (versionFile == nullptr) {
127 LOGE("Open the version file error:%d", errno);
128 return -E_SYSTEM_API_FAIL;
129 }
130 size_t writeSize = fwrite(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
131 if (writeSize != sizeof(VersionFileBlock)) {
132 LOGE("Write version file head error:%d", errno);
133 errCode = -E_SYSTEM_API_FAIL;
134 } else {
135 errCode = E_OK;
136 tag.assign(block.tag, block.tag + sizeof(block.tag));
137 }
138
139 fclose(versionFile);
140 versionFile = nullptr;
141 return errCode;
142 }
143
ChangeVersionFile(const std::string & versionFileDir,uint32_t version,std::vector<uint8_t> & tag,bool isChangeTag)144 int ChangeVersionFile(const std::string &versionFileDir, uint32_t version, std::vector<uint8_t> &tag,
145 bool isChangeTag)
146 {
147 FILE *versionFile = fopen(versionFileDir.c_str(), "rb+");
148 if (versionFile == nullptr) {
149 LOGE("Open the version file error:%d", errno);
150 return -E_SYSTEM_API_FAIL;
151 }
152 VersionFileBlock block;
153 size_t operateSize = fread(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
154 if (operateSize != sizeof(VersionFileBlock)) {
155 fclose(versionFile);
156 LOGE("Read file error:%d", errno);
157 return -E_SYSTEM_API_FAIL;
158 };
159 int errCode = CheckFileBlock(block);
160 if (errCode != E_OK) {
161 goto END;
162 }
163 TransferHostFileBlockToNet(block);
164 block.version = version;
165
166 if (isChangeTag) {
167 RAND_bytes(block.tag, sizeof(block.tag));
168 tag.assign(block.tag, block.tag + sizeof(block.tag));
169 }
170
171 TransferHostFileBlockToNet(block);
172 errCode = CalcFileBlockCheckSum(block);
173 if (errCode != E_OK) {
174 goto END;
175 }
176 #ifdef OS_TYPE_MAC
177 fseeko(versionFile, 0LL, SEEK_SET);
178 #else
179 fseeko64(versionFile, 0LL, SEEK_SET);
180 #endif
181 operateSize = fwrite(&block, 1, sizeof(VersionFileBlock), versionFile);
182 if (operateSize != sizeof(VersionFileBlock)) {
183 LOGE("write the file error:%d", errno);
184 errCode = -E_SYSTEM_API_FAIL;
185 goto END;
186 }
187 END:
188 fclose(versionFile);
189 versionFile = nullptr;
190 return errCode;
191 }
192
GetVersionAndTag(const std::string & versionFileDir,uint32_t & version,std::vector<uint8_t> & tag)193 int GetVersionAndTag(const std::string &versionFileDir, uint32_t &version, std::vector<uint8_t> &tag)
194 {
195 FILE *versionFile = fopen(versionFileDir.c_str(), "rb+");
196 if (versionFile == nullptr) {
197 LOGE("Open the version file error:%d", errno);
198 return -E_SYSTEM_API_FAIL;
199 }
200 int errCode = E_OK;
201 VersionFileBlock block;
202 size_t readSize = fread(static_cast<void *>(&block), 1, sizeof(VersionFileBlock), versionFile);
203 if (readSize != sizeof(VersionFileBlock)) {
204 LOGE("read the file error:%d", errno);
205 errCode = -E_SYSTEM_API_FAIL;
206 goto END;
207 };
208 errCode = CheckFileBlock(block);
209 if (errCode != E_OK) {
210 LOGE("Check the file block error");
211 goto END;
212 }
213 TransferNetFileBlockToHost(block);
214 version = block.version;
215 tag.assign(block.tag, block.tag + sizeof(block.tag));
216 END:
217 fclose(versionFile);
218 versionFile = nullptr;
219 return errCode;
220 }
221 }
222
223 MultiVerVacuum MultiVerNaturalStore::shadowTrimmer_;
MultiVerNaturalStore()224 MultiVerNaturalStore::MultiVerNaturalStore()
225 : multiVerData_(nullptr),
226 commitHistory_(nullptr),
227 multiVerKvStorage_(nullptr),
228 multiVerEngine_(nullptr),
229 trimmerImpl_(nullptr),
230 maxRecordTimestamp_(0),
231 maxCommitVersion_(0)
232 {}
233
~MultiVerNaturalStore()234 MultiVerNaturalStore::~MultiVerNaturalStore()
235 {
236 Clear();
237 UnRegisterNotificationEventType(NATURAL_STORE_COMMIT_EVENT);
238 }
239
Clear()240 void MultiVerNaturalStore::Clear()
241 {
242 if (trimmerImpl_ != nullptr) {
243 shadowTrimmer_.Abort(GetStringIdentifier());
244 delete trimmerImpl_;
245 trimmerImpl_ = nullptr;
246 }
247 {
248 std::lock_guard<std::mutex> lock(commitHistMutex_);
249 if (commitHistory_ != nullptr) {
250 commitHistory_->Close();
251 delete commitHistory_;
252 commitHistory_ = nullptr;
253 }
254 }
255 {
256 std::lock_guard<std::mutex> lock(multiDataMutex_);
257 if (multiVerData_ != nullptr) {
258 multiVerData_->Close();
259 delete multiVerData_;
260 multiVerData_ = nullptr;
261 }
262 }
263
264 {
265 std::lock_guard<std::mutex> lock(syncerKvMutex_);
266 if (multiVerKvStorage_ != nullptr) {
267 multiVerKvStorage_->Close();
268 delete multiVerKvStorage_;
269 multiVerKvStorage_ = nullptr;
270 }
271 }
272 multiVerEngine_ = nullptr;
273 }
274
InitStorages(const KvDBProperties & kvDBProp,bool isChangeTag)275 int MultiVerNaturalStore::InitStorages(const KvDBProperties &kvDBProp, bool isChangeTag)
276 {
277 std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
278 std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
279 bool isNeedCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
280 CipherType cipherType;
281 CipherPassword passwd;
282 kvDBProp.GetPassword(cipherType, passwd);
283
284 IKvDBMultiVerDataStorage::Property multiVerProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
285 IKvDBCommitStorage::Property commitProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
286 MultiVerKvDataStorage::Property multiVerKvProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
287
288 int errCode = DBCommon::CreateStoreDirectory(dataDir, identifierDir, DBConstant::MULTI_SUB_DIR, isNeedCreate);
289 if (errCode != E_OK) {
290 return errCode;
291 }
292
293 errCode = CheckVersion(kvDBProp);
294 if (errCode != E_OK) {
295 LOGE("Upgrade multi ver failed:%d", errCode);
296 return errCode;
297 }
298
299 errCode = multiVerData_->Open(multiVerProp);
300 if (errCode != E_OK) {
301 LOGE("MultiVer::InitStorages open multiVerData fail! errCode[%d]", errCode);
302 return errCode;
303 }
304
305 errCode = commitHistory_->Open(commitProp);
306 if (errCode != E_OK) {
307 LOGE("MultiVer::InitStorages open commitHistory fail! errCode[%d]", errCode);
308 return errCode;
309 }
310
311 errCode = multiVerKvStorage_->Open(multiVerKvProp);
312 if (errCode != E_OK) {
313 LOGE("Open multi ver kv storage failed:%d", errCode);
314 return errCode;
315 }
316
317 errCode = RecoverFromException();
318 if (errCode != E_OK) {
319 LOGE("Recover multi version storage failed:%d", errCode);
320 return errCode;
321 }
322 return InitStorageContext(isChangeTag);
323 }
324
CheckSubStorageVersion(const KvDBProperties & kvDBProp,bool & isSubStorageAllExist) const325 int MultiVerNaturalStore::CheckSubStorageVersion(const KvDBProperties &kvDBProp, bool &isSubStorageAllExist) const
326 {
327 std::string dataDir = kvDBProp.GetStringProp(KvDBProperties::DATA_DIR, "");
328 std::string identifierDir = kvDBProp.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
329 bool isNeedCreate = kvDBProp.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
330 CipherType cipherType;
331 CipherPassword passwd;
332 kvDBProp.GetPassword(cipherType, passwd);
333
334 IKvDBMultiVerDataStorage::Property multiVerProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
335 IKvDBCommitStorage::Property commitProp = {dataDir, identifierDir, isNeedCreate, cipherType, passwd};
336 MultiVerKvDataStorage::Property multiVerKvProp = {dataDir, identifierDir, true, cipherType, passwd};
337
338 bool isDataStorageExist = false;
339 bool isCommitStorageExist = false;
340 bool isKvStorageAllExist = false;
341 int errCode = multiVerData_->CheckVersion(multiVerProp, isDataStorageExist);
342 if (errCode != E_OK) {
343 return errCode;
344 }
345 errCode = commitHistory_->CheckVersion(commitProp, isCommitStorageExist);
346 if (errCode != E_OK) {
347 return errCode;
348 }
349 errCode = multiVerKvStorage_->CheckVersion(multiVerKvProp, isKvStorageAllExist);
350 if (errCode != E_OK) {
351 return errCode;
352 }
353 if ((isDataStorageExist != isCommitStorageExist) || (isCommitStorageExist != isKvStorageAllExist)) {
354 // In case failure happens during open progress, some dbFile will not exist, we should recover from this
355 LOGW("[MultiVerStore][CheckSubVer] Detect File Lost, isDataExist=%d, isCommitExist=%d, isKvAllExist=%d.",
356 isDataStorageExist, isCommitStorageExist, isKvStorageAllExist);
357 }
358 isSubStorageAllExist = isDataStorageExist && isCommitStorageExist && isKvStorageAllExist;
359 return E_OK;
360 }
361
CreateStorages()362 int MultiVerNaturalStore::CreateStorages()
363 {
364 int errCode = E_OK;
365 IKvDBFactory *factory = IKvDBFactory::GetCurrent();
366 if (factory == nullptr) {
367 return -E_INVALID_DB;
368 }
369 multiVerData_ = factory->CreateMultiVerStorage(errCode);
370 if (multiVerData_ == nullptr) {
371 return errCode;
372 }
373
374 commitHistory_ = factory->CreateMultiVerCommitStorage(errCode);
375 if (commitHistory_ == nullptr) {
376 return errCode;
377 }
378
379 multiVerKvStorage_ = new (std::nothrow) MultiVerKvDataStorage;
380 if (multiVerKvStorage_ == nullptr) {
381 return -E_OUT_OF_MEMORY;
382 }
383 return E_OK;
384 }
385
ClearTempFile(const KvDBProperties & kvDBProp)386 int MultiVerNaturalStore::ClearTempFile(const KvDBProperties &kvDBProp)
387 {
388 std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
389 commitHistory_, multiVerKvStorage_);
390 (void)operation->ClearExportedTempFiles(kvDBProp);
391 int errCode = operation->RekeyRecover(kvDBProp);
392 if (errCode != E_OK) {
393 LOGE("Recover for open db failed in multi version:%d", errCode);
394 return errCode;
395 }
396
397 errCode = operation->ClearImportTempFile(kvDBProp);
398 if (errCode != E_OK) {
399 LOGE("Recover import temp file for open db failed in multi version:%d", errCode);
400 }
401 return errCode;
402 }
403
404 // Open the database
Open(const KvDBProperties & kvDBProp)405 int MultiVerNaturalStore::Open(const KvDBProperties &kvDBProp)
406 {
407 StorageEngineAttr poolSize = {0, 1, 0, 16}; // 1 write 16 read at most.
408 int errCode = CreateStorages();
409 if (errCode != E_OK) {
410 goto ERROR;
411 }
412
413 MyProp() = kvDBProp;
414 errCode = ClearTempFile(kvDBProp);
415 if (errCode != E_OK) {
416 goto ERROR;
417 }
418
419 errCode = InitStorages(kvDBProp);
420 if (errCode != E_OK) {
421 goto ERROR;
422 }
423
424 errCode = RegisterNotificationEventType(NATURAL_STORE_COMMIT_EVENT);
425 if (errCode != E_OK) {
426 LOGE("RegisterEventType failed!");
427 goto ERROR;
428 }
429
430 multiVerEngine_ = std::make_unique<MultiVerStorageEngine>();
431 errCode = multiVerEngine_->InitDatabases(this, multiVerData_, commitHistory_, multiVerKvStorage_, poolSize);
432 if (errCode != E_OK) {
433 goto ERROR;
434 }
435 // Start the trimming;
436 trimmerImpl_ = new (std::nothrow) MultiVerVacuumExecutorImpl(this);
437 if (trimmerImpl_ == nullptr) {
438 errCode = -E_OUT_OF_MEMORY;
439 goto ERROR;
440 }
441
442 shadowTrimmer_.Launch(GetStringIdentifier(), trimmerImpl_);
443 StartSyncer();
444 return E_OK;
445 ERROR:
446 Clear();
447 return errCode;
448 }
449
Close()450 void MultiVerNaturalStore::Close()
451 {
452 // Abort the trimming;
453 SyncAbleKvDB::Close();
454 Clear();
455 }
456
NewConnection(int & errCode)457 GenericKvDBConnection *MultiVerNaturalStore::NewConnection(int &errCode)
458 {
459 auto connection = new (std::nothrow) MultiVerNaturalStoreConnection(this);
460 if (connection == nullptr) {
461 errCode = -E_OUT_OF_MEMORY;
462 return nullptr;
463 }
464
465 errCode = E_OK;
466 return connection;
467 }
468
469 // Get interface for syncer.
GetSyncInterface()470 IKvDBSyncInterface *MultiVerNaturalStore::GetSyncInterface()
471 {
472 return this;
473 }
474
475 // Get interface type of this kvdb.
GetInterfaceType() const476 int MultiVerNaturalStore::GetInterfaceType() const
477 {
478 return SYNC_MVD;
479 }
480
481 // Get the interface ref-count, in order to access asynchronously.
IncRefCount()482 void MultiVerNaturalStore::IncRefCount()
483 {
484 IncObjRef(this);
485 }
486
487 // Drop the interface ref-count.
DecRefCount()488 void MultiVerNaturalStore::DecRefCount()
489 {
490 DecObjRef(this);
491 }
492
493 // Get the identifier of this kvdb.
GetIdentifier() const494 std::vector<uint8_t> MultiVerNaturalStore::GetIdentifier() const
495 {
496 std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
497 std::vector<uint8_t> identifierVect(identifier.begin(), identifier.end());
498 return identifierVect;
499 }
500
GetStringIdentifier() const501 std::string MultiVerNaturalStore::GetStringIdentifier() const
502 {
503 std::string identifier = MyProp().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
504 std::vector<uint8_t> idVect(identifier.begin(), identifier.end());
505 return VEC_TO_STR(idVect);
506 }
507
508 // Get the max timestamp of all entries in database.
GetMaxTimestamp(Timestamp & stamp) const509 void MultiVerNaturalStore::GetMaxTimestamp(Timestamp &stamp) const
510 {
511 std::lock_guard<std::mutex> lock(maxTimeMutex_);
512 stamp = maxRecordTimestamp_;
513 }
514
SetMaxTimestamp(Timestamp stamp)515 void MultiVerNaturalStore::SetMaxTimestamp(Timestamp stamp)
516 {
517 std::lock_guard<std::mutex> lock(maxTimeMutex_);
518 maxRecordTimestamp_ = (stamp > maxRecordTimestamp_) ? stamp : maxRecordTimestamp_;
519 }
520
521 // Get meta data associated with the given key.
GetMetaData(const Key & key,Value & value) const522 int MultiVerNaturalStore::GetMetaData(const Key &key, Value &value) const
523 {
524 int errCode = E_OK;
525 auto handle = GetHandle(false, errCode);
526 if (handle == nullptr) {
527 return errCode;
528 }
529
530 errCode = handle->GetMetaData(key, value);
531 ReleaseHandle(handle);
532 return errCode;
533 }
534
535 // Put meta data as a key-value entry.
PutMetaData(const Key & key,const Value & value,bool isInTransaction)536 int MultiVerNaturalStore::PutMetaData(const Key &key, const Value &value, bool isInTransaction)
537 {
538 (void)isInTransaction;
539 int errCode = E_OK;
540 auto handle = GetHandle(true, errCode);
541 if (handle == nullptr) {
542 return errCode;
543 }
544
545 errCode = handle->PutMetaData(key, value);
546 ReleaseHandle(handle);
547 return errCode;
548 }
549
DeleteMetaData(const std::vector<Key> & keys)550 int MultiVerNaturalStore::DeleteMetaData(const std::vector<Key> &keys)
551 {
552 return -E_NOT_SUPPORT;
553 }
554
555 // Get all meta data keys.
GetAllMetaKeys(std::vector<Key> & keys) const556 int MultiVerNaturalStore::GetAllMetaKeys(std::vector<Key> &keys) const
557 {
558 return E_OK;
559 }
560
IsCommitExisted(const MultiVerCommitNode & commit) const561 bool MultiVerNaturalStore::IsCommitExisted(const MultiVerCommitNode &commit) const
562 {
563 int errCode = E_OK;
564 auto handle = GetHandle(false, errCode);
565 if (handle == nullptr) {
566 return false;
567 }
568
569 bool result = handle->IsCommitExisted(commit, errCode);
570 ReleaseHandle(handle);
571 return result;
572 }
573
GetDeviceLatestCommit(std::map<std::string,MultiVerCommitNode> & commitMap) const574 int MultiVerNaturalStore::GetDeviceLatestCommit(std::map<std::string, MultiVerCommitNode> &commitMap) const
575 {
576 int errCode = E_OK;
577 auto handle = GetHandle(false, errCode);
578 if (handle == nullptr) {
579 return -E_BUSY;
580 }
581
582 errCode = handle->GetDeviceLatestCommit(commitMap);
583 ReleaseHandle(handle);
584 return errCode;
585 }
586
GetCommitTree(const std::map<std::string,MultiVerCommitNode> & commitMap,std::vector<MultiVerCommitNode> & commits) const587 int MultiVerNaturalStore::GetCommitTree(const std::map<std::string, MultiVerCommitNode> &commitMap,
588 std::vector<MultiVerCommitNode> &commits) const
589 {
590 int errCode = E_OK;
591 auto handle = GetHandle(false, errCode);
592 if (handle == nullptr) {
593 return -E_BUSY;
594 }
595
596 errCode = handle->GetCommitTree(commitMap, commits);
597 ReleaseHandle(handle);
598 return errCode;
599 }
600
GetCommitData(const MultiVerCommitNode & commit,std::vector<MultiVerKvEntry * > & entries) const601 int MultiVerNaturalStore::GetCommitData(const MultiVerCommitNode &commit, std::vector<MultiVerKvEntry *> &entries) const
602 {
603 int errCode = E_OK;
604 auto handle = GetHandle(false, errCode);
605 if (handle == nullptr) {
606 return -E_BUSY;
607 }
608
609 errCode = handle->GetCommitData(commit, entries);
610 ReleaseHandle(handle);
611 return errCode;
612 }
613
CreateKvEntry(const std::vector<uint8_t> & data)614 MultiVerKvEntry *MultiVerNaturalStore::CreateKvEntry(const std::vector<uint8_t> &data)
615 {
616 auto kvEntry = new (std::nothrow) GenericMultiVerKvEntry;
617 if (kvEntry == nullptr) {
618 return nullptr;
619 }
620
621 int errCode = kvEntry->DeSerialData(data);
622 if (errCode != E_OK) {
623 LOGE("deserialize data into kv entry failed:%d", errCode);
624 delete kvEntry;
625 kvEntry = nullptr;
626 }
627 return kvEntry;
628 }
629
ReleaseKvEntry(const MultiVerKvEntry * entry)630 void MultiVerNaturalStore::ReleaseKvEntry(const MultiVerKvEntry *entry)
631 {
632 if (entry != nullptr) {
633 delete entry;
634 entry = nullptr;
635 }
636 }
637
IsValueSliceExisted(const ValueSliceHash & value) const638 bool MultiVerNaturalStore::IsValueSliceExisted(const ValueSliceHash &value) const
639 {
640 int errCode = E_OK;
641 auto handle = GetHandle(false, errCode);
642 if (handle == nullptr) {
643 return false;
644 }
645
646 bool result = handle->IsValueSliceExisted(value, errCode);
647 ReleaseHandle(handle);
648 return result;
649 }
650
GetValueSlice(const ValueSliceHash & hashValue,ValueSlice & sliceValue) const651 int MultiVerNaturalStore::GetValueSlice(const ValueSliceHash &hashValue, ValueSlice &sliceValue) const
652 {
653 int errCode = E_OK;
654 auto handle = GetHandle(false, errCode);
655 if (handle == nullptr) {
656 return -E_BUSY;
657 }
658
659 errCode = handle->GetValueSlice(hashValue, sliceValue);
660 ReleaseHandle(handle);
661 return errCode;
662 }
663
PutValueSlice(const ValueSliceHash & hashValue,const ValueSlice & sliceValue) const664 int MultiVerNaturalStore::PutValueSlice(const ValueSliceHash &hashValue, const ValueSlice &sliceValue) const
665 {
666 int errCode = E_OK;
667 auto handle = GetHandle(true, errCode);
668 if (handle == nullptr) {
669 return -E_BUSY;
670 }
671
672 errCode = handle->PutValueSlice(hashValue, sliceValue, false);
673 ReleaseHandle(handle);
674 return errCode;
675 }
676
PutCommitData(const MultiVerCommitNode & commit,const std::vector<MultiVerKvEntry * > & entries,const std::string & deviceName)677 int MultiVerNaturalStore::PutCommitData(const MultiVerCommitNode &commit, const std::vector<MultiVerKvEntry *> &entries,
678 const std::string &deviceName)
679 {
680 int errCode = E_OK;
681 auto handle = GetHandle(true, errCode);
682 if (handle == nullptr) {
683 return -E_BUSY;
684 }
685
686 errCode = handle->PutCommitData(commit, entries, deviceName);
687 ReleaseHandle(handle);
688 return errCode;
689 }
690
MergeSyncCommit(const MultiVerCommitNode & commit,const std::vector<MultiVerCommitNode> & commits)691 int MultiVerNaturalStore::MergeSyncCommit(const MultiVerCommitNode &commit,
692 const std::vector<MultiVerCommitNode> &commits)
693 {
694 int errCode = E_OK;
695 auto handle = GetHandle(true, errCode);
696 if (handle == nullptr) {
697 return -E_BUSY;
698 }
699
700 errCode = handle->MergeSyncCommit(commit, commits);
701 ReleaseHandle(handle);
702 return errCode;
703 }
704
NotifyStartSyncOperation()705 void MultiVerNaturalStore::NotifyStartSyncOperation()
706 {
707 shadowTrimmer_.Pause(GetStringIdentifier());
708 }
709
NotifyFinishSyncOperation()710 void MultiVerNaturalStore::NotifyFinishSyncOperation()
711 {
712 shadowTrimmer_.Continue(GetStringIdentifier(), true);
713 }
714
TransferSyncCommitDevInfo(MultiVerCommitNode & commit,const std::string & devId,bool isSyncedIn) const715 int MultiVerNaturalStore::TransferSyncCommitDevInfo(MultiVerCommitNode &commit, const std::string &devId,
716 bool isSyncedIn) const
717 {
718 std::string hashDevId = DBCommon::TransferHashString(devId);
719 if (isSyncedIn) {
720 // The size of the device info must be hash_size + tag_size;
721 if (commit.deviceInfo.size() == hashDevId.size() + MULTI_VER_TAG_SIZE) {
722 // If the hash device info is matched with the local, just remove the hash device info.
723 if (commit.deviceInfo.compare(0, hashDevId.size(), hashDevId) == 0) {
724 commit.deviceInfo = commit.deviceInfo.substr(hashDevId.size(), MULTI_VER_TAG_SIZE);
725 }
726 return E_OK;
727 }
728 LOGE("Unexpected dev info for sync in:%zu", commit.deviceInfo.size());
729 return -E_UNEXPECTED_DATA;
730 } else {
731 // If the device info only contains the tag info, it must be local node.
732 if (commit.deviceInfo.size() == MULTI_VER_TAG_SIZE) {
733 commit.deviceInfo.insert(0, hashDevId);
734 } else if (commit.deviceInfo.size() != hashDevId.size() + MULTI_VER_TAG_SIZE) {
735 LOGE("Unexpected dev info for sync out:%zu", commit.deviceInfo.size());
736 return -E_UNEXPECTED_DATA;
737 }
738 return E_OK;
739 }
740 }
741
Rekey(const CipherPassword & passwd)742 int MultiVerNaturalStore::Rekey(const CipherPassword &passwd)
743 {
744 if (multiVerEngine_ == nullptr) {
745 return -E_INVALID_DB;
746 }
747 int errCode = multiVerEngine_->TryToDisable(false, OperatePerm::REKEY_MONOPOLIZE_PERM);
748 if (errCode != E_OK) {
749 return errCode;
750 }
751 StopSyncer();
752 shadowTrimmer_.Pause(GetStringIdentifier());
753 errCode = multiVerEngine_->TryToDisable(true, OperatePerm::REKEY_MONOPOLIZE_PERM);
754 if (errCode != E_OK) {
755 multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
756 shadowTrimmer_.Continue(GetStringIdentifier(), true);
757 StartSyncer();
758 return errCode;
759 }
760
761 std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
762 commitHistory_, multiVerKvStorage_);
763 errCode = operation->Rekey(passwd);
764
765 multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
766 shadowTrimmer_.Continue(GetStringIdentifier(), true);
767 StartSyncer();
768
769 return errCode;
770 }
771
Export(const std::string & filePath,const CipherPassword & passwd)772 int MultiVerNaturalStore::Export(const std::string &filePath, const CipherPassword &passwd)
773 {
774 if (multiVerEngine_ == nullptr) {
775 return -E_INVALID_DB;
776 }
777 std::string localDev;
778 int errCode = GetLocalIdentity(localDev);
779 if (errCode != E_OK) {
780 LOGE("Failed to GetLocalIdentity!");
781 }
782 // Exclusively write resources
783 auto handle = GetHandle(true, errCode);
784 if (handle == nullptr) {
785 return errCode;
786 }
787
788 std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
789 commitHistory_, multiVerKvStorage_);
790 operation->SetLocalDevId(localDev);
791 errCode = operation->Export(filePath, passwd);
792
793 ReleaseHandle(handle);
794
795 return errCode;
796 }
797
Import(const std::string & filePath,const CipherPassword & passwd)798 int MultiVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd)
799 {
800 if (multiVerEngine_ == nullptr) {
801 return -E_INVALID_DB;
802 }
803 std::string localDev;
804 int errCode = GetLocalIdentity(localDev);
805 if (errCode != E_OK) {
806 LOGE("Failed to get the local identity!");
807 localDev.resize(0);
808 }
809 errCode = multiVerEngine_->TryToDisable(false, OperatePerm::IMPORT_MONOPOLIZE_PERM);
810 if (errCode != E_OK) {
811 return errCode;
812 }
813 StopSyncer();
814 shadowTrimmer_.Abort(GetStringIdentifier());
815 std::unique_ptr<MultiVerDatabaseOper> operation;
816 errCode = multiVerEngine_->TryToDisable(true, OperatePerm::IMPORT_MONOPOLIZE_PERM);
817 if (errCode != E_OK) {
818 goto END;
819 }
820 operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_, commitHistory_, multiVerKvStorage_);
821 operation->SetLocalDevId(localDev);
822 errCode = operation->Import(filePath, passwd);
823 END:
824 multiVerEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
825 shadowTrimmer_.Launch(GetStringIdentifier(), trimmerImpl_);
826 StartSyncer();
827 return errCode;
828 }
829
GetCurrentTimestamp()830 uint64_t MultiVerNaturalStore::GetCurrentTimestamp()
831 {
832 return GetTimestamp();
833 }
834
GetDiffEntries(const CommitID & begin,const CommitID & end,MultiVerDiffData & data) const835 int MultiVerNaturalStore::GetDiffEntries(const CommitID &begin, const CommitID &end, MultiVerDiffData &data) const
836 {
837 // Get one connection.
838 int errCode = E_OK;
839 auto handle = GetHandle(false, errCode);
840 if (handle == nullptr) {
841 return errCode;
842 }
843
844 errCode = handle->GetDiffEntries(begin, end, data);
845 ReleaseHandle(handle);
846 return errCode;
847 }
848
RecoverFromException()849 int MultiVerNaturalStore::RecoverFromException()
850 {
851 // Get the latest local version and the head node.
852 if (multiVerData_ == nullptr || commitHistory_ == nullptr) {
853 return -E_INVALID_DB;
854 }
855
856 IKvDBMultiVerTransaction *transaction = nullptr;
857 int errCode = multiVerData_->StartWrite(KvDataType::KV_DATA_SYNC_P2P, transaction);
858 if (transaction == nullptr) {
859 goto END;
860 }
861 errCode = transaction->StartTransaction();
862 if (errCode != E_OK) {
863 goto END;
864 }
865
866 errCode = CompareVerDataAndLog(transaction);
867 if (errCode != E_OK) {
868 LOGE("Compare the version data and log failed:%d", errCode);
869 transaction->RollBackTransaction();
870 goto END;
871 }
872 errCode = transaction->CommitTransaction();
873 END:
874 if (transaction != nullptr) {
875 multiVerData_->ReleaseTransaction(transaction);
876 transaction = nullptr;
877 }
878 return errCode;
879 }
880
CompareVerDataAndLog(IKvDBMultiVerTransaction * transaction) const881 int MultiVerNaturalStore::CompareVerDataAndLog(IKvDBMultiVerTransaction *transaction) const
882 {
883 // Get the latest local version, we only care the local data.
884 Version maxLocalVersion = 0;
885 int errCode = transaction->GetMaxVersion(MultiVerDataType::NATIVE_TYPE, maxLocalVersion);
886 if (errCode != E_OK) {
887 return errCode;
888 }
889
890 CommitID headerId = commitHistory_->GetHeader(errCode);
891 if (errCode != E_OK) {
892 return errCode;
893 }
894
895 if (headerId.empty()) {
896 if (maxLocalVersion != 0) {
897 return transaction->ClearEntriesByVersion(maxLocalVersion);
898 }
899 return E_OK;
900 }
901
902 IKvDBCommit *commitHead = commitHistory_->GetCommit(headerId, errCode);
903 if (commitHead == nullptr) {
904 return errCode;
905 }
906
907 // compare the version
908 if (commitHead->GetCommitVersion() < maxLocalVersion) {
909 LOGD("Delete entries");
910 errCode = transaction->ClearEntriesByVersion(maxLocalVersion);
911 } else {
912 errCode = E_OK;
913 }
914
915 commitHistory_->ReleaseCommit(commitHead);
916 commitHead = nullptr;
917 return errCode;
918 }
919
GetMaxCommitVersion() const920 Version MultiVerNaturalStore::GetMaxCommitVersion() const
921 {
922 return maxCommitVersion_;
923 }
924
SetMaxCommitVersion(const Version & version)925 void MultiVerNaturalStore::SetMaxCommitVersion(const Version &version)
926 {
927 maxCommitVersion_ = (version > maxCommitVersion_) ? version : maxCommitVersion_;
928 }
929
GetHandle(bool isWrite,int & errCode,bool isTrimming,OperatePerm perm) const930 MultiVerStorageExecutor *MultiVerNaturalStore::GetHandle(bool isWrite, int &errCode,
931 bool isTrimming, OperatePerm perm) const
932 {
933 if (multiVerEngine_ == nullptr) {
934 errCode = -E_INVALID_DB;
935 return nullptr;
936 }
937
938 if (isWrite && !isTrimming) {
939 // stop the trimming
940 shadowTrimmer_.Pause(GetStringIdentifier());
941 }
942 StorageExecutor *handle = nullptr;
943 if (isTrimming) {
944 handle = multiVerEngine_->FindExecutor(isWrite, OperatePerm::NORMAL_PERM, errCode, 0);
945 } else {
946 handle = multiVerEngine_->FindExecutor(isWrite, perm, errCode);
947 }
948
949 if (handle == nullptr) {
950 if (isWrite && !isTrimming) {
951 // restart the trimming
952 shadowTrimmer_.Continue(GetStringIdentifier(), false);
953 }
954 } else {
955 if (!handle->GetWritable() && isTrimming) {
956 static_cast<MultiVerStorageExecutor *>(handle)->InitCurrentReadVersion();
957 }
958 }
959 return static_cast<MultiVerStorageExecutor *>(handle);
960 }
961
ReleaseHandle(MultiVerStorageExecutor * & handle,bool isTrimming) const962 void MultiVerNaturalStore::ReleaseHandle(MultiVerStorageExecutor *&handle, bool isTrimming) const
963 {
964 if (multiVerEngine_ == nullptr || handle == nullptr) {
965 return;
966 }
967 bool isCorrupted = handle->GetCorruptedStatus();
968 bool isWrite = handle->GetWritable();
969 StorageExecutor *databaseHandle = handle;
970 multiVerEngine_->Recycle(databaseHandle);
971 handle = nullptr;
972 if (isCorrupted) {
973 CorruptNotify();
974 }
975 if (isWrite && !isTrimming) {
976 // restart the trimming.
977 LOGI("Release handle and continue vacuum data!");
978 shadowTrimmer_.Continue(GetStringIdentifier(), true);
979 }
980 }
981
InitStorageContext(bool isChangeTag)982 int MultiVerNaturalStore::InitStorageContext(bool isChangeTag)
983 {
984 int errCode = InitStorageContextVersion(isChangeTag);
985 if (errCode != E_OK) {
986 return errCode;
987 }
988
989 maxCommitVersion_ = commitHistory_->GetMaxCommitVersion(errCode);
990 if (errCode != E_OK) {
991 LOGE("Get the max commit version failed:%d", errCode);
992 }
993 return errCode;
994 }
995
InitStorageContextVersion(bool isChangeTag)996 int MultiVerNaturalStore::InitStorageContextVersion(bool isChangeTag)
997 {
998 std::string verFilePath;
999 int errCode = GetVersionFilePath(MyProp(), verFilePath);
1000 if (errCode != E_OK) {
1001 return errCode;
1002 }
1003
1004 if (!OS::CheckPathExistence(verFilePath)) {
1005 return CreateNewVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_);
1006 }
1007 if (isChangeTag) {
1008 return ChangeVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_, isChangeTag);
1009 }
1010 uint32_t version = 0;
1011 return GetVersionAndTag(verFilePath, version, branchTag_);
1012 }
1013
GetCurrentTag(std::vector<uint8_t> & tag) const1014 void MultiVerNaturalStore::GetCurrentTag(std::vector<uint8_t> &tag) const
1015 {
1016 tag = branchTag_;
1017 }
1018
AddVersionConstraintToList(Version version)1019 void MultiVerNaturalStore::AddVersionConstraintToList(Version version)
1020 {
1021 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1022 versionConstraints_.insert(version);
1023 }
1024
RemoveVersionConstraintFromList(Version version)1025 void MultiVerNaturalStore::RemoveVersionConstraintFromList(Version version)
1026 {
1027 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1028 auto iter = versionConstraints_.find(version);
1029 if (iter != versionConstraints_.end()) {
1030 versionConstraints_.erase(iter);
1031 // Auto launch the vacuum.
1032 shadowTrimmer_.AutoRelaunchOnce(GetStringIdentifier());
1033 }
1034 }
1035
GetMaxTrimmableVersion() const1036 Version MultiVerNaturalStore::GetMaxTrimmableVersion() const
1037 {
1038 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1039 if (versionConstraints_.empty()) {
1040 return UINT64_MAX;
1041 }
1042 return *(versionConstraints_.begin());
1043 }
1044
TransObserverTypeToRegisterFunctionType(int observerType,RegisterFuncType & type) const1045 int MultiVerNaturalStore::TransObserverTypeToRegisterFunctionType(int observerType, RegisterFuncType &type) const
1046 {
1047 if (observerType == static_cast<uint32_t>(NATURAL_STORE_COMMIT_EVENT)) {
1048 type = RegisterFuncType::OBSERVER_MULTI_VERSION_NS_COMMIT_EVENT;
1049 return E_OK;
1050 }
1051 return -E_NOT_SUPPORT;
1052 }
1053
GetDbProperties() const1054 const KvDBProperties &MultiVerNaturalStore::GetDbProperties() const
1055 {
1056 return GetMyProperties();
1057 }
1058
RemoveKvDB(const KvDBProperties & properties)1059 int MultiVerNaturalStore::RemoveKvDB(const KvDBProperties &properties)
1060 {
1061 std::string storeOnlyDir;
1062 std::string storeDir;
1063 GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE_SQLITE, storeDir, storeOnlyDir);
1064 int errCodeVersion = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_DATA_STORE);
1065 int errCodeCommit = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_COMMIT_STORE);
1066 int errCodeValue = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_VALUE_STORE);
1067 int errCodeMeta = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_META_STORE);
1068 LOGD("Delete the versionStorage:%d, commitStorage:%d, valueStorage:%d, metaStorage:%d",
1069 errCodeVersion, errCodeCommit, errCodeValue, errCodeMeta);
1070 DBCommon::RemoveAllFilesOfDirectory(storeDir, true);
1071 DBCommon::RemoveAllFilesOfDirectory(storeOnlyDir, true);
1072 if (errCodeVersion == E_OK && errCodeCommit == E_OK) {
1073 return E_OK;
1074 }
1075 if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == -E_NOT_FOUND) {
1076 return -E_NOT_FOUND;
1077 }
1078 if (errCodeVersion == E_OK && errCodeCommit == -E_NOT_FOUND) {
1079 return E_OK;
1080 }
1081 if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == E_OK) {
1082 return E_OK;
1083 }
1084 return errCodeCommit;
1085 }
1086
GetKvDBSize(const KvDBProperties & properties,uint64_t & size) const1087 int MultiVerNaturalStore::GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const
1088 {
1089 std::string storeOnlyDir;
1090 std::string storeDir;
1091 GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE_SQLITE, storeDir, storeOnlyDir);
1092
1093 std::vector<std::string> storageNames = {
1094 DBConstant::MULTI_VER_DATA_STORE,
1095 DBConstant::MULTI_VER_COMMIT_STORE,
1096 DBConstant::MULTI_VER_VALUE_STORE,
1097 DBConstant::MULTI_VER_META_STORE
1098 };
1099
1100 // there only calculate db related file size
1101 for (const auto &storageName : storageNames) {
1102 uint64_t dbSize = 0;
1103 int errCode = KvDBUtils::GetKvDbSize(storeDir, storeOnlyDir, storageName, dbSize);
1104 if (errCode == E_OK) {
1105 size += dbSize;
1106 continue;
1107 }
1108
1109 if (errCode == -E_NOT_FOUND) {
1110 return -E_NOT_FOUND;
1111 }
1112
1113 size = 0;
1114 return errCode;
1115 }
1116 return E_OK;
1117 }
1118
GetDbPropertyForUpdate()1119 KvDBProperties &MultiVerNaturalStore::GetDbPropertyForUpdate()
1120 {
1121 return MyProp();
1122 }
1123
CheckVersion(const KvDBProperties & kvDBProp) const1124 int MultiVerNaturalStore::CheckVersion(const KvDBProperties &kvDBProp) const
1125 {
1126 LOGD("[MultiVerStore][CheckVer] Current Overall Version: %u.", MULTI_VER_STORE_VERSION_CURRENT);
1127 bool isVerFileExist = false;
1128 int errCode = CheckOverallVersionViaVersionFile(kvDBProp, isVerFileExist);
1129 if (errCode != E_OK) {
1130 return errCode;
1131 }
1132 bool isSubStorageExist = false;
1133 errCode = CheckSubStorageVersion(kvDBProp, isSubStorageExist);
1134 if (errCode != E_OK) {
1135 return errCode;
1136 }
1137 if (isVerFileExist != isSubStorageExist) {
1138 LOGW("[MultiVerStore][CheckVer] Detect File Lost, isVerFileExist=%d, isSubStorageExist=%d.",
1139 isVerFileExist, isSubStorageExist);
1140 }
1141 return E_OK;
1142 }
1143
CheckOverallVersionViaVersionFile(const KvDBProperties & kvDBProp,bool & isVerFileExist) const1144 int MultiVerNaturalStore::CheckOverallVersionViaVersionFile(const KvDBProperties &kvDBProp, bool &isVerFileExist) const
1145 {
1146 std::string verFilePath;
1147 int errCode = GetVersionFilePath(kvDBProp, verFilePath);
1148 if (errCode != E_OK) {
1149 return errCode;
1150 }
1151 // Absent of version file may because: 1: Newly created database; 2: An already created database lost version file.
1152 // In both case, we returned E_OK here. After each sub storage be successfully open and upgrade, create verFile.
1153 if (!OS::CheckPathExistence(verFilePath)) {
1154 LOGD("[MultiVerStore][CheckOverVer] No Version File.");
1155 isVerFileExist = false;
1156 return E_OK;
1157 }
1158 isVerFileExist = true;
1159
1160 uint32_t overallVersion = 0;
1161 std::vector<uint8_t> branchTagInVerFile;
1162 errCode = GetVersionAndTag(verFilePath, overallVersion, branchTagInVerFile);
1163 if (errCode != E_OK) {
1164 LOGE("[MultiVerStore][CheckOverVer] GetVersionAndTag fail, errCode=%d.", errCode);
1165 return errCode;
1166 }
1167 LOGD("[MultiVerStore][CheckOverVer] overallVersion=%u, tag=%s.", overallVersion, VEC_TO_STR(branchTagInVerFile));
1168 if (overallVersion > MULTI_VER_STORE_VERSION_CURRENT) {
1169 LOGE("[MultiVerStore][CheckOverVer] Version Not Support!");
1170 return -E_VERSION_NOT_SUPPORT;
1171 }
1172 return E_OK;
1173 }
1174
GetVersionFilePath(const KvDBProperties & kvDBProp,std::string & outPath) const1175 int MultiVerNaturalStore::GetVersionFilePath(const KvDBProperties &kvDBProp, std::string &outPath) const
1176 {
1177 std::string verFiledir;
1178 int errCode = GetWorkDir(kvDBProp, verFiledir);
1179 if (errCode != E_OK) {
1180 LOGE("[MultiVerStore][GetVerFilePath] GetWorkDir fail, errCode=%d", errCode);
1181 return errCode;
1182 }
1183 outPath = verFiledir + "/" + DBConstant::MULTI_SUB_DIR + "/version";
1184 return E_OK;
1185 }
1186
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const1187 int MultiVerNaturalStore::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
1188 {
1189 (void)keyPrefix;
1190 return -E_NOT_SUPPORT;
1191 }
1192
SetSendDataInterceptor(const PushDataInterceptor & interceptor)1193 void MultiVerNaturalStore::SetSendDataInterceptor(const PushDataInterceptor &interceptor)
1194 {
1195 (void)interceptor;
1196 return;
1197 }
1198
SetReceiveDataInterceptor(const DataInterceptor & interceptor)1199 void MultiVerNaturalStore::SetReceiveDataInterceptor(const DataInterceptor &interceptor)
1200 {
1201 (void)interceptor;
1202 return;
1203 }
1204
1205 DEFINE_OBJECT_TAG_FACILITIES(MultiVerNaturalStore)
1206 } // namespace DistributedDB
1207 #endif
1208