1 /*
2 * Copyright (c) 2022-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 "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 return ERR_OK;
147 }
148
149 HILOG_WARN("ExecuteSql failed");
150 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
151 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
152 }
153 return ERR_APPEXECFWK_FORM_COMMON_CODE;
154 }
155
InsertData(const std::string & tableName,const std::string & key)156 ErrCode FormRdbDataMgr::InsertData(const std::string &tableName, const std::string &key)
157 {
158 HILOG_DEBUG("InsertData start");
159 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
160 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
161 return ERR_APPEXECFWK_FORM_COMMON_CODE;
162 }
163
164 if (!IsFormRdbLoaded()) {
165 HILOG_ERROR("null FormInfoRdbStore");
166 return ERR_APPEXECFWK_FORM_COMMON_CODE;
167 }
168
169 NativeRdb::ValuesBucket valuesBucket;
170 valuesBucket.PutString(FORM_KEY, key);
171 int32_t ret = NativeRdb::E_OK;
172 {
173 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
174 int64_t rowId = -1;
175 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
176 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
177 }
178 if (ret == NativeRdb::E_OK) {
179 return ERR_OK;
180 }
181
182 HILOG_WARN("Insert operation failed, key=%{public}s", key.c_str());
183 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
184 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
185 }
186 return ERR_APPEXECFWK_FORM_COMMON_CODE;
187 }
188
InsertData(const std::string & tableName,const std::string & key,const std::string & value)189 ErrCode FormRdbDataMgr::InsertData(const std::string &tableName, const std::string &key, const std::string &value)
190 {
191 HILOG_DEBUG("InsertData start");
192 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
193 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
194 return ERR_APPEXECFWK_FORM_COMMON_CODE;
195 }
196
197 if (!IsFormRdbLoaded()) {
198 HILOG_ERROR("null FormInfoRdbStore");
199 return ERR_APPEXECFWK_FORM_COMMON_CODE;
200 }
201
202 NativeRdb::ValuesBucket valuesBucket;
203 valuesBucket.PutString(FORM_KEY, key);
204 valuesBucket.PutString(FORM_VALUE, value);
205 int32_t ret = NativeRdb::E_OK;
206 {
207 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
208 int64_t rowId = -1;
209 ret = rdbStore_->InsertWithConflictResolution(rowId, tableName, valuesBucket,
210 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
211 }
212
213 if (ret == NativeRdb::E_OK) {
214 return ERR_OK;
215 }
216
217 HILOG_WARN("Insert operation failed, key=%{public}s", key.c_str());
218 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
219 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
220 }
221 return ERR_APPEXECFWK_FORM_COMMON_CODE;
222 }
223
DeleteData(const std::string & tableName,const std::string & key)224 ErrCode FormRdbDataMgr::DeleteData(const std::string &tableName, const std::string &key)
225 {
226 HILOG_DEBUG("DeleteData start");
227 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
228 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
229 return ERR_APPEXECFWK_FORM_COMMON_CODE;
230 }
231
232 if (!IsFormRdbLoaded()) {
233 HILOG_ERROR("null FormInfoRdbStore");
234 return ERR_APPEXECFWK_FORM_COMMON_CODE;
235 }
236
237 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
238 absRdbPredicates.EqualTo(FORM_KEY, key);
239 int32_t ret = NativeRdb::E_OK;
240 {
241 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
242 int32_t rowId = -1;
243 ret = rdbStore_->Delete(rowId, absRdbPredicates);
244 }
245
246 if (ret == NativeRdb::E_OK) {
247 return ERR_OK;
248 }
249
250 HILOG_WARN("Delete operation failed, key=%{public}s", key.c_str());
251 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
252 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
253 return ERR_OK;
254 }
255 return ERR_APPEXECFWK_FORM_COMMON_CODE;
256 }
257
QueryData(const std::string & tableName,const std::string & key,std::string & value)258 ErrCode FormRdbDataMgr::QueryData(const std::string &tableName, const std::string &key,
259 std::string &value)
260 {
261 HILOG_DEBUG("QueryData start");
262 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
263 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
264 return ERR_APPEXECFWK_FORM_COMMON_CODE;
265 }
266
267 if (!IsFormRdbLoaded()) {
268 HILOG_ERROR("null FormInfoRdbStore");
269 return ERR_APPEXECFWK_FORM_COMMON_CODE;
270 }
271
272 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
273 absRdbPredicates.EqualTo(FORM_KEY, key);
274 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
275 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
276 guard.unlock();
277
278 if (absSharedResultSet == nullptr) {
279 HILOG_ERROR("null absSharedResultSet");
280 return ERR_APPEXECFWK_FORM_COMMON_CODE;
281 }
282
283 ScopeGuard stateGuard([absSharedResultSet] {
284 if (absSharedResultSet) {
285 absSharedResultSet->Close();
286 }
287 });
288 if (!absSharedResultSet->HasBlock()) {
289 HILOG_ERROR("absSharedResultSet has no block");
290 return ERR_APPEXECFWK_FORM_COMMON_CODE;
291 }
292 int32_t ret = absSharedResultSet->GoToFirstRow();
293 if (ret != NativeRdb::E_OK) {
294 HILOG_ERROR("GoToFirstRow failed, ret:%{public}" PRId32 "", ret);
295 } else {
296 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, value);
297 }
298 absSharedResultSet->Close();
299
300 if (ret == NativeRdb::E_OK) {
301 return ERR_OK;
302 }
303
304 HILOG_WARN("Query operation failed, key=%{public}s", key.c_str());
305 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
306 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
307 }
308 return ERR_APPEXECFWK_FORM_COMMON_CODE;
309 }
310
QueryData(const std::string & tableName,const std::string & key,std::unordered_map<std::string,std::string> & values)311 ErrCode FormRdbDataMgr::QueryData(const std::string &tableName, const std::string &key,
312 std::unordered_map<std::string, std::string> &values)
313 {
314 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
315 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
316 return ERR_APPEXECFWK_FORM_COMMON_CODE;
317 }
318
319 if (!IsFormRdbLoaded()) {
320 HILOG_ERROR("null FormInfoRdbStore");
321 return ERR_APPEXECFWK_FORM_COMMON_CODE;
322 }
323
324 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
325 absRdbPredicates.BeginsWith(FORM_KEY, key);
326 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
327 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
328 guard.unlock();
329 if (absSharedResultSet == nullptr) {
330 HILOG_ERROR("null absSharedResultSet");
331 return ERR_APPEXECFWK_FORM_COMMON_CODE;
332 }
333
334 ScopeGuard stateGuard([absSharedResultSet] {
335 if (absSharedResultSet) {
336 absSharedResultSet->Close();
337 }
338 });
339
340 if (!absSharedResultSet->HasBlock()) {
341 HILOG_ERROR("absSharedResultSet has no block");
342 return ERR_APPEXECFWK_FORM_COMMON_CODE;
343 }
344
345 int32_t ret = absSharedResultSet->GoToFirstRow();
346 if (ret == NativeRdb::E_OK) {
347 do {
348 std::string resultKey;
349 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
350 if (ret != NativeRdb::E_OK) {
351 HILOG_ERROR("GetString key failed");
352 break;
353 }
354
355 std::string resultValue;
356 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, resultValue);
357 if (ret != NativeRdb::E_OK) {
358 HILOG_ERROR("GetString value failed");
359 break;
360 }
361
362 values.emplace(resultKey, resultValue);
363 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
364 }
365 absSharedResultSet->Close();
366 if (ret == NativeRdb::E_OK) {
367 return ERR_OK;
368 }
369
370 HILOG_WARN("Query operation failed, key=%{public}s", key.c_str());
371 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
372 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
373 }
374 return ERR_APPEXECFWK_FORM_COMMON_CODE;
375 }
376
QueryAllData(const std::string & tableName,std::unordered_map<std::string,std::string> & datas)377 ErrCode FormRdbDataMgr::QueryAllData(const std::string &tableName,
378 std::unordered_map<std::string, std::string> &datas)
379 {
380 HILOG_DEBUG("QueryAllData start");
381 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
382 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
383 return ERR_APPEXECFWK_FORM_COMMON_CODE;
384 }
385
386 if (!IsFormRdbLoaded()) {
387 HILOG_ERROR("null FormInfoRdbStore");
388 return ERR_APPEXECFWK_FORM_COMMON_CODE;
389 }
390
391 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
392 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
393 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
394 guard.unlock();
395 if (absSharedResultSet == nullptr) {
396 HILOG_ERROR("null absSharedResultSet");
397 return ERR_APPEXECFWK_FORM_COMMON_CODE;
398 }
399
400 ScopeGuard stateGuard([absSharedResultSet] {
401 if (absSharedResultSet) {
402 absSharedResultSet->Close();
403 }
404 });
405 if (!absSharedResultSet->HasBlock()) {
406 HILOG_ERROR("absSharedResultSet has no block");
407 return ERR_APPEXECFWK_FORM_COMMON_CODE;
408 }
409
410 int32_t ret = absSharedResultSet->GoToFirstRow();
411 if (ret == NativeRdb::E_OK) {
412 do {
413 std::string resultKey;
414 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
415 if (ret != NativeRdb::E_OK) {
416 HILOG_ERROR("GetString key failed");
417 break;
418 }
419
420 std::string resultValue;
421 ret = absSharedResultSet->GetString(FORM_VALUE_INDEX, resultValue);
422 if (ret != NativeRdb::E_OK) {
423 HILOG_ERROR("GetString value failed");
424 break;
425 }
426
427 datas.emplace(resultKey, resultValue);
428 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
429 }
430 absSharedResultSet->Close();
431
432 if (ret == NativeRdb::E_OK) {
433 return ERR_OK;
434 }
435
436 HILOG_WARN("Query all data operation failed");
437 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
438 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
439 }
440 return ERR_APPEXECFWK_FORM_COMMON_CODE;
441 }
442
QueryAllKeys(const std::string & tableName,std::set<std::string> & datas)443 ErrCode FormRdbDataMgr::QueryAllKeys(const std::string &tableName, std::set<std::string> &datas)
444 {
445 HILOG_DEBUG("QueryAllKeys start");
446 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
447 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
448 return ERR_APPEXECFWK_FORM_COMMON_CODE;
449 }
450
451 if (!IsFormRdbLoaded()) {
452 HILOG_ERROR("null FormInfoRdbStore");
453 return ERR_APPEXECFWK_FORM_COMMON_CODE;
454 }
455
456 NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
457 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
458 auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
459 guard.unlock();
460 if (absSharedResultSet == nullptr) {
461 HILOG_ERROR("null absSharedResultSet");
462 return ERR_APPEXECFWK_FORM_COMMON_CODE;
463 }
464
465 ScopeGuard stateGuard([absSharedResultSet] {
466 if (absSharedResultSet) {
467 absSharedResultSet->Close();
468 }
469 });
470
471 if (!absSharedResultSet->HasBlock()) {
472 HILOG_ERROR("HasBlock failed");
473 return ERR_APPEXECFWK_FORM_COMMON_CODE;
474 }
475 int32_t ret = absSharedResultSet->GoToFirstRow();
476 if (ret == NativeRdb::E_OK) {
477 do {
478 std::string resultKey;
479 ret = absSharedResultSet->GetString(FORM_KEY_INDEX, resultKey);
480 if (ret != NativeRdb::E_OK) {
481 HILOG_ERROR("GetString key failed");
482 break;
483 }
484 datas.insert(resultKey);
485 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
486 }
487 absSharedResultSet->Close();
488
489 if (ret == NativeRdb::E_OK) {
490 return ERR_OK;
491 }
492
493 HILOG_WARN("Query all keys operation failed");
494 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
495 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
496 }
497 return ERR_APPEXECFWK_FORM_COMMON_CODE;
498 }
499
QueryData(const NativeRdb::AbsRdbPredicates & absRdbPredicates)500 std::shared_ptr<NativeRdb::AbsSharedResultSet> FormRdbDataMgr::QueryData(
501 const NativeRdb::AbsRdbPredicates &absRdbPredicates)
502 {
503 HILOG_DEBUG("QueryData start");
504 if (!IsFormRdbLoaded()) {
505 HILOG_ERROR("null FormInfoRdbStore");
506 return nullptr;
507 }
508
509 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
510 return rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
511 }
512
QuerySql(const std::string & sql)513 std::shared_ptr<NativeRdb::AbsSharedResultSet> FormRdbDataMgr::QuerySql(const std::string &sql)
514 {
515 HILOG_DEBUG("QuerySql start");
516 if (!IsFormRdbLoaded()) {
517 HILOG_ERROR("null FormInfoRdbStore");
518 return nullptr;
519 }
520
521 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
522 return rdbStore_->QuerySql(sql, std::vector<std::string>());
523 }
524
InsertData(const std::string & tableName,const NativeRdb::ValuesBucket & valuesBucket,int64_t & rowId)525 bool FormRdbDataMgr::InsertData(
526 const std::string &tableName, const NativeRdb::ValuesBucket &valuesBucket, int64_t &rowId)
527 {
528 HILOG_DEBUG("InsertData start");
529 if (formRdbTableCfgMap_.find(tableName) == formRdbTableCfgMap_.end()) {
530 HILOG_ERROR("Form rdb hasn't initialized this table:%{public}s", tableName.c_str());
531 return false;
532 }
533
534 if (!IsFormRdbLoaded()) {
535 HILOG_ERROR("null FormInfoRdbStore");
536 return false;
537 }
538
539 int32_t ret = NativeRdb::E_OK;
540 {
541 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
542 ret = rdbStore_->InsertWithConflictResolution(
543 rowId, tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
544 }
545
546 if (ret == NativeRdb::E_OK) {
547 return true;
548 }
549
550 HILOG_WARN("Insert operation failed");
551 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
552 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
553 }
554 return ret == NativeRdb::E_OK;
555 }
556
DeleteData(const NativeRdb::AbsRdbPredicates & absRdbPredicates)557 bool FormRdbDataMgr::DeleteData(const NativeRdb::AbsRdbPredicates &absRdbPredicates)
558 {
559 if (!IsFormRdbLoaded()) {
560 HILOG_ERROR("null FormInfoRdbStore");
561 return false;
562 }
563
564 int32_t ret = NativeRdb::E_OK;
565 {
566 std::shared_lock<std::shared_mutex> guard(rdbStoreMutex_);
567 int32_t rowId = -1;
568 ret = rdbStore_->Delete(rowId, absRdbPredicates);
569 }
570
571 if (ret == NativeRdb::E_OK) {
572 return true;
573 }
574
575 HILOG_WARN("Delete operation failed");
576 if (CheckAndRebuildRdbStore(ret) == ERR_OK) {
577 HILOG_WARN("Check rdb corrupt,rebuild form rdb successfully");
578 return true;
579 }
580 return false;
581 }
582
IsFormRdbLoaded()583 bool FormRdbDataMgr::IsFormRdbLoaded()
584 {
585 std::unique_lock<std::shared_mutex> guard(rdbStoreMutex_);
586 if (rdbStore_ != nullptr) {
587 return true;
588 }
589
590 HILOG_WARN("null Rdb, need to reload");
591 if (LoadRdbStore() != ERR_OK) {
592 HILOG_ERROR("Load rdb failed");
593 return false;
594 }
595
596 for (auto iter = formRdbTableCfgMap_.begin(); iter != formRdbTableCfgMap_.end(); iter++) {
597 std::string createTableSql = !iter->second.createTableSql.empty() ? iter->second.createTableSql
598 : "CREATE TABLE IF NOT EXISTS " + iter->second.tableName
599 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
600 int32_t ret = rdbStore_->ExecuteSql(createTableSql);
601 if (ret != NativeRdb::E_OK) {
602 HILOG_ERROR("Recreate form rdb table failed, ret:%{public}" PRId32 ", name is %{public}s",
603 ret, iter->first.c_str());
604 }
605 }
606 return true;
607 }
608
CheckAndRebuildRdbStore(int32_t rdbOperateRet)609 ErrCode FormRdbDataMgr::CheckAndRebuildRdbStore(int32_t rdbOperateRet)
610 {
611 if (rdbOperateRet != NativeRdb::E_SQLITE_CORRUPT) {
612 HILOG_INFO("errorCode:%{public}" PRId32, rdbOperateRet);
613 return ERR_APPEXECFWK_FORM_COMMON_CODE;
614 }
615
616 std::unique_lock<std::shared_mutex> guard(rdbStoreMutex_);
617 int64_t curTime = FormUtil::GetCurrentMillisecond();
618 if ((curTime - lastRdbBuildTime_) <= MIN_FORM_RDB_REBUILD_INTERVAL) {
619 return ERR_APPEXECFWK_FORM_RDB_REPEATED_BUILD;
620 }
621
622 ErrCode ret = LoadRdbStore();
623 if (ret != ERR_OK) {
624 HILOG_ERROR("Reload form rdb failed, ret:%{public}" PRId32 ".", ret);
625 return ERR_APPEXECFWK_FORM_COMMON_CODE;
626 }
627 lastRdbBuildTime_ = curTime;
628
629 for (auto iter = formRdbTableCfgMap_.begin(); iter != formRdbTableCfgMap_.end(); iter++) {
630 std::string createTableSql = !iter->second.createTableSql.empty() ? iter->second.createTableSql
631 : "CREATE TABLE IF NOT EXISTS " + iter->second.tableName
632 + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
633 int32_t result = rdbStore_->ExecuteSql(createTableSql);
634 if (result != NativeRdb::E_OK) {
635 HILOG_ERROR("Recreate form rdb table failed, ret:%{public}" PRId32 ", name is %{public}s",
636 result, iter->first.c_str());
637 }
638 }
639 return ERR_OK;
640 }
641
LoadRdbStore()642 ErrCode FormRdbDataMgr::LoadRdbStore()
643 {
644 std::string rdbPath = Constants::FORM_MANAGER_SERVICE_PATH + Constants::FORM_RDB_NAME;
645 NativeRdb::RdbStoreConfig rdbStoreConfig(
646 rdbPath,
647 NativeRdb::StorageMode::MODE_DISK,
648 false,
649 std::vector<uint8_t>(),
650 Constants::FORM_JOURNAL_MODE,
651 Constants::FORM_SYNC_MODE,
652 "",
653 NativeRdb::SecurityLevel::S1);
654 rdbStoreConfig.SetAllowRebuild(true);
655 int32_t errCode = NativeRdb::E_OK;
656 RdbStoreDataCallBackFormInfoStorage rdbDataCallBack_(rdbPath);
657
658 rdbStore_ = nullptr;
659 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, Constants::FORM_RDB_VERSION,
660 rdbDataCallBack_, errCode);
661 if (errCode != NativeRdb::E_OK) {
662 HILOG_ERROR("Form rdb store init fail, err code is %{public}" PRId32 "", errCode);
663 FormEventReport::SendFormFailedEvent(FormEventName::CALLEN_DB_FAILED, HiSysEventType::FAULT,
664 static_cast<int64_t>(CallDbFiledErrorType::DATABASE_RESET_CONNECT_FAILED));
665 rdbStore_ = nullptr;
666 return ERR_APPEXECFWK_FORM_COMMON_CODE;
667 }
668 return ERR_OK;
669 }
670 } // namespace AppExecFwk
671 } // namespace OHOS