• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &paramList,
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