• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include "rdb_data_manager.h"
17 
18 #include "app_log_wrapper.h"
19 #include "bundle_memory_guard.h"
20 #include "bundle_util.h"
21 #include "scope_guard.h"
22 
23 #include <thread>
24 
25 namespace OHOS {
26 namespace AppExecFwk {
27 namespace {
28 const std::string BMS_KEY = "KEY";
29 const std::string BMS_VALUE = "VALUE";
30 const int32_t BMS_KEY_INDEX = 0;
31 const int32_t BMS_VALUE_INDEX = 1;
32 const int32_t WRITE_TIMEOUT = 300; // 300s
33 const int32_t CLOSE_TIME = 20; // delay 20s stop rdbStore
34 }
35 
RdbDataManager(const BmsRdbConfig & bmsRdbConfig)36 RdbDataManager::RdbDataManager(const BmsRdbConfig &bmsRdbConfig)
37     : bmsRdbConfig_(bmsRdbConfig)
38 {
39 }
40 
~RdbDataManager()41 RdbDataManager::~RdbDataManager()
42 {
43     rdbStore_ = nullptr;
44 }
45 
ClearCache()46 void RdbDataManager::ClearCache()
47 {
48     NativeRdb::RdbHelper::ClearCache();
49 }
50 
GetRdbStore()51 std::shared_ptr<NativeRdb::RdbStore> RdbDataManager::GetRdbStore()
52 {
53     std::lock_guard<std::mutex> lock(rdbMutex_);
54     if (rdbStore_ != nullptr) {
55         return rdbStore_;
56     }
57     NativeRdb::RdbStoreConfig rdbStoreConfig(bmsRdbConfig_.dbPath + bmsRdbConfig_.dbName);
58     rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
59     rdbStoreConfig.SetWriteTime(WRITE_TIMEOUT);
60     int32_t errCode = NativeRdb::E_OK;
61     BmsRdbOpenCallback bmsRdbOpenCallback(bmsRdbConfig_);
62     rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(
63         rdbStoreConfig,
64         bmsRdbConfig_.version,
65         bmsRdbOpenCallback,
66         errCode);
67     DelayCloseRdbStore();
68     return rdbStore_;
69 }
70 
InsertData(const std::string & key,const std::string & value)71 bool RdbDataManager::InsertData(const std::string &key, const std::string &value)
72 {
73     APP_LOGD("InsertData start");
74     auto rdbStore = GetRdbStore();
75     if (rdbStore == nullptr) {
76         APP_LOGE("RdbStore is null");
77         return false;
78     }
79 
80     int64_t rowId = -1;
81     NativeRdb::ValuesBucket valuesBucket;
82     valuesBucket.PutString(BMS_KEY, key);
83     valuesBucket.PutString(BMS_VALUE, value);
84     auto ret = rdbStore->InsertWithConflictResolution(
85         rowId, bmsRdbConfig_.tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
86     return ret == NativeRdb::E_OK;
87 }
88 
InsertData(const NativeRdb::ValuesBucket & valuesBucket)89 bool RdbDataManager::InsertData(const NativeRdb::ValuesBucket &valuesBucket)
90 {
91     APP_LOGD("InsertData start");
92     auto rdbStore = GetRdbStore();
93     if (rdbStore == nullptr) {
94         APP_LOGE("RdbStore is null");
95         return false;
96     }
97 
98     int64_t rowId = -1;
99     auto ret = rdbStore->InsertWithConflictResolution(
100         rowId, bmsRdbConfig_.tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
101     return ret == NativeRdb::E_OK;
102 }
103 
BatchInsert(int64_t & outInsertNum,const std::vector<NativeRdb::ValuesBucket> & valuesBuckets)104 bool RdbDataManager::BatchInsert(int64_t &outInsertNum, const std::vector<NativeRdb::ValuesBucket> &valuesBuckets)
105 {
106     APP_LOGD("BatchInsert start");
107     auto rdbStore = GetRdbStore();
108     if (rdbStore == nullptr) {
109         APP_LOGE("RdbStore is null");
110         return false;
111     }
112     auto ret = rdbStore->BatchInsert(outInsertNum, bmsRdbConfig_.tableName, valuesBuckets);
113     return ret == NativeRdb::E_OK;
114 }
115 
UpdateData(const std::string & key,const std::string & value)116 bool RdbDataManager::UpdateData(const std::string &key, const std::string &value)
117 {
118     APP_LOGD("UpdateData start");
119     auto rdbStore = GetRdbStore();
120     if (rdbStore == nullptr) {
121         APP_LOGE("RdbStore is null");
122         return false;
123     }
124 
125     int32_t rowId = -1;
126     NativeRdb::AbsRdbPredicates absRdbPredicates(bmsRdbConfig_.tableName);
127     absRdbPredicates.EqualTo(BMS_KEY, key);
128     NativeRdb::ValuesBucket valuesBucket;
129     valuesBucket.PutString(BMS_KEY, key);
130     valuesBucket.PutString(BMS_VALUE, value);
131     auto ret = rdbStore->Update(rowId, valuesBucket, absRdbPredicates);
132     return ret == NativeRdb::E_OK;
133 }
134 
UpdateData(const NativeRdb::ValuesBucket & valuesBucket,const NativeRdb::AbsRdbPredicates & absRdbPredicates)135 bool RdbDataManager::UpdateData(
136     const NativeRdb::ValuesBucket &valuesBucket, const NativeRdb::AbsRdbPredicates &absRdbPredicates)
137 {
138     APP_LOGD("UpdateData start");
139     auto rdbStore = GetRdbStore();
140     if (rdbStore == nullptr) {
141         APP_LOGE("RdbStore is null");
142         return false;
143     }
144     if (absRdbPredicates.GetTableName() != bmsRdbConfig_.tableName) {
145         APP_LOGE("RdbStore table is invalid");
146         return false;
147     }
148     int32_t rowId = -1;
149     auto ret = rdbStore->Update(rowId, valuesBucket, absRdbPredicates);
150     return ret == NativeRdb::E_OK;
151 }
152 
DeleteData(const std::string & key)153 bool RdbDataManager::DeleteData(const std::string &key)
154 {
155     APP_LOGD("DeleteData start");
156     auto rdbStore = GetRdbStore();
157     if (rdbStore == nullptr) {
158         APP_LOGE("RdbStore is null");
159         return false;
160     }
161 
162     int32_t rowId = -1;
163     NativeRdb::AbsRdbPredicates absRdbPredicates(bmsRdbConfig_.tableName);
164     absRdbPredicates.EqualTo(BMS_KEY, key);
165     auto ret = rdbStore->Delete(rowId, absRdbPredicates);
166     return ret == NativeRdb::E_OK;
167 }
168 
DeleteData(const NativeRdb::AbsRdbPredicates & absRdbPredicates)169 bool RdbDataManager::DeleteData(const NativeRdb::AbsRdbPredicates &absRdbPredicates)
170 {
171     auto rdbStore = GetRdbStore();
172     if (rdbStore == nullptr) {
173         APP_LOGE("RdbStore is null");
174         return false;
175     }
176     if (absRdbPredicates.GetTableName() != bmsRdbConfig_.tableName) {
177         APP_LOGE("RdbStore table is invalid");
178         return false;
179     }
180     int32_t rowId = -1;
181     auto ret = rdbStore->Delete(rowId, absRdbPredicates);
182     return ret == NativeRdb::E_OK;
183 }
184 
QueryData(const std::string & key,std::string & value)185 bool RdbDataManager::QueryData(const std::string &key, std::string &value)
186 {
187     APP_LOGD("QueryData start");
188     auto rdbStore = GetRdbStore();
189     if (rdbStore == nullptr) {
190         APP_LOGE("RdbStore is null");
191         return false;
192     }
193 
194     NativeRdb::AbsRdbPredicates absRdbPredicates(bmsRdbConfig_.tableName);
195     absRdbPredicates.EqualTo(BMS_KEY, key);
196     auto absSharedResultSet = rdbStore->Query(absRdbPredicates, std::vector<std::string>());
197     if (absSharedResultSet == nullptr) {
198         APP_LOGE("absSharedResultSet failed");
199         return false;
200     }
201     ScopeGuard stateGuard([&] { absSharedResultSet->Close(); });
202     if (!absSharedResultSet->HasBlock()) {
203         APP_LOGE("absSharedResultSet has no block");
204         return false;
205     }
206     auto ret = absSharedResultSet->GoToFirstRow();
207     if (ret != NativeRdb::E_OK) {
208         APP_LOGE("GoToFirstRow failed, ret: %{public}d", ret);
209         return false;
210     }
211 
212     ret = absSharedResultSet->GetString(BMS_VALUE_INDEX, value);
213     if (ret != NativeRdb::E_OK) {
214         APP_LOGE("QueryData failed, ret: %{public}d", ret);
215         return false;
216     }
217 
218     return true;
219 }
220 
QueryData(const NativeRdb::AbsRdbPredicates & absRdbPredicates)221 std::shared_ptr<NativeRdb::AbsSharedResultSet> RdbDataManager::QueryData(
222     const NativeRdb::AbsRdbPredicates &absRdbPredicates)
223 {
224     APP_LOGD("QueryData start");
225     auto rdbStore = GetRdbStore();
226     if (rdbStore == nullptr) {
227         APP_LOGE("RdbStore is null");
228         return nullptr;
229     }
230     if (absRdbPredicates.GetTableName() != bmsRdbConfig_.tableName) {
231         APP_LOGE("RdbStore table is invalid");
232         return nullptr;
233     }
234     auto absSharedResultSet = rdbStore->Query(absRdbPredicates, std::vector<std::string>());
235     if (absSharedResultSet == nullptr || !absSharedResultSet->HasBlock()) {
236         APP_LOGE("absSharedResultSet failed");
237         return nullptr;
238     }
239     return absSharedResultSet;
240 }
241 
QueryAllData(std::map<std::string,std::string> & datas)242 bool RdbDataManager::QueryAllData(std::map<std::string, std::string> &datas)
243 {
244     APP_LOGD("QueryAllData start");
245     auto rdbStore = GetRdbStore();
246     if (rdbStore == nullptr) {
247         APP_LOGE("RdbStore is null");
248         return false;
249     }
250 
251     NativeRdb::AbsRdbPredicates absRdbPredicates(bmsRdbConfig_.tableName);
252     auto absSharedResultSet = rdbStore->Query(absRdbPredicates, std::vector<std::string>());
253     if (absSharedResultSet == nullptr) {
254         APP_LOGE("absSharedResultSet failed");
255         return false;
256     }
257     ScopeGuard stateGuard([&] { absSharedResultSet->Close(); });
258     if (!absSharedResultSet->HasBlock()) {
259         APP_LOGE("absSharedResultSet has no block");
260         return false;
261     }
262 
263     if (absSharedResultSet->GoToFirstRow() != NativeRdb::E_OK) {
264         APP_LOGE("GoToFirstRow failed");
265         return false;
266     }
267 
268     do {
269         std::string key;
270         if (absSharedResultSet->GetString(BMS_KEY_INDEX, key) != NativeRdb::E_OK) {
271             APP_LOGE("GetString key failed");
272             return false;
273         }
274 
275         std::string value;
276         if (absSharedResultSet->GetString(BMS_VALUE_INDEX, value) != NativeRdb::E_OK) {
277             APP_LOGE("GetString value failed");
278             return false;
279         }
280 
281         datas.emplace(key, value);
282     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
283     return !datas.empty();
284 }
285 
CreateTable()286 bool RdbDataManager::CreateTable()
287 {
288     std::string createTableSql;
289     if (bmsRdbConfig_.createTableSql.empty()) {
290         createTableSql = std::string(
291             "CREATE TABLE IF NOT EXISTS "
292             + bmsRdbConfig_.tableName
293             + "(KEY TEXT NOT NULL PRIMARY KEY, VALUE TEXT NOT NULL);");
294     } else {
295         createTableSql = bmsRdbConfig_.createTableSql;
296     }
297     auto rdbStore = GetRdbStore();
298     if (rdbStore == nullptr) {
299         APP_LOGE("RdbStore is null");
300         return false;
301     }
302     int ret = rdbStore->ExecuteSql(createTableSql);
303     if (ret != NativeRdb::E_OK) {
304         APP_LOGE("CreateTable failed, ret: %{public}d", ret);
305         return false;
306     }
307     for (const auto &sql : bmsRdbConfig_.insertColumnSql) {
308         int32_t insertRet = rdbStore->ExecuteSql(sql);
309         if (insertRet != NativeRdb::E_OK) {
310             APP_LOGW("ExecuteSql insertColumnSql failed, insertRet: %{public}d", insertRet);
311         }
312     }
313     return true;
314 }
315 
DelayCloseRdbStore()316 void RdbDataManager::DelayCloseRdbStore()
317 {
318     APP_LOGD("RdbDataManager DelayCloseRdbStore start");
319     std::weak_ptr<RdbDataManager> weakPtr = shared_from_this();
320     auto task = [weakPtr]() {
321         APP_LOGD("RdbDataManager DelayCloseRdbStore thread begin");
322         std::this_thread::sleep_for(std::chrono::seconds(CLOSE_TIME));
323         auto sharedPtr = weakPtr.lock();
324         if (sharedPtr == nullptr) {
325             return;
326         }
327         std::lock_guard<std::mutex> lock(sharedPtr->rdbMutex_);
328         sharedPtr->rdbStore_ = nullptr;
329         APP_LOGD("RdbDataManager DelayCloseRdbStore thread end");
330     };
331     std::thread closeRdbStoreThread(task);
332     closeRdbStoreThread.detach();
333 }
334 }  // namespace AppExecFwk
335 }  // namespace OHOS
336