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