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