• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "timer_database.h"
16 #include "time_hilog.h"
17 #include "time_common.h"
18 
19 namespace OHOS {
20 namespace MiscServices {
21 constexpr const char *CREATE_TIME_TIMER_HOLD_ON_REBOOT = "CREATE TABLE IF NOT EXISTS hold_on_reboot "
22                                                          "(timerId INTEGER PRIMARY KEY, "
23                                                          "type INTEGER, "
24                                                          "flag INTEGER, "
25                                                          "windowLength INTEGER, "
26                                                          "interval INTEGER, "
27                                                          "uid INTEGER, "
28                                                          "bundleName TEXT, "
29                                                          "wantAgent TEXT, "
30                                                          "state INTEGER, "
31                                                          "triggerTime INTEGER, "
32                                                          "pid INTEGER, "
33                                                          "name TEXT)";
34 
35 constexpr const char *CREATE_TIME_TIMER_DROP_ON_REBOOT = "CREATE TABLE IF NOT EXISTS drop_on_reboot "
36                                                          "(timerId INTEGER PRIMARY KEY, "
37                                                          "type INTEGER, "
38                                                          "flag INTEGER, "
39                                                          "windowLength INTEGER, "
40                                                          "interval INTEGER, "
41                                                          "uid INTEGER, "
42                                                          "bundleName TEXT, "
43                                                          "wantAgent TEXT, "
44                                                          "state INTEGER, "
45                                                          "triggerTime INTEGER, "
46                                                          "pid INTEGER, "
47                                                          "name TEXT)";
48 
49 constexpr const char *HOLD_ON_REBOOT_ADD_PID_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN pid INTEGER";
50 constexpr const char *HOLD_ON_REBOOT_ADD_NAME_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN name TEXT";
51 constexpr const char *DROP_ON_REBOOT_ADD_PID_COLUMN = "ALTER TABLE drop_on_reboot ADD COLUMN pid INTEGER";
52 constexpr const char *DROP_ON_REBOOT_ADD_NAME_COLUMN = "ALTER TABLE drop_on_reboot ADD COLUMN name TEXT";
TimeDatabase()53 TimeDatabase::TimeDatabase()
54 {
55     int errCode = OHOS::NativeRdb::E_OK;
56     OHOS::NativeRdb::RdbStoreConfig config(DB_NAME);
57     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
58     config.SetEncryptStatus(false);
59     config.SetReadConSize(1);
60     TimeDBOpenCallback timeDBOpenCallback;
61     store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode);
62     TIME_HILOGI(TIME_MODULE_SERVICE, "Gets time database, ret: %{public}d", errCode);
63     if (errCode == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
64         auto ret = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(config);
65         if (ret != OHOS::NativeRdb::E_OK) {
66             TIME_HILOGE(TIME_MODULE_SERVICE, "delete corrupt database failed, ret: %{public}d", ret);
67             return;
68         }
69         store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode);
70     }
71 }
72 
GetInstance()73 TimeDatabase &TimeDatabase::GetInstance()
74 {
75     static TimeDatabase timeDatabase;
76     return timeDatabase;
77 }
78 
RecoverDataBase()79 bool TimeDatabase::RecoverDataBase()
80 {
81     OHOS::NativeRdb::RdbStoreConfig config(DB_NAME);
82     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
83     config.SetEncryptStatus(false);
84     config.SetReadConSize(1);
85     auto ret = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(config);
86     if (ret != OHOS::NativeRdb::E_OK) {
87         TIME_HILOGE(TIME_MODULE_SERVICE, "delete corrupt database failed, ret: %{public}d", ret);
88         return false;
89     }
90     TimeDBOpenCallback timeDbOpenCallback;
91     int errCode;
92     store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDbOpenCallback, errCode);
93     return true;
94 }
95 
GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)96 int GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
97 {
98     int value = 0;
99     resultSet->GetInt(line, value);
100     return value;
101 }
102 
GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)103 int64_t GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
104 {
105     int64_t value = 0;
106     resultSet->GetLong(line, value);
107     return value;
108 }
109 
GetString(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)110 std::string GetString(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
111 {
112     std::string value = "";
113     resultSet->GetString(line, value);
114     return value;
115 }
116 
Insert(const std::string & table,const OHOS::NativeRdb::ValuesBucket & insertValues)117 bool TimeDatabase::Insert(const std::string &table, const OHOS::NativeRdb::ValuesBucket &insertValues)
118 {
119     if (store_ == nullptr) {
120         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
121         return false;
122     }
123 
124     int64_t outRowId = 0;
125     int ret = store_->Insert(outRowId, table, insertValues);
126     if (ret != OHOS::NativeRdb::E_OK) {
127         TIME_HILOGE(TIME_MODULE_SERVICE, "insert values failed, ret: %{public}d", ret);
128         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
129             return false;
130         }
131         if (!RecoverDataBase()) {
132             return false;
133         }
134         ret = store_->Insert(outRowId, table, insertValues);
135         if (ret != OHOS::NativeRdb::E_OK) {
136             TIME_HILOGE(TIME_MODULE_SERVICE, "Insert values after RecoverDataBase failed, ret: %{public}d", ret);
137         }
138     }
139     return true;
140 }
141 
Update(const OHOS::NativeRdb::ValuesBucket values,const OHOS::NativeRdb::AbsRdbPredicates & predicates)142 bool TimeDatabase::Update(
143     const OHOS::NativeRdb::ValuesBucket values, const OHOS::NativeRdb::AbsRdbPredicates &predicates)
144 {
145     if (store_ == nullptr) {
146         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
147         return false;
148     }
149 
150     int changedRows = 0;
151     int ret = store_->Update(changedRows, values, predicates);
152     if (ret != OHOS::NativeRdb::E_OK) {
153         TIME_HILOGE(TIME_MODULE_SERVICE, "update values failed, ret: %{public}d", ret);
154         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
155             return false;
156         }
157         if (!RecoverDataBase()) {
158             return false;
159         }
160         ret = store_->Update(changedRows, values, predicates);
161         if (ret != OHOS::NativeRdb::E_OK) {
162             TIME_HILOGE(TIME_MODULE_SERVICE, "Update values after RecoverDataBase failed, ret: %{public}d", ret);
163         }
164     }
165     return true;
166 }
167 
Query(const OHOS::NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns)168 std::shared_ptr<OHOS::NativeRdb::ResultSet> TimeDatabase::Query(
169     const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> &columns)
170 {
171     if (store_ == nullptr) {
172         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
173         return nullptr;
174     }
175     auto result = store_->Query(predicates, columns);
176     int count;
177     if (result->GetRowCount(count) == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
178         RecoverDataBase();
179         return nullptr;
180     }
181     return result;
182 }
183 
Delete(const OHOS::NativeRdb::AbsRdbPredicates & predicates)184 bool TimeDatabase::Delete(const OHOS::NativeRdb::AbsRdbPredicates &predicates)
185 {
186     if (store_ == nullptr) {
187         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
188         return false;
189     }
190 
191     int deletedRows = 0;
192     int ret = store_->Delete(deletedRows, predicates);
193     if (ret != OHOS::NativeRdb::E_OK) {
194         TIME_HILOGE(TIME_MODULE_SERVICE, "delete values failed, ret: %{public}d", ret);
195         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
196             return false;
197         }
198         if (!RecoverDataBase()) {
199             return false;
200         }
201         ret = store_->Delete(deletedRows, predicates);
202         if (ret != OHOS::NativeRdb::E_OK) {
203             TIME_HILOGE(TIME_MODULE_SERVICE, "Delete values after RecoverDataBase failed, ret: %{public}d", ret);
204         }
205     }
206     return true;
207 }
208 
ClearDropOnReboot()209 void TimeDatabase::ClearDropOnReboot()
210 {
211     TIME_HILOGI(TIME_MODULE_SERVICE, "Clears drop_on_reboot table");
212     if (store_ == nullptr) {
213         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
214         return;
215     }
216     int ret = store_->ExecuteSql("DELETE FROM drop_on_reboot");
217     if (ret != OHOS::NativeRdb::E_OK) {
218         TIME_HILOGE(TIME_MODULE_SERVICE, "Clears drop_on_reboot table failed");
219         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
220             return;
221         }
222         if (!RecoverDataBase()) {
223             return;
224         }
225         ret = store_->ExecuteSql("DELETE FROM drop_on_reboot");
226         if (ret != OHOS::NativeRdb::E_OK) {
227             TIME_HILOGE(TIME_MODULE_SERVICE, "Clears after RecoverDataBase failed, ret: %{public}d", ret);
228         }
229     }
230 }
231 
TimeDBCreateTables(OHOS::NativeRdb::RdbStore & store)232 int TimeDBCreateTables(OHOS::NativeRdb::RdbStore &store)
233 {
234     TIME_HILOGI(TIME_MODULE_SERVICE, "Creates hold_on_reboot table");
235     // Creates hold_on_reboot table.
236     int ret = store.ExecuteSql(CREATE_TIME_TIMER_HOLD_ON_REBOOT);
237     if (ret != OHOS::NativeRdb::E_OK) {
238         TIME_HILOGE(TIME_MODULE_SERVICE, "Creates hold_on_reboot table failed, ret: %{public}d", ret);
239         return ret;
240     }
241 
242     TIME_HILOGI(TIME_MODULE_SERVICE, "Creates drop_on_reboot table");
243     // Creates drop_on_reboot table.
244     ret = store.ExecuteSql(CREATE_TIME_TIMER_DROP_ON_REBOOT);
245     if (ret != OHOS::NativeRdb::E_OK) {
246         TIME_HILOGE(TIME_MODULE_SERVICE, "Creates drop_on_reboot table failed, ret: %{public}d", ret);
247         return ret;
248     }
249     return ret;
250 }
251 
OnCreate(OHOS::NativeRdb::RdbStore & store)252 int TimeDBOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
253 {
254     TIME_HILOGI(TIME_MODULE_SERVICE, "OnCreate");
255     auto initRet = TimeDBCreateTables(store);
256     if (initRet != OHOS::NativeRdb::E_OK) {
257         TIME_HILOGE(TIME_MODULE_SERVICE, "Init database failed: %{public}d", initRet);
258         return initRet;
259     }
260     return OHOS::NativeRdb::E_OK;
261 }
262 
OnOpen(OHOS::NativeRdb::RdbStore & store)263 int TimeDBOpenCallback::OnOpen(OHOS::NativeRdb::RdbStore &store)
264 {
265     return OHOS::NativeRdb::E_OK;
266 }
267 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)268 int TimeDBOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
269 {
270     if (oldVersion < DATABASE_OPEN_VERSION_2 && newVersion >= DATABASE_OPEN_VERSION_2) {
271         int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_PID_COLUMN);
272         if (ret != OHOS::NativeRdb::E_OK) {
273             TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret);
274             return ret;
275         }
276         ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_PID_COLUMN);
277         if (ret != OHOS::NativeRdb::E_OK) {
278             TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret);
279             return ret;
280         }
281     }
282     if (oldVersion < DATABASE_OPEN_VERSION_3 && newVersion >= DATABASE_OPEN_VERSION_3) {
283         int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_NAME_COLUMN);
284         if (ret != OHOS::NativeRdb::E_OK) {
285             TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret);
286             return ret;
287         }
288         ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_NAME_COLUMN);
289         if (ret != OHOS::NativeRdb::E_OK) {
290             TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret);
291             return ret;
292         }
293     }
294     return OHOS::NativeRdb::E_OK;
295 }
296 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)297 int TimeDBOpenCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
298 {
299     return OHOS::NativeRdb::E_OK;
300 }
301 }
302 }