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 "single_ver_database_oper.h"
17 
18 #include "db_errno.h"
19 #include "log_print.h"
20 #include "db_constant.h"
21 #include "db_common.h"
22 #include "platform_specific.h"
23 
24 namespace DistributedDB {
SingleVerDatabaseOper(SQLiteSingleVerNaturalStore * naturalStore,SQLiteStorageEngine * storageEngine)25 SingleVerDatabaseOper::SingleVerDatabaseOper(SQLiteSingleVerNaturalStore *naturalStore,
26     SQLiteStorageEngine *storageEngine)
27     : singleVerNaturalStore_(naturalStore),
28       storageEngine_(storageEngine)
29 {}
30 
SetSecOpt(const std::string & path,bool isDir) const31 int SingleVerDatabaseOper::SetSecOpt(const std::string &path, bool isDir) const
32 {
33     std::string currentMetaPath = path + "/" + DBConstant::METADB_DIR;
34     std::string currentMainPath = path + "/" + DBConstant::MAINDB_DIR;
35     if (!isDir) {
36         currentMetaPath = currentMetaPath + "/" + DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
37         currentMainPath = currentMainPath + "/" + DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
38     }
39     SecurityOption option;
40     int mainSecLabel = singleVerNaturalStore_->GetDbProperties().GetSecLabel();
41     option.securityLabel = ((mainSecLabel >= SecurityLabel::S2) ? SecurityLabel::S2 : mainSecLabel);
42     int errCode = RuntimeContext::GetInstance()->SetSecurityOption(currentMetaPath, option);
43     if (errCode != E_OK && errCode != -E_NOT_SUPPORT) {
44         return errCode;
45     }
46 
47     option.securityLabel = singleVerNaturalStore_->GetDbProperties().GetSecLabel();
48     option.securityFlag = singleVerNaturalStore_->GetDbProperties().GetSecFlag();
49     errCode = RuntimeContext::GetInstance()->SetSecurityOption(currentMainPath, option);
50     if (errCode != E_OK && errCode != -E_NOT_SUPPORT) {
51         return errCode;
52     }
53     return E_OK;
54 }
55 
Rekey(const CipherPassword & passwd)56 int SingleVerDatabaseOper::Rekey(const CipherPassword &passwd)
57 {
58     if (singleVerNaturalStore_ == nullptr || storageEngine_ == nullptr) {
59         return -E_INVALID_DB;
60     }
61 
62     return ExecuteRekey(passwd, singleVerNaturalStore_->GetDbProperties());
63 }
64 
Import(const std::string & filePath,const CipherPassword & passwd)65 int SingleVerDatabaseOper::Import(const std::string &filePath, const CipherPassword &passwd)
66 {
67     if (singleVerNaturalStore_ == nullptr || storageEngine_ == nullptr) {
68         return -E_INVALID_DB;
69     }
70 
71     return ExecuteImport(filePath, passwd, singleVerNaturalStore_->GetDbProperties());
72 }
73 
Export(const std::string & filePath,const CipherPassword & passwd) const74 int SingleVerDatabaseOper::Export(const std::string &filePath, const CipherPassword &passwd) const
75 {
76     if (singleVerNaturalStore_ == nullptr || storageEngine_ == nullptr) {
77         return -E_INVALID_DB;
78     }
79 
80     return ExecuteExport(filePath, passwd, singleVerNaturalStore_->GetDbProperties());
81 }
82 
RekeyPreHandle(const CipherPassword & passwd,int & errCode)83 bool SingleVerDatabaseOper::RekeyPreHandle(const CipherPassword &passwd, int &errCode)
84 {
85     if (singleVerNaturalStore_->GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false)) {
86         errCode = -E_NOT_SUPPORT;
87         return false;
88     }
89 
90     CipherType cipherType;
91     CipherPassword cachePasswd;
92     singleVerNaturalStore_->GetDbProperties().GetPassword(cipherType, cachePasswd);
93 
94     if (cachePasswd.GetSize() == 0 && passwd.GetSize() == 0) {
95         errCode = E_OK;
96         return false;
97     }
98 
99     // need invoke sqlite3 rekey
100     if (cachePasswd.GetSize() > 0 && passwd.GetSize() > 0) {
101         errCode = RunRekeyLogic(cipherType, passwd);
102         return false;
103     }
104 
105     return true;
106 }
107 
BackupDb(const CipherPassword & passwd) const108 int SingleVerDatabaseOper::BackupDb(const CipherPassword &passwd) const
109 {
110     std::string filePrefix;
111     int errCode = GetCtrlFilePrefix(singleVerNaturalStore_->GetDbProperties(), filePrefix);
112     if (errCode != E_OK) {
113         return errCode;
114     }
115 
116     // create backup dir
117     std::string backupDir = filePrefix + DBConstant::PATH_BACKUP_POSTFIX;
118     errCode = DBCommon::CreateDirectory(backupDir);
119     if (errCode != E_OK) {
120         LOGE("create backup dir failed:%d.", errCode);
121         return errCode;
122     }
123 
124     std::vector<std::string> dbDir {DBConstant::MAINDB_DIR, DBConstant::METADB_DIR, DBConstant::CACHEDB_DIR};
125     for (const auto &item : dbDir) {
126         if (DBCommon::CreateDirectory(backupDir + "/" + item) != E_OK) {
127             return -E_SYSTEM_API_FAIL;
128         }
129     }
130 
131     errCode = SetSecOpt(backupDir, true);
132     if (errCode != E_OK) {
133         LOGE("Set backup dir secOption failed, errCode = [%d]", errCode);
134         return errCode;
135     }
136 
137     // export db to backup
138     errCode = RunExportLogic(passwd, filePrefix);
139     if (errCode != E_OK) {
140         return errCode;
141     }
142 
143     return SetSecOpt(backupDir, false); // set file SecOpt
144 }
145 
CloseStorages()146 int SingleVerDatabaseOper::CloseStorages()
147 {
148     // close old db
149     storageEngine_->Release();
150     int errCode = RekeyRecover(singleVerNaturalStore_->GetDbProperties());
151     if (errCode != E_OK) {
152         LOGE("Recover failed after rekey ok:%d.", errCode);
153         int innerCode = InitStorageEngine();
154         if (innerCode != E_OK) {
155             LOGE("ReInit the handlePool failed:%d", innerCode);
156         }
157     }
158     return errCode;
159 }
160 
RekeyPostHandle(const CipherPassword & passwd)161 int SingleVerDatabaseOper::RekeyPostHandle(const CipherPassword &passwd)
162 {
163     CipherType cipherType;
164     CipherPassword oldPasswd;
165     singleVerNaturalStore_->GetDbPropertyForUpdate().GetPassword(cipherType, oldPasswd);
166     singleVerNaturalStore_->GetDbPropertyForUpdate().SetPassword(cipherType, passwd);
167     singleVerNaturalStore_->GetDbPropertyForUpdate().SetBoolProp(
168         KvDBProperties::ENCRYPTED_MODE, (passwd.GetSize() != 0));
169 
170     return InitStorageEngine();
171 }
172 
ExportMainDB(const std::string & currentDir,const CipherPassword & passwd,const std::string & dbDir) const173 int SingleVerDatabaseOper::ExportMainDB(const std::string &currentDir, const CipherPassword &passwd,
174     const std::string &dbDir) const
175 {
176     std::string backupDbName = dbDir + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
177         DBConstant::DB_EXTENSION;
178     std::string currentDb = currentDir + "/" + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
179         DBConstant::DB_EXTENSION;
180 
181     CipherType cipherType;
182     CipherPassword currPasswd;
183     singleVerNaturalStore_->GetDbProperties().GetPassword(cipherType, currPasswd);
184     LOGD("Begin the sqlite main database export!");
185     int errCode = SQLiteUtils::ExportDatabase(currentDb, cipherType, currPasswd, backupDbName, passwd);
186     if (errCode != E_OK) {
187         LOGE("Export the database failed:%d", errCode);
188     }
189 
190     return errCode;
191 }
192 
ExportMetaDB(const std::string & currentDir,const CipherPassword & passwd,const std::string & dbDir) const193 int SingleVerDatabaseOper::ExportMetaDB(const std::string &currentDir, const CipherPassword &passwd,
194     const std::string &dbDir) const
195 {
196     std::string backupDbName = dbDir + DBConstant::METADB_DIR + "/" + DBConstant::SINGLE_VER_META_STORE +
197         DBConstant::DB_EXTENSION;
198     std::string currentDb = currentDir + "/" + DBConstant::METADB_DIR  + "/" + DBConstant::SINGLE_VER_META_STORE +
199         DBConstant::DB_EXTENSION;
200     if (!OS::CheckPathExistence(currentDb)) { // Is S2 label, can access
201         LOGD("No metaDB, no need Export metaDB.");
202         return E_OK;
203     }
204 
205     // Set metaDB db passwd same as mainDB temp, may be not need
206     LOGI("Begin the sqlite meta database export.");
207     int errCode = SQLiteUtils::ExportDatabase(currentDb, CipherType::DEFAULT, CipherPassword(),
208         backupDbName, CipherPassword());
209     if (errCode != E_OK) {
210         LOGE("Export the database failed:%d", errCode);
211     }
212 
213     return errCode;
214 }
215 
ExportAllDatabases(const std::string & currentDir,const CipherPassword & passwd,const std::string & dbDir) const216 int SingleVerDatabaseOper::ExportAllDatabases(const std::string &currentDir, const CipherPassword &passwd,
217     const std::string &dbDir) const
218 {
219     int errCode = ExportMainDB(currentDir, passwd, dbDir);
220     if (errCode != E_OK) {
221         LOGE("Export MainDB fail, errCode = [%d]", errCode);
222         return errCode;
223     }
224 
225     errCode = ExportMetaDB(currentDir, passwd, dbDir);
226     if (errCode != E_OK) {
227         LOGE("Export MetaDB fail, errCode = [%d]", errCode);
228         return errCode;
229     }
230     return errCode;
231 }
232 
BackupDatabase(const ImportFileInfo & info) const233 int SingleVerDatabaseOper::BackupDatabase(const ImportFileInfo &info) const
234 {
235     std::string currentMainFile = info.currentDir + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
236         DBConstant::DB_EXTENSION;
237     std::string backupMainFile = info.backupDir + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
238         DBConstant::DB_EXTENSION;
239     int errCode = DBCommon::CopyFile(currentMainFile, backupMainFile);
240     if (errCode != E_OK) {
241         LOGE("Backup the current database error:%d", errCode);
242         return errCode;
243     }
244 
245     std::string currentMetaFile = info.currentDir + DBConstant::METADB_DIR + "/" + DBConstant::SINGLE_VER_META_STORE +
246         DBConstant::DB_EXTENSION;
247     if (OS::CheckPathExistence(currentMetaFile)) {
248         std::string backupMetaFile = info.backupDir + DBConstant::METADB_DIR + "/" + DBConstant::SINGLE_VER_META_STORE +
249             DBConstant::DB_EXTENSION;
250         errCode = DBCommon::CopyFile(currentMetaFile, backupMetaFile);
251         if (errCode != E_OK) {
252             LOGE("Backup the current database error:%d", errCode);
253             return errCode;
254         }
255     }
256     return E_OK;
257 }
258 
BackupCurrentDatabase(const ImportFileInfo & info) const259 int SingleVerDatabaseOper::BackupCurrentDatabase(const ImportFileInfo &info) const
260 {
261     storageEngine_->Release();
262     // create the pre flag file.
263     int errCode = OS::CreateFileByFileName(info.curValidFile);
264     if (errCode != E_OK) {
265         LOGE("create ctrl file failed:%d.", errCode);
266         return errCode;
267     }
268 
269     // create backup dir
270     errCode = DBCommon::CreateDirectory(info.backupDir);
271     if (errCode != E_OK) {
272         LOGE("Create backup dir failed:%d.", errCode);
273         return errCode;
274     }
275 
276     std::vector<std::string> dbDir {DBConstant::MAINDB_DIR, DBConstant::METADB_DIR, DBConstant::CACHEDB_DIR};
277     for (const auto &item : dbDir) {
278         if (DBCommon::CreateDirectory(info.backupDir + "/" + item) != E_OK) {
279             return -E_SYSTEM_API_FAIL;
280         }
281     }
282 
283     errCode = SetSecOpt(info.backupDir, true);
284     if (errCode != E_OK) {
285         LOGE("[singleVer][BackupCurrentDatabase]Set secOpt to dir fail, errCode = [%d]", errCode);
286         return errCode;
287     }
288 
289     errCode = BackupDatabase(info);
290     if (errCode != E_OK) {
291         LOGE("[SingleVerDatabaseOper][BackupCurrentDatabase] backup current database fail, errCode = [%d]", errCode);
292         return errCode;
293     }
294 
295     // Protect the loss of label information when the abnormal scene is restored
296     errCode = SetSecOpt(info.backupDir, false);
297     if (errCode != E_OK) {
298         LOGE("[singleVer][BackupCurrentDatabase]Set secOpt to file fail, errCode = [%d]", errCode);
299         return errCode;
300     }
301 
302     // rename
303     int innerCode = rename(info.curValidFile.c_str(), info.backValidFile.c_str());
304     if (innerCode != 0) {
305         LOGE("Failed to rename the file after the backup:%d", errno);
306         errCode = -E_SYSTEM_API_FAIL;
307     }
308     return errCode;
309 }
310 
ClearCurrentDatabase(const ImportFileInfo & info) const311 int SingleVerDatabaseOper::ClearCurrentDatabase(const ImportFileInfo &info) const
312 {
313     int errCode = DBCommon::RemoveAllFilesOfDirectory(info.currentDir, false);
314     if (errCode != E_OK) {
315         return errCode;
316     }
317 
318     std::vector<std::string> dbExtensionVec { DBConstant::MAINDB_DIR, DBConstant::METADB_DIR, DBConstant::CACHEDB_DIR };
319     for (const auto &item : dbExtensionVec) {
320         if (DBCommon::CreateDirectory(info.currentDir + "/" + item) != E_OK) {
321             return -E_SYSTEM_API_FAIL;
322         }
323     }
324     return errCode;
325 }
326 
ImportUnpackedMainDatabase(const ImportFileInfo & info,const CipherPassword & srcPasswd) const327 int SingleVerDatabaseOper::ImportUnpackedMainDatabase(const ImportFileInfo &info,
328     const CipherPassword &srcPasswd) const
329 {
330     std::string unpackedMainFile = info.unpackedDir + DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE +
331         DBConstant::DB_EXTENSION;
332     std::string currentMainFile = info.currentDir + DBConstant::MAINDB_DIR + "/" +
333         DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
334     CipherType cipherType;
335     CipherPassword passwd;
336     singleVerNaturalStore_->GetDbProperties().GetPassword(cipherType, passwd);
337 
338     std::string unpackedOldMainFile = info.unpackedDir + "/" + DBConstant::SINGLE_VER_DATA_STORE +
339         DBConstant::DB_EXTENSION;
340     bool isMainDbExisted = OS::CheckPathExistence(unpackedMainFile);
341     bool isOldMainDbExisted = OS::CheckPathExistence(unpackedOldMainFile); // version < 3, mainDb in singer_ver/
342     if (isMainDbExisted && isOldMainDbExisted) {
343         LOGE("Unpacked dir existed two diff version mainDb!");
344         return -E_INVALID_FILE;
345     }
346 
347     int errCode = E_OK;
348     if (isMainDbExisted) {
349         errCode = SQLiteUtils::ExportDatabase(unpackedMainFile, cipherType, srcPasswd, currentMainFile, passwd);
350         if (errCode != E_OK) {
351             LOGE("Export the unpacked main database to current error:%d", errCode);
352             return -E_INVALID_FILE;
353         }
354     }
355 
356     if (isOldMainDbExisted) {
357         errCode = SQLiteUtils::ExportDatabase(unpackedOldMainFile, cipherType, srcPasswd, currentMainFile, passwd);
358         if (errCode != E_OK) {
359             LOGE("Export the unpacked old version(<3) main database to current error:%d", errCode);
360             return -E_INVALID_FILE;
361         }
362     }
363     return errCode;
364 }
365 
ImportUnpackedMetaDatabase(const ImportFileInfo & info) const366 int SingleVerDatabaseOper::ImportUnpackedMetaDatabase(const ImportFileInfo &info) const
367 {
368     LOGI("MetaDB existed, need import, no need upgrade!");
369     std::string unpackedMetaFile = info.unpackedDir + DBConstant::METADB_DIR + "/" +
370         DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
371     std::string currentMetaFile = info.currentDir + DBConstant::METADB_DIR + "/" +
372         DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
373     int errCode = SQLiteUtils::ExportDatabase(unpackedMetaFile, CipherType::DEFAULT, CipherPassword(),
374         currentMetaFile, CipherPassword());
375     if (errCode != E_OK) {
376         LOGE("export the unpacked meta database to current error:%d", errCode);
377         errCode = -E_INVALID_FILE;
378     }
379     return errCode;
380 }
381 
ImportUnpackedDatabase(const ImportFileInfo & info,const CipherPassword & srcPasswd) const382 int SingleVerDatabaseOper::ImportUnpackedDatabase(const ImportFileInfo &info, const CipherPassword &srcPasswd) const
383 {
384     std::string unpackedMetaFile = info.unpackedDir + DBConstant::METADB_DIR + "/" +
385         DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
386     bool metaDbExisted = OS::CheckPathExistence(unpackedMetaFile);
387     int errCode = ClearCurrentDatabase(info);
388     if (errCode != E_OK) {
389         return errCode;
390     }
391 
392     errCode = ImportUnpackedMainDatabase(info, srcPasswd);
393     if (errCode != E_OK) {
394         LOGE("import unpacked mainDb fail, errCode = [%d]", errCode);
395         return errCode;
396     }
397 
398     if (metaDbExisted) { // Is S2 label, no need deal
399         errCode = ImportUnpackedMetaDatabase(info);
400         if (errCode != E_OK) {
401             LOGE("import unpacked metaDb fail, errCode = [%d]", errCode);
402             return errCode;
403         }
404     }
405 
406     (void)SetSecOpt(info.currentDir, false); // not care err, Make sure to set the label
407 
408     // reinitialize the database, and delete the backup database.
409     errCode = singleVerNaturalStore_->InitDatabaseContext(singleVerNaturalStore_->GetDbProperties(), true);
410     if (errCode != E_OK) {
411         LOGE("InitDatabaseContext error:%d", errCode);
412         return errCode;
413     }
414 
415     // rename the flag file.
416     int innerCode = rename(info.backValidFile.c_str(), info.curValidFile.c_str());
417     if (innerCode != E_OK) {
418         LOGE("Failed to rename after the import operation:%d", errno);
419         errCode = -E_SYSTEM_API_FAIL;
420     }
421     return errCode;
422 }
423 
ImportPostHandle() const424 int SingleVerDatabaseOper::ImportPostHandle() const
425 {
426     return singleVerNaturalStore_->InitDatabaseContext(singleVerNaturalStore_->GetDbProperties(), true);
427 }
428 
429 // private begin
RunExportLogic(const CipherPassword & passwd,const std::string & filePrefix) const430 int SingleVerDatabaseOper::RunExportLogic(const CipherPassword &passwd, const std::string &filePrefix) const
431 {
432     std::string currentMainDb = filePrefix + "/" + DBConstant::MAINDB_DIR + "/" +
433         DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
434     CipherType cipherType;
435     CipherPassword currPasswd;
436     singleVerNaturalStore_->GetDbProperties().GetPassword(cipherType, currPasswd);
437 
438     // get backup db name
439     std::string backupMainDbName = filePrefix + DBConstant::PATH_BACKUP_POSTFIX + "/" + DBConstant::MAINDB_DIR + "/" +
440         DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
441 
442     int errCode = SQLiteUtils::ExportDatabase(currentMainDb, cipherType, currPasswd, backupMainDbName, passwd);
443     if (errCode != E_OK) {
444         LOGE("single ver database export mainDb fail, errCode = [%d]", errCode);
445         return errCode;
446     }
447 
448     std::string currentMetaDb = filePrefix + "/" + DBConstant::METADB_DIR + "/" +
449         DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
450     if (!OS::CheckPathExistence(currentMetaDb)) {
451         LOGD("No metaDB, no need Export metaDB.");
452         return E_OK;
453     }
454 
455     LOGI("Begin export metaDB to back up!");
456     std::string backupMetaDbName = filePrefix + DBConstant::PATH_BACKUP_POSTFIX + "/" + DBConstant::METADB_DIR + "/" +
457         DBConstant::SINGLE_VER_META_STORE + DBConstant::DB_EXTENSION;
458     // Set metaDB db passwd same as mainDB temp, may be not need
459     errCode = SQLiteUtils::ExportDatabase(currentMetaDb, CipherType::DEFAULT, CipherPassword(),
460         backupMetaDbName, CipherPassword());
461     if (errCode != E_OK) {
462         LOGE("single ver database export metaDb fail, errCode = [%d]", errCode);
463         return errCode;
464     }
465     return errCode;
466 }
467 
InitStorageEngine()468 int SingleVerDatabaseOper::InitStorageEngine()
469 {
470     OpenDbProperties option;
471     InitDataBaseOption(option);
472     bool isMemoryMode = singleVerNaturalStore_->GetDbProperties().GetBoolProp(KvDBProperties::MEMORY_MODE, false);
473     // Use 1 read handle to check passwd
474     StorageEngineAttr poolSize = {0, 1, 1, 16}; // at most 1 write 16 read.
475     if (isMemoryMode) {
476         poolSize.minWriteNum = 1; // keep at least one connection.
477     }
478 
479     std::string identify = singleVerNaturalStore_->GetDbProperties().GetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
480     int errCode = storageEngine_->InitSQLiteStorageEngine(poolSize, option, identify);
481     if (errCode != E_OK) {
482         LOGE("[SingleVerOper]Init the sqlite storage engine failed:%d", errCode);
483     }
484     return errCode;
485 }
486 
InitDataBaseOption(OpenDbProperties & option) const487 void SingleVerDatabaseOper::InitDataBaseOption(OpenDbProperties &option) const
488 {
489     const KvDBProperties properties = singleVerNaturalStore_->GetDbProperties();
490     const std::string dataDir = properties.GetStringProp(KvDBProperties::DATA_DIR, "");
491     const std::string identifierDir = properties.GetStringProp(KvDBProperties::IDENTIFIER_DIR, "");
492     std::string uri = dataDir + "/" + identifierDir + "/" + DBConstant::SINGLE_SUB_DIR + "/" +
493         DBConstant::MAINDB_DIR + "/" + DBConstant::SINGLE_VER_DATA_STORE + DBConstant::DB_EXTENSION;
494     bool isMemoryDb  = properties.GetBoolProp(KvDBProperties::MEMORY_MODE, false);
495     if (isMemoryDb) {
496         uri = identifierDir + DBConstant::SQLITE_MEMDB_IDENTIFY;
497         LOGD("Begin create memory natural store database");
498     }
499 
500     std::vector<std::string> createTableSqls;
501     CipherType cipherType;
502     CipherPassword passwd;
503     properties.GetPassword(cipherType, passwd);
504     bool isCreate = properties.GetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
505 
506     SecurityOption securityOpt;
507     securityOpt.securityLabel = properties.GetSecLabel();
508     securityOpt.securityFlag = properties.GetSecFlag();
509 
510     option = {uri, isCreate, isMemoryDb, createTableSqls, cipherType, passwd};
511     std::string dirPath = dataDir + "/" + identifierDir + "/" + DBConstant::SINGLE_SUB_DIR;
512     option.subdir = dirPath;
513     option.securityOpt = securityOpt;
514     option.conflictReslovePolicy = properties.GetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, 0);
515 }
516 
RunRekeyLogic(CipherType type,const CipherPassword & passwd)517 int SingleVerDatabaseOper::RunRekeyLogic(CipherType type, const CipherPassword &passwd)
518 {
519     OpenDbProperties option;
520     InitDataBaseOption(option);
521     option.createIfNecessary = true;
522     option.cipherType = type;
523     sqlite3 *db = nullptr;
524 
525     // open one temporary connection.
526     int errCode = SQLiteUtils::OpenDatabase(option, db);
527     if (errCode != E_OK) {
528         LOGE("[RunRekeyLogic] Open database new connect fail!, errCode = [%d]", errCode);
529         goto END;
530     }
531 
532     errCode = SQLiteUtils::Rekey(db, passwd);
533     if (errCode != E_OK) {
534         LOGE("[RunRekeyLogic] Rekey fail!, errCode = [%d]", errCode);
535         goto END;
536     }
537 
538     // Release all the connections, update the passwd and re-initialize the storage engine.
539     storageEngine_->Release();
540     singleVerNaturalStore_->GetDbPropertyForUpdate().SetPassword(type, passwd);
541     errCode = InitStorageEngine();
542     if (errCode != E_OK) {
543         LOGE("Init storage engine while rekey open failed:%d", errCode);
544     }
545 
546     // Rekey while locked before init storage engine, it can not open file, but rekey successfully
547     if (storageEngine_->GetEngineState() != EngineState::MAINDB && errCode == -E_EKEYREVOKED) {
548         LOGI("Rekey successfully, locked state init state successfully, need ignore open file failed!");
549         errCode = -E_FORBID_CACHEDB;
550     }
551 
552 END:
553     if (db != nullptr) {
554         (void)sqlite3_close_v2(db);
555         db = nullptr;
556     }
557     return errCode;
558 }
559 } // namespace DistributedDB
560