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 {
__anon7f720ac30202(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 = BindInt64(idx, start, end);
179 if (ret != SQLITE_OK) {
180 return ret;
181 }
182 return Step(infos);
183 }
184
SelectData(const std::string & iface,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)185 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, uint64_t start, uint64_t end,
186 std::vector<NetStatsInfo> &infos)
187 {
188 infos.clear();
189 std::string sql = "SELECT * FROM " + std::string(IFACE_TABLE) + " t WHERE 1=1 AND t.IFace = ?" +
190 " AND t.Date >= ?" + " AND t.Date <= ?";
191 int32_t ret = statement_.Prepare(sqlite_, sql);
192 if (ret != SQLITE_OK) {
193 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
194 return STATS_ERR_READ_DATA_FAIL;
195 }
196 int32_t idx = 1;
197 ret = statement_.BindText(idx, iface);
198 if (ret != SQLITE_OK) {
199 NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
200 return STATS_ERR_READ_DATA_FAIL;
201 }
202 ret = BindInt64(idx, start, end);
203 if (ret != SQLITE_OK) {
204 return ret;
205 }
206 return Step(infos);
207 }
208
SelectData(const std::string & iface,const uint32_t uid,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)209 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, const uint32_t uid, uint64_t start, uint64_t end,
210 std::vector<NetStatsInfo> &infos)
211 {
212 infos.clear();
213 std::string sql = "SELECT * FROM " + std::string(UID_TABLE) + " t WHERE 1=1 AND t.UID = ?" + " AND t.IFace = ?" +
214 " AND t.Date >= ?" + " AND t.Date <= ?";
215 int32_t ret = statement_.Prepare(sqlite_, sql);
216 if (ret != SQLITE_OK) {
217 NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
218 return STATS_ERR_READ_DATA_FAIL;
219 }
220 int32_t idx = 1;
221 ret = statement_.BindInt32(idx, uid);
222 if (ret != SQLITE_OK) {
223 NETMGR_LOG_E("bind int32 ret:%{public}d", ret);
224 return STATS_ERR_READ_DATA_FAIL;
225 }
226 ret = statement_.BindText(++idx, iface);
227 if (ret != SQLITE_OK) {
228 NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
229 return STATS_ERR_READ_DATA_FAIL;
230 }
231 ret = BindInt64(idx, start, end);
232 if (ret != SQLITE_OK) {
233 return ret;
234 }
235 return Step(infos);
236 }
237
DeleteData(const std::string & tableName,uint64_t start,uint64_t end)238 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t start, uint64_t end)
239 {
240 std::string sql =
241 "DELETE FROM " + tableName + " WHERE Date >= " + std::to_string(start) + " AND Date <= " + std::to_string(end);
242 return ExecSql(sql, nullptr, sqlCallback);
243 }
244
DeleteData(const std::string & tableName,uint64_t uid)245 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t uid)
246 {
247 std::string sql = "DELETE FROM " + tableName + " WHERE UID = " + std::to_string(uid);
248 return ExecSql(sql, nullptr, sqlCallback);
249 }
250
Close()251 int32_t NetStatsDatabaseHelper::Close()
252 {
253 int32_t ret = sqlite3_close_v2(sqlite_);
254 return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
255 }
256
ClearData(const std::string & tableName)257 int32_t NetStatsDatabaseHelper::ClearData(const std::string &tableName)
258 {
259 std::string sql = "DELETE FROM " + tableName;
260 std::string shrinkMemSql = "PRAGMA shrink_memory";
261 int32_t execSqlRet = ExecSql(sql, nullptr, sqlCallback);
262 if (execSqlRet != NETMANAGER_SUCCESS) {
263 NETMGR_LOG_E("Delete data failed");
264 return execSqlRet;
265 }
266 execSqlRet = ExecSql(shrinkMemSql, nullptr, sqlCallback);
267 if (execSqlRet != NETMANAGER_SUCCESS) {
268 NETMGR_LOG_E("Delete data failed");
269 return execSqlRet;
270 }
271 sql = "VACUUM";
272 execSqlRet = ExecSql(sql, nullptr, sqlCallback);
273 if (execSqlRet != NETMANAGER_SUCCESS) {
274 NETMGR_LOG_E("Delete data failed");
275 return execSqlRet;
276 }
277 return ExecSql(shrinkMemSql, nullptr, sqlCallback);
278 }
279
Step(std::vector<NetStatsInfo> & infos)280 int32_t NetStatsDatabaseHelper::Step(std::vector<NetStatsInfo> &infos)
281 {
282 int32_t rc = statement_.Step();
283 NETMGR_LOG_I("Step result:%{public}d", rc);
284 while (rc != SQLITE_DONE) {
285 int32_t i = 0;
286 NetStatsInfo info;
287 if (statement_.GetColumnCount() == UID_PARAM_NUM) {
288 statement_.GetColumnInt(i, info.uid_);
289 ++i;
290 }
291 statement_.GetColumnString(i, info.iface_);
292 statement_.GetColumnLong(++i, info.date_);
293 statement_.GetColumnLong(++i, info.rxBytes_);
294 statement_.GetColumnLong(++i, info.rxPackets_);
295 statement_.GetColumnLong(++i, info.txBytes_);
296 statement_.GetColumnLong(++i, info.txPackets_);
297 infos.emplace_back(info);
298 rc = statement_.Step();
299 NETMGR_LOG_D("Step result:%{public}d", rc);
300 }
301 statement_.ResetStatementAndClearBindings();
302 return NETMANAGER_SUCCESS;
303 }
304
BindInt64(int32_t idx,uint64_t start,uint64_t end)305 int32_t NetStatsDatabaseHelper::BindInt64(int32_t idx, uint64_t start, uint64_t end)
306 {
307 int32_t ret = statement_.BindInt64(++idx, start);
308 if (ret != SQLITE_OK) {
309 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
310 return STATS_ERR_READ_DATA_FAIL;
311 }
312 ret = statement_.BindInt64(++idx, end);
313 if (ret != SQLITE_OK) {
314 NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
315 return STATS_ERR_READ_DATA_FAIL;
316 }
317
318 return ret;
319 }
320 } // namespace NetManagerStandard
321 } // namespace OHOS
322