• 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 
16 #include "timer_database.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";
53 constexpr const char *DB_NAME = "/data/service/el1/public/database/time/time.db";
54 constexpr int DATABASE_OPEN_VERSION_2 = 2;
55 constexpr int DATABASE_OPEN_VERSION_3 = 3;
TimeDatabase()56 TimeDatabase::TimeDatabase()
57 {
58     int errCode = OHOS::NativeRdb::E_OK;
59     OHOS::NativeRdb::RdbStoreConfig config(DB_NAME);
60     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
61     config.SetEncryptStatus(false);
62     config.SetReadConSize(1);
63     TimeDBOpenCallback timeDBOpenCallback;
64     store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode);
65     TIME_HILOGI(TIME_MODULE_SERVICE, "Gets time database, ret: %{public}d", errCode);
66     if (errCode == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
67         auto ret = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(config);
68         if (ret != OHOS::NativeRdb::E_OK) {
69             TIME_HILOGE(TIME_MODULE_SERVICE, "delete corrupt database failed, ret: %{public}d", ret);
70             return;
71         }
72         store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode);
73     }
74 }
75 
GetInstance()76 TimeDatabase &TimeDatabase::GetInstance()
77 {
78     static TimeDatabase timeDatabase;
79     return timeDatabase;
80 }
81 
RecoverDataBase()82 bool TimeDatabase::RecoverDataBase()
83 {
84     OHOS::NativeRdb::RdbStoreConfig config(DB_NAME);
85     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
86     config.SetEncryptStatus(false);
87     config.SetReadConSize(1);
88     auto ret = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(config);
89     if (ret != OHOS::NativeRdb::E_OK) {
90         TIME_HILOGE(TIME_MODULE_SERVICE, "delete corrupt database failed, ret: %{public}d", ret);
91         return false;
92     }
93     TimeDBOpenCallback timeDbOpenCallback;
94     int errCode;
95     store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDbOpenCallback, errCode);
96     if (store_ == nullptr) {
97         return false;
98     }
99     return true;
100 }
101 
GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)102 int GetInt(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
103 {
104     int value = 0;
105     resultSet->GetInt(line, value);
106     return value;
107 }
108 
GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)109 int64_t GetLong(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
110 {
111     int64_t value = 0;
112     resultSet->GetLong(line, value);
113     return value;
114 }
115 
GetString(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet,int line)116 std::string GetString(std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet, int line)
117 {
118     std::string value = "";
119     resultSet->GetString(line, value);
120     return value;
121 }
122 
Insert(const std::string & table,const OHOS::NativeRdb::ValuesBucket & insertValues)123 bool TimeDatabase::Insert(const std::string &table, const OHOS::NativeRdb::ValuesBucket &insertValues)
124 {
125     auto store = store_;
126     if (store == nullptr) {
127         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
128         return false;
129     }
130 
131     int64_t outRowId = 0;
132     auto ret = store->Insert(outRowId, table, insertValues);
133     if (ret != OHOS::NativeRdb::E_OK) {
134         TIME_HILOGE(TIME_MODULE_SERVICE, "insert values failed, ret: %{public}d", ret);
135         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
136             return false;
137         }
138         if (!RecoverDataBase()) {
139             return false;
140         }
141         store = store_;
142         if (store == nullptr) {
143             TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
144             return false;
145         }
146         ret = store->Insert(outRowId, table, insertValues);
147         if (ret != OHOS::NativeRdb::E_OK) {
148             TIME_HILOGE(TIME_MODULE_SERVICE, "Insert values after RecoverDataBase failed, ret: %{public}d", ret);
149         }
150     }
151     return true;
152 }
153 
Update(const OHOS::NativeRdb::ValuesBucket values,const OHOS::NativeRdb::AbsRdbPredicates & predicates)154 bool TimeDatabase::Update(
155     const OHOS::NativeRdb::ValuesBucket values, const OHOS::NativeRdb::AbsRdbPredicates &predicates)
156 {
157     auto store = store_;
158     if (store == nullptr) {
159         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
160         return false;
161     }
162 
163     int changedRows = 0;
164     auto ret = store->Update(changedRows, values, predicates);
165     if (ret != OHOS::NativeRdb::E_OK) {
166         TIME_HILOGE(TIME_MODULE_SERVICE, "update values failed, ret: %{public}d", ret);
167         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
168             return false;
169         }
170         if (!RecoverDataBase()) {
171             return false;
172         }
173         store = store_;
174         if (store == nullptr) {
175             TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
176             return false;
177         }
178         ret = store->Update(changedRows, values, predicates);
179         if (ret != OHOS::NativeRdb::E_OK) {
180             TIME_HILOGE(TIME_MODULE_SERVICE, "Update values after RecoverDataBase failed, ret: %{public}d", ret);
181         }
182     }
183     return true;
184 }
185 
Query(const OHOS::NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns)186 std::shared_ptr<OHOS::NativeRdb::ResultSet> TimeDatabase::Query(
187     const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector<std::string> &columns)
188 {
189     auto store = store_;
190     if (store == nullptr) {
191         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
192         return nullptr;
193     }
194     auto result = store->Query(predicates, columns);
195     if (result == nullptr) {
196         TIME_HILOGE(TIME_MODULE_SERVICE, "result is nullptr");
197         return nullptr;
198     }
199     int count;
200     if (result->GetRowCount(count) == OHOS::NativeRdb::E_SQLITE_CORRUPT) {
201         RecoverDataBase();
202         result->Close();
203         return nullptr;
204     }
205     return result;
206 }
207 
Delete(const OHOS::NativeRdb::AbsRdbPredicates & predicates)208 bool TimeDatabase::Delete(const OHOS::NativeRdb::AbsRdbPredicates &predicates)
209 {
210     auto store = store_;
211     if (store == nullptr) {
212         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
213         return false;
214     }
215 
216     int deletedRows = 0;
217     auto ret = store->Delete(deletedRows, predicates);
218     if (ret != OHOS::NativeRdb::E_OK) {
219         TIME_HILOGE(TIME_MODULE_SERVICE, "delete values failed, ret: %{public}d", ret);
220         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
221             return false;
222         }
223         if (!RecoverDataBase()) {
224             return false;
225         }
226         store = store_;
227         if (store == nullptr) {
228             TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
229             return false;
230         }
231         ret = store->Delete(deletedRows, predicates);
232         if (ret != OHOS::NativeRdb::E_OK) {
233             TIME_HILOGE(TIME_MODULE_SERVICE, "Delete values after RecoverDataBase failed, ret: %{public}d", ret);
234         }
235     }
236     return true;
237 }
238 
ClearDropOnReboot()239 void TimeDatabase::ClearDropOnReboot()
240 {
241     TIME_HILOGI(TIME_MODULE_SERVICE, "Clears drop_on_reboot table");
242     auto store = store_;
243     if (store == nullptr) {
244         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
245         return;
246     }
247     auto ret = store->ExecuteSql("DELETE FROM drop_on_reboot");
248     if (ret != OHOS::NativeRdb::E_OK) {
249         TIME_HILOGE(TIME_MODULE_SERVICE, "Clears drop_on_reboot table failed");
250         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
251             return;
252         }
253         if (!RecoverDataBase()) {
254             return;
255         }
256         store = store_;
257         if (store == nullptr) {
258             TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
259             return;
260         }
261         ret = store->ExecuteSql("DELETE FROM drop_on_reboot");
262         if (ret != OHOS::NativeRdb::E_OK) {
263             TIME_HILOGE(TIME_MODULE_SERVICE, "Clears after RecoverDataBase failed, ret: %{public}d", ret);
264         }
265     }
266 }
267 
ClearInvaildDataInHoldOnReboot()268 void TimeDatabase::ClearInvaildDataInHoldOnReboot()
269 {
270     TIME_HILOGI(TIME_MODULE_SERVICE, "Clears hold_on_reboot table");
271     auto store = store_;
272     if (store == nullptr) {
273         TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
274         return;
275     }
276     auto ret = store->ExecuteSql("DELETE FROM hold_on_reboot WHERE state = 0 OR type = 2 OR type = 3");
277     if (ret != OHOS::NativeRdb::E_OK) {
278         TIME_HILOGE(TIME_MODULE_SERVICE, "Clears hold_on_reboot table failed");
279         if (ret != OHOS::NativeRdb::E_SQLITE_CORRUPT) {
280             return;
281         }
282         if (!RecoverDataBase()) {
283             return;
284         }
285         store = store_;
286         if (store == nullptr) {
287             TIME_HILOGE(TIME_MODULE_SERVICE, "store_ is nullptr");
288             return;
289         }
290         ret = store->ExecuteSql("DELETE FROM hold_on_reboot WHERE state = 0 OR type = 2 OR type = 3");
291         if (ret != OHOS::NativeRdb::E_OK) {
292             TIME_HILOGE(TIME_MODULE_SERVICE, "Clears after RecoverDataBase failed, ret: %{public}d", ret);
293         }
294     }
295 }
296 
TimeDBCreateTables(OHOS::NativeRdb::RdbStore & store)297 int TimeDBCreateTables(OHOS::NativeRdb::RdbStore &store)
298 {
299     TIME_HILOGI(TIME_MODULE_SERVICE, "Creates hold_on_reboot table");
300     // Creates hold_on_reboot table.
301     int ret = store.ExecuteSql(CREATE_TIME_TIMER_HOLD_ON_REBOOT);
302     if (ret != OHOS::NativeRdb::E_OK) {
303         TIME_HILOGE(TIME_MODULE_SERVICE, "Creates hold_on_reboot table failed, ret: %{public}d", ret);
304         return ret;
305     }
306 
307     TIME_HILOGI(TIME_MODULE_SERVICE, "Creates drop_on_reboot table");
308     // Creates drop_on_reboot table.
309     ret = store.ExecuteSql(CREATE_TIME_TIMER_DROP_ON_REBOOT);
310     if (ret != OHOS::NativeRdb::E_OK) {
311         TIME_HILOGE(TIME_MODULE_SERVICE, "Creates drop_on_reboot table failed, ret: %{public}d", ret);
312         return ret;
313     }
314     return ret;
315 }
316 
OnCreate(OHOS::NativeRdb::RdbStore & store)317 int TimeDBOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &store)
318 {
319     TIME_HILOGI(TIME_MODULE_SERVICE, "OnCreate");
320     auto initRet = TimeDBCreateTables(store);
321     if (initRet != OHOS::NativeRdb::E_OK) {
322         TIME_HILOGE(TIME_MODULE_SERVICE, "Init database failed: %{public}d", initRet);
323         return initRet;
324     }
325     return OHOS::NativeRdb::E_OK;
326 }
327 
OnOpen(OHOS::NativeRdb::RdbStore & store)328 int TimeDBOpenCallback::OnOpen(OHOS::NativeRdb::RdbStore &store)
329 {
330     return OHOS::NativeRdb::E_OK;
331 }
332 
OnUpgrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)333 int TimeDBOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
334 {
335     if (oldVersion < DATABASE_OPEN_VERSION_2 && newVersion >= DATABASE_OPEN_VERSION_2) {
336         int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_PID_COLUMN);
337         if (ret != OHOS::NativeRdb::E_OK) {
338             TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret);
339             return ret;
340         }
341         ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_PID_COLUMN);
342         if (ret != OHOS::NativeRdb::E_OK) {
343             TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret);
344             return ret;
345         }
346     }
347     if (oldVersion < DATABASE_OPEN_VERSION_3 && newVersion >= DATABASE_OPEN_VERSION_3) {
348         int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_NAME_COLUMN);
349         if (ret != OHOS::NativeRdb::E_OK) {
350             TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret);
351             return ret;
352         }
353         ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_NAME_COLUMN);
354         if (ret != OHOS::NativeRdb::E_OK) {
355             TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret);
356             return ret;
357         }
358     }
359     return OHOS::NativeRdb::E_OK;
360 }
361 
OnDowngrade(OHOS::NativeRdb::RdbStore & store,int oldVersion,int newVersion)362 int TimeDBOpenCallback::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion)
363 {
364     return OHOS::NativeRdb::E_OK;
365 }
366 }
367 }
368