1 /*
2 * Copyright (c) 2022 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 "net_stats_database_helper.h"
17
18 #include <cstdlib>
19 #include <filesystem>
20
21 #include "net_manager_constants.h"
22 #include "net_mgr_log_wrapper.h"
23 #include "net_stats_constants.h"
24 #include "net_stats_database_defines.h"
25 #include "net_stats_info.h"
26
27 namespace OHOS {
28 namespace NetManagerStandard {
29 using namespace NetStatsDatabaseDefines;
30 namespace {
__anona0e9b5420202(void *notUsed, int argc, char **argv, char **colName) 31 NetStatsDatabaseHelper::SqlCallback sqlCallback = [](void *notUsed, int argc, char **argv, char **colName) {
32 std::string data;
33 for (int i = 0; i < argc; i++) {
34 data.append(colName[i]).append(" = ").append(argv[i] ? argv[i] : "nullptr\n");
35 }
36 NETMGR_LOG_D("Recv data: %{public}s", data.c_str());
37 return 0;
38 };
39
CheckFilePath(const std::string & fileName)40 bool CheckFilePath(const std::string &fileName)
41 {
42 char tmpPath[PATH_MAX] = {0};
43 const auto pos = fileName.find_last_of('/');
44 const auto dir = fileName.substr(0, pos);
45 if (!realpath(dir.c_str(), tmpPath)) {
46 NETMGR_LOG_E("Get realPath failed error: %{public}d, %{public}s", errno, strerror(errno));
47 return false;
48 }
49 if (strcmp(tmpPath, dir.c_str()) != 0) {
50 NETMGR_LOG_E("file name is illegal fileName: %{public}s, tmpPath: %{public}s", fileName.c_str(), tmpPath);
51 return false;
52 }
53 return true;
54 }
55 } // namespace
56
NetStatsDatabaseHelper(const std::string & path)57 NetStatsDatabaseHelper::NetStatsDatabaseHelper(const std::string &path)
58 {
59 if (!CheckFilePath(path)) {
60 return;
61 }
62 Open(path);
63 }
64
~NetStatsDatabaseHelper()65 NetStatsDatabaseHelper::~NetStatsDatabaseHelper()
66 {
67 Close();
68 sqlite_ = nullptr;
69 }
70
ExecSql(const std::string & sql,void * recv,SqlCallback callback)71 int32_t NetStatsDatabaseHelper::ExecSql(const std::string &sql, void *recv, SqlCallback callback)
72 {
73 char *errMsg = nullptr;
74 int32_t ret = sqlite3_exec(sqlite_, sql.c_str(), callback, recv, &errMsg);
75 NETMGR_LOG_D("EXEC SQL : %{public}s", sql.c_str());
76 if (errMsg != nullptr) {
77 NETMGR_LOG_E("Exec sql failed err:%{public}s", errMsg);
78 sqlite3_free(errMsg);
79 }
80 return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
81 }
82
CreateTable(const std::string & tableName,const std::string & tableInfo)83 int32_t NetStatsDatabaseHelper::CreateTable(const std::string &tableName, const std::string &tableInfo)
84 {
85 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName + "(" + tableInfo + ");";
86 int32_t ret = ExecSql(sql, nullptr, sqlCallback);
87 if (ret != NETMANAGER_SUCCESS) {
88 return STATS_ERR_CREATE_TABLE_FAIL;
89 }
90 return NETMANAGER_SUCCESS;
91 }
92
Open(const std::string & path)93 int32_t NetStatsDatabaseHelper::Open(const std::string &path)
94 {
95 int32_t ret = sqlite3_open_v2(path.c_str(), &sqlite_,
96 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
97 return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
98 }
99
InsertData(const std::string & tableName,const std::string & paramList,const NetStatsInfo & info)100 int32_t NetStatsDatabaseHelper::InsertData(const std::string &tableName, const std::string ¶mList,
101 const NetStatsInfo &info)
102 {
103 std::string params;
104 int32_t paramCount = count(paramList.begin(), paramList.end(), ',') + 1;
105 for (int32_t i = 0; i < paramCount; ++i) {
106 params += "?";
107 if (i != paramCount - 1) {
108 params += ",";
109 }
110 }
111 std::string sql = "INSERT INTO " + tableName + " (" + paramList + ") " + "VALUES" + " (" + params + ") ";
112 int32_t ret = statement_.Prepare(sqlite_, sql);
113 if (ret != SQLITE_OK) {
114 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
115 return STATS_ERR_WRITE_DATA_FAIL;
116 }
117 int32_t idx = 1;
118 if (paramCount == UID_PARAM_NUM) {
119 statement_.BindInt32(idx, info.uid_);
120 ++idx;
121 }
122 statement_.BindText(idx, info.iface_);
123 statement_.BindInt64(++idx, info.date_);
124 statement_.BindInt64(++idx, info.rxBytes_);
125 statement_.BindInt64(++idx, info.rxPackets_);
126 statement_.BindInt64(++idx, info.txBytes_);
127 statement_.BindInt64(++idx, info.txPackets_);
128 ret = statement_.Step();
129 statement_.ResetStatementAndClearBindings();
130 if (ret != SQLITE_DONE) {
131 NETMGR_LOG_E("Step failed ret:%{public}d", ret);
132 return STATS_ERR_WRITE_DATA_FAIL;
133 }
134 return NETMANAGER_SUCCESS;
135 }
136
SelectData(std::vector<NetStatsInfo> & infos,const std::string & tableName,uint64_t start,uint64_t end)137 int32_t NetStatsDatabaseHelper::SelectData(std::vector<NetStatsInfo> &infos, const std::string &tableName,
138 uint64_t start, uint64_t end)
139 {
140 infos.clear();
141 std::string sql = "SELECT * FROM " + tableName + " t WHERE 1=1 AND t.Date >= ?" + " AND t.Date <= ?";
142 int32_t ret = statement_.Prepare(sqlite_, sql);
143 if (ret != SQLITE_OK) {
144 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
145 return STATS_ERR_READ_DATA_FAIL;
146 }
147 int32_t idx = 1;
148 ret = statement_.BindInt64(idx, start);
149 if (ret != SQLITE_OK) {
150 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
151 return STATS_ERR_READ_DATA_FAIL;
152 }
153 ret = statement_.BindInt64(++idx, end);
154 if (ret != SQLITE_OK) {
155 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
156 return STATS_ERR_READ_DATA_FAIL;
157 }
158 return Step(infos);
159 }
160
SelectData(const uint32_t uid,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)161 int32_t NetStatsDatabaseHelper::SelectData(const uint32_t uid, uint64_t start, uint64_t end,
162 std::vector<NetStatsInfo> &infos)
163 {
164 infos.clear();
165 std::string sql = "SELECT * FROM " + std::string(UID_TABLE) + " t WHERE 1=1 AND t.UID == ?" + " AND t.Date >= ?" +
166 " AND t.Date <= ?";
167 int32_t ret = statement_.Prepare(sqlite_, sql);
168 if (ret != SQLITE_OK) {
169 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
170 return STATS_ERR_READ_DATA_FAIL;
171 }
172 int32_t idx = 1;
173 ret = statement_.BindInt32(idx, uid);
174 if (ret != SQLITE_OK) {
175 NETMGR_LOG_E("Bind int32 failed ret:%{public}d", ret);
176 return STATS_ERR_READ_DATA_FAIL;
177 }
178 ret = statement_.BindInt64(++idx, start);
179 if (ret != SQLITE_OK) {
180 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
181 return STATS_ERR_READ_DATA_FAIL;
182 }
183 ret = statement_.BindInt64(++idx, end);
184 if (ret != SQLITE_OK) {
185 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
186 return STATS_ERR_READ_DATA_FAIL;
187 }
188 return Step(infos);
189 }
190
SelectData(const std::string & iface,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)191 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, uint64_t start, uint64_t end,
192 std::vector<NetStatsInfo> &infos)
193 {
194 infos.clear();
195 std::string sql = "SELECT * FROM " + std::string(IFACE_TABLE) + " t WHERE 1=1 AND t.IFace = ?" +
196 " AND t.Date >= ?" + " AND t.Date <= ?";
197 int32_t ret = statement_.Prepare(sqlite_, sql);
198 if (ret != SQLITE_OK) {
199 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
200 return STATS_ERR_READ_DATA_FAIL;
201 }
202 int32_t idx = 1;
203 ret = statement_.BindText(idx, iface);
204 if (ret != SQLITE_OK) {
205 NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
206 return STATS_ERR_READ_DATA_FAIL;
207 }
208 ret = statement_.BindInt64(++idx, start);
209 if (ret != SQLITE_OK) {
210 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
211 return STATS_ERR_READ_DATA_FAIL;
212 }
213 ret = statement_.BindInt64(++idx, end);
214 if (ret != SQLITE_OK) {
215 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
216 return STATS_ERR_READ_DATA_FAIL;
217 }
218 return Step(infos);
219 }
220
SelectData(const std::string & iface,const uint32_t uid,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)221 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, const uint32_t uid, uint64_t start, uint64_t end,
222 std::vector<NetStatsInfo> &infos)
223 {
224 infos.clear();
225 std::string sql = "SELECT * FROM " + std::string(UID_TABLE) + " t WHERE 1=1 AND t.UID = ?" + " AND t.IFace = ?" +
226 " AND t.Date >= ?" + " AND t.Date <= ?";
227 int32_t ret = statement_.Prepare(sqlite_, sql);
228 if (ret != SQLITE_OK) {
229 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
230 return STATS_ERR_READ_DATA_FAIL;
231 }
232 int32_t idx = 1;
233 ret = statement_.BindInt32(idx, uid);
234 if (ret != SQLITE_OK) {
235 NETMGR_LOG_E("bind int32 ret:%{public}d", ret);
236 return STATS_ERR_READ_DATA_FAIL;
237 }
238 ret = statement_.BindText(++idx, iface);
239 if (ret != SQLITE_OK) {
240 NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
241 return STATS_ERR_READ_DATA_FAIL;
242 }
243 ret = statement_.BindInt64(++idx, start);
244 if (ret != SQLITE_OK) {
245 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
246 return STATS_ERR_READ_DATA_FAIL;
247 }
248 ret = statement_.BindInt64(++idx, end);
249 if (ret != SQLITE_OK) {
250 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
251 return STATS_ERR_READ_DATA_FAIL;
252 }
253 return Step(infos);
254 }
255
DeleteData(const std::string & tableName,uint64_t start,uint64_t end)256 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t start, uint64_t end)
257 {
258 std::string sql =
259 "DELETE FROM " + tableName + " WHERE Date >= " + std::to_string(start) + " AND Date <= " + std::to_string(end);
260 return ExecSql(sql, nullptr, sqlCallback);
261 }
262
DeleteData(const std::string & tableName,uint64_t uid)263 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t uid)
264 {
265 std::string sql = "DELETE FROM " + tableName + " WHERE UID = " + std::to_string(uid);
266 return ExecSql(sql, nullptr, sqlCallback);
267 }
268
Close()269 int32_t NetStatsDatabaseHelper::Close()
270 {
271 int32_t ret = sqlite3_close_v2(sqlite_);
272 return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
273 }
274
ClearData(const std::string & tableName)275 int32_t NetStatsDatabaseHelper::ClearData(const std::string &tableName)
276 {
277 std::string sql = "DELETE FROM " + tableName;
278 std::string shrinkMemSql = "PRAGMA shrink_memory";
279 int32_t execSqlRet = ExecSql(sql, nullptr, sqlCallback);
280 if (execSqlRet != NETMANAGER_SUCCESS) {
281 NETMGR_LOG_E("Delete data failed");
282 return execSqlRet;
283 }
284 execSqlRet = ExecSql(shrinkMemSql, nullptr, sqlCallback);
285 if (execSqlRet != NETMANAGER_SUCCESS) {
286 NETMGR_LOG_E("Delete data failed");
287 return execSqlRet;
288 }
289 sql = "VACUUM";
290 execSqlRet = ExecSql(sql, nullptr, sqlCallback);
291 if (execSqlRet != NETMANAGER_SUCCESS) {
292 NETMGR_LOG_E("Delete data failed");
293 return execSqlRet;
294 }
295 return ExecSql(shrinkMemSql, nullptr, sqlCallback);
296 }
297
Step(std::vector<NetStatsInfo> & infos)298 int32_t NetStatsDatabaseHelper::Step(std::vector<NetStatsInfo> &infos)
299 {
300 int32_t rc = statement_.Step();
301 NETMGR_LOG_I("Step result:%{public}d", rc);
302 while (rc != SQLITE_DONE) {
303 int32_t i = 0;
304 NetStatsInfo info;
305 if (statement_.GetColumnCount() == UID_PARAM_NUM) {
306 statement_.GetColumnInt(i, info.uid_);
307 ++i;
308 }
309 statement_.GetColumnString(i, info.iface_);
310 statement_.GetColumnLong(++i, info.date_);
311 statement_.GetColumnLong(++i, info.rxBytes_);
312 statement_.GetColumnLong(++i, info.rxPackets_);
313 statement_.GetColumnLong(++i, info.txBytes_);
314 statement_.GetColumnLong(++i, info.txPackets_);
315 infos.emplace_back(info);
316 rc = statement_.Step();
317 NETMGR_LOG_D("Step result:%{public}d", rc);
318 }
319 statement_.ResetStatementAndClearBindings();
320 return NETMANAGER_SUCCESS;
321 }
322 } // namespace NetManagerStandard
323 } // namespace OHOS
324