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