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
16 #include "app_details_rdb_data_manager.h"
17 #include "app_details_base_item.h"
18 #include "app_details_meta_item.h"
19 #include "app_details_rdb_data_define.h"
20 #include "app_details_rdb_item.h"
21 #include "app_details_rdb_open_callback.h"
22 #include "app_domain_verify_hilog.h"
23 #include "cpp/mutex.h"
24 #include "rdb_errno.h"
25 #include "rdb_store.h"
26 #include "values_bucket.h"
27 #include "rdb_helper.h"
28 #include <functional>
29 #include <string>
30 #include <variant>
31 #include <vector>
32 #include "app_details_rdb_const_define.h"
33
34 namespace OHOS {
35 namespace AppDomainVerify {
AppDetailsRdbDataMgr(bool isCreated)36 AppDetailsRdbDataMgr::AppDetailsRdbDataMgr(bool isCreated)
37 {
38 conf_.rdbName = APP_DETAILS_RDB_NAME;
39 conf_.rdbPath = APP_DETAILS_RDB_PATH;
40 conf_.version = APP_DETAILS_RDB_VERSION;
41 conf_.fileCreated = isCreated;
42 };
43
AppDetailsRdbDataMgr(const RdbConfigInfo & info)44 AppDetailsRdbDataMgr::AppDetailsRdbDataMgr(const RdbConfigInfo& info)
45 {
46 conf_ = info;
47 };
48
~AppDetailsRdbDataMgr()49 AppDetailsRdbDataMgr::~AppDetailsRdbDataMgr()
50 {
51 if (closeHandler_ != nullptr) {
52 closeHandler_->RemoveTask(CLOSE_TASK_ID);
53 }
54 };
55
ExecWithTrans(TransCallback cb)56 bool AppDetailsRdbDataMgr::ExecWithTrans(TransCallback cb)
57 {
58 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call");
59 auto rdbStore = GetRdbStore();
60 auto ret = rdbStore->BeginTransaction();
61 if (ret != NativeRdb::E_OK) {
62 return false;
63 }
64 if (cb()) {
65 ret = rdbStore->Commit();
66 if (ret != NativeRdb::E_OK) {
67 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "commit err:%{public}d", ret);
68 return false;
69 }
70 return true;
71 }
72 ret = rdbStore->RollBack();
73 if (ret != NativeRdb::E_OK) {
74 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "roll err:%{public}d.", ret);
75 }
76 return false;
77 }
78
QueryDataByDomain(const std::string & tableName,const std::string & domain,std::vector<AppDetailsRdbItem> & itemVec)79 bool AppDetailsRdbDataMgr::QueryDataByDomain(
80 const std::string& tableName, const std::string &domain, std::vector<AppDetailsRdbItem> &itemVec)
81 {
82 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call.");
83 NativeRdb::AbsRdbPredicates absRdbPred(tableName);
84 absRdbPred.EqualTo(DETAILS_DOMAIN, domain);
85 std::vector<std::string> columns = {};
86 RdbForEachRetCb eachCb = [&itemVec](std::shared_ptr<AbsSharedResultSet> retSet)->bool {
87 AppDetailsRdbItem item;
88 if (!item.GetRdbItem(retSet)) {
89 return false;
90 }
91 itemVec.emplace_back(item);
92 return true;
93 };
94 return Query(absRdbPred, columns, eachCb);
95 }
96
PostDelayCloseTask(int32_t delayTime)97 void AppDetailsRdbDataMgr::PostDelayCloseTask(int32_t delayTime)
98 {
99 if (runner_ == nullptr) {
100 runner_ = AppExecFwk::EventRunner::Create("closeRdb", AppExecFwk::ThreadMode::FFRT);
101 }
102 if (closeHandler_ == nullptr) {
103 closeHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
104 }
105 if (closeHandler_ == nullptr) {
106 return;
107 }
108 std::weak_ptr<AppDetailsRdbDataMgr> weakPtr = shared_from_this();
109 auto task = [weakPtr]() {
110 auto appDetailsRdbMgr = weakPtr.lock();
111 if (appDetailsRdbMgr != nullptr) {
112 std::lock_guard<ffrt::mutex> lock(appDetailsRdbMgr->mtx_);
113 appDetailsRdbMgr->rdbStore_ = nullptr;
114 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb close");
115 }
116 return;
117 };
118 closeHandler_->RemoveTask(CLOSE_TASK_ID);
119 closeHandler_->PostTask(task, CLOSE_TASK_ID, delayTime);
120 return;
121 }
122
InsertDataBatch(const std::string & tableName,std::vector<AppDetailsRdbItem> & infoVec)123 bool AppDetailsRdbDataMgr::InsertDataBatch(const std::string& tableName, std::vector<AppDetailsRdbItem>& infoVec)
124 {
125 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
126 auto rdbStore = GetRdbStore();
127 if (!rdbStore) {
128 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
129 return false;
130 }
131 std::vector<NativeRdb::ValuesBucket> rows;
132 for (auto& info : infoVec) {
133 NativeRdb::ValuesBucket valuesBucket;
134 info.AddRdbItemToBucket(valuesBucket);
135 rows.emplace_back(valuesBucket);
136 }
137 int64_t num = 0;
138 return CheckRdbReturnIfOk(rdbStore_->BatchInsert(num, tableName, rows));
139 };
140
CreateMetaData()141 bool AppDetailsRdbDataMgr::CreateMetaData()
142 {
143 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
144 auto rdbStore = GetRdbStore();
145 if (!rdbStore) {
146 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
147 return false;
148 }
149 std::string sql = "CREATE TABLE IF NOT EXISTS " + META_DATA +
150 "("
151 "TABLE_NAME TEXT NOT NULL PRIMARY KEY,"
152 "TABLE_VERSION TEXT,"
153 "TABLE_EXT_INFO TEXT,"
154 "UPDATE_TIME TEXT"
155 ");";
156 auto ret = rdbStore->ExecuteSql(sql);
157 if (ret != NativeRdb::E_OK) {
158 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "exec sql fail. ret:%{public}d", ret);
159 return false;
160 }
161 return true;
162 };
163
UpdateMetaData(std::vector<MetaItem> & itemVec)164 bool AppDetailsRdbDataMgr::UpdateMetaData(std::vector<MetaItem> &itemVec)
165 {
166 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
167 auto rdbStore = GetRdbStore();
168 if (!rdbStore) {
169 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
170 return false;
171 }
172 for (auto& item : itemVec) {
173 NativeRdb::ValuesBucket valuesBucket;
174 item.AddRdbItemToBucket(valuesBucket);
175 int64_t rowId = 0;
176 auto ret = rdbStore->InsertWithConflictResolution(rowId, META_DATA, valuesBucket,
177 NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
178 if (ret != NativeRdb::E_OK) {
179 return CheckRdbReturnIfOk(ret);
180 }
181 }
182 return true;
183 };
184
QueryMetaData(const std::string & tableName,MetaItem & info)185 bool AppDetailsRdbDataMgr::QueryMetaData(const std::string &tableName, MetaItem &info)
186 {
187 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call.");
188 NativeRdb::AbsRdbPredicates absRdbPred(META_DATA);
189 absRdbPred.EqualTo(META_TABLE_NAME, tableName);
190 std::vector<std::string> columns = {};
191 auto rdbStore = GetRdbStore();
192 if (!rdbStore) {
193 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
194 return false;
195 }
196 std::vector<MetaItem> itemVec;
197 RdbForEachRetCb eachCb = [&itemVec](std::shared_ptr<AbsSharedResultSet> retSet)->bool {
198 MetaItem item;
199 if (!item.GetRdbItem(retSet)) {
200 return false;
201 }
202 itemVec.emplace_back(item);
203 return true;
204 };
205 if (Query(absRdbPred, columns, eachCb)) {
206 info = itemVec.front();
207 return true;
208 };
209 return false;
210 };
211
CreateTable(const std::string & tableName)212 bool AppDetailsRdbDataMgr::CreateTable(const std::string &tableName)
213 {
214 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
215 std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName
216 + " ("
217 "ID TEXT NOT NULL PRIMARY KEY,"
218 "SCHEME TEXT,"
219 "DOMAIN TEXT,"
220 "PATH_TYPE TEXT,"
221 "PATH TEXT,"
222 "BUNDLE_NAME TEXT"
223 + " );";
224 auto rdbStore = GetRdbStore();
225 if (!rdbStore) {
226 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
227 return false;
228 }
229 auto ret = rdbStore->ExecuteSql(sql);
230 if (ret != NativeRdb::E_OK) {
231 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "exec sql fail. ret:%{public}d", ret);
232 return false;
233 }
234 return true;
235 };
236
CreateRegularIndex(const std::string & tableName,const std::string & colName)237 bool AppDetailsRdbDataMgr::CreateRegularIndex(const std::string& tableName, const std::string& colName)
238 {
239 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
240 std::string sql = "CREATE INDEX IF NOT EXISTS " + colName + "_INDEX " + "ON " + tableName + " (" + colName + ");";
241 auto rdbStore = GetRdbStore();
242 if (!rdbStore) {
243 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
244 return false;
245 }
246 auto ret = rdbStore->ExecuteSql(sql);
247 if (ret != NativeRdb::E_OK) {
248 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "exec sql fail. ret:%{public}d", ret);
249 return false;
250 }
251 return true;
252 };
253
DeleteTable(const std::string & tableName)254 bool AppDetailsRdbDataMgr::DeleteTable(const std::string &tableName)
255 {
256 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "Called");
257 std::string sql = "DROP TABLE IF EXISTS " + tableName + ";";
258 auto rdbStore = GetRdbStore();
259 if (!rdbStore) {
260 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "Get rdbStore fail.");
261 return false;
262 }
263 auto ret = rdbStore->ExecuteSql(sql);
264 if (ret != NativeRdb::E_OK) {
265 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "Exec sql fail. ret:%{public}d", ret);
266 return false;
267 }
268 return true;
269 };
270
GetDbVersion()271 std::string AppDetailsRdbDataMgr::GetDbVersion()
272 {
273 auto rdbStore = GetRdbStore();
274 if (!rdbStore) {
275 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
276 return "";
277 }
278 int version = -1;
279 rdbStore->GetVersion(version);
280 if (version != -1) {
281 return std::to_string(version);
282 }
283 return "";
284 };
285
RenameTable(const std::string & oldName,const std::string & newName)286 bool AppDetailsRdbDataMgr::RenameTable(const std::string &oldName, const std::string &newName)
287 {
288 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
289 std::string sql = "ALTER TABLE " + oldName + " RENAME TO " + newName + ";";
290 auto rdbStore = GetRdbStore();
291 if (!rdbStore) {
292 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail.");
293 return false;
294 }
295 auto ret = rdbStore->ExecuteSql(sql);
296 if (ret != NativeRdb::E_OK) {
297 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "exec sql fail. ret:%{public}d", ret);
298 return false;
299 }
300 return true;
301 };
302
GetRdbStore()303 std::shared_ptr<NativeRdb::RdbStore> AppDetailsRdbDataMgr::GetRdbStore()
304 {
305 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
306 std::lock_guard<ffrt::mutex> lock(mtx_);
307 if (rdbStore_ != nullptr) {
308 return rdbStore_;
309 }
310 NativeRdb::RdbStoreConfig rdbStoreConfig(conf_.rdbPath + conf_.rdbName);
311 rdbStoreConfig.SetCreateNecessary(conf_.fileCreated);
312 rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
313 int32_t errCode = NativeRdb::E_OK;
314 AppDetailsRdbOpenCallback appDomainVerifyRdbOpenCallback(conf_);
315 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(
316 rdbStoreConfig, conf_.version, appDomainVerifyRdbOpenCallback, errCode);
317 if (errCode == NativeRdb::E_OK) {
318 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore success.");
319 PostDelayCloseTask(CLOSE_DELAY_TIME_S);
320 } else {
321 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "get rdbStore fail, err:%{public}d", errCode);
322 }
323 return rdbStore_;
324 };
325
CheckRdbReturnIfOk(int errcode)326 bool AppDetailsRdbDataMgr::CheckRdbReturnIfOk(int errcode)
327 {
328 if (errcode != NativeRdb::E_OK) {
329 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb failed, ret: %{public}d", errcode);
330 return false;
331 }
332 return true;
333 }
334
Query(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns,RdbForEachRetCb cb)335 bool AppDetailsRdbDataMgr::Query(const NativeRdb::AbsRdbPredicates& predicates,
336 const std::vector<std::string>& columns, RdbForEachRetCb cb)
337 {
338 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
339 auto rdbStore = GetRdbStore();
340 if (!rdbStore) {
341 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb store is null");
342 return false;
343 }
344 auto absSharedResultSet = rdbStore->Query(predicates, columns);
345 if (absSharedResultSet == nullptr) {
346 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdbStore query absSharedResultSet failed");
347 return false;
348 }
349 auto guard = std::unique_ptr<void, std::function<void(void*)>>(nullptr,
350 [&](void*) {
351 absSharedResultSet->Close();
352 });
353 if (!absSharedResultSet->HasBlock()) {
354 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "absSharedResultSet has no block");
355 return false;
356 }
357 if (CheckRdbReturnIfOk(absSharedResultSet->GoToFirstRow())) {
358 do {
359 if (!cb(absSharedResultSet)) {
360 return false;
361 }
362 } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
363 } else {
364 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "GoToFirstRow fail, seems rdb table empty");
365 return false;
366 }
367 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
368 return true;
369 };
370
371 }
372 }
373