• 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 
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