• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "local_database_oper.h"
17 
18 #include "log_print.h"
19 #include "platform_specific.h"
20 #include "db_errno.h"
21 #include "db_constant.h"
22 #include "db_common.h"
23 
24 namespace DistributedDB {
LocalDatabaseOper(SQLiteLocalKvDB * localKvDb,SQLiteStorageEngine * storageEngine)25 LocalDatabaseOper::LocalDatabaseOper(SQLiteLocalKvDB *localKvDb, SQLiteStorageEngine *storageEngine)
26     : localKvDb_(localKvDb),
27       storageEngine_(storageEngine)
28 {}
29 
Rekey(const CipherPassword & passwd)30 int LocalDatabaseOper::Rekey(const CipherPassword &passwd)
31 {
32     if (localKvDb_ == nullptr || storageEngine_ == nullptr) {
33         return -E_INVALID_DB;
34     }
35 
36     return ExecuteRekey(passwd, localKvDb_->GetDbProperties());
37 }
38 
Import(const std::string & filePath,const CipherPassword & passwd)39 int LocalDatabaseOper::Import(const std::string &filePath, const CipherPassword &passwd)
40 {
41     if (localKvDb_ == nullptr || storageEngine_ == nullptr) {
42         return -E_INVALID_DB;
43     }
44 
45     return ExecuteImport(filePath, passwd, localKvDb_->GetDbProperties());
46 }
47 
Export(const std::string & filePath,const CipherPassword & passwd) const48 int LocalDatabaseOper::Export(const std::string &filePath, const CipherPassword &passwd) const
49 {
50     return ExecuteExport(filePath, passwd, localKvDb_->GetDbProperties());
51 }
52 
RekeyPreHandle(const CipherPassword & passwd,int & errCode)53 bool LocalDatabaseOper::RekeyPreHandle(const CipherPassword &passwd, int &errCode)
54 {
55     CipherType cipherType;
56     CipherPassword cachePasswd;
57     localKvDb_->GetDbProperties().GetPassword(cipherType, cachePasswd);
58 
59     if (cachePasswd.GetSize() == 0 && passwd.GetSize() == 0) {
60         errCode = E_OK;
61         return false;
62     }
63 
64     // need invoke sqlite3 rekey
65     if (cachePasswd.GetSize() > 0 && passwd.GetSize() > 0) {
66         errCode = localKvDb_->RunRekeyLogic(cipherType, passwd);
67         return false;
68     }
69 
70     return true;
71 }
72 
BackupDb(const CipherPassword & passwd) const73 int LocalDatabaseOper::BackupDb(const CipherPassword &passwd) const
74 {
75     std::string filePrefix;
76     int errCode = GetCtrlFilePrefix(localKvDb_->GetDbProperties(), filePrefix);
77     if (errCode != E_OK) {
78         return errCode;
79     }
80 
81     // create backup dir
82     std::string backupDir = filePrefix + DBConstant::PATH_BACKUP_POSTFIX;
83     errCode = DBCommon::CreateDirectory(backupDir);
84     if (errCode != E_OK) {
85         LOGE("create backup dir failed:%d.", errCode);
86         return errCode;
87     }
88 
89     // export db to backup
90     CipherType cipherType;
91     CipherPassword oldPasswd;
92     localKvDb_->GetDbProperties().GetPassword(cipherType, oldPasswd);
93     std::string backupDbName = backupDir + "/" + DBConstant::LOCAL_DATABASE_NAME + DBConstant::SQLITE_DB_EXTENSION;
94     return localKvDb_->RunExportLogic(cipherType, passwd, backupDbName);
95 }
96 
CloseStorages()97 int LocalDatabaseOper::CloseStorages()
98 {
99     // close old db
100     storageEngine_->Release();
101     int errCode = RekeyRecover(localKvDb_->GetDbProperties());
102     if (errCode != E_OK) {
103         LOGE("Recover failed after rekey ok:%d.", errCode);
104         int innerCode = localKvDb_->InitDatabaseContext(localKvDb_->GetDbProperties());
105         if (innerCode != E_OK) {
106             LOGE("ReInit the handlePool failed:%d", innerCode);
107         }
108     }
109     return errCode;
110 }
111 
RekeyPostHandle(const CipherPassword & passwd)112 int LocalDatabaseOper::RekeyPostHandle(const CipherPassword &passwd)
113 {
114     CipherType cipherType;
115     CipherPassword oldPasswd;
116     localKvDb_->GetDbPropertyForUpdate().GetPassword(cipherType, oldPasswd);
117     localKvDb_->GetDbPropertyForUpdate().SetPassword(cipherType, passwd);
118     return localKvDb_->InitDatabaseContext(localKvDb_->GetDbProperties());
119 }
120 
ExportAllDatabases(const std::string & currentDir,const CipherPassword & passwd,const std::string & dbDir) const121 int LocalDatabaseOper::ExportAllDatabases(const std::string &currentDir, const CipherPassword &passwd,
122     const std::string &dbDir) const
123 {
124     std::string backupDbName = dbDir + DBConstant::LOCAL_DATABASE_NAME + DBConstant::SQLITE_DB_EXTENSION;
125     std::string currentDb = currentDir + "/" + DBConstant::LOCAL_DATABASE_NAME + DBConstant::SQLITE_DB_EXTENSION;
126 
127     CipherType cipherType;
128     CipherPassword currPasswd;
129     localKvDb_->GetDbProperties().GetPassword(cipherType, currPasswd);
130     int errCode = SQLiteUtils::ExportDatabase(currentDb, cipherType, currPasswd, backupDbName, passwd);
131     if (errCode != E_OK) {
132         LOGE("Export the database failed:%d", errCode);
133     }
134     return errCode;
135 }
136 
BackupCurrentDatabase(const ImportFileInfo & info) const137 int LocalDatabaseOper::BackupCurrentDatabase(const ImportFileInfo &info) const
138 {
139     storageEngine_->Release();
140     // create the pre flag file.
141     int errCode = OS::CreateFileByFileName(info.curValidFile);
142     if (errCode != E_OK) {
143         LOGE("create ctrl file failed:%d.", errCode);
144         return errCode;
145     }
146 
147     // create backup dir
148     errCode = DBCommon::CreateDirectory(info.backupDir);
149     if (errCode != E_OK) {
150         LOGE("Create backup dir failed:%d.", errCode);
151         (void)RemoveFile(info.curValidFile);
152         return errCode;
153     }
154 
155     std::string currentFile = info.currentDir + DBConstant::LOCAL_DATABASE_NAME +
156         DBConstant::SQLITE_DB_EXTENSION;
157     std::string backupFile = info.backupDir + DBConstant::LOCAL_DATABASE_NAME +
158         DBConstant::SQLITE_DB_EXTENSION;
159     errCode = DBCommon::CopyFile(currentFile, backupFile);
160     if (errCode != E_OK) {
161         LOGE("Backup the current database error:%d", errCode);
162         return errCode;
163     }
164     int innerCode = rename(info.curValidFile.c_str(), info.backValidFile.c_str());
165     if (innerCode != 0) {
166         LOGE("Failed to rename the file after the backup:%d", errno);
167         errCode = -E_SYSTEM_API_FAIL;
168     }
169     return errCode;
170 }
171 
ImportUnpackedDatabase(const ImportFileInfo & info,const CipherPassword & srcPasswd) const172 int LocalDatabaseOper::ImportUnpackedDatabase(const ImportFileInfo &info, const CipherPassword &srcPasswd) const
173 {
174     // create backup dir
175     int errCode = DBCommon::RemoveAllFilesOfDirectory(info.currentDir, false);
176     if (errCode != E_OK) {
177         return errCode;
178     }
179 
180     std::string unpackedFile = info.unpackedDir + DBConstant::LOCAL_DATABASE_NAME + DBConstant::SQLITE_DB_EXTENSION;
181     std::string currentFile = info.currentDir + DBConstant::LOCAL_DATABASE_NAME + DBConstant::SQLITE_DB_EXTENSION;
182     CipherType cipherType;
183     CipherPassword passwd;
184     localKvDb_->GetDbProperties().GetPassword(cipherType, passwd);
185     errCode = SQLiteUtils::ExportDatabase(unpackedFile, cipherType, srcPasswd, currentFile, passwd);
186     DBCommon::RemoveAllFilesOfDirectory(info.unpackedDir);
187     if (errCode != E_OK) {
188         LOGE("export the unpacked database to current error:%d", errCode);
189         errCode = -E_INVALID_FILE;
190         return errCode;
191     }
192 
193     // reinitialize the database, and delete the backup database.
194     errCode = localKvDb_->InitDatabaseContext(localKvDb_->GetDbProperties());
195     if (errCode != E_OK) {
196         LOGE("InitDatabaseContext error:%d", errCode);
197         return errCode;
198     }
199 
200     // rename the flag file.
201     int innerCode = rename(info.backValidFile.c_str(), info.curValidFile.c_str());
202     if (innerCode != E_OK) {
203         LOGE("Failed to rename after the import operation:%d", errno);
204         errCode = -E_SYSTEM_API_FAIL;
205     }
206 
207     return errCode;
208 }
209 
ImportPostHandle() const210 int LocalDatabaseOper::ImportPostHandle() const
211 {
212     return localKvDb_->InitDatabaseContext(localKvDb_->GetDbProperties());
213 }
214 } // namespace DistributedDB
215