• 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 
31 constexpr const char* SELECT_FROM = "SELECT * FROM ";
32 constexpr const char* DELETE_FROM = "DELETE FROM ";
33 constexpr const char* UPDATE = "UPDATE ";
34 constexpr const char* ALTER_TABLE = "ALTER TABLE ";
35 constexpr const char* DATA_MORE_THAN = " AND t.Date >= ?";
36 constexpr const char* DATA_LESS_THAN = " AND t.Date <= ?";
37 constexpr const char* INSERT_OR_REPLACE_INTO = "INSERT OR REPLACE INTO ";
38 constexpr const char* SET_FLAG = " SET Flag = ";
39 constexpr const char* SET_USERID = " SET UserId = ";
40 namespace {
__anone4d128c40202(void *notUsed, int argc, char **argv, char **colName) 41 NetStatsDatabaseHelper::SqlCallback sqlCallback = [](void *notUsed, int argc, char **argv, char **colName) {
42     std::string data;
43     for (int i = 0; i < argc; i++) {
44         data.append(colName[i]).append(" = ").append(argv[i] ? argv[i] : "nullptr\n");
45     }
46     NETMGR_LOG_D("Recv data: %{public}s", data.c_str());
47     return 0;
48 };
49 
CheckFilePath(const std::string & fileName)50 bool CheckFilePath(const std::string &fileName)
51 {
52     char tmpPath[PATH_MAX] = {0};
53     const auto pos = fileName.find_last_of('/');
54     const auto dir = fileName.substr(0, pos);
55     if (!realpath(dir.c_str(), tmpPath)) {
56         NETMGR_LOG_E("Get realPath failed error: %{public}d, %{public}s", errno, strerror(errno));
57         return false;
58     }
59     if (strcmp(tmpPath, dir.c_str()) != 0) {
60         NETMGR_LOG_E("file name is illegal fileName: %{public}s, tmpPath: %{public}s", fileName.c_str(), tmpPath);
61         return false;
62     }
63     return true;
64 }
65 } // namespace
66 
67 ffrt::mutex NetStatsDatabaseHelper::sqliteMutex_;
68 
NetStatsDatabaseHelper(const std::string & path)69 NetStatsDatabaseHelper::NetStatsDatabaseHelper(const std::string &path)
70 {
71     if (!CheckFilePath(path)) {
72         return;
73     }
74     Open(path);
75     path_ = path;
76     isDisplayTrafficAncoList_ = CommonUtils::IsNeedDisplayTrafficAncoList();
77 }
78 
~NetStatsDatabaseHelper()79 NetStatsDatabaseHelper::~NetStatsDatabaseHelper()
80 {
81     Close();
82     sqlite_ = nullptr;
83 }
84 
ExecSql(const std::string & sql,void * recv,SqlCallback callback)85 int32_t NetStatsDatabaseHelper::ExecSql(const std::string &sql, void *recv, SqlCallback callback)
86 {
87     char *errMsg = nullptr;
88     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
89     int32_t ret = sqlite3_exec(sqlite_, sql.c_str(), callback, recv, &errMsg);
90     lock.unlock();
91     NETMGR_LOG_D("EXEC SQL : %{public}s", sql.c_str());
92     if (errMsg != nullptr) {
93         NETMGR_LOG_E("Exec sql failed err:%{public}s, path: %{public}s", errMsg, path_.c_str());
94         sqlite3_free(errMsg);
95     }
96     int32_t rettmp = DeleteAndBackup(ret);
97     if (rettmp == SQLITE_OK && rettmp != ret) {
98         std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
99         int32_t ret = sqlite3_exec(sqlite_, sql.c_str(), callback, recv, &errMsg);
100         lock.unlock();
101     }
102 
103     return rettmp == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
104 }
105 
CreateTable(const std::string & tableName,const std::string & tableInfo)106 int32_t NetStatsDatabaseHelper::CreateTable(const std::string &tableName, const std::string &tableInfo)
107 {
108     std::string sql = CREATE_TABLE_IF_NOT_EXISTS + tableName + "(" + tableInfo + ");";
109     int32_t ret = ExecSql(sql, nullptr, sqlCallback);
110     if (ret != NETMANAGER_SUCCESS) {
111         return STATS_ERR_CREATE_TABLE_FAIL;
112     }
113     return NETMANAGER_SUCCESS;
114 }
115 
Open(const std::string & path)116 int32_t NetStatsDatabaseHelper::Open(const std::string &path)
117 {
118     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
119     int32_t ret = sqlite3_open_v2(path.c_str(), &sqlite_,
120                                   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nullptr);
121     return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
122 }
123 
InsertData(const std::string & tableName,const std::string & paramList,const NetStatsInfo & info)124 int32_t NetStatsDatabaseHelper::InsertData(const std::string &tableName, const std::string &paramList,
125                                            const NetStatsInfo &info)
126 {
127     std::string params;
128     int32_t paramCount = count(paramList.begin(), paramList.end(), ',') + 1;
129     for (int32_t i = 0; i < paramCount; ++i) {
130         params += "?";
131         if (i != paramCount - 1) {
132             params += ",";
133         }
134     }
135     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
136     std::string sql = "INSERT INTO " + tableName + " (" + paramList + ") " + "VALUES" + " (" + params + ") ";
137     int32_t ret = statement_.Prepare(sqlite_, sql);
138     int32_t rettmp = DeleteAndBackup(ret);
139     if (rettmp != SQLITE_OK) {
140         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
141         return STATS_ERR_WRITE_DATA_FAIL;
142     }
143     if (rettmp != ret) {
144         statement_.Prepare(sqlite_, sql);
145     }
146     int32_t idx = 1;
147     if (paramCount == UID_PARAM_NUM) {
148         statement_.BindInt64(idx, info.uid_);
149         ++idx;
150     }
151     statement_.BindText(idx, info.iface_);
152     statement_.BindInt64(++idx, info.date_);
153     statement_.BindInt64(++idx, info.rxBytes_);
154     statement_.BindInt64(++idx, info.rxPackets_);
155     statement_.BindInt64(++idx, info.txBytes_);
156     statement_.BindInt64(++idx, info.txPackets_);
157     if (paramCount == UID_PARAM_NUM) {
158         statement_.BindText(++idx, info.ident_);
159     }
160     statement_.BindInt64(++idx, info.flag_);
161     statement_.BindInt64(++idx, info.userId_);
162     ret = statement_.Step();
163     statement_.ResetStatementAndClearBindings();
164     if (ret != SQLITE_DONE) {
165         NETMGR_LOG_E("Step failed ret:%{public}d", ret);
166         return STATS_ERR_WRITE_DATA_FAIL;
167     }
168     return NETMANAGER_SUCCESS;
169 }
170 
SelectData(std::vector<NetStatsInfo> & infos,const std::string & tableName,uint64_t start,uint64_t end)171 int32_t NetStatsDatabaseHelper::SelectData(std::vector<NetStatsInfo> &infos, const std::string &tableName,
172                                            uint64_t start, uint64_t end)
173 {
174     infos.clear();
175     std::string sql = SELECT_FROM + tableName + " t WHERE 1=1" + DATA_MORE_THAN + DATA_LESS_THAN;
176     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
177     int32_t ret = statement_.Prepare(sqlite_, sql);
178     int32_t rettmp = DeleteAndBackup(ret);
179     if (rettmp != SQLITE_OK) {
180         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
181         return STATS_ERR_READ_DATA_FAIL;
182     }
183     if (rettmp != ret) {
184         statement_.Prepare(sqlite_, sql);
185     }
186     int32_t idx = 1;
187     ret = statement_.BindInt64(idx, start);
188     if (ret != SQLITE_OK) {
189         NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
190         return STATS_ERR_READ_DATA_FAIL;
191     }
192     ret = statement_.BindInt64(++idx, end);
193     if (ret != SQLITE_OK) {
194         NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
195         return STATS_ERR_READ_DATA_FAIL;
196     }
197     return Step(infos);
198 }
199 
SelectData(const uint32_t uid,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)200 int32_t NetStatsDatabaseHelper::SelectData(const uint32_t uid, uint64_t start, uint64_t end,
201                                            std::vector<NetStatsInfo> &infos)
202 {
203     infos.clear();
204     std::string sql = SELECT_FROM + std::string(UID_TABLE) + " t WHERE 1=1 AND t.UID == ?" + DATA_MORE_THAN +
205                       DATA_LESS_THAN;
206     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
207     int32_t ret = statement_.Prepare(sqlite_, sql);
208     int32_t rettmp = DeleteAndBackup(ret);
209     if (rettmp != SQLITE_OK) {
210         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
211         return STATS_ERR_READ_DATA_FAIL;
212     }
213     if (rettmp != ret) {
214         statement_.Prepare(sqlite_, sql);
215     }
216     int32_t idx = 1;
217     ret = statement_.BindInt64(idx, uid);
218     if (ret != SQLITE_OK) {
219         NETMGR_LOG_E("Bind int32 failed ret:%{public}d", ret);
220         return STATS_ERR_READ_DATA_FAIL;
221     }
222     ret = BindInt64(idx, start, end);
223     if (ret != SQLITE_OK) {
224         return ret;
225     }
226     return Step(infos);
227 }
228 
SelectData(const std::string & iface,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)229 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, uint64_t start, uint64_t end,
230                                            std::vector<NetStatsInfo> &infos)
231 {
232     infos.clear();
233     std::string sql = SELECT_FROM + std::string(IFACE_TABLE) + " t WHERE 1=1 AND t.IFace = ?" +
234                       DATA_MORE_THAN + DATA_LESS_THAN;
235     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
236     int32_t ret = statement_.Prepare(sqlite_, sql);
237     int32_t rettmp = DeleteAndBackup(ret);
238     if (rettmp != SQLITE_OK) {
239         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
240         return STATS_ERR_READ_DATA_FAIL;
241     }
242     if (rettmp != ret) {
243         statement_.Prepare(sqlite_, sql);
244     }
245     int32_t idx = 1;
246     ret = statement_.BindText(idx, iface);
247     if (ret != SQLITE_OK) {
248         NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
249         return STATS_ERR_READ_DATA_FAIL;
250     }
251     ret = BindInt64(idx, start, end);
252     if (ret != SQLITE_OK) {
253         return ret;
254     }
255     return Step(infos);
256 }
257 
SelectData(const std::string & iface,const uint32_t uid,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)258 int32_t NetStatsDatabaseHelper::SelectData(const std::string &iface, const uint32_t uid, uint64_t start, uint64_t end,
259                                            std::vector<NetStatsInfo> &infos)
260 {
261     infos.clear();
262     std::string sql = SELECT_FROM + std::string(UID_TABLE) + " t WHERE 1=1 AND t.UID = ?" + " AND t.IFace = ?" +
263                       DATA_MORE_THAN + DATA_LESS_THAN;
264     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
265     int32_t ret = statement_.Prepare(sqlite_, sql);
266     int32_t rettmp = DeleteAndBackup(ret);
267     if (rettmp != SQLITE_OK) {
268         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
269         return STATS_ERR_READ_DATA_FAIL;
270     }
271     if (rettmp != ret) {
272         statement_.Prepare(sqlite_, sql);
273     }
274     int32_t idx = 1;
275     ret = statement_.BindInt64(idx, uid);
276     if (ret != SQLITE_OK) {
277         NETMGR_LOG_E("bind int32 ret:%{public}d", ret);
278         return STATS_ERR_READ_DATA_FAIL;
279     }
280     ret = statement_.BindText(++idx, iface);
281     if (ret != SQLITE_OK) {
282         NETMGR_LOG_E("Bind text failed ret:%{public}d", ret);
283         return STATS_ERR_READ_DATA_FAIL;
284     }
285     ret = BindInt64(idx, start, end);
286     if (ret != SQLITE_OK) {
287         return ret;
288     }
289     return Step(infos);
290 }
291 
QueryData(const std::string & tableName,const std::string & ident,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)292 int32_t NetStatsDatabaseHelper::QueryData(const std::string &tableName, const std::string &ident, uint64_t start,
293                                           uint64_t end, std::vector<NetStatsInfo> &infos)
294 {
295     infos.clear();
296     std::string sql =
297         SELECT_FROM + tableName + " t WHERE 1=1 AND t.Ident = ?" + DATA_MORE_THAN + DATA_LESS_THAN;
298     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
299     int32_t ret = statement_.Prepare(sqlite_, sql);
300     int32_t rettmp = DeleteAndBackup(ret);
301     if (rettmp != SQLITE_OK) {
302         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
303         return STATS_ERR_READ_DATA_FAIL;
304     }
305     if (rettmp != ret) {
306         statement_.Prepare(sqlite_, sql);
307     }
308     int32_t idx = 1;
309     ret = statement_.BindText(idx, ident);
310     if (ret != SQLITE_OK) {
311         NETMGR_LOG_E("bind text ret:%{public}d", ret);
312         return STATS_ERR_READ_DATA_FAIL;
313     }
314     ret = BindInt64(idx, start, end);
315     if (ret != SQLITE_OK) {
316         return ret;
317     }
318     return Step(infos);
319 }
320 
QueryData(const std::string & tableName,const std::string & ident,const int32_t userId,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)321 int32_t NetStatsDatabaseHelper::QueryData(const std::string &tableName, const std::string &ident, const int32_t userId,
322                                           uint64_t start, uint64_t end, std::vector<NetStatsInfo> &infos)
323 {
324     infos.clear();
325     std::string sql =
326         SELECT_FROM + tableName + " t WHERE 1=1 AND t.Ident = ? " + " AND t.UserId = ? " +
327         DATA_MORE_THAN + DATA_LESS_THAN;
328     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
329     int32_t ret = statement_.Prepare(sqlite_, sql);
330     if (ret != SQLITE_OK) {
331         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
332         return STATS_ERR_READ_DATA_FAIL;
333     }
334     int32_t idx = 1;
335     ret = statement_.BindText(idx, ident);
336     if (ret != SQLITE_OK) {
337         NETMGR_LOG_E("bind text ret:%{public}d", ret);
338         return STATS_ERR_READ_DATA_FAIL;
339     }
340     ret = statement_.BindInt32(++idx, userId);
341     if (ret != SQLITE_OK) {
342         return ret;
343     }
344     ret = BindInt64(idx, start, end);
345     if (ret != SQLITE_OK) {
346         return ret;
347     }
348     return Step(infos);
349 }
350 
QueryData(const std::string & tableName,const uint32_t uid,const std::string & ident,uint64_t start,uint64_t end,std::vector<NetStatsInfo> & infos)351 int32_t NetStatsDatabaseHelper::QueryData(const std::string &tableName, const uint32_t uid, const std::string &ident,
352                                           uint64_t start, uint64_t end, std::vector<NetStatsInfo> &infos)
353 {
354     infos.clear();
355     std::string sql = SELECT_FROM + tableName + " t WHERE 1=1 AND T.UID = ? AND t.Ident = ?" + DATA_MORE_THAN +
356                       DATA_LESS_THAN;
357     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
358     int32_t ret = statement_.Prepare(sqlite_, sql);
359     int32_t rettmp = DeleteAndBackup(ret);
360     if (rettmp != SQLITE_OK) {
361         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
362         return STATS_ERR_READ_DATA_FAIL;
363     }
364     if (rettmp != ret) {
365         statement_.Prepare(sqlite_, sql);
366     }
367     int32_t idx = 1;
368     ret = statement_.BindInt64(idx, uid);
369     if (ret != SQLITE_OK) {
370         NETMGR_LOG_E("bind int32 ret:%{public}d", ret);
371         return STATS_ERR_READ_DATA_FAIL;
372     }
373     ret = statement_.BindText(++idx, ident);
374     if (ret != SQLITE_OK) {
375         NETMGR_LOG_E("bind text ret:%{public}d", ret);
376         return STATS_ERR_READ_DATA_FAIL;
377     }
378     ret = BindInt64(idx, start, end);
379     if (ret != SQLITE_OK) {
380         return ret;
381     }
382     return Step(infos);
383 }
384 
DeleteData(const std::string & tableName,uint64_t start,uint64_t end)385 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t start, uint64_t end)
386 {
387     std::string sql =
388         DELETE_FROM + tableName + " WHERE Date >= " + std::to_string(start) + " AND Date <= " + std::to_string(end);
389     return ExecSql(sql, nullptr, sqlCallback);
390 }
391 
DeleteData(const std::string & tableName,uint64_t uid)392 int32_t NetStatsDatabaseHelper::DeleteData(const std::string &tableName, uint64_t uid)
393 {
394     std::string sql = DELETE_FROM + tableName + " WHERE UID = ?";
395     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
396     int32_t ret = statement_.Prepare(sqlite_, sql);
397     int32_t rettmp = DeleteAndBackup(ret);
398     if (rettmp != SQLITE_OK) {
399         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
400         return STATS_ERR_WRITE_DATA_FAIL;
401     }
402     if (rettmp != ret) {
403         statement_.Prepare(sqlite_, sql);
404     }
405     int32_t idx = 1;
406     statement_.BindInt64(idx, uid);
407     ret = statement_.Step();
408     statement_.ResetStatementAndClearBindings();
409     if (ret != SQLITE_DONE) {
410         NETMGR_LOG_E("Step failed ret:%{public}d", ret);
411         return STATS_ERR_WRITE_DATA_FAIL;
412     }
413     return NETMANAGER_SUCCESS;
414 }
415 
Close()416 int32_t NetStatsDatabaseHelper::Close()
417 {
418     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
419     int32_t ret = sqlite3_close_v2(sqlite_);
420     return ret == SQLITE_OK ? NETMANAGER_SUCCESS : NETMANAGER_ERROR;
421 }
422 
ClearData(const std::string & tableName)423 int32_t NetStatsDatabaseHelper::ClearData(const std::string &tableName)
424 {
425     std::string sql = DELETE_FROM + tableName;
426     std::string shrinkMemSql = "PRAGMA shrink_memory";
427     int32_t execSqlRet = ExecSql(sql, nullptr, sqlCallback);
428     if (execSqlRet != NETMANAGER_SUCCESS) {
429         NETMGR_LOG_E("Delete data failed");
430         return execSqlRet;
431     }
432     execSqlRet = ExecSql(shrinkMemSql, nullptr, sqlCallback);
433     if (execSqlRet != NETMANAGER_SUCCESS) {
434         NETMGR_LOG_E("Delete data failed");
435         return execSqlRet;
436     }
437     sql = "VACUUM";
438     execSqlRet = ExecSql(sql, nullptr, sqlCallback);
439     if (execSqlRet != NETMANAGER_SUCCESS) {
440         NETMGR_LOG_E("Delete data failed");
441         return execSqlRet;
442     }
443     return ExecSql(shrinkMemSql, nullptr, sqlCallback);
444 }
445 
Step(std::vector<NetStatsInfo> & infos)446 int32_t NetStatsDatabaseHelper::Step(std::vector<NetStatsInfo> &infos)
447 {
448     int32_t rc = statement_.Step();
449     NETMGR_LOG_D("Step result:%{public}d", rc);
450     while (rc != SQLITE_DONE) {
451         if (rc != SQLITE_ROW) {
452             NETMGR_LOG_E("sqlite step error: %{public}d", rc);
453             statement_.ResetStatementAndClearBindings();
454             return STATS_ERR_READ_DATA_FAIL;
455         }
456         int32_t i = 0;
457         NetStatsInfo info;
458         if (statement_.GetColumnCount() == UID_PARAM_NUM) {
459             statement_.GetColumnInt(i, info.uid_);
460             ++i;
461         }
462         statement_.GetColumnString(i, info.iface_);
463         statement_.GetColumnLong(++i, info.date_);
464         statement_.GetColumnLong(++i, info.rxBytes_);
465         statement_.GetColumnLong(++i, info.rxPackets_);
466         statement_.GetColumnLong(++i, info.txBytes_);
467         statement_.GetColumnLong(++i, info.txPackets_);
468         if (statement_.GetColumnCount() == UID_PARAM_NUM) {
469             statement_.GetColumnString(++i, info.ident_);
470         }
471         statement_.GetColumnInt(++i, info.flag_);
472         statement_.GetColumnInt(++i, info.userId_);
473         infos.emplace_back(info);
474         rc = statement_.Step();
475         NETMGR_LOG_D("Step result:%{public}d", rc);
476     }
477     statement_.ResetStatementAndClearBindings();
478     return NETMANAGER_SUCCESS;
479 }
480 
BindInt64(int32_t idx,uint64_t start,uint64_t end)481 int32_t NetStatsDatabaseHelper::BindInt64(int32_t idx, uint64_t start, uint64_t end)
482 {
483     int32_t ret = statement_.BindInt64(++idx, start);
484     if (ret != SQLITE_OK) {
485         NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
486         return STATS_ERR_READ_DATA_FAIL;
487     }
488     ret = statement_.BindInt64(++idx, end);
489     if (ret != SQLITE_OK) {
490         NETMGR_LOG_E("Bind int64 failed ret:%{public}d", ret);
491         return STATS_ERR_READ_DATA_FAIL;
492     }
493 
494     return ret;
495 }
496 
Upgrade()497 int32_t NetStatsDatabaseHelper::Upgrade()
498 {
499     auto ret = ExecTableUpgrade(UID_TABLE, Version_1);
500     if (ret != NETMANAGER_SUCCESS) {
501         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_TABLE, Version_1);
502     }
503     ret = ExecTableUpgrade(UID_SIM_TABLE, Version_2);
504     if (ret != NETMANAGER_SUCCESS) {
505         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_2);
506     }
507     ret = ExecTableUpgrade(UID_TABLE, Version_3);
508     if (ret != NETMANAGER_SUCCESS) {
509         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_TABLE, Version_3);
510     }
511     ret = ExecTableUpgrade(UID_SIM_TABLE, Version_3);
512     if (ret != NETMANAGER_SUCCESS) {
513         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_3);
514     }
515     ret = ExecTableUpgrade(UID_SIM_TABLE, Version_4);
516     if (ret != NETMANAGER_SUCCESS) {
517         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_4);
518     }
519     ret = ExecTableUpgrade(UID_SIM_TABLE, Version_5);
520     if (ret != NETMANAGER_SUCCESS) {
521         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_5);
522     }
523     ret = ExecTableUpgrade(UID_TABLE, Version_6);
524     if (ret != NETMANAGER_SUCCESS) {
525         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_6);
526     }
527     ret = ExecTableUpgrade(UID_SIM_TABLE, Version_6);
528     if (ret != NETMANAGER_SUCCESS) {
529         NETMGR_LOG_E("Upgrade db failed. table is %{public}s, version is %{public}d", UID_SIM_TABLE, Version_6);
530     }
531     return ret;
532 }
533 
ExecTableUpgrade(const std::string & tableName,TableVersion newVersion)534 int32_t NetStatsDatabaseHelper::ExecTableUpgrade(const std::string &tableName, TableVersion newVersion)
535 {
536     TableVersion oldVersion;
537     auto ret = GetTableVersion(oldVersion, tableName);
538     if (ret != SQLITE_OK) {
539         NETMGR_LOG_E("ExecTableUpgrade getTableVersion failed. ret = %{public}d", ret);
540         return NETMANAGER_ERROR;
541     }
542     if (oldVersion == newVersion) {
543         return NETMANAGER_SUCCESS;
544     }
545     NETMGR_LOG_I("ExecTableUpgrade tableName = %{public}s, oldVersion = %{public}d, newVersion = %{public}d",
546                  tableName.c_str(), oldVersion, newVersion);
547     ExecUpgradeSql(tableName, oldVersion, newVersion);
548     if (oldVersion != newVersion) {
549         NETMGR_LOG_E("ExecTableUpgrade error. oldVersion = %{public}d, newVersion = %{public}d",
550                      oldVersion, newVersion);
551         return NETMANAGER_ERROR;
552     }
553     ret = UpdateTableVersion(oldVersion, tableName);
554     if (ret != NETMANAGER_SUCCESS) {
555         NETMGR_LOG_E("ExecTableUpgrade updateVersion failed. ret = %{public}d", ret);
556         return NETMANAGER_ERROR;
557     }
558     return NETMANAGER_SUCCESS;
559 }
560 
ExecUpgradeSql(const std::string & tableName,TableVersion & oldVersion,TableVersion newVersion)561 void NetStatsDatabaseHelper::ExecUpgradeSql(const std::string &tableName, TableVersion &oldVersion,
562                                             TableVersion newVersion)
563 {
564     int32_t ret = NETMANAGER_SUCCESS;
565     if (oldVersion < Version_1 && newVersion >= Version_1) {
566         std::string sql = ALTER_TABLE + tableName + " ADD COLUMN Ident CHAR(100) NOT NULL DEFAULT '';";
567         ret = ExecSql(sql, nullptr, sqlCallback);
568         if (ret != SQLITE_OK) {
569             NETMGR_LOG_E("ExecTableUpgrade version_1 failed. ret = %{public}d", ret);
570         }
571         oldVersion = Version_1;
572     }
573     if (oldVersion < Version_2 && newVersion >= Version_2) {
574         ret = DeleteData(tableName, Sim_UID);
575         if (ret != SQLITE_OK) {
576             NETMGR_LOG_E("ExecTableUpgrade Version_2 failed. ret = %{public}d", ret);
577         }
578         oldVersion = Version_2;
579     }
580     if (oldVersion < Version_3 && newVersion >= Version_3) {
581         std::string sql = ALTER_TABLE + tableName + " ADD COLUMN Flag INTEGER NOT NULL DEFAULT 0;";
582         ret = ExecSql(sql, nullptr, sqlCallback);
583         if (ret != SQLITE_OK) {
584             NETMGR_LOG_E("ExecTableUpgrade version_3 failed. ret = %{public}d", ret);
585         }
586         oldVersion = Version_3;
587     }
588     if (oldVersion < Version_4 && newVersion >= Version_4) {
589         std::string sql = UPDATE + tableName + SET_FLAG + std::to_string(STATS_DATA_FLAG_SIM) +
590                           " WHERE Flag = " + std::to_string(STATS_DATA_FLAG_DEFAULT) + ";";
591         ret = ExecSql(sql, nullptr, sqlCallback);
592         if (ret != SQLITE_OK) {
593             NETMGR_LOG_E("ExecTableUpgrade Version_4 failed. ret = %{public}d", ret);
594         }
595         oldVersion = Version_4;
596     }
597     if (oldVersion < Version_5 && newVersion >= Version_5) {
598         if (isDisplayTrafficAncoList_) {
599             std::string sqlsim = UPDATE + tableName + SET_FLAG + std::to_string(STATS_DATA_FLAG_SIM_BASIC) +
600                               " WHERE Flag = " + std::to_string(STATS_DATA_FLAG_SIM) + ";";
601             ret = ExecSql(sqlsim, nullptr, sqlCallback);
602             std::string sqlsim2 = UPDATE + tableName + SET_FLAG + std::to_string(STATS_DATA_FLAG_SIM2_BASIC) +
603                               " WHERE Flag = " + std::to_string(STATS_DATA_FLAG_SIM2) + ";";
604             int32_t retsim2 = ExecSql(sqlsim2, nullptr, sqlCallback);
605             if (ret != SQLITE_OK || retsim2 != SQLITE_OK) {
606                 NETMGR_LOG_E("ExecTableUpgrade Version_5 failed. ret = %{public}d", ret);
607             }
608         }
609         oldVersion = Version_5;
610     }
611     ExecUpgradeSqlNext(tableName, oldVersion, newVersion);
612 }
613 
ExecUpgradeSqlNext(const std::string & tableName,TableVersion & oldVersion,TableVersion newVersion)614 void NetStatsDatabaseHelper::ExecUpgradeSqlNext(const std::string &tableName, TableVersion &oldVersion,
615                                                 TableVersion newVersion)
616 {
617     int32_t ret = NETMANAGER_SUCCESS;
618     if (oldVersion < Version_6 && newVersion >= Version_6) {
619         std::string sql = ALTER_TABLE + tableName + " ADD COLUMN UserId INTEGER NOT NULL DEFAULT 0;";
620         ret = ExecSql(sql, nullptr, sqlCallback);
621         if (ret != SQLITE_OK) {
622             NETMGR_LOG_E("ExecTableUpgrade Version_6 failed. ret = %{public}d", ret);
623         }
624         oldVersion = Version_6;
625     }
626 }
627 
GetTableVersion(TableVersion & version,const std::string & tableName)628 int32_t NetStatsDatabaseHelper::GetTableVersion(TableVersion &version, const std::string &tableName)
629 {
630     std::string sql = SELECT_FROM + std::string(VERSION_TABLE) + " WHERE Name = ?;";
631     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
632     int32_t ret = statement_.Prepare(sqlite_, sql);
633     int32_t rettmp = DeleteAndBackup(ret);
634     if (rettmp != SQLITE_OK) {
635         NETMGR_LOG_E("Prepare failed ret:%{public}d", ret);
636         return STATS_ERR_READ_DATA_FAIL;
637     }
638     if (rettmp != ret) {
639         statement_.Prepare(sqlite_, sql);
640     }
641     int32_t idx = 1;
642     ret = statement_.BindText(idx, tableName);
643     if (ret != SQLITE_OK) {
644         NETMGR_LOG_E("bind text ret:%{public}d", ret);
645         return STATS_ERR_READ_DATA_FAIL;
646     }
647     int32_t rc = statement_.Step();
648     auto v = static_cast<uint32_t>(Version_0);
649     while (rc != SQLITE_DONE) {
650         if (rc == SQLITE_ROW) {
651             int32_t i = 1;
652             statement_.GetColumnInt(i, v);
653             rc = statement_.Step();
654         } else {
655             NETMGR_LOG_E("Step failed with rc:%{public}d", rc);
656             break;
657         }
658     }
659     statement_.ResetStatementAndClearBindings();
660     version = static_cast<TableVersion>(v);
661     return NETMANAGER_SUCCESS;
662 }
663 
UpdateTableVersion(TableVersion version,const std::string & tableName)664 int32_t NetStatsDatabaseHelper::UpdateTableVersion(TableVersion version, const std::string &tableName)
665 {
666     std::string sql = INSERT_OR_REPLACE_INTO + std::string(VERSION_TABLE) + "(Name, Version) VALUES('" +
667                       tableName + "', " + std::to_string(version) + ");";
668     return ExecSql(sql, nullptr, sqlCallback);
669 }
670 
UpdateStatsFlag(const std::string & tableName,uint32_t uid,uint32_t flag)671 int32_t NetStatsDatabaseHelper::UpdateStatsFlag(const std::string &tableName, uint32_t uid, uint32_t flag)
672 {
673     std::string sql = UPDATE + tableName + SET_FLAG + std::to_string(flag) +
674                       " WHERE UID = " + std::to_string(uid);
675     return ExecSql(sql, nullptr, sqlCallback);
676 }
677 
UpdateStatsFlagByUserId(const std::string & tableName,int32_t userId,uint32_t flag)678 int32_t NetStatsDatabaseHelper::UpdateStatsFlagByUserId(const std::string &tableName, int32_t userId, uint32_t flag)
679 {
680     std::string sql = UPDATE + tableName + SET_FLAG + std::to_string(flag) +
681                       " WHERE UserId = " + std::to_string(userId);
682     return ExecSql(sql, nullptr, sqlCallback);
683 }
684 
UpdateStatsUserIdByUserId(const std::string & tableName,int32_t oldUserId,int32_t newUserId)685 int32_t NetStatsDatabaseHelper::UpdateStatsUserIdByUserId(const std::string &tableName,
686     int32_t oldUserId, int32_t newUserId)
687 {
688     std::string sql = UPDATE + tableName + SET_USERID + std::to_string(newUserId) +
689                       " WHERE UserId = " + std::to_string(oldUserId);
690     return ExecSql(sql, nullptr, sqlCallback);
691 }
692 
UpdateDataFlag(const std::string & tableName,uint32_t oldFlag,uint32_t newFlag)693 int32_t NetStatsDatabaseHelper::UpdateDataFlag(const std::string &tableName, uint32_t oldFlag, uint32_t newFlag)
694 {
695     std::string sql =
696         UPDATE + tableName + SET_FLAG + std::to_string(newFlag) + " WHERE Flag = " + std::to_string(oldFlag);
697     return ExecSql(sql, nullptr, sqlCallback);
698 }
699 
BackupNetStatsData(const std::string & sourceDb,const std::string & backupDb)700 bool NetStatsDatabaseHelper::BackupNetStatsData(const std::string &sourceDb, const std::string &backupDb)
701 {
702     NETMGR_LOG_I("BackupNetStatsData start");
703     sqlite3* source = nullptr;
704     sqlite3* backup = nullptr;
705     int32_t ret = sqlite3_open(sourceDb.c_str(), &source);
706     if (ret != SQLITE_OK) {
707         NETMGR_LOG_E("sqlite3_open failed ret:%{public}d", ret);
708         return false;
709     }
710     ret = sqlite3_open(backupDb.c_str(), &backup);
711     if (ret != SQLITE_OK) {
712         NETMGR_LOG_E("sqlite3_open failed ret:%{public}d", ret);
713         return false;
714     }
715 
716     sqlite3_backup* pBackup = sqlite3_backup_init(backup, "main", source, "main");
717     int rc = -1;
718     if (pBackup) {
719         while ((rc = sqlite3_backup_step(pBackup, -1)) == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
720             if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
721                 break;
722             }
723         }
724         if (rc != SQLITE_DONE) {
725             NETMGR_LOG_E("Backup failed: %{public}s, ret: %{public}d", sqlite3_errmsg(backup), rc);
726         } else {
727             NETMGR_LOG_E("Backup completed successfully");
728         }
729         sqlite3_backup_finish(pBackup);
730     } else {
731         NETMGR_LOG_E("Failed to initialize backup: %{public}s", sqlite3_errmsg(backup));
732     }
733 
734     sqlite3_close(source);
735     sqlite3_close(backup);
736     return (rc == SQLITE_DONE);
737 }
738 
BackupNetStatsDataDB(const std::string & sourceDb,const std::string & backupDb)739 bool NetStatsDatabaseHelper::BackupNetStatsDataDB(const std::string &sourceDb, const std::string &backupDb)
740 {
741     NETMGR_LOG_I("BackupNetStatsDataDB");
742     std::unique_lock<ffrt::mutex> lock(sqliteMutex_);
743     bool ret = BackupNetStatsData(sourceDb, backupDb);
744     return ret;
745 }
746 
DeleteAndBackup(int32_t errCode)747 int32_t NetStatsDatabaseHelper::DeleteAndBackup(int32_t errCode)
748 {
749     if (errCode != SQLITE_NOTADB || (path_ != NET_STATS_DATABASE_BACK_PATH &&
750         path_ != NET_STATS_DATABASE_PATH)) {
751         return errCode;
752     }
753     if (path_.find(NET_STATS_DATABASE_BACK_PATH) != std::string::npos) {
754         CommonUtils::DeleteFile(NET_STATS_DATABASE_BACK_PATH);
755         return errCode;
756     }
757 
758     CommonUtils::DeleteFile(NET_STATS_DATABASE_PATH);
759     bool backupRet = BackupNetStatsData(NET_STATS_DATABASE_BACK_PATH, NET_STATS_DATABASE_PATH);
760     if (backupRet) {
761         return SQLITE_OK;
762     }
763 
764     return errCode;
765 }
766 } // namespace NetManagerStandard
767 } // namespace OHOS
768