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