1 /*
2 * Copyright (c) 2023 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 "pkg_db_helper.h"
17 #include "bundle_installer_interface.h"
18 #include "hilog_wrapper.h"
19 #include "pkg_database.h"
20
21 using namespace OHOS::NativeRdb;
22
23 namespace OHOS {
24 namespace ExternalDeviceManager {
25 std::shared_ptr<PkgDbHelper> PkgDbHelper::instance_;
26 bool g_dbInitSucc = false;
27
PkgDbHelper()28 PkgDbHelper::PkgDbHelper()
29 {
30 rightDatabase_ = PkgDataBase::GetInstance();
31 g_dbInitSucc = rightDatabase_->InitDB();
32 }
33
GetInstance()34 std::shared_ptr<PkgDbHelper> PkgDbHelper::GetInstance()
35 {
36 static std::mutex instanceMutex;
37 std::lock_guard<std::mutex> guard(instanceMutex);
38 if (instance_ == nullptr || !g_dbInitSucc) {
39 EDM_LOGE(MODULE_PKG_MGR, "PkgDbHelper reset to new instance");
40 instance_.reset(new PkgDbHelper());
41 }
42 return instance_;
43 }
44
DeleteAndNoOtherOperation(const std::string & whereClause,const std::vector<std::string> & whereArgs)45 int32_t PkgDbHelper::DeleteAndNoOtherOperation(
46 const std::string &whereClause, const std::vector<std::string> &whereArgs)
47 {
48 int32_t ret = rightDatabase_->BeginTransaction();
49 if (ret < PKG_OK) {
50 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
51 return ret;
52 }
53 int32_t changedRows = 0;
54 ret = rightDatabase_->Delete(changedRows, whereClause, whereArgs);
55 if (ret < PKG_OK) {
56 EDM_LOGE(MODULE_PKG_MGR, "Delete error: %{public}d", ret);
57 (void)rightDatabase_->RollBack();
58 return ret;
59 }
60 ret = rightDatabase_->Commit();
61 if (ret < PKG_OK) {
62 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
63 (void)rightDatabase_->RollBack();
64 }
65 return ret;
66 }
67
DeleteRightRecord(const std::string & bundleName)68 int32_t PkgDbHelper::DeleteRightRecord(const std::string &bundleName)
69 {
70 std::lock_guard<std::mutex> guard(databaseMutex_);
71 std::string whereClause = {"bundleName = ?"};
72 std::vector<std::string> whereArgs = {bundleName};
73 int32_t ret = DeleteAndNoOtherOperation(whereClause, whereArgs);
74 if (ret != PKG_OK) {
75 EDM_LOGE(MODULE_PKG_MGR, "failed: detale(uid, dev, app): %{public}d", ret);
76 }
77 return ret;
78 }
79
AddOrUpdateRightRecord(const std::string & bundleName,const std::string & bundleAbility,const std::string & driverInfo)80 int32_t PkgDbHelper::AddOrUpdateRightRecord(
81 const std::string & bundleName, const std::string & bundleAbility, const std::string &driverInfo)
82 {
83 std::lock_guard<std::mutex> guard(databaseMutex_);
84 int32_t ret = rightDatabase_->BeginTransaction();
85 if (ret < PKG_OK) {
86 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
87 return ret;
88 }
89 bool isUpdate = false;
90 ret = CheckIfNeedUpdateEx(isUpdate, bundleAbility);
91 if (ret < PKG_OK) {
92 EDM_LOGE(MODULE_PKG_MGR, "check if need update error: %{public}d", ret);
93 return ret;
94 }
95 ret = AddOrUpdateRightRecordEx(isUpdate, bundleName, bundleAbility, driverInfo);
96 if (ret < PKG_OK) {
97 EDM_LOGE(MODULE_PKG_MGR, "add or update error: %{public}d", ret);
98 return ret;
99 }
100 ret = rightDatabase_->Commit();
101 if (ret < PKG_OK) {
102 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
103 (void)rightDatabase_->RollBack();
104 }
105 return ret;
106 }
107
CheckIfNeedUpdateEx(bool & isUpdate,const std::string & bundleAbility)108 int32_t PkgDbHelper::CheckIfNeedUpdateEx(
109 bool &isUpdate, const std::string &bundleAbility)
110 {
111 std::vector<std::string> columns;
112 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
113 rdbPredicates.BeginWrap()
114 ->EqualTo("bundleAbility", bundleAbility)
115 ->EndWrap();
116 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
117 if (resultSet == nullptr) {
118 EDM_LOGE(MODULE_PKG_MGR, "Query error");
119 (void)rightDatabase_->RollBack();
120 return PKG_RDB_EXECUTE_FAILTURE;
121 }
122 int32_t rowCount = 0;
123 if (resultSet->GetRowCount(rowCount) != E_OK) {
124 EDM_LOGE(MODULE_PKG_MGR, "GetRowCount error");
125 (void)rightDatabase_->RollBack();
126 return PKG_RDB_EXECUTE_FAILTURE;
127 }
128 isUpdate = (rowCount > 0 ? true : false);
129
130 return PKG_OK;
131 }
132
AddOrUpdateRightRecordEx(bool isUpdate,const std::string & bundleName,const std::string & bundleAbility,const std::string & driverInfo)133 int32_t PkgDbHelper::AddOrUpdateRightRecordEx(bool isUpdate,
134 const std::string & bundleName, const std::string & bundleAbility, const std::string &driverInfo)
135 {
136 int32_t ret = 0;
137 ValuesBucket values;
138 values.Clear();
139 values.PutString("bundleName", bundleName);
140 values.PutString("bundleAbility", bundleAbility);
141 values.PutString("driverInfo", driverInfo);
142 EDM_LOGI(MODULE_PKG_MGR, "bundleName: %{public}s driverInfo: %{public}s",
143 bundleName.c_str(), driverInfo.c_str());
144 if (isUpdate) {
145 int32_t changedRows = 0;
146 ret = rightDatabase_->Update(changedRows, values, "bundleAbility = ?",
147 std::vector<std::string> {bundleAbility});
148 } else {
149 ret = rightDatabase_->Insert(values);
150 }
151 if (ret < PKG_OK) {
152 EDM_LOGE(MODULE_PKG_MGR, "Insert or Update error: %{public}d", ret);
153 (void)rightDatabase_->RollBack();
154 }
155 return ret;
156 }
157
QueryAllDriverInfos(std::vector<std::string> & driverInfos)158 int32_t PkgDbHelper::QueryAllDriverInfos(std::vector<std::string> &driverInfos)
159 {
160 std::lock_guard<std::mutex> guard(databaseMutex_);
161 std::vector<std::string> columns = {"driverInfo"};
162 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
163 return QueryAndGetResultColumnValues(rdbPredicates, columns, "driverInfo", driverInfos);
164 }
165
QueryAllBundleAbilityNames(const std::string & bundleName,std::vector<std::string> & bundleAbilityNames)166 int32_t PkgDbHelper::QueryAllBundleAbilityNames(const std::string &bundleName,
167 std::vector<std::string> &bundleAbilityNames)
168 {
169 std::lock_guard<std::mutex> guard(databaseMutex_);
170 std::vector<std::string> columns = {"bundleAbility"};
171 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
172 rdbPredicates.EqualTo("bundleName", bundleName)->Distinct();
173 return QueryAndGetResultColumnValues(rdbPredicates, columns, "bundleAbility", bundleAbilityNames);
174 }
175
QueryAllSize(std::vector<std::string> & allBundleAbility)176 int32_t PkgDbHelper::QueryAllSize(std::vector<std::string> &allBundleAbility)
177 {
178 std::lock_guard<std::mutex> guard(databaseMutex_);
179 std::vector<std::string> columns = {"bundleAbility"};
180 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
181 return QueryAndGetResultColumnValues(rdbPredicates, columns, "bundleAbility", allBundleAbility);
182 }
183
QueryAndGetResultColumnValues(const RdbPredicates & rdbPredicates,const std::vector<std::string> & columns,const std::string & columnName,std::vector<std::string> & columnValues)184 int32_t PkgDbHelper::QueryAndGetResultColumnValues(const RdbPredicates &rdbPredicates,
185 const std::vector<std::string> &columns, const std::string &columnName, std::vector<std::string> &columnValues)
186 {
187 int32_t ret = rightDatabase_->BeginTransaction();
188 if (ret < PKG_OK) {
189 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
190 return ret;
191 }
192 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
193 if (resultSet == nullptr) {
194 EDM_LOGE(MODULE_PKG_MGR, "Query error");
195 (void)rightDatabase_->RollBack();
196 return PKG_RDB_EXECUTE_FAILTURE;
197 }
198 ret = rightDatabase_->Commit();
199 if (ret < PKG_OK) {
200 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
201 (void)rightDatabase_->RollBack();
202 return ret;
203 }
204 int32_t rowCount = 0;
205 int32_t columnIndex = 0;
206 if (resultSet->GetRowCount(rowCount) != E_OK || resultSet->GetColumnIndex(columnName, columnIndex) != E_OK) {
207 EDM_LOGE(MODULE_PKG_MGR, "get table info failed");
208 return PKG_RDB_EXECUTE_FAILTURE;
209 }
210 bool endFlag = false;
211 for (int32_t i = 0; (i < rowCount) && !endFlag; i++) {
212 if (resultSet->GoToRow(i) != E_OK) {
213 EDM_LOGE(MODULE_PKG_MGR, "GoToRow %{public}d", i);
214 return PKG_RDB_EXECUTE_FAILTURE;
215 }
216 std::string tempStr;
217 if (resultSet->GetString(columnIndex, tempStr) == E_OK) {
218 columnValues.push_back(tempStr);
219 }
220 resultSet->IsEnded(endFlag);
221 }
222 int32_t position = 0;
223 resultSet->GetRowIndex(position);
224 resultSet->IsEnded(endFlag);
225 EDM_LOGI(MODULE_PKG_MGR, "idx=%{public}d rows=%{public}d pos=%{public}d ret=%{public}zu end=%{public}s",
226 columnIndex, rowCount, position, columnValues.size(), (endFlag ? "yes" : "no"));
227 return columnValues.size();
228 }
229
QueryBundleInfoNames(const std::string & driverInfo)230 std::string PkgDbHelper::QueryBundleInfoNames(const std::string &driverInfo)
231 {
232 std::lock_guard<std::mutex> guard(databaseMutex_);
233 std::vector<std::string> columns = {"bundleAbility"};
234 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
235 rdbPredicates.EqualTo("driverInfo", driverInfo)->Distinct();
236 int32_t ret = rightDatabase_->BeginTransaction();
237 if (ret < PKG_OK) {
238 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
239 return "";
240 }
241 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
242 if (resultSet == nullptr) {
243 EDM_LOGE(MODULE_PKG_MGR, "Query error");
244 (void)rightDatabase_->RollBack();
245 return "";
246 }
247 ret = rightDatabase_->Commit();
248 if (ret < PKG_OK) {
249 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
250 (void)rightDatabase_->RollBack();
251 return "";
252 }
253 int32_t rowCount = 0;
254 ret = resultSet->GetRowCount(rowCount);
255 if (ret != E_OK || rowCount == 0) {
256 EDM_LOGE(MODULE_PKG_MGR, "Query data error: %{public}d, count: %{public}d", ret, rowCount);
257 return "";
258 }
259 ret = resultSet->GoToRow(0);
260 if (ret != E_OK) {
261 EDM_LOGE(MODULE_PKG_MGR, "GoToRow 0 error: %{public}d", ret);
262 return "";
263 }
264 std::string s;
265 ret = resultSet->GetString(0, s);
266 if (ret != E_OK) {
267 EDM_LOGE(MODULE_PKG_MGR, "get value error: %{public}d", ret);
268 return "";
269 }
270 return s;
271 }
272 } // namespace USB
273 } // namespace OHOS
274