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