• 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<ffrt::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<ffrt::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     ANS_LOGI("Create rdbStore successfully");
116     return NativeRdb::E_OK;
117 }
118 
Destroy()119 int32_t DistributedRdbHelper::Destroy()
120 {
121     ANS_LOGD("Destory rdbStore");
122 
123     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
124     if (rdbStore_ == nullptr) {
125         ANS_LOGE("notification rdb is null");
126         return NativeRdb::E_ERROR;
127     }
128     rdbStore_ = nullptr;
129     int32_t ret = NativeRdb::RdbHelper::DeleteRdbStore(notificationRdbConfig_.dbPath + notificationRdbConfig_.dbName);
130     if (ret != NativeRdb::E_OK) {
131         ANS_LOGE("failed to destroy db store");
132         return NativeRdb::E_ERROR;
133     }
134     ANS_LOGI("destroy db store successfully");
135     return NativeRdb::E_OK;
136 }
137 
InsertData(const std::string & key,const std::string & value)138 int32_t DistributedRdbHelper::InsertData(const std::string &key, const std::string &value)
139 {
140     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
141     if (rdbStore_ == nullptr) {
142         ANS_LOGE("notification rdb is null");
143         return NativeRdb::E_ERROR;
144     }
145     int64_t rowId = -1;
146     NativeRdb::ValuesBucket valuesBucket;
147     valuesBucket.PutString(NOTIFICATION_KEY, key);
148     valuesBucket.PutString(NOTIFICATION_VALUE, value);
149     int32_t ret = rdbStore_->InsertWithConflictResolution(rowId, notificationRdbConfig_.tableName,
150         valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
151     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
152         RestoreForMasterSlaver();
153     }
154     if (ret != NativeRdb::E_OK) {
155         ANS_LOGE("Insert operation failed, result: %{public}d, key=%{public}s.", ret, key.c_str());
156         return NativeRdb::E_ERROR;
157     }
158     return NativeRdb::E_OK;
159 }
160 
InsertBatchData(const std::unordered_map<std::string,std::string> & values)161 int32_t DistributedRdbHelper::InsertBatchData(const std::unordered_map<std::string, std::string> &values)
162 {
163     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
164     if (rdbStore_ == nullptr) {
165         ANS_LOGE("notification rdb is null");
166         return NativeRdb::E_ERROR;
167     }
168     int64_t rowId = -1;
169     std::vector<NativeRdb::ValuesBucket> buckets;
170     for (auto &value : values) {
171         NativeRdb::ValuesBucket valuesBucket;
172         valuesBucket.PutString(NOTIFICATION_KEY, value.first);
173         valuesBucket.PutString(NOTIFICATION_VALUE, value.second);
174         buckets.emplace_back(valuesBucket);
175     }
176     int32_t ret = rdbStore_->BatchInsert(rowId, notificationRdbConfig_.tableName, buckets);
177     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
178         RestoreForMasterSlaver();
179     }
180     if (ret != NativeRdb::E_OK) {
181         ANS_LOGE("Insert batch operation failed, result: %{public}d.", ret);
182         return NativeRdb::E_ERROR;
183     }
184     return NativeRdb::E_OK;
185 }
186 
DeleteData(const std::string & key)187 int32_t DistributedRdbHelper::DeleteData(const std::string &key)
188 {
189     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
190     if (rdbStore_ == nullptr) {
191         ANS_LOGE("notification rdb is null");
192         return NativeRdb::E_ERROR;
193     }
194     int32_t ret = NativeRdb::E_OK;
195     int32_t rowId = -1;
196     ret = DeleteData(notificationRdbConfig_.tableName, key, rowId);
197     if (ret != NativeRdb::E_OK) {
198         ANS_LOGE("Delete operation failed, result: %{public}d.", ret);
199         return NativeRdb::E_ERROR;
200     }
201     return NativeRdb::E_OK;
202 }
203 
QueryData(const std::string & key,std::string & value)204 int32_t DistributedRdbHelper::QueryData(const std::string &key, std::string &value)
205 {
206     ANS_LOGD("QueryData start");
207     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
208     if (rdbStore_ == nullptr) {
209         ANS_LOGE("notification rdb is null");
210         return NativeRdb::E_ERROR;
211     }
212     int32_t ret = QueryData(notificationRdbConfig_.tableName, key, value);
213     if (ret != NativeRdb::E_OK) {
214         ANS_LOGE("Delete operation failed, result: %{public}d.", ret);
215         return NativeRdb::E_ERROR;
216     }
217     return NativeRdb::E_OK;
218 }
219 
QueryDataBeginWithKey(const std::string & key,std::unordered_map<std::string,std::string> & values)220 int32_t DistributedRdbHelper::QueryDataBeginWithKey(
221     const std::string &key, std::unordered_map<std::string, std::string> &values)
222 {
223     ANS_LOGD("QueryData BeginWithKey start");
224     std::lock_guard<ffrt::mutex> lock(rdbStorePtrMutex_);
225     if (rdbStore_ == nullptr) {
226         ANS_LOGE("notification rdb is null");
227         return NativeRdb::E_ERROR;
228     }
229     int32_t ret = QueryDataBeginWithKey(notificationRdbConfig_.tableName, key, values);
230     if (ret == NativeRdb::E_ERROR) {
231         return ret;
232     }
233     if (ret == NativeRdb::E_EMPTY_VALUES_BUCKET && values.empty()) {
234         ANS_LOGI("notification rdb is empty.");
235         return NativeRdb::E_EMPTY_VALUES_BUCKET;
236     }
237     return NativeRdb::E_OK;
238 }
239 
QueryDataBeginWithKey(const std::string tableName,const std::string key,std::unordered_map<std::string,std::string> & values)240 int32_t DistributedRdbHelper::QueryDataBeginWithKey(
241     const std::string tableName, const std::string key, std::unordered_map<std::string, std::string> &values)
242 {
243     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
244     absRdbPredicates.BeginsWith(NOTIFICATION_KEY, key);
245     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
246     if (absSharedResultSet == nullptr) {
247         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
248         return NativeRdb::E_ERROR;
249     }
250 
251     int32_t ret = absSharedResultSet->GoToFirstRow();
252     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
253         RestoreForMasterSlaver();
254     }
255     if (ret != NativeRdb::E_OK) {
256         ANS_LOGD("GoToFirstRow failed from %{public}s table.It is empty!, key=%{public}s",
257             tableName.c_str(), key.c_str());
258         absSharedResultSet->Close();
259         return NativeRdb::E_EMPTY_VALUES_BUCKET;
260     }
261 
262     do {
263         std::string resultKey;
264         ret = absSharedResultSet->GetString(NOTIFICATION_KEY_INDEX, resultKey);
265         if (ret != NativeRdb::E_OK) {
266             ANS_LOGE("Failed to GetString key from %{public}s table.", tableName.c_str());
267             absSharedResultSet->Close();
268             return NativeRdb::E_ERROR;
269         }
270 
271         std::string resultValue;
272         ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, resultValue);
273         if (ret != NativeRdb::E_OK) {
274             ANS_LOGE("GetString value failed from %{public}s table", tableName.c_str());
275             absSharedResultSet->Close();
276             return NativeRdb::E_ERROR;
277         }
278         values.emplace(resultKey, resultValue);
279     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
280     absSharedResultSet->Close();
281     return NativeRdb::E_OK;
282 }
283 
QueryData(const std::string tableName,const std::string key,std::string & value)284 int32_t DistributedRdbHelper::QueryData(const std::string tableName, const std::string key, std::string &value)
285 {
286     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
287     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
288     auto absSharedResultSet = rdbStore_->Query(absRdbPredicates, std::vector<std::string>());
289     if (absSharedResultSet == nullptr) {
290         ANS_LOGE("absSharedResultSet failed from %{public}s table.", tableName.c_str());
291         return NativeRdb::E_ERROR;
292     }
293 
294     int32_t ret = absSharedResultSet->GoToFirstRow();
295     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
296         RestoreForMasterSlaver();
297     }
298     if (ret != NativeRdb::E_OK) {
299         ANS_LOGW("GoToFirstRow failed from %{public}s table. It is empty!, key=%{public}s",
300             tableName.c_str(), key.c_str());
301         absSharedResultSet->Close();
302         return NativeRdb::E_EMPTY_VALUES_BUCKET;
303     }
304     ret = absSharedResultSet->GetString(NOTIFICATION_VALUE_INDEX, value);
305     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
306         RestoreForMasterSlaver();
307     }
308     if (ret != NativeRdb::E_OK) {
309         ANS_LOGE("GetString value failed from %{public}s table.", tableName.c_str());
310         absSharedResultSet->Close();
311         return NativeRdb::E_ERROR;
312     }
313     absSharedResultSet->Close();
314     return NativeRdb::E_OK;
315 }
316 
DeleteData(const std::string tableName,const std::string key,int32_t & rowId)317 int32_t DistributedRdbHelper::DeleteData(const std::string tableName, const std::string key, int32_t &rowId)
318 {
319     NativeRdb::AbsRdbPredicates absRdbPredicates(tableName);
320     absRdbPredicates.EqualTo(NOTIFICATION_KEY, key);
321     int32_t ret = rdbStore_->Delete(rowId, absRdbPredicates);
322     if (ret == NativeRdb::E_SQLITE_CORRUPT) {
323         RestoreForMasterSlaver();
324     }
325     if (ret != NativeRdb::E_OK) {
326         ANS_LOGW("Delete operation failed from %{public}s, result: %{public}d, key=%{public}s.",
327             tableName.c_str(), ret, key.c_str());
328         return NativeRdb::E_ERROR;
329     }
330     return NativeRdb::E_OK;
331 }
332 
RestoreForMasterSlaver()333 int32_t DistributedRdbHelper::RestoreForMasterSlaver()
334 {
335     ANS_LOGI("RestoreForMasterSlaver start");
336     int32_t result = rdbStore_->Restore("");
337     ANS_LOGI("RestoreForMasterSlaver result = %{public}d", result);
338     return result;
339 }
340 }
341 }
342