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)536 int MultiVerNaturalStore::PutMetaData(const Key &key, const Value &value)
537 {
538 int errCode = E_OK;
539 auto handle = GetHandle(true, errCode);
540 if (handle == nullptr) {
541 return errCode;
542 }
543
544 errCode = handle->PutMetaData(key, value);
545 ReleaseHandle(handle);
546 return errCode;
547 }
548
DeleteMetaData(const std::vector<Key> & keys)549 int MultiVerNaturalStore::DeleteMetaData(const std::vector<Key> &keys)
550 {
551 return -E_NOT_SUPPORT;
552 }
553
554 // Get all meta data keys.
GetAllMetaKeys(std::vector<Key> & keys) const555 int MultiVerNaturalStore::GetAllMetaKeys(std::vector<Key> &keys) const
556 {
557 return E_OK;
558 }
559
IsCommitExisted(const MultiVerCommitNode & commit) const560 bool MultiVerNaturalStore::IsCommitExisted(const MultiVerCommitNode &commit) const
561 {
562 int errCode = E_OK;
563 auto handle = GetHandle(false, errCode);
564 if (handle == nullptr) {
565 return false;
566 }
567
568 bool result = handle->IsCommitExisted(commit, errCode);
569 ReleaseHandle(handle);
570 return result;
571 }
572
GetDeviceLatestCommit(std::map<std::string,MultiVerCommitNode> & commitMap) const573 int MultiVerNaturalStore::GetDeviceLatestCommit(std::map<std::string, MultiVerCommitNode> &commitMap) const
574 {
575 int errCode = E_OK;
576 auto handle = GetHandle(false, errCode);
577 if (handle == nullptr) {
578 return -E_BUSY;
579 }
580
581 errCode = handle->GetDeviceLatestCommit(commitMap);
582 ReleaseHandle(handle);
583 return errCode;
584 }
585
GetCommitTree(const std::map<std::string,MultiVerCommitNode> & commitMap,std::vector<MultiVerCommitNode> & commits) const586 int MultiVerNaturalStore::GetCommitTree(const std::map<std::string, MultiVerCommitNode> &commitMap,
587 std::vector<MultiVerCommitNode> &commits) const
588 {
589 int errCode = E_OK;
590 auto handle = GetHandle(false, errCode);
591 if (handle == nullptr) {
592 return -E_BUSY;
593 }
594
595 errCode = handle->GetCommitTree(commitMap, commits);
596 ReleaseHandle(handle);
597 return errCode;
598 }
599
GetCommitData(const MultiVerCommitNode & commit,std::vector<MultiVerKvEntry * > & entries) const600 int MultiVerNaturalStore::GetCommitData(const MultiVerCommitNode &commit, std::vector<MultiVerKvEntry *> &entries) const
601 {
602 int errCode = E_OK;
603 auto handle = GetHandle(false, errCode);
604 if (handle == nullptr) {
605 return -E_BUSY;
606 }
607
608 errCode = handle->GetCommitData(commit, entries);
609 ReleaseHandle(handle);
610 return errCode;
611 }
612
CreateKvEntry(const std::vector<uint8_t> & data)613 MultiVerKvEntry *MultiVerNaturalStore::CreateKvEntry(const std::vector<uint8_t> &data)
614 {
615 auto kvEntry = new (std::nothrow) GenericMultiVerKvEntry;
616 if (kvEntry == nullptr) {
617 return nullptr;
618 }
619
620 int errCode = kvEntry->DeSerialData(data);
621 if (errCode != E_OK) {
622 LOGE("deserialize data into kv entry failed:%d", errCode);
623 delete kvEntry;
624 kvEntry = nullptr;
625 }
626 return kvEntry;
627 }
628
ReleaseKvEntry(const MultiVerKvEntry * entry)629 void MultiVerNaturalStore::ReleaseKvEntry(const MultiVerKvEntry *entry)
630 {
631 if (entry != nullptr) {
632 delete entry;
633 entry = nullptr;
634 }
635 }
636
IsValueSliceExisted(const ValueSliceHash & value) const637 bool MultiVerNaturalStore::IsValueSliceExisted(const ValueSliceHash &value) const
638 {
639 int errCode = E_OK;
640 auto handle = GetHandle(false, errCode);
641 if (handle == nullptr) {
642 return false;
643 }
644
645 bool result = handle->IsValueSliceExisted(value, errCode);
646 ReleaseHandle(handle);
647 return result;
648 }
649
GetValueSlice(const ValueSliceHash & hashValue,ValueSlice & sliceValue) const650 int MultiVerNaturalStore::GetValueSlice(const ValueSliceHash &hashValue, ValueSlice &sliceValue) const
651 {
652 int errCode = E_OK;
653 auto handle = GetHandle(false, errCode);
654 if (handle == nullptr) {
655 return -E_BUSY;
656 }
657
658 errCode = handle->GetValueSlice(hashValue, sliceValue);
659 ReleaseHandle(handle);
660 return errCode;
661 }
662
PutValueSlice(const ValueSliceHash & hashValue,const ValueSlice & sliceValue) const663 int MultiVerNaturalStore::PutValueSlice(const ValueSliceHash &hashValue, const ValueSlice &sliceValue) const
664 {
665 int errCode = E_OK;
666 auto handle = GetHandle(true, errCode);
667 if (handle == nullptr) {
668 return -E_BUSY;
669 }
670
671 errCode = handle->PutValueSlice(hashValue, sliceValue, false);
672 ReleaseHandle(handle);
673 return errCode;
674 }
675
PutCommitData(const MultiVerCommitNode & commit,const std::vector<MultiVerKvEntry * > & entries,const std::string & deviceName)676 int MultiVerNaturalStore::PutCommitData(const MultiVerCommitNode &commit, const std::vector<MultiVerKvEntry *> &entries,
677 const std::string &deviceName)
678 {
679 int errCode = E_OK;
680 auto handle = GetHandle(true, errCode);
681 if (handle == nullptr) {
682 return -E_BUSY;
683 }
684
685 errCode = handle->PutCommitData(commit, entries, deviceName);
686 ReleaseHandle(handle);
687 return errCode;
688 }
689
MergeSyncCommit(const MultiVerCommitNode & commit,const std::vector<MultiVerCommitNode> & commits)690 int MultiVerNaturalStore::MergeSyncCommit(const MultiVerCommitNode &commit,
691 const std::vector<MultiVerCommitNode> &commits)
692 {
693 int errCode = E_OK;
694 auto handle = GetHandle(true, errCode);
695 if (handle == nullptr) {
696 return -E_BUSY;
697 }
698
699 errCode = handle->MergeSyncCommit(commit, commits);
700 ReleaseHandle(handle);
701 return errCode;
702 }
703
NotifyStartSyncOperation()704 void MultiVerNaturalStore::NotifyStartSyncOperation()
705 {
706 shadowTrimmer_.Pause(GetStringIdentifier());
707 }
708
NotifyFinishSyncOperation()709 void MultiVerNaturalStore::NotifyFinishSyncOperation()
710 {
711 shadowTrimmer_.Continue(GetStringIdentifier(), true);
712 }
713
TransferSyncCommitDevInfo(MultiVerCommitNode & commit,const std::string & devId,bool isSyncedIn) const714 int MultiVerNaturalStore::TransferSyncCommitDevInfo(MultiVerCommitNode &commit, const std::string &devId,
715 bool isSyncedIn) const
716 {
717 std::string hashDevId = DBCommon::TransferHashString(devId);
718 if (isSyncedIn) {
719 // The size of the device info must be hash_size + tag_size;
720 if (commit.deviceInfo.size() == hashDevId.size() + MULTI_VER_TAG_SIZE) {
721 // If the hash device info is matched with the local, just remove the hash device info.
722 if (commit.deviceInfo.compare(0, hashDevId.size(), hashDevId) == 0) {
723 commit.deviceInfo = commit.deviceInfo.substr(hashDevId.size(), MULTI_VER_TAG_SIZE);
724 }
725 return E_OK;
726 }
727 LOGE("Unexpected dev info for sync in:%zu", commit.deviceInfo.size());
728 return -E_UNEXPECTED_DATA;
729 } else {
730 // If the device info only contains the tag info, it must be local node.
731 if (commit.deviceInfo.size() == MULTI_VER_TAG_SIZE) {
732 commit.deviceInfo.insert(0, hashDevId);
733 } else if (commit.deviceInfo.size() != hashDevId.size() + MULTI_VER_TAG_SIZE) {
734 LOGE("Unexpected dev info for sync out:%zu", commit.deviceInfo.size());
735 return -E_UNEXPECTED_DATA;
736 }
737 return E_OK;
738 }
739 }
740
Rekey(const CipherPassword & passwd)741 int MultiVerNaturalStore::Rekey(const CipherPassword &passwd)
742 {
743 if (multiVerEngine_ == nullptr) {
744 return -E_INVALID_DB;
745 }
746 int errCode = multiVerEngine_->TryToDisable(false, OperatePerm::REKEY_MONOPOLIZE_PERM);
747 if (errCode != E_OK) {
748 return errCode;
749 }
750 StopSyncer();
751 shadowTrimmer_.Pause(GetStringIdentifier());
752 errCode = multiVerEngine_->TryToDisable(true, OperatePerm::REKEY_MONOPOLIZE_PERM);
753 if (errCode != E_OK) {
754 multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
755 shadowTrimmer_.Continue(GetStringIdentifier(), true);
756 StartSyncer();
757 return errCode;
758 }
759
760 std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
761 commitHistory_, multiVerKvStorage_);
762 errCode = operation->Rekey(passwd);
763
764 multiVerEngine_->Enable(OperatePerm::REKEY_MONOPOLIZE_PERM);
765 shadowTrimmer_.Continue(GetStringIdentifier(), true);
766 StartSyncer();
767
768 return errCode;
769 }
770
Export(const std::string & filePath,const CipherPassword & passwd)771 int MultiVerNaturalStore::Export(const std::string &filePath, const CipherPassword &passwd)
772 {
773 if (multiVerEngine_ == nullptr) {
774 return -E_INVALID_DB;
775 }
776 std::string localDev;
777 int errCode = GetLocalIdentity(localDev);
778 if (errCode != E_OK) {
779 LOGE("Failed to GetLocalIdentity!");
780 }
781 // Exclusively write resources
782 auto handle = GetHandle(true, errCode);
783 if (handle == nullptr) {
784 return errCode;
785 }
786
787 std::unique_ptr<MultiVerDatabaseOper> operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_,
788 commitHistory_, multiVerKvStorage_);
789 operation->SetLocalDevId(localDev);
790 errCode = operation->Export(filePath, passwd);
791
792 ReleaseHandle(handle);
793
794 return errCode;
795 }
796
Import(const std::string & filePath,const CipherPassword & passwd)797 int MultiVerNaturalStore::Import(const std::string &filePath, const CipherPassword &passwd)
798 {
799 if (multiVerEngine_ == nullptr) {
800 return -E_INVALID_DB;
801 }
802 std::string localDev;
803 int errCode = GetLocalIdentity(localDev);
804 if (errCode != E_OK) {
805 LOGE("Failed to get the local identity!");
806 localDev.resize(0);
807 }
808 errCode = multiVerEngine_->TryToDisable(false, OperatePerm::IMPORT_MONOPOLIZE_PERM);
809 if (errCode != E_OK) {
810 return errCode;
811 }
812 StopSyncer();
813 shadowTrimmer_.Abort(GetStringIdentifier());
814 std::unique_ptr<MultiVerDatabaseOper> operation;
815 errCode = multiVerEngine_->TryToDisable(true, OperatePerm::IMPORT_MONOPOLIZE_PERM);
816 if (errCode != E_OK) {
817 goto END;
818 }
819 operation = std::make_unique<MultiVerDatabaseOper>(this, multiVerData_, commitHistory_, multiVerKvStorage_);
820 operation->SetLocalDevId(localDev);
821 errCode = operation->Import(filePath, passwd);
822 END:
823 multiVerEngine_->Enable(OperatePerm::IMPORT_MONOPOLIZE_PERM);
824 shadowTrimmer_.Launch(GetStringIdentifier(), trimmerImpl_);
825 StartSyncer();
826 return errCode;
827 }
828
GetCurrentTimestamp()829 uint64_t MultiVerNaturalStore::GetCurrentTimestamp()
830 {
831 return GetTimestamp();
832 }
833
GetDiffEntries(const CommitID & begin,const CommitID & end,MultiVerDiffData & data) const834 int MultiVerNaturalStore::GetDiffEntries(const CommitID &begin, const CommitID &end, MultiVerDiffData &data) const
835 {
836 // Get one connection.
837 int errCode = E_OK;
838 auto handle = GetHandle(false, errCode);
839 if (handle == nullptr) {
840 return errCode;
841 }
842
843 errCode = handle->GetDiffEntries(begin, end, data);
844 ReleaseHandle(handle);
845 return errCode;
846 }
847
RecoverFromException()848 int MultiVerNaturalStore::RecoverFromException()
849 {
850 // Get the latest local version and the head node.
851 if (multiVerData_ == nullptr || commitHistory_ == nullptr) {
852 return -E_INVALID_DB;
853 }
854
855 IKvDBMultiVerTransaction *transaction = nullptr;
856 int errCode = multiVerData_->StartWrite(KvDataType::KV_DATA_SYNC_P2P, transaction);
857 if (transaction == nullptr) {
858 goto END;
859 }
860 errCode = transaction->StartTransaction();
861 if (errCode != E_OK) {
862 goto END;
863 }
864
865 errCode = CompareVerDataAndLog(transaction);
866 if (errCode != E_OK) {
867 LOGE("Compare the version data and log failed:%d", errCode);
868 transaction->RollBackTransaction();
869 goto END;
870 }
871 errCode = transaction->CommitTransaction();
872 END:
873 if (transaction != nullptr) {
874 multiVerData_->ReleaseTransaction(transaction);
875 transaction = nullptr;
876 }
877 return errCode;
878 }
879
CompareVerDataAndLog(IKvDBMultiVerTransaction * transaction) const880 int MultiVerNaturalStore::CompareVerDataAndLog(IKvDBMultiVerTransaction *transaction) const
881 {
882 // Get the latest local version, we only care the local data.
883 Version maxLocalVersion = 0;
884 int errCode = transaction->GetMaxVersion(MultiVerDataType::NATIVE_TYPE, maxLocalVersion);
885 if (errCode != E_OK) {
886 return errCode;
887 }
888
889 CommitID headerId = commitHistory_->GetHeader(errCode);
890 if (errCode != E_OK) {
891 return errCode;
892 }
893
894 if (headerId.empty()) {
895 if (maxLocalVersion != 0) {
896 return transaction->ClearEntriesByVersion(maxLocalVersion);
897 }
898 return E_OK;
899 }
900
901 IKvDBCommit *commitHead = commitHistory_->GetCommit(headerId, errCode);
902 if (commitHead == nullptr) {
903 return errCode;
904 }
905
906 // compare the version
907 if (commitHead->GetCommitVersion() < maxLocalVersion) {
908 LOGD("Delete entries");
909 errCode = transaction->ClearEntriesByVersion(maxLocalVersion);
910 } else {
911 errCode = E_OK;
912 }
913
914 commitHistory_->ReleaseCommit(commitHead);
915 commitHead = nullptr;
916 return errCode;
917 }
918
GetMaxCommitVersion() const919 Version MultiVerNaturalStore::GetMaxCommitVersion() const
920 {
921 return maxCommitVersion_;
922 }
923
SetMaxCommitVersion(const Version & version)924 void MultiVerNaturalStore::SetMaxCommitVersion(const Version &version)
925 {
926 maxCommitVersion_ = (version > maxCommitVersion_) ? version : maxCommitVersion_;
927 }
928
GetHandle(bool isWrite,int & errCode,bool isTrimming,OperatePerm perm) const929 MultiVerStorageExecutor *MultiVerNaturalStore::GetHandle(bool isWrite, int &errCode,
930 bool isTrimming, OperatePerm perm) const
931 {
932 if (multiVerEngine_ == nullptr) {
933 errCode = -E_INVALID_DB;
934 return nullptr;
935 }
936
937 if (isWrite && !isTrimming) {
938 // stop the trimming
939 shadowTrimmer_.Pause(GetStringIdentifier());
940 }
941 StorageExecutor *handle = nullptr;
942 if (isTrimming) {
943 handle = multiVerEngine_->FindExecutor(isWrite, OperatePerm::NORMAL_PERM, errCode, 0);
944 } else {
945 handle = multiVerEngine_->FindExecutor(isWrite, perm, errCode);
946 }
947
948 if (handle == nullptr) {
949 if (isWrite && !isTrimming) {
950 // restart the trimming
951 shadowTrimmer_.Continue(GetStringIdentifier(), false);
952 }
953 } else {
954 if (!handle->GetWritable() && isTrimming) {
955 static_cast<MultiVerStorageExecutor *>(handle)->InitCurrentReadVersion();
956 }
957 }
958 return static_cast<MultiVerStorageExecutor *>(handle);
959 }
960
ReleaseHandle(MultiVerStorageExecutor * & handle,bool isTrimming) const961 void MultiVerNaturalStore::ReleaseHandle(MultiVerStorageExecutor *&handle, bool isTrimming) const
962 {
963 if (multiVerEngine_ == nullptr || handle == nullptr) {
964 return;
965 }
966 bool isCorrupted = handle->GetCorruptedStatus();
967 bool isWrite = handle->GetWritable();
968 StorageExecutor *databaseHandle = handle;
969 multiVerEngine_->Recycle(databaseHandle);
970 handle = nullptr;
971 if (isCorrupted) {
972 CorruptNotify();
973 }
974 if (isWrite && !isTrimming) {
975 // restart the trimming.
976 LOGI("Release handle and continue vacuum data!");
977 shadowTrimmer_.Continue(GetStringIdentifier(), true);
978 }
979 }
980
InitStorageContext(bool isChangeTag)981 int MultiVerNaturalStore::InitStorageContext(bool isChangeTag)
982 {
983 int errCode = InitStorageContextVersion(isChangeTag);
984 if (errCode != E_OK) {
985 return errCode;
986 }
987
988 maxCommitVersion_ = commitHistory_->GetMaxCommitVersion(errCode);
989 if (errCode != E_OK) {
990 LOGE("Get the max commit version failed:%d", errCode);
991 }
992 return errCode;
993 }
994
InitStorageContextVersion(bool isChangeTag)995 int MultiVerNaturalStore::InitStorageContextVersion(bool isChangeTag)
996 {
997 std::string verFilePath;
998 int errCode = GetVersionFilePath(MyProp(), verFilePath);
999 if (errCode != E_OK) {
1000 return errCode;
1001 }
1002
1003 if (!OS::CheckPathExistence(verFilePath)) {
1004 return CreateNewVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_);
1005 }
1006 if (isChangeTag) {
1007 return ChangeVersionFile(verFilePath, MULTI_VER_STORE_VERSION_CURRENT, branchTag_, isChangeTag);
1008 }
1009 uint32_t version = 0;
1010 return GetVersionAndTag(verFilePath, version, branchTag_);
1011 }
1012
GetCurrentTag(std::vector<uint8_t> & tag) const1013 void MultiVerNaturalStore::GetCurrentTag(std::vector<uint8_t> &tag) const
1014 {
1015 tag = branchTag_;
1016 }
1017
AddVersionConstraintToList(Version version)1018 void MultiVerNaturalStore::AddVersionConstraintToList(Version version)
1019 {
1020 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1021 versionConstraints_.insert(version);
1022 }
1023
RemoveVersionConstraintFromList(Version version)1024 void MultiVerNaturalStore::RemoveVersionConstraintFromList(Version version)
1025 {
1026 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1027 auto iter = versionConstraints_.find(version);
1028 if (iter != versionConstraints_.end()) {
1029 versionConstraints_.erase(iter);
1030 // Auto launch the vacuum.
1031 shadowTrimmer_.AutoRelaunchOnce(GetStringIdentifier());
1032 }
1033 }
1034
GetMaxTrimmableVersion() const1035 Version MultiVerNaturalStore::GetMaxTrimmableVersion() const
1036 {
1037 std::lock_guard<std::mutex> lock(versionConstraintMutex_);
1038 if (versionConstraints_.empty()) {
1039 return UINT64_MAX;
1040 }
1041 return *(versionConstraints_.begin());
1042 }
1043
TransObserverTypeToRegisterFunctionType(int observerType,RegisterFuncType & type) const1044 int MultiVerNaturalStore::TransObserverTypeToRegisterFunctionType(int observerType, RegisterFuncType &type) const
1045 {
1046 if (observerType == static_cast<uint32_t>(NATURAL_STORE_COMMIT_EVENT)) {
1047 type = OBSERVER_MULTI_VERSION_NS_COMMIT_EVENT;
1048 return E_OK;
1049 }
1050 return -E_NOT_SUPPORT;
1051 }
1052
GetDbProperties() const1053 const KvDBProperties &MultiVerNaturalStore::GetDbProperties() const
1054 {
1055 return GetMyProperties();
1056 }
1057
RemoveKvDB(const KvDBProperties & properties)1058 int MultiVerNaturalStore::RemoveKvDB(const KvDBProperties &properties)
1059 {
1060 std::string storeOnlyDir;
1061 std::string storeDir;
1062 GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE, storeDir, storeOnlyDir);
1063 int errCodeVersion = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_DATA_STORE);
1064 int errCodeCommit = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_COMMIT_STORE);
1065 int errCodeValue = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_VALUE_STORE);
1066 int errCodeMeta = KvDBUtils::RemoveKvDB(storeDir, storeOnlyDir, DBConstant::MULTI_VER_META_STORE);
1067 LOGD("Delete the versionStorage:%d, commitStorage:%d, valueStorage:%d, metaStorage:%d",
1068 errCodeVersion, errCodeCommit, errCodeValue, errCodeMeta);
1069 DBCommon::RemoveAllFilesOfDirectory(storeDir, true);
1070 DBCommon::RemoveAllFilesOfDirectory(storeOnlyDir, true);
1071 if (errCodeVersion == E_OK && errCodeCommit == E_OK) {
1072 return E_OK;
1073 }
1074 if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == -E_NOT_FOUND) {
1075 return -E_NOT_FOUND;
1076 }
1077 if (errCodeVersion == E_OK && errCodeCommit == -E_NOT_FOUND) {
1078 return E_OK;
1079 }
1080 if (errCodeVersion == -E_NOT_FOUND && errCodeCommit == E_OK) {
1081 return E_OK;
1082 }
1083 return errCodeCommit;
1084 }
1085
GetKvDBSize(const KvDBProperties & properties,uint64_t & size) const1086 int MultiVerNaturalStore::GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const
1087 {
1088 std::string storeOnlyDir;
1089 std::string storeDir;
1090 GenericKvDB::GetStoreDirectory(properties, KvDBProperties::MULTI_VER_TYPE, storeDir, storeOnlyDir);
1091
1092 std::vector<std::string> storageNames = {
1093 DBConstant::MULTI_VER_DATA_STORE,
1094 DBConstant::MULTI_VER_COMMIT_STORE,
1095 DBConstant::MULTI_VER_VALUE_STORE,
1096 DBConstant::MULTI_VER_META_STORE
1097 };
1098
1099 // there only calculate db related file size
1100 for (const auto &storageName : storageNames) {
1101 uint64_t dbSize = 0;
1102 int errCode = KvDBUtils::GetKvDbSize(storeDir, storeOnlyDir, storageName, dbSize);
1103 if (errCode == E_OK) {
1104 size += dbSize;
1105 continue;
1106 }
1107
1108 if (errCode == -E_NOT_FOUND) {
1109 return -E_NOT_FOUND;
1110 }
1111
1112 size = 0;
1113 return errCode;
1114 }
1115 return E_OK;
1116 }
1117
GetDbPropertyForUpdate()1118 KvDBProperties &MultiVerNaturalStore::GetDbPropertyForUpdate()
1119 {
1120 return MyProp();
1121 }
1122
CheckVersion(const KvDBProperties & kvDBProp) const1123 int MultiVerNaturalStore::CheckVersion(const KvDBProperties &kvDBProp) const
1124 {
1125 LOGD("[MultiVerStore][CheckVer] Current Overall Version: %u.", MULTI_VER_STORE_VERSION_CURRENT);
1126 bool isVerFileExist = false;
1127 int errCode = CheckOverallVersionViaVersionFile(kvDBProp, isVerFileExist);
1128 if (errCode != E_OK) {
1129 return errCode;
1130 }
1131 bool isSubStorageExist = false;
1132 errCode = CheckSubStorageVersion(kvDBProp, isSubStorageExist);
1133 if (errCode != E_OK) {
1134 return errCode;
1135 }
1136 if (isVerFileExist != isSubStorageExist) {
1137 LOGW("[MultiVerStore][CheckVer] Detect File Lost, isVerFileExist=%d, isSubStorageExist=%d.",
1138 isVerFileExist, isSubStorageExist);
1139 }
1140 return E_OK;
1141 }
1142
CheckOverallVersionViaVersionFile(const KvDBProperties & kvDBProp,bool & isVerFileExist) const1143 int MultiVerNaturalStore::CheckOverallVersionViaVersionFile(const KvDBProperties &kvDBProp, bool &isVerFileExist) const
1144 {
1145 std::string verFilePath;
1146 int errCode = GetVersionFilePath(kvDBProp, verFilePath);
1147 if (errCode != E_OK) {
1148 return errCode;
1149 }
1150 // Absent of version file may because: 1: Newly created database; 2: An already created database lost version file.
1151 // In both case, we returned E_OK here. After each sub storage be successfully open and upgrade, create verFile.
1152 if (!OS::CheckPathExistence(verFilePath)) {
1153 LOGD("[MultiVerStore][CheckOverVer] No Version File.");
1154 isVerFileExist = false;
1155 return E_OK;
1156 }
1157 isVerFileExist = true;
1158
1159 uint32_t overallVersion = 0;
1160 std::vector<uint8_t> branchTagInVerFile;
1161 errCode = GetVersionAndTag(verFilePath, overallVersion, branchTagInVerFile);
1162 if (errCode != E_OK) {
1163 LOGE("[MultiVerStore][CheckOverVer] GetVersionAndTag fail, errCode=%d.", errCode);
1164 return errCode;
1165 }
1166 LOGD("[MultiVerStore][CheckOverVer] overallVersion=%u, tag=%s.", overallVersion, VEC_TO_STR(branchTagInVerFile));
1167 if (overallVersion > MULTI_VER_STORE_VERSION_CURRENT) {
1168 LOGE("[MultiVerStore][CheckOverVer] Version Not Support!");
1169 return -E_VERSION_NOT_SUPPORT;
1170 }
1171 return E_OK;
1172 }
1173
GetVersionFilePath(const KvDBProperties & kvDBProp,std::string & outPath) const1174 int MultiVerNaturalStore::GetVersionFilePath(const KvDBProperties &kvDBProp, std::string &outPath) const
1175 {
1176 std::string verFiledir;
1177 int errCode = GetWorkDir(kvDBProp, verFiledir);
1178 if (errCode != E_OK) {
1179 LOGE("[MultiVerStore][GetVerFilePath] GetWorkDir fail, errCode=%d", errCode);
1180 return errCode;
1181 }
1182 outPath = verFiledir + "/" + DBConstant::MULTI_SUB_DIR + "/version";
1183 return E_OK;
1184 }
1185
DeleteMetaDataByPrefixKey(const Key & keyPrefix) const1186 int MultiVerNaturalStore::DeleteMetaDataByPrefixKey(const Key &keyPrefix) const
1187 {
1188 (void)keyPrefix;
1189 return -E_NOT_SUPPORT;
1190 }
1191
SetDataInterceptor(const PushDataInterceptor & interceptor)1192 void MultiVerNaturalStore::SetDataInterceptor(const PushDataInterceptor &interceptor)
1193 {
1194 (void)interceptor;
1195 return;
1196 }
1197
1198 DEFINE_OBJECT_TAG_FACILITIES(MultiVerNaturalStore)
1199 } // namespace DistributedDB
1200 #endif
1201