• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "distributed_rdb_helper.h"
16 
17 #include "ans_log_wrapper.h"
18 namespace OHOS {
19 namespace Notification {
20 
21 namespace {
22 const std::string NOTIFICATION_KEY = "KEY";
23 const std::string NOTIFICATION_VALUE = "VALUE";
24 const int32_t NOTIFICATION_KEY_INDEX = 0;
25 const int32_t NOTIFICATION_VALUE_INDEX = 1;
26 } // namespace
27 
RdbCallBack(const DistributedRdbConfig & notificationRdbConfig)28 RdbCallBack::RdbCallBack(const DistributedRdbConfig &notificationRdbConfig)
29     : notificationRdbConfig_(notificationRdbConfig)
30 {
31     ANS_LOGD("create rdb store callback instance");
32 }
33 
~RdbCallBack()34 RdbCallBack::~RdbCallBack()
35 {
36     ANS_LOGD("destroy rdb store callback instance");
37 }
38 
OnCreate(NativeRdb::RdbStore & rdbStore)39 int32_t RdbCallBack::OnCreate(NativeRdb::RdbStore &rdbStore)
40 {
41     ANS_LOGD("OnCreate");
42     int ret = NativeRdb::E_OK;
43     if (hasTableInit_) {
44         return ret;
45     }
46     std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + notificationRdbConfig_.tableName
47         + " (KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);";
48     ret = rdbStore.ExecuteSql(createTableSql);
49     if (ret == NativeRdb::E_OK) {
50         hasTableInit_ = true;
51         ANS_LOGD("createTable succeed");
52     }
53     return ret;
54 }
55 
OnUpgrade(NativeRdb::RdbStore & rdbStore,int32_t oldVersion,int32_t newVersion)56 int32_t RdbCallBack::OnUpgrade(NativeRdb::RdbStore &rdbStore, int32_t oldVersion, int32_t newVersion)
57 {
58     ANS_LOGD("OnUpgrade currentVersion: %{public}d, targetVersion: %{public}d",
59         oldVersion, newVersion);
60     return NativeRdb::E_OK;
61 }
62 
OnDowngrade(NativeRdb::RdbStore & rdbStore,int currentVersion,int targetVersion)63 int32_t RdbCallBack::OnDowngrade(NativeRdb::RdbStore &rdbStore, int currentVersion, int targetVersion)
64 {
65     ANS_LOGD("OnDowngrade  currentVersion: %{public}d, targetVersion: %{public}d",
66         currentVersion, targetVersion);
67     return NativeRdb::E_OK;
68 }
69 
OnOpen(NativeRdb::RdbStore & rdbStore)70 int32_t RdbCallBack::OnOpen(NativeRdb::RdbStore &rdbStore)
71 {
72     ANS_LOGD("OnOpen");
73     return NativeRdb::E_OK;
74 }
75 
onCorruption(std::string databaseFile)76 int32_t RdbCallBack::onCorruption(std::string databaseFile)
77 {
78     return NativeRdb::E_OK;
79 }
80 
DistributedRdbHelper(const DistributedRdbConfig & notificationRdbConfig)81 DistributedRdbHelper::DistributedRdbHelper(const DistributedRdbConfig &notificationRdbConfig)
82     : notificationRdbConfig_(notificationRdbConfig)
83 {
84     ANS_LOGD("create notification rdb data manager");
85 }
86 
Init()87 int32_t DistributedRdbHelper::Init()
88 {
89     ANS_LOGD("Create rdbStore");
90     {
91         std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
92         if (rdbStore_ != nullptr) {
93             ANS_LOGD("notification rdb has existed");
94             return NativeRdb::E_OK;
95         }
96     }
97     NativeRdb::RdbStoreConfig config(
98             notificationRdbConfig_.dbPath + notificationRdbConfig_.dbName,
99             NativeRdb::StorageMode::MODE_DISK,
100             false,
101             std::vector<uint8_t>(),
102             notificationRdbConfig_.journalMode,
103             notificationRdbConfig_.syncMode);
104     config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
105     config.SetHaMode(NativeRdb::HAMode::MAIN_REPLICA);
106     RdbCallBack rdbDataCallBack_(notificationRdbConfig_);
107     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
108     int32_t ret = NativeRdb::E_OK;
109     rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, notificationRdbConfig_.version,
110         rdbDataCallBack_, ret);
111     if (rdbStore_ == nullptr) {
112         ANS_LOGE("notification rdb init fail");
113         return NativeRdb::E_ERROR;
114     }
115     return NativeRdb::E_OK;
116 }
117 
Destroy()118 int32_t DistributedRdbHelper::Destroy()
119 {
120     ANS_LOGD("Destory rdbStore");
121 
122     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
123     if (rdbStore_ == nullptr) {
124         ANS_LOGE("notification rdb is null");
125         return NativeRdb::E_ERROR;
126     }
127     rdbStore_ = nullptr;
128     int32_t ret = NativeRdb::RdbHelper::DeleteRdbStore(notificationRdbConfig_.dbPath + notificationRdbConfig_.dbName);
129     if (ret != NativeRdb::E_OK) {
130         ANS_LOGE("failed to destroy db store");
131         return NativeRdb::E_ERROR;
132     }
133     ANS_LOGD("destroy db store successfully");
134     return NativeRdb::E_OK;
135 }
136 
InsertData(const std::string & key,const std::string & value)137 int32_t DistributedRdbHelper::InsertData(const std::string &key, const std::string &value)
138 {
139     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
140     if (rdbStore_ == nullptr) {
141         ANS_LOGE("notification rdb is null");
142         return NativeRdb::E_ERROR;
143     }
144     int64_t rowId = -1;
145     NativeRdb::ValuesBucket valuesBucket;
146     valuesBucket.PutString(NOTIFICATION_KEY, key);
147     valuesBucket.PutString(NOTIFICATION_VALUE, value);
148     int32_t ret = rdbStore_->InsertWithConflictResolution(rowId, notificationRdbConfig_.tableName,
149         valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
150     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
151         RestoreForMasterSlaver();
152     }
153     if (ret != NativeRdb::E_OK) {
154         ANS_LOGE("Insert operation failed, result: %{public}d, key=%{public}s.", ret, key.c_str());
155         return NativeRdb::E_ERROR;
156     }
157     return NativeRdb::E_OK;
158 }
159 
InsertBatchData(const std::unordered_map<std::string,std::string> & values)160 int32_t DistributedRdbHelper::InsertBatchData(const std::unordered_map<std::string, std::string> &values)
161 {
162     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
163     if (rdbStore_ == nullptr) {
164         ANS_LOGE("notification rdb is null");
165         return NativeRdb::E_ERROR;
166     }
167     int64_t rowId = -1;
168     std::vector<NativeRdb::ValuesBucket> buckets;
169     for (auto &value : values) {
170         NativeRdb::ValuesBucket valuesBucket;
171         valuesBucket.PutString(NOTIFICATION_KEY, value.first);
172         valuesBucket.PutString(NOTIFICATION_VALUE, value.second);
173         buckets.emplace_back(valuesBucket);
174     }
175     int32_t ret = rdbStore_->BatchInsert(rowId, notificationRdbConfig_.tableName, buckets);
176     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
177         RestoreForMasterSlaver();
178     }
179     if (ret != NativeRdb::E_OK) {
180         ANS_LOGE("Insert batch operation failed, result: %{public}d.", ret);
181         return NativeRdb::E_ERROR;
182     }
183     return NativeRdb::E_OK;
184 }
185 
DeleteData(const std::string & key)186 int32_t DistributedRdbHelper::DeleteData(const std::string &key)
187 {
188     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
189     if (rdbStore_ == nullptr) {
190         ANS_LOGE("notification rdb is null");
191         return NativeRdb::E_ERROR;
192     }
193     int32_t ret = NativeRdb::E_OK;
194     int32_t rowId = -1;
195     ret = DeleteData(notificationRdbConfig_.tableName, key, rowId);
196     if (ret != NativeRdb::E_OK) {
197         ANS_LOGE("Delete operation failed, result: %{public}d.", ret);
198         return NativeRdb::E_ERROR;
199     }
200     return NativeRdb::E_OK;
201 }
202 
QueryData(const std::string & key,std::string & value)203 int32_t DistributedRdbHelper::QueryData(const std::string &key, std::string &value)
204 {
205     ANS_LOGD("QueryData start");
206     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
207     if (rdbStore_ == nullptr) {
208         ANS_LOGE("notification rdb is null");
209         return NativeRdb::E_ERROR;
210     }
211     int32_t ret = QueryData(notificationRdbConfig_.tableName, key, value);
212     if (ret != NativeRdb::E_OK) {
213         ANS_LOGE("Delete operation failed, result: %{public}d.", ret);
214         return NativeRdb::E_ERROR;
215     }
216     return NativeRdb::E_OK;
217 }
218 
QueryDataBeginWithKey(const std::string & key,std::unordered_map<std::string,std::string> & values)219 int32_t DistributedRdbHelper::QueryDataBeginWithKey(
220     const std::string &key, std::unordered_map<std::string, std::string> &values)
221 {
222     ANS_LOGD("QueryData BeginWithKey start");
223     std::lock_guard<std::mutex> lock(rdbStorePtrMutex_);
224     if (rdbStore_ == nullptr) {
225         ANS_LOGE("notification rdb is null");
226         return NativeRdb::E_ERROR;
227     }
228     int32_t ret = QueryDataBeginWithKey(notificationRdbConfig_.tableName, key, values);
229     if (ret == NativeRdb::E_ERROR) {
230         return ret;
231     }
232     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && values.empty()) {
233         ANS_LOGI("notification rdb is empty.");
234         return NativeRdb::E_EMPTY_VALUES_BUCKET;
235     }
236     return NativeRdb::E_OK;
237 }
238 
QueryDataBeginWithKey(const std::string tableName,const std::string key,std::unordered_map<std::string,std::string> & values)239 int32_t DistributedRdbHelper::QueryDataBeginWithKey(
240     const std::string tableName, const std::string key, std::unordered_map<std::string, std::string> &values)
241 {
242     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
243     absRdbPredicates.BeginsWith(NOTIFICATION_KEY, key);
244     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
245     if (absSharedResultSet == nullptr) {
246         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
247         return NativeRdb::E_ERROR;
248     }
249 
250     int32_t ret = absSharedResultSet->GoToFirstRow();
251     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
252         RestoreForMasterSlaver();
253     }
254     if (ret != NativeRdb::E_OK) {
255         ANS_LOGD("GoToFirstRow failed from %{public}s table.It is empty!, key=%{public}s",
256             tableName.c_str(), key.c_str());
257         return NativeRdb::E_EMPTY_VALUES_BUCKET;
258     }
259 
260     do {
261         std::string resultKey;
262         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
263         if (ret != NativeRdb::E_OK) {
264             ANS_LOGE("Failed to GetString key from %{public}s table.", tableName.c_str());
265             return NativeRdb::E_ERROR;
266         }
267 
268         std::string resultValue;
269         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
270         if (ret != NativeRdb::E_OK) {
271             ANS_LOGE("GetString value failed from %{public}s table", tableName.c_str());
272             return NativeRdb::E_ERROR;
273         }
274         values.emplace(resultKey, resultValue);
275     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
276     absSharedResultSet->Close();
277     return NativeRdb::E_OK;
278 }
279 
QueryData(const std::string tableName,const std::string key,std::string & value)280 int32_t DistributedRdbHelper::QueryData(const std::string tableName, const std::string key, std::string &value)
281 {
282     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
283     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
284     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
285     if (absSharedResultSet == nullptr) {
286         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
287         return NativeRdb::E_ERROR;
288     }
289 
290     int32_t ret = absSharedResultSet->GoToFirstRow();
291     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
292         RestoreForMasterSlaver();
293     }
294     if (ret != NativeRdb::E_OK) {
295         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
296             tableName.c_str(), key.c_str());
297         return NativeRdb::E_EMPTY_VALUES_BUCKET;
298     }
299     ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, value);
300     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
301         RestoreForMasterSlaver();
302     }
303     if (ret != NativeRdb::E_OK) {
304         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
305         return NativeRdb::E_ERROR;
306     }
307     absSharedResultSet->Close();
308     return NativeRdb::E_OK;
309 }
310 
DeleteData(const std::string tableName,const std::string key,int32_t & rowId)311 int32_t DistributedRdbHelper::DeleteData(const std::string tableName, const std::string key, int32_t &rowId)
312 {
313     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
314     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
315     int32_t ret = rdbStore_->Delete(rowId, absRdbPredicates);
316     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
317         RestoreForMasterSlaver();
318     }
319     if (ret != NativeRdb::E_OK) {
320         ANS_LOGW("Delete operation failed from %{public}s, result: %{public}d, key=%{public}s.",
321             tableName.c_str(), ret, key.c_str());
322         return NativeRdb::E_ERROR;
323     }
324     return NativeRdb::E_OK;
325 }
326 
RestoreForMasterSlaver()327 int32_t DistributedRdbHelper::RestoreForMasterSlaver()
328 {
329     ANS_LOGI("RestoreForMasterSlaver start");
330     int32_t result = rdbStore_->Restore("");
331     ANS_LOGI("RestoreForMasterSlaver result = %{public}d", result);
332     return result;
333 }
334 }
335 }
336