• 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 "sqlite_database_utils.h"
17 
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <algorithm>
23 #include <cstdio>
24 #ifdef WINDOWS_PLATFORM
25 #include <dir.h>
26 #endif
27 #include <fstream>
28 #include <climits>
29 
30 #include "logger.h"
31 #include "rdb_errno.h"
32 
33 #ifdef WINDOWS_PLATFORM
34 #define REALPATH(relPath, absPath, ...) (_fullpath(absPath, relPath, ##__VA_ARGS__))
35 #define MKDIR(filePath) (mkdir(filePath))
36 #else
37 #define REALPATH(absPath, relPath, ...) (realpath(absPath, relPath))
38 #define MKDIR(filePath) (mkdir(filePath, g_mkdirMode))
39 #endif
40 
41 namespace OHOS {
42 namespace NativeRdb {
43 std::map<std::string, int> SqliteDatabaseUtils::g_statementType = SqliteDatabaseUtils::MapInit();
44 std::mutex SqliteDatabaseUtils::g_locker;
45 // Set the file access permissions is 777
46 int SqliteDatabaseUtils::g_mkdirMode = 0771;
MapInit()47 std::map<std::string, int> SqliteDatabaseUtils::MapInit()
48 {
49     std::map<std::string, int> temp;
50     temp["SEL"] = STATEMENT_SELECT;
51     temp["INS"] = STATEMENT_UPDATE;
52     temp["UPD"] = STATEMENT_UPDATE;
53     temp["REP"] = STATEMENT_UPDATE;
54     temp["DEL"] = STATEMENT_UPDATE;
55     temp["ATT"] = STATEMENT_ATTACH;
56     temp["DET"] = STATEMENT_DETACH;
57     temp["COM"] = STATEMENT_COMMIT;
58     temp["END"] = STATEMENT_COMMIT;
59     temp["ROL"] = STATEMENT_ROLLBACK;
60     temp["BEG"] = STATEMENT_BEGIN;
61     temp["PRA"] = STATEMENT_PRAGMA;
62     temp["CRE"] = STATEMENT_DDL;
63     temp["DRO"] = STATEMENT_DDL;
64     temp["ALT"] = STATEMENT_DDL;
65 
66     return temp;
67 }
68 
69 /**
70  * Obtains the type of SQL statement.
71  */
GetSqlStatementType(std::string sql)72 int SqliteDatabaseUtils::GetSqlStatementType(std::string sql)
73 {
74     if (sql.empty()) {
75         return STATEMENT_OTHER;
76     }
77     sql.erase(0, sql.find_first_not_of(" "));
78     sql.erase(sql.find_last_not_of(" ") + 1);
79 
80     if (sql.length() < SQL_FIRST_CHARACTER) {
81         return STATEMENT_OTHER;
82     }
83     sql = sql.substr(0, SQL_FIRST_CHARACTER);
84     std::string prefixSql = sql;
85     transform(sql.begin(), sql.end(), prefixSql.begin(), ::toupper);
86     prefixSql = prefixSql.c_str();
87     auto iter = g_statementType.find(prefixSql);
88     if (iter != g_statementType.end()) {
89         return iter->second;
90     }
91     return STATEMENT_OTHER;
92 }
93 
94 /**
95  * Delete the specified file.
96  */
DeleteFile(std::string & fileName)97 void SqliteDatabaseUtils::DeleteFile(std::string &fileName)
98 {
99     if (access(fileName.c_str(), F_OK) != 0) {
100         LOG_ERROR("File %{private}s does not exist", fileName.c_str());
101         return;
102     }
103     if (!remove(fileName.c_str())) {
104         LOG_ERROR("FileName= %{private}s has been deleted", fileName.c_str());
105         return;
106     }
107     LOG_INFO("Failed to delete File %{private}s", fileName.c_str());
108 }
109 
110 /**
111  * Rename file.
112  */
RenameFile(std::string & oldFileName,std::string & newFileName)113 bool SqliteDatabaseUtils::RenameFile(std::string &oldFileName, std::string &newFileName)
114 {
115     if (access(oldFileName.c_str(), F_OK) != 0) {
116         LOG_ERROR("File %{private}s does not exist", oldFileName.c_str());
117         return false;
118     }
119     if (rename(oldFileName.c_str(), newFileName.c_str())) {
120         LOG_ERROR("Rename oldFileName = %{private}s to newFileName  %{private}s", oldFileName.c_str(),
121             newFileName.c_str());
122         return true;
123     }
124     return false;
125 }
126 
127 /**
128  * Get and Check default path.
129  */
GetDefaultDatabasePath(std::string & baseDir,std::string & name,int & errorCode)130 std::string SqliteDatabaseUtils::GetDefaultDatabasePath(std::string &baseDir, std::string &name, int &errorCode)
131 {
132     std::unique_lock<std::mutex> lock(g_locker);
133     if (access(baseDir.c_str(), F_OK) != 0) {
134         if (MKDIR(baseDir.c_str())) {
135             errorCode = E_CREATE_FOLDER_FAIL;
136         }
137     }
138 #if defined(WINDOWS_PLATFORM)
139     std::string databasePath = baseDir + "\\rdb";
140 #else
141     std::string databasePath = baseDir + "/rdb";
142 #endif
143     if (access(databasePath.c_str(), F_OK) != 0) {
144         if (MKDIR(databasePath.c_str())) {
145             errorCode = E_CREATE_FOLDER_FAIL;
146         }
147     }
148     char canonicalPath[PATH_MAX + 1] = { 0 };
149     if (REALPATH(databasePath.c_str(), canonicalPath, PATH_MAX) == nullptr) {
150         LOG_ERROR("Failed to obtain real path, errno:%{public}d", errno);
151         errorCode = E_INVALID_FILE_PATH;
152         return "";
153     }
154     std::string realFilePath(canonicalPath);
155 #if defined(WINDOWS_PLATFORM)
156     realFilePath = realFilePath.append("\\").append(name);
157 #else
158     realFilePath = realFilePath.append("/").append(name);
159 #endif
160     return realFilePath;
161 }
162 
163 /**
164  * Get corrupt path from database path.
165  */
GetCorruptPath(std::string & path,int & errorCode)166 std::string SqliteDatabaseUtils::GetCorruptPath(std::string &path, int &errorCode)
167 {
168     std::string databaseFile = path;
169     std::string name = databaseFile.substr(databaseFile.find_last_of("/") + 1);
170     std::string parentFile = databaseFile.substr(0, databaseFile.find_last_of("/"));
171     std::string databaseTypeDir = parentFile.substr(parentFile.find_last_of("/") + 1);
172     size_t posDatabaseType = databaseTypeDir.find("_encrypt");
173 
174     bool isEncrypt = false;
175     if (posDatabaseType != databaseTypeDir.npos) {
176         std::string databaseTypeDirStr = databaseTypeDir.substr(posDatabaseType);
177         std::string end = "_encrypt";
178         if (databaseTypeDirStr.compare(end) == 0) {
179             isEncrypt = true;
180         }
181     }
182 
183     std::string databaseDir = parentFile.substr(0, parentFile.find_last_of("/"));
184     std::string encrypt = isEncrypt ? "_encrypt" : "";
185     std::string corruptTypeDir = "corrupt" + encrypt;
186     std::string corruptPath = databaseDir + "/" + corruptTypeDir;
187 
188     if (access(corruptPath.c_str(), F_OK) != 0) {
189         if (MKDIR(corruptPath.c_str())) {
190             errorCode = E_CREATE_FOLDER_FAIL;
191         }
192     }
193     corruptPath = corruptPath + "/" + name;
194     return corruptPath;
195 }
196 } // namespace NativeRdb
197 } // namespace OHOS