• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "download_data_ability.h"
17 
18 #include <mutex>
19 
20 #include "ability_loader.h"
21 #include "common_event.h"
22 #include "constant.h"
23 #include "data_ability_predicates.h"
24 #include "db_path.h"
25 #include "file_utils.h"
26 #include "log.h"
27 #include "predicates_convert.h"
28 #include "rdb_predicates.h"
29 #include "sql_analyzer.h"
30 #include "uri_utils.h"
31 
32 
33 namespace OHOS::AppExecFwk {
34 REGISTER_AA(DownloadDataAbility);
35 namespace {
36 std::mutex g_mutex;
37 }
38 using namespace OHOS::Request::Download;
39 
40 std::shared_ptr<DownloadDataBase> DownloadDataAbility::database_ = nullptr;
41 std::map<std::string, int> DownloadDataAbility::uriValueMap_ = {
42     {"/com.ohos.download/download/downloadInfo", DOWNLOAD_INFO}};
43 
DownloadDataAbility()44 DownloadDataAbility::DownloadDataAbility()
45 {
46 }
47 
~DownloadDataAbility()48 DownloadDataAbility::~DownloadDataAbility()
49 {
50 }
51 
Dump(const std::string & extra)52 void DownloadDataAbility::Dump(const std::string &extra)
53 {
54     DOWNLOAD_HILOGE("DownloadDataAbility ====>Dump:%{public}s", extra.c_str());
55     FileUtils fileUtils;
56     std::string dirStr = DBPath::DUMP_PATH;
57     fileUtils.WriteStringToFileAppend(dirStr, extra);
58 }
59 
OnStart(const Want & want)60 void DownloadDataAbility::OnStart(const Want &want)
61 {
62     DOWNLOAD_HILOGE("DownloadDataAbility OnStart");
63     std::string basePath = GetDatabaseDir();
64     DBPath::RDB_PATH = basePath + "/";
65     DBPath::RDB_BACKUP_PATH = basePath + "/backup/";
66     DBPath::DUMP_PATH = GetFilesDir() + "/";
67 }
68 
UriParse(Uri & uri)69 int DownloadDataAbility::UriParse(Uri &uri)
70 {
71     UriUtils uriUtils;
72     int parseCode = uriUtils.UriParse(uri, uriValueMap_);
73     return parseCode;
74 }
75 
76 /**
77  * @brief DownloadDataAbility BeginTransaction emptiness problems
78  *
79  * @param code the return number of BeginTransaction
80  * @param mutex transmission parameter : lock
81  *
82  * @return BeginTransaction emptiness true or false
83  */
IsBeginTransactionOK(int code,std::mutex & mutex)84 bool DownloadDataAbility::IsBeginTransactionOK(int code, std::mutex &mutex)
85 {
86     mutex.try_lock();
87     if (code != 0) {
88         DOWNLOAD_HILOGE("IsBeginTransactionOK fail");
89         mutex.unlock();
90         return false;
91     }
92     return true;
93 }
94 
95 /**
96  * @brief DownloadDataAbility Commit emptiness problems
97  *
98  * @param code the return number of Commit
99  * @param mutex transmission parameter : lock
100  *
101  * @return Commit emptiness true or false
102  */
IsCommitOk(int code,std::mutex & mutex)103 bool DownloadDataAbility::IsCommitOk(int code, std::mutex &mutex)
104 {
105     mutex.try_lock();
106     if (code != 0) {
107         DOWNLOAD_HILOGE("IsCommitOk fail");
108         mutex.unlock();
109         return false;
110     }
111     return true;
112 }
113 
114 /**
115  * @brief DownloadDataAbility Insert database
116  *
117  * @param uri Determine the data table name based on the URI
118  * @param value Insert the data value of the database
119  *
120  * @return Insert database results code
121  */
Insert(const Uri & uri,const NativeRdb::ValuesBucket & value)122 int DownloadDataAbility::Insert(const Uri &uri, const NativeRdb::ValuesBucket &value)
123 {
124     DOWNLOAD_HILOGE("DownloadDataAbility Insert OnStart");
125     SqlAnalyzer sqlAnalyzer;
126     bool isOk = sqlAnalyzer.CheckValuesBucket(value);
127     if (!isOk) {
128         DOWNLOAD_HILOGE("DownloadDataAbility CheckValuesBucket is error");
129         return RDB_EXECUTE_FAIL;
130     }
131     g_mutex.lock();
132     database_ = DownloadDataBase::GetInstance();
133     int ret = database_->BeginTransaction();
134     if (!IsBeginTransactionOK(ret, g_mutex)) {
135         g_mutex.unlock();
136         return RDB_EXECUTE_FAIL;
137     }
138     int resultId = InsertExecute(uri, value);
139     DOWNLOAD_HILOGE("DownloadDataAbility Insert id %{public}d", resultId);
140     if (resultId == OPERATION_ERROR) {
141         DOWNLOAD_HILOGE("DownloadDataAbility Insert error");
142         ret = database_->RollBack();
143         g_mutex.unlock();
144         return OPERATION_ERROR;
145     }
146     ret = database_->Commit();
147     if (!IsCommitOk(ret, g_mutex)) {
148         DOWNLOAD_HILOGE("DownloadDataAbility Insert error Commit");
149         database_->RollBack();
150         g_mutex.unlock();
151         return RDB_EXECUTE_FAIL;
152     }
153     g_mutex.unlock();
154     DataBaseNotifyChange(DOWNLOAD_INSERT, uri);
155     return resultId;
156 }
157 
InsertExecute(const Uri & uri,const NativeRdb::ValuesBucket & value)158 int DownloadDataAbility::InsertExecute(const Uri &uri, const NativeRdb::ValuesBucket &value)
159 {
160     int rowId = RDB_EXECUTE_FAIL;
161     OHOS::Uri uriTemp = uri;
162     int parseCode = UriParse(uriTemp);
163     switch (parseCode) {
164         case DOWNLOAD_INFO:
165             rowId = database_->Insert(value);
166             break;
167         default:
168             DOWNLOAD_HILOGE("DownloadDataAbility ====>no match uri action");
169             break;
170     }
171     DOWNLOAD_HILOGI("DownloadDataAbility InsertExecute id = %{public}d", rowId);
172     return rowId;
173 }
174 
175 /**
176  * @brief DownloadDataAbility BatchInsert database
177  *
178  * @param uri Determine the data table name based on the URI
179  * @param value Insert the data values of the database
180  *
181  * @return Insert database results code
182  */
BatchInsert(const Uri & uri,const std::vector<NativeRdb::ValuesBucket> & values)183 int DownloadDataAbility::BatchInsert(const Uri &uri, const std::vector<NativeRdb::ValuesBucket> &values)
184 {
185     int rowRet = RDB_EXECUTE_FAIL;
186     int size = values.size();
187     if (size <= 0) {
188         DOWNLOAD_HILOGE("BatchInsert value is error");
189         return rowRet;
190     }
191     g_mutex.lock();
192     database_ = DownloadDataBase::GetInstance();
193     int ret = database_->BeginTransaction();
194     if (!IsBeginTransactionOK(ret, g_mutex)) {
195         g_mutex.unlock();
196         return RDB_EXECUTE_FAIL;
197     }
198     int count = 0;
199     for (int i = 0; i < size; i++) {
200         ++count;
201         OHOS::NativeRdb::ValuesBucket rawValues = values[i];
202         int code = InsertExecute(uri, rawValues);
203         if (code == RDB_EXECUTE_FAIL) {
204             database_->RollBack();
205             g_mutex.unlock();
206             return code;
207         }
208         if (count % TRANSACTION_COUNT == 0) {
209             int markRet = database_->Commit();
210             int beginRet = database_->BeginTransaction();
211             if (!IsCommitOk(markRet, g_mutex) || !IsBeginTransactionOK(beginRet, g_mutex)) {
212                 database_->RollBack();
213                 g_mutex.unlock();
214                 return RDB_EXECUTE_FAIL;
215             }
216         }
217     }
218     int markRet = database_->Commit();
219     if (!IsCommitOk(markRet, g_mutex)) {
220         database_->RollBack();
221         g_mutex.unlock();
222         return RDB_EXECUTE_FAIL;
223     }
224     g_mutex.unlock();
225     DataBaseNotifyChange(DOWNLOAD_INSERT, uri);
226     return RDB_EXECUTE_OK;
227 }
228 
229 /**
230  * @brief DownloadDataAbility Update database
231  *
232  * @param uri Determine the data table name based on the URI
233  * @param predicates Update the data value of the condition
234  *
235  * @return Update database results code
236  */
Update(const Uri & uri,const NativeRdb::ValuesBucket & value,const NativeRdb::DataAbilityPredicates & predicates)237 int DownloadDataAbility::Update(
238     const Uri &uri, const NativeRdb::ValuesBucket &value, const NativeRdb::DataAbilityPredicates &predicates)
239 {
240     SqlAnalyzer sqlAnalyzer;
241     bool isOk = sqlAnalyzer.CheckValuesBucket(value);
242     if (!isOk) {
243         DOWNLOAD_HILOGE("DownloadDataAbility CheckValuesBucket is error");
244         return RDB_EXECUTE_FAIL;
245     }
246     g_mutex.lock();
247     database_ = DownloadDataBase::GetInstance();
248     PredicatesConvert predicatesConvert;
249     int ret = RDB_EXECUTE_FAIL;
250     OHOS::Uri uriTemp = uri;
251     int parseCode = UriParse(uriTemp);
252     OHOS::NativeRdb::DataAbilityPredicates dataAbilityPredicates = predicates;
253     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
254     switch (parseCode) {
255         case DOWNLOAD_INFO:
256             rdbPredicates = predicatesConvert.ConvertPredicates(TABLE_NAME, dataAbilityPredicates);
257             ret = database_->Update(value, rdbPredicates);
258             break;
259         default:
260             DOWNLOAD_HILOGE("DownloadDataAbility ====>no match uri action");
261             break;
262     }
263     g_mutex.unlock();
264     DataBaseNotifyChange(DOWNLOAD_UPDATE, uri);
265     return ret;
266 }
267 
268 /**
269  * @brief DownloadDataAbility Delete database
270  *
271  * @param uri Determine the data table name based on the URI
272  * @param predicates Delete the data values of the condition
273  *
274  * @return Delete database results code
275  */
Delete(const Uri & uri,const NativeRdb::DataAbilityPredicates & predicates)276 int DownloadDataAbility::Delete(const Uri &uri, const NativeRdb::DataAbilityPredicates &predicates)
277 {
278     g_mutex.lock();
279     database_ = DownloadDataBase::GetInstance();
280     PredicatesConvert predicatesConvert;
281     int ret = RDB_EXECUTE_FAIL;
282     OHOS::Uri uriTemp = uri;
283     int parseCode = UriParse(uriTemp);
284     OHOS::NativeRdb::DataAbilityPredicates dataAbilityPredicates = predicates;
285     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
286     switch (parseCode) {
287         case DOWNLOAD_INFO:
288             rdbPredicates = predicatesConvert.ConvertPredicates(TABLE_NAME, dataAbilityPredicates);
289             ret = database_->Delete(rdbPredicates);
290             break;
291         default:
292             DOWNLOAD_HILOGE("DownloadDataAbility ====>no match uri action");
293             break;
294     }
295     g_mutex.unlock();
296     DataBaseNotifyChange(DOWNLOAD_DELETE, uri);
297     return ret;
298 }
299 
300 /**
301  * @brief DownloadDataAbility Query database
302  *
303  * @param uri Determine the data table name based on the URI
304  * @param columns Columns returned by query
305  * @param predicates Query the data values of the condition
306  *
307  * @return Query database results
308  */
Query(const Uri & uri,const std::vector<std::string> & columns,const NativeRdb::DataAbilityPredicates & predicates)309 std::shared_ptr<NativeRdb::AbsSharedResultSet> DownloadDataAbility::Query(
310     const Uri &uri, const std::vector<std::string> &columns, const NativeRdb::DataAbilityPredicates &predicates)
311 {
312     DOWNLOAD_HILOGI("DownloadDataAbility ====>Query start");
313     database_ = DownloadDataBase::GetInstance();
314     PredicatesConvert predicatesConvert;
315     std::shared_ptr<NativeRdb::AbsSharedResultSet> result;
316     OHOS::Uri uriTemp = uri;
317     UriUtils uriUtils;
318     int parseCode = uriUtils.UriParse(uriTemp, uriValueMap_);
319     OHOS::NativeRdb::DataAbilityPredicates dataAbilityPredicates = predicates;
320     OHOS::NativeRdb::RdbPredicates rdbPredicates("");
321     std::vector<std::string> columnsTemp = columns;
322     switch (parseCode) {
323         case DOWNLOAD_INFO:
324             rdbPredicates = predicatesConvert.ConvertPredicates(TABLE_NAME, dataAbilityPredicates);
325             result = database_->Query(rdbPredicates, columnsTemp);
326             break;
327         default:
328             DOWNLOAD_HILOGE("DownloadDataAbility ====>no match uri action");
329             break;
330     }
331     std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> sharedPtrResult = std::move(result);
332     DOWNLOAD_HILOGI("DownloadDataAbility ====>Query end");
333     return sharedPtrResult;
334 }
335 
DataBaseNotifyChange(int code,Uri uri)336 void DownloadDataAbility::DataBaseNotifyChange(int code, Uri uri)
337 {
338     CommonEvent::SendChange(code);
339 }
340 } // namespace OHOS::AppExecFwk