• 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 {
__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 &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 = 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