1 /*
2 * Copyright (c) 2022-2024 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 "form_rdb_data_mgr.h"
16
17 #include <cinttypes>
18 #include <thread>
19 #include <filesystem>
20 #include <sstream>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include "fms_log_wrapper.h"
24 #include "form_constants.h"
25 #include "form_mgr_errors.h"
26 #include "form_util.h"
27 #include "scope_guard.h"
28 #include "form_event_report.h"
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 const std::string FORM_KEY = "KEY";
34 const std::string FORM_VALUE = "VALUE";
35 const int32_t FORM_KEY_INDEX = 0;
36 const int32_t FORM_VALUE_INDEX = 1;
37 const int64_t MIN_FORM_RDB_REBUILD_INTERVAL = 10000; // 10s
38 } // namespace
RdbStoreDataCallBackFormInfoStorage(const std::string &rdbPath)39 RdbStoreDataCallBackFormInfoStorage::RdbStoreDataCallBackFormInfoStorage(const std::string &rdbPath)
40 : rdbPath_(rdbPath)
41 {
42 HILOG_DEBUG("Create rdb store callback instance");
43 }
44
~RdbStoreDataCallBackFormInfoStorage()45 RdbStoreDataCallBackFormInfoStorage::~RdbStoreDataCallBackFormInfoStorage()
46 {
47 HILOG_DEBUG("Destroy rdb store callback instance");
48 }
49
OnCreate(NativeRdb::RdbStore &rdbStore)50 int32_t RdbStoreDataCallBackFormInfoStorage::OnCreate(NativeRdb::RdbStore &rdbStore)
51 {
52 HILOG_DEBUG("OnCreate");
53 return NativeRdb::E_OK;
54 }
55
OnUpgrade( NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)56 int32_t RdbStoreDataCallBackFormInfoStorage::OnUpgrade(
57 NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
58 {
59 HILOG_DEBUG("OnUpgrade currentVersion: %{plubic}d, targetVersion: %{plubic}d",
60 currentVersion, targetVersion);
61 return NativeRdb::E_OK;
62 }
63
OnDowngrade( NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)64 int32_t RdbStoreDataCallBackFormInfoStorage::OnDowngrade(
65 NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
66 {
67 HILOG_DEBUG("OnDowngrade currentVersion: %{plubic}d, targetVersion: %{plubic}d",
68 currentVersion, targetVersion);
69 return NativeRdb::E_OK;
70 }
71
OnOpen(NativeRdb::RdbStore &rdbStore)72 int32_t RdbStoreDataCallBackFormInfoStorage::OnOpen(NativeRdb::RdbStore &rdbStore)
73 {
74 HILOG_DEBUG("OnOpen");
75 return NativeRdb::E_OK;
76 }
77
onCorruption(std::string databaseFile)78 int32_t RdbStoreDataCallBackFormInfoStorage::onCorruption(std::string databaseFile)
79 {
80 FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
81 static_cast<int64_t>(CallDbFiledErrorType::DATABASE_EXIT_ABNORMA));
82 return NativeRdb::E_OK;
83 }
84
FormRdbDataMgr()85 FormRdbDataMgr::FormRdbDataMgr()
86 {
87 HILOG_INFO("Create");
88 }
89
~FormRdbDataMgr()90 FormRdbDataMgr::~FormRdbDataMgr()
91 {
92 HILOG_INFO("Destruct");
93 }
94
InitFormRdbTable(const FormRdbTableConfig &formRdbTableConfig)95 ErrCode FormRdbDataMgr::InitFormRdbTable(const FormRdbTableConfig &formRdbTableConfig)
96 {
97 HILOG_INFO("Init");
98 if (formRdbTableConfig.tableName.empty()) {
99 HILOG_ERROR("empty FormRdbTableName");
100 return ERR_APPEXECFWK_FORM_COMMON_CODE;
101 }
102
103 auto formRdbTableCfgIter = formRdbTableCfgMap_.find(formRdbTableConfig.tableName);
104 if (formRdbTableCfgIter != formRdbTableCfgMap_.end()) {
105 formRdbTableCfgMap_[formRdbTableConfig.tableName] = formRdbTableConfig;
106 } else {
107 formRdbTableCfgMap_.emplace(formRdbTableConfig.tableName, formRdbTableConfig);
108 }
109
110 if (rdbStore_ == nullptr && LoadRdbStore() != ERR_OK) {
111 HILOG_ERROR("null FormInfoRdbStore");
112 return ERR_APPEXECFWK_FORM_COMMON_CODE;
113 }
114
115 std::string createTableSql = !formRdbTableConfig.createTableSql.empty() ? formRdbTableConfig.createTableSql
116 : "CREATE TABLE IF NOT EXISTS " + formRdbTableConfig.tableName
117 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
118 int32_t ret = NativeRdb::E_OK;
119 {
120 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
121 ret = rdbStore_->ExecuteSql(createTableSql);
122 }
123
124 if (ret != NativeRdb::E_OK) {
125 HILOG_ERROR("Create rdb table failed, ret:%{public}" PRId32 "", ret);
126 return ERR_APPEXECFWK_FORM_COMMON_CODE;
127 }
128
129 return ERR_OK;
130 }
131
ExecuteSql(const std::string &sql)132 ErrCode FormRdbDataMgr::ExecuteSql(const std::string &sql)
133 {
134 if (!IsFormRdbLoaded()) {
135 HILOG_ERROR("null FormInfoRdbStore");
136 return ERR_APPEXECFWK_FORM_COMMON_CODE;
137 }
138
139 int32_t ret = NativeRdb::E_OK;
140 {
141 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
142 ret = rdbStore_->ExecuteSql(sql);
143 }
144
145 if (ret == NativeRdb::E_OK) {
146 if (rdbStore_->IsSlaveDiffFromMaster()) {
147 auto backupRet = rdbStore_->Backup("");
148 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
149 }
150 } else {
151 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
152 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
153 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
154 ret = rdbStore_->ExecuteSql(sql);
155 }
156 }
157
158 if (ret == NativeRdb::E_OK) {
159 return ERR_OK;
160 }
161
162 HILOG_WARN("ExecuteSql failed, ret=%{public}" PRId32, ret);
163 return ERR_APPEXECFWK_FORM_COMMON_CODE;
164 }
165
InsertData(const std::string &tableName, const std::string &key)166 ErrCode FormRdbDataMgr::InsertData(const std::string &tableName, const std::string &key)
167 {
168 HILOG_DEBUG("InsertData start");
169 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
170 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
171 return ERR_APPEXECFWK_FORM_COMMON_CODE;
172 }
173
174 if (!IsFormRdbLoaded()) {
175 HILOG_ERROR("null FormInfoRdbStore");
176 return ERR_APPEXECFWK_FORM_COMMON_CODE;
177 }
178
179 NativeRdb::ValuesBucket valuesBucket;
180 valuesBucket.PutString(FORM_KEY, key);
181 int32_t ret = NativeRdb::E_OK;
182 {
183 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
184 int64_t rowId = -1;
185 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
186 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
187 }
188
189 if (ret == NativeRdb::E_OK) {
190 if (rdbStore_->IsSlaveDiffFromMaster()) {
191 auto backupRet = rdbStore_->Backup("");
192 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
193 }
194 } else {
195 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
196 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
197 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
198 int64_t rowId = -1;
199 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
200 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
201 }
202 }
203
204 if (ret == NativeRdb::E_OK) {
205 return ERR_OK;
206 }
207 HILOG_WARN("Insert operation failed, key=%{public}s, ret=%{public}" PRId32, key.c_str(), ret);
208 return ERR_APPEXECFWK_FORM_COMMON_CODE;
209 }
210
InsertData(const std::string &tableName, const std::string &key, const std::string &value)211 ErrCode FormRdbDataMgr::InsertData(const std::string &tableName, const std::string &key, const std::string &value)
212 {
213 HILOG_DEBUG("InsertData start");
214 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
215 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
216 return ERR_APPEXECFWK_FORM_COMMON_CODE;
217 }
218
219 if (!IsFormRdbLoaded()) {
220 HILOG_ERROR("null FormInfoRdbStore");
221 return ERR_APPEXECFWK_FORM_COMMON_CODE;
222 }
223
224 NativeRdb::ValuesBucket valuesBucket;
225 valuesBucket.PutString(FORM_KEY, key);
226 valuesBucket.PutString(FORM_VALUE, value);
227 int32_t ret = NativeRdb::E_OK;
228 {
229 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
230 int64_t rowId = -1;
231 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
232 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
233 }
234
235 if (ret == NativeRdb::E_OK) {
236 if (rdbStore_->IsSlaveDiffFromMaster()) {
237 auto backupRet = rdbStore_->Backup("");
238 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
239 }
240 } else {
241 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
242 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
243 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
244 int64_t rowId = -1;
245 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
246 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
247 }
248 }
249
250 if (ret == NativeRdb::E_OK) {
251 return ERR_OK;
252 }
253
254 HILOG_WARN("Insert operation failed, key=%{public}s, ret=%{public}" PRId32, key.c_str(), ret);
255 return ERR_APPEXECFWK_FORM_COMMON_CODE;
256 }
257
DeleteData(const std::string &tableName, const std::string &key)258 ErrCode FormRdbDataMgr::DeleteData(const std::string &tableName, const std::string &key)
259 {
260 HILOG_DEBUG("DeleteData start");
261 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
262 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
263 return ERR_APPEXECFWK_FORM_COMMON_CODE;
264 }
265
266 if (!IsFormRdbLoaded()) {
267 HILOG_ERROR("null FormInfoRdbStore");
268 return ERR_APPEXECFWK_FORM_COMMON_CODE;
269 }
270
271 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
272 absRdbPredicates.EqualTo(FORM_KEY, key);
273 int32_t ret = NativeRdb::E_OK;
274 {
275 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
276 int32_t rowId = -1;
277 ret = rdbStore_->Delete(rowId, absRdbPredicates);
278 }
279
280 if (ret == NativeRdb::E_OK) {
281 if (rdbStore_->IsSlaveDiffFromMaster()) {
282 auto backupRet = rdbStore_->Backup("");
283 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
284 }
285 } else {
286 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
287 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
288 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
289 int32_t rowId = -1;
290 ret = rdbStore_->Delete(rowId, absRdbPredicates);
291 }
292 }
293
294 if (ret == NativeRdb::E_OK) {
295 return ERR_OK;
296 }
297
298 HILOG_WARN("Delete operation failed, key=%{public}s, ret=%{public}" PRId32, key.c_str(), ret);
299 return ERR_APPEXECFWK_FORM_COMMON_CODE;
300 }
301
QueryData(const std::string &tableName, const std::string &key, std::string &value)302 ErrCode FormRdbDataMgr::QueryData(const std::string &tableName, const std::string &key,
303 std::string &value)
304 {
305 HILOG_DEBUG("QueryData start");
306 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
307 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
308 return ERR_APPEXECFWK_FORM_COMMON_CODE;
309 }
310
311 if (!IsFormRdbLoaded()) {
312 HILOG_ERROR("null FormInfoRdbStore");
313 return ERR_APPEXECFWK_FORM_COMMON_CODE;
314 }
315
316 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
317 absRdbPredicates.EqualTo(FORM_KEY, key);
318 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
319 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
320 guard.unlock();
321
322 if (absSharedResultSet == nullptr) {
323 HILOG_ERROR("null absSharedResultSet");
324 return ERR_APPEXECFWK_FORM_COMMON_CODE;
325 }
326
327 ScopeGuard stateGuard([absSharedResultSet] {
328 if (absSharedResultSet) {
329 absSharedResultSet->Close();
330 }
331 });
332 if (!absSharedResultSet->HasBlock()) {
333 HILOG_ERROR("absSharedResultSet has no block");
334 return ERR_APPEXECFWK_FORM_COMMON_CODE;
335 }
336 int32_t ret = absSharedResultSet->GoToFirstRow();
337 if (ret != NativeRdb::E_OK) {
338 HILOG_ERROR("GoToFirstRow failed, ret:%{public}" PRId32 "", ret);
339 } else {
340 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, value);
341 }
342 absSharedResultSet->Close();
343
344 if (ret == NativeRdb::E_OK) {
345 return ERR_OK;
346 }
347
348 HILOG_WARN("Query operation failed, key=%{public}s", key.c_str());
349 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
350 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
351 }
352 return ERR_APPEXECFWK_FORM_COMMON_CODE;
353 }
354
QueryData(const std::string &tableName, const std::string &key, std::unordered_map<std::string, std::string> &values)355 ErrCode FormRdbDataMgr::QueryData(const std::string &tableName, const std::string &key,
356 std::unordered_map<std::string, std::string> &values)
357 {
358 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
359 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
360 return ERR_APPEXECFWK_FORM_COMMON_CODE;
361 }
362
363 if (!IsFormRdbLoaded()) {
364 HILOG_ERROR("null FormInfoRdbStore");
365 return ERR_APPEXECFWK_FORM_COMMON_CODE;
366 }
367
368 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
369 absRdbPredicates.BeginsWith(FORM_KEY, key);
370 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
371 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
372 guard.unlock();
373 if (absSharedResultSet == nullptr) {
374 HILOG_ERROR("null absSharedResultSet");
375 return ERR_APPEXECFWK_FORM_COMMON_CODE;
376 }
377
378 ScopeGuard stateGuard([absSharedResultSet] {
379 if (absSharedResultSet) {
380 absSharedResultSet->Close();
381 }
382 });
383
384 if (!absSharedResultSet->HasBlock()) {
385 HILOG_ERROR("absSharedResultSet has no block");
386 return ERR_APPEXECFWK_FORM_COMMON_CODE;
387 }
388
389 int32_t ret = absSharedResultSet->GoToFirstRow();
390 if (ret == NativeRdb::E_OK) {
391 do {
392 std::string resultKey;
393 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
394 if (ret != NativeRdb::E_OK) {
395 HILOG_ERROR("GetString key failed");
396 break;
397 }
398
399 std::string resultValue;
400 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, resultValue);
401 if (ret != NativeRdb::E_OK) {
402 HILOG_ERROR("GetString value failed");
403 break;
404 }
405
406 values.emplace(resultKey, resultValue);
407 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
408 }
409 absSharedResultSet->Close();
410 if (ret == NativeRdb::E_OK) {
411 return ERR_OK;
412 }
413
414 HILOG_WARN("Query operation failed, key=%{public}s", key.c_str());
415 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
416 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
417 }
418 return ERR_APPEXECFWK_FORM_COMMON_CODE;
419 }
420
QueryAllData(const std::string &tableName, std::unordered_map<std::string, std::string> &datas)421 ErrCode FormRdbDataMgr::QueryAllData(const std::string &tableName,
422 std::unordered_map<std::string, std::string> &datas)
423 {
424 HILOG_DEBUG("QueryAllData start");
425 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
426 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
427 return ERR_APPEXECFWK_FORM_COMMON_CODE;
428 }
429
430 if (!IsFormRdbLoaded()) {
431 HILOG_ERROR("null FormInfoRdbStore");
432 return ERR_APPEXECFWK_FORM_COMMON_CODE;
433 }
434
435 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
436 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
437 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
438 guard.unlock();
439 if (absSharedResultSet == nullptr) {
440 HILOG_ERROR("null absSharedResultSet");
441 return ERR_APPEXECFWK_FORM_COMMON_CODE;
442 }
443
444 ScopeGuard stateGuard([absSharedResultSet] {
445 if (absSharedResultSet) {
446 absSharedResultSet->Close();
447 }
448 });
449 if (!absSharedResultSet->HasBlock()) {
450 HILOG_ERROR("absSharedResultSet has no block");
451 return ERR_APPEXECFWK_FORM_COMMON_CODE;
452 }
453
454 int32_t ret = absSharedResultSet->GoToFirstRow();
455 if (ret == NativeRdb::E_OK) {
456 do {
457 std::string resultKey;
458 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
459 if (ret != NativeRdb::E_OK) {
460 HILOG_ERROR("GetString key failed");
461 break;
462 }
463
464 std::string resultValue;
465 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, resultValue);
466 if (ret != NativeRdb::E_OK) {
467 HILOG_ERROR("GetString value failed");
468 break;
469 }
470
471 datas.emplace(resultKey, resultValue);
472 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
473 }
474 absSharedResultSet->Close();
475
476 if (ret == NativeRdb::E_OK) {
477 return ERR_OK;
478 }
479
480 HILOG_WARN("Query all data operation failed");
481 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
482 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
483 }
484 return ERR_APPEXECFWK_FORM_COMMON_CODE;
485 }
486
QueryAllKeys(const std::string &tableName, std::set<std::string> &datas)487 ErrCode FormRdbDataMgr::QueryAllKeys(const std::string &tableName, std::set<std::string> &datas)
488 {
489 HILOG_DEBUG("QueryAllKeys start");
490 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
491 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
492 return ERR_APPEXECFWK_FORM_COMMON_CODE;
493 }
494
495 if (!IsFormRdbLoaded()) {
496 HILOG_ERROR("null FormInfoRdbStore");
497 return ERR_APPEXECFWK_FORM_COMMON_CODE;
498 }
499
500 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
501 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
502 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
503 guard.unlock();
504 if (absSharedResultSet == nullptr) {
505 HILOG_ERROR("null absSharedResultSet");
506 return ERR_APPEXECFWK_FORM_COMMON_CODE;
507 }
508
509 ScopeGuard stateGuard([absSharedResultSet] {
510 if (absSharedResultSet) {
511 absSharedResultSet->Close();
512 }
513 });
514
515 if (!absSharedResultSet->HasBlock()) {
516 HILOG_ERROR("HasBlock failed");
517 return ERR_APPEXECFWK_FORM_COMMON_CODE;
518 }
519 int32_t ret = absSharedResultSet->GoToFirstRow();
520 if (ret == NativeRdb::E_OK) {
521 do {
522 std::string resultKey;
523 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
524 if (ret != NativeRdb::E_OK) {
525 HILOG_ERROR("GetString key failed");
526 break;
527 }
528 datas.insert(resultKey);
529 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
530 }
531 absSharedResultSet->Close();
532
533 if (ret == NativeRdb::E_OK) {
534 return ERR_OK;
535 }
536
537 HILOG_WARN("Query all keys operation failed");
538 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
539 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
540 }
541 return ERR_APPEXECFWK_FORM_COMMON_CODE;
542 }
543
QueryData( const NativeRdb::AbsRdbPredicates &absRdbPredicates)544 std::shared_ptr<NativeRdb::AbsSharedResultSet> FormRdbDataMgr::QueryData(
545 const NativeRdb::AbsRdbPredicates &absRdbPredicates)
546 {
547 HILOG_DEBUG("QueryData start");
548 if (!IsFormRdbLoaded()) {
549 HILOG_ERROR("null FormInfoRdbStore");
550 return nullptr;
551 }
552
553 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
554 return rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
555 }
556
QuerySql(const std::string &sql)557 std::shared_ptr<NativeRdb::AbsSharedResultSet> FormRdbDataMgr::QuerySql(const std::string &sql)
558 {
559 HILOG_DEBUG("QuerySql start");
560 if (!IsFormRdbLoaded()) {
561 HILOG_ERROR("null FormInfoRdbStore");
562 return nullptr;
563 }
564
565 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
566 return rdbStore_->QuerySql(sql, std::vector<std::string>());
567 }
568
InsertData( const std::string &tableName, const NativeRdb::ValuesBucket &valuesBucket, int64_t &rowId)569 bool FormRdbDataMgr::InsertData(
570 const std::string &tableName, const NativeRdb::ValuesBucket &valuesBucket, int64_t &rowId)
571 {
572 HILOG_DEBUG("InsertData start");
573 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
574 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
575 return false;
576 }
577
578 if (!IsFormRdbLoaded()) {
579 HILOG_ERROR("null FormInfoRdbStore");
580 return false;
581 }
582
583 int32_t ret = NativeRdb::E_OK;
584 {
585 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
586 ret = rdbStore_->InsertWithConflictResolution(
587 rowId, tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
588 }
589
590 if (ret == NativeRdb::E_OK) {
591 if (rdbStore_->IsSlaveDiffFromMaster()) {
592 auto backupRet = rdbStore_->Backup("");
593 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
594 }
595 } else {
596 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
597 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
598 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
599 ret = rdbStore_->InsertWithConflictResolution(
600 rowId, tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
601 }
602 }
603
604 if (ret == NativeRdb::E_OK) {
605 return true;
606 }
607
608 HILOG_WARN("Insert operation failed, ret=%{public}" PRId32, ret);
609 return false;
610 }
611
DeleteData(const NativeRdb::AbsRdbPredicates &absRdbPredicates)612 bool FormRdbDataMgr::DeleteData(const NativeRdb::AbsRdbPredicates &absRdbPredicates)
613 {
614 if (!IsFormRdbLoaded()) {
615 HILOG_ERROR("null FormInfoRdbStore");
616 return false;
617 }
618
619 int32_t ret = NativeRdb::E_OK;
620 {
621 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
622 int32_t rowId = -1;
623 ret = rdbStore_->Delete(rowId, absRdbPredicates);
624 }
625
626 if (ret == NativeRdb::E_OK) {
627 if (rdbStore_->IsSlaveDiffFromMaster()) {
628 auto backupRet = rdbStore_->Backup("");
629 HILOG_WARN("rdb slave corrupt, backup from master, ret=%{public}" PRId32, backupRet);
630 }
631 } else {
632 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
633 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
634 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
635 int32_t rowId = -1;
636 ret = rdbStore_->Delete(rowId, absRdbPredicates);
637 }
638 }
639
640 if (ret == NativeRdb::E_OK) {
641 return true;
642 }
643
644 HILOG_WARN("Delete operation failed, ret=%{public}" PRId32, ret);
645 return false;
646 }
647
IsFormRdbLoaded()648 bool FormRdbDataMgr::IsFormRdbLoaded()
649 {
650 std::unique_lock<std::shared_mutex> guard(rdbStoreMutex_);
651 if (rdbStore_ != nullptr) {
652 return true;
653 }
654
655 HILOG_WARN("null Rdb, need to reload");
656 if (LoadRdbStore() != ERR_OK) {
657 HILOG_ERROR("Load rdb failed");
658 return false;
659 }
660
661 for (auto iter = formRdbTableCfgMap_.begin(); iter != formRdbTableCfgMap_.end(); iter++) {
662 std::string createTableSql = !iter->second.createTableSql.empty() ? iter->second.createTableSql
663 : "CREATE TABLE IF NOT EXISTS " + iter->second.tableName
664 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
665 int32_t ret = rdbStore_->ExecuteSql(createTableSql);
666 if (ret != NativeRdb::E_OK) {
667 HILOG_ERROR("Recreate form rdb table failed, ret:%{public}" PRId32 ", name is %{public}s",
668 ret, iter->first.c_str());
669 }
670 }
671 return true;
672 }
673
CheckAndRebuildRdbStore(int32_t rdbOperateRet)674 ErrCode FormRdbDataMgr::CheckAndRebuildRdbStore(int32_t rdbOperateRet)
675 {
676 if (rdbOperateRet != NativeRdb::E_SQLITE_CORRUPT) {
677 HILOG_INFO("errorCode:%{public}" PRId32, rdbOperateRet);
678 return ERR_APPEXECFWK_FORM_COMMON_CODE;
679 }
680
681 std::unique_lock<std::shared_mutex> guard(rdbStoreMutex_);
682 int64_t curTime = FormUtil::GetCurrentMillisecond();
683 if ((curTime - lastRdbBuildTime_) <= MIN_FORM_RDB_REBUILD_INTERVAL) {
684 return ERR_APPEXECFWK_FORM_RDB_REPEATED_BUILD;
685 }
686
687 auto restoreRet = rdbStore_->Restore("");
688 if (restoreRet == NativeRdb::E_OK) {
689 HILOG_INFO("Restore rdb succeeded");
690 } else {
691 HILOG_WARN("Restore rdb failed, errorCode:%{public}" PRId32, restoreRet);
692 }
693
694 ErrCode ret = LoadRdbStore();
695 if (ret != ERR_OK) {
696 HILOG_ERROR("Reload form rdb failed, ret:%{public}" PRId32 ".", ret);
697 return ERR_APPEXECFWK_FORM_COMMON_CODE;
698 }
699 lastRdbBuildTime_ = curTime;
700
701 if (restoreRet != NativeRdb::E_OK) {
702 //fallback restoration if Restore() did not work
703 for (auto iter = formRdbTableCfgMap_.begin(); iter != formRdbTableCfgMap_.end(); iter++) {
704 std::string createTableSql = !iter->second.createTableSql.empty() ? iter->second.createTableSql
705 : "CREATE TABLE IF NOT EXISTS " + iter->second.tableName
706 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
707 int32_t result = rdbStore_->ExecuteSql(createTableSql);
708 if (result != NativeRdb::E_OK) {
709 HILOG_ERROR("Recreate form rdb table failed, ret:%{public}" PRId32 ", name is %{public}s",
710 result, iter->first.c_str());
711 }
712 }
713 }
714 return ERR_OK;
715 }
716
LoadRdbStore()717 ErrCode FormRdbDataMgr::LoadRdbStore()
718 {
719 std::string rdbPath = Constants::FORM_MANAGER_SERVICE_PATH + Constants::FORM_RDB_NAME;
720 NativeRdb::RdbStoreConfig rdbStoreConfig(
721 rdbPath,
722 NativeRdb::StorageMode::MODE_DISK,
723 false,
724 std::vector<uint8_t>(),
725 Constants::FORM_JOURNAL_MODE,
726 Constants::FORM_SYNC_MODE,
727 "",
728 NativeRdb::SecurityLevel::S1);
729 rdbStoreConfig.SetAllowRebuild(true);
730 rdbStoreConfig.SetHaMode(NativeRdb::HAMode::MAIN_REPLICA);
731 int32_t errCode = NativeRdb::E_OK;
732 RdbStoreDataCallBackFormInfoStorage rdbDataCallBack_(rdbPath);
733
734 rdbStore_ = nullptr;
735 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, Constants::FORM_RDB_VERSION,
736 rdbDataCallBack_, errCode);
737 if (errCode != NativeRdb::E_OK) {
738 HILOG_ERROR("Form rdb store init fail, err code is %{public}" PRId32 "", errCode);
739 FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
740 static_cast<int64_t>(CallDbFiledErrorType::DATABASE_RESET_CONNECT_FAILED));
741 rdbStore_ = nullptr;
742 return ERR_APPEXECFWK_FORM_COMMON_CODE;
743 }
744 return ERR_OK;
745 }
746 } // namespace AppExecFwk
747 } // namespace OHOS