• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 #define MLOG_TAG "FetchResult"
16 
17 #include "fetch_result.h"
18 #include "album_asset.h"
19 #include "media_log.h"
20 #include "medialibrary_tracer.h"
21 
22 using namespace std;
23 
24 namespace OHOS {
25 namespace Media {
26 static const unordered_map<string, ResultSetDataType> RESULT_TYPE_MAP = {
27     { MEDIA_DATA_DB_ID, TYPE_INT32 },
28     { MEDIA_DATA_DB_NAME, TYPE_STRING },
29     { MEDIA_DATA_DB_RELATIVE_PATH, TYPE_STRING },
30     { MEDIA_DATA_DB_MEDIA_TYPE, TYPE_INT32 },
31     { MEDIA_DATA_DB_PARENT_ID, TYPE_INT32 },
32     { MEDIA_DATA_DB_SIZE, TYPE_INT64 },
33     { MEDIA_DATA_DB_DATE_ADDED, TYPE_INT64 },
34     { MEDIA_DATA_DB_DATE_MODIFIED, TYPE_INT64 },
35     { MEDIA_DATA_DB_DATE_TAKEN, TYPE_INT64 },
36     { MEDIA_DATA_DB_FILE_PATH, TYPE_STRING },
37     { MEDIA_DATA_DB_MIME_TYPE, TYPE_STRING },
38     { MEDIA_DATA_DB_TITLE, TYPE_STRING },
39     { MEDIA_DATA_DB_ARTIST, TYPE_STRING },
40     { MEDIA_DATA_DB_ALBUM, TYPE_STRING },
41     { MEDIA_DATA_DB_WIDTH, TYPE_INT32 },
42     { MEDIA_DATA_DB_HEIGHT, TYPE_INT32 },
43     { MEDIA_DATA_DB_DURATION, TYPE_INT32 },
44     { MEDIA_DATA_DB_ORIENTATION, TYPE_INT32 },
45     { MEDIA_DATA_DB_BUCKET_ID, TYPE_INT32 },
46     { MEDIA_DATA_DB_BUCKET_NAME, TYPE_STRING },
47     { MEDIA_DATA_DB_TIME_PENDING, TYPE_INT64 },
48     { MEDIA_DATA_DB_IS_PENDING, TYPE_INT32 },
49     { MEDIA_DATA_DB_IS_FAV, TYPE_INT32 },
50     { MEDIA_DATA_DB_DATE_TRASHED, TYPE_INT64 },
51     { MEDIA_DATA_DB_SELF_ID, TYPE_STRING },
52     { MEDIA_DATA_DB_RECYCLE_PATH, TYPE_STRING },
53     { MEDIA_DATA_DB_IS_TRASH, TYPE_INT32 },
54     { MEDIA_DATA_DB_AUDIO_ALBUM, TYPE_STRING },
55 };
56 
57 template <class T>
FetchResult(const shared_ptr<DataShare::DataShareResultSet> & resultset)58 FetchResult<T>::FetchResult(const shared_ptr<DataShare::DataShareResultSet> &resultset)
59 {
60     count_ = 0;
61     if (resultset != nullptr) {
62         resultset->GetRowCount(count_);
63     }
64     isContain_ = count_ > 0;
65     isClosed_ = false;
66     resultset_ = resultset;
67     networkId_ = "";
68     resultNapiType_ = ResultNapiType::TYPE_NAPI_MAX;
69     if (std::is_same<T, FileAsset>::value) {
70         fetchResType_ = FetchResType::TYPE_FILE;
71     } else if (std::is_same<T, AlbumAsset>::value) {
72         fetchResType_ = FetchResType::TYPE_ALBUM;
73     } else if (std::is_same<T, SmartAlbumAsset>::value) {
74         fetchResType_ = FetchResType::TYPE_SMARTALBUM;
75     } else {
76         MEDIA_ERR_LOG("unsupported FetchResType");
77         fetchResType_ = FetchResType::TYPE_FILE;
78     }
79 }
80 
81 template <class T>
82 // empty constructor napi
FetchResult()83 FetchResult<T>::FetchResult()
84     : isContain_(false), isClosed_(false), count_(0), resultNapiType_(ResultNapiType::TYPE_NAPI_MAX),
85       resultset_(nullptr) {}
86 
87 template <class T>
~FetchResult()88 FetchResult<T>::~FetchResult() {}
89 
90 template <class T>
Close()91 void FetchResult<T>::Close()
92 {
93     isClosed_ = true;
94 }
95 
96 template <class T>
IsContain()97 bool FetchResult<T>::IsContain()
98 {
99     return isContain_;
100 }
101 
102 template <class T>
GetCount()103 int32_t FetchResult<T>::GetCount()
104 {
105     return count_;
106 }
107 
108 template <class T>
IsClosed()109 bool FetchResult<T>::IsClosed()
110 {
111     return isClosed_;
112 }
113 
114 template <class T>
SetInfo(unique_ptr<FetchResult<T>> & fetch)115 void FetchResult<T>::SetInfo(unique_ptr<FetchResult<T>> &fetch)
116 {
117     isContain_ = fetch->isContain_;
118     isClosed_ = fetch->isClosed_;
119     count_ = fetch->count_;
120     networkId_ = fetch->networkId_;
121     resultNapiType_ = fetch->resultNapiType_;
122     typeMask_ = fetch->typeMask_;
123 }
124 
125 template <class T>
SetNetworkId(const string & networkId)126 void FetchResult<T>::SetNetworkId(const string &networkId)
127 {
128     networkId_ = networkId;
129 }
130 
131 template <class T>
GetObjectAtPosition(int32_t index)132 unique_ptr<T> FetchResult<T>::GetObjectAtPosition(int32_t index)
133 {
134     if ((index < 0) || (index > (count_ - 1)) || (resultset_ == nullptr)) {
135         MEDIA_ERR_LOG("index not proper or rs is null");
136         return nullptr;
137     }
138 
139     if (resultset_->GoToRow(index) != 0) {
140         MEDIA_ERR_LOG("failed to go to row at index pos");
141         return nullptr;
142     }
143 
144     return GetObject();
145 }
146 
147 template <class T>
GetFirstObject()148 unique_ptr<T> FetchResult<T>::GetFirstObject()
149 {
150     if ((resultset_ == nullptr) || (resultset_->GoToFirstRow() != 0)) {
151         MEDIA_ERR_LOG("resultset is null|first row failed");
152         return nullptr;
153     }
154 
155     return GetObject();
156 }
157 
158 template <class T>
GetNextObject()159 unique_ptr<T> FetchResult<T>::GetNextObject()
160 {
161     if ((resultset_ == nullptr) || (resultset_->GoToNextRow() != 0)) {
162         MEDIA_ERR_LOG("resultset is null|go to next row failed");
163         return nullptr;
164     }
165 
166     return GetObject();
167 }
168 
169 template <class T>
GetLastObject()170 unique_ptr<T> FetchResult<T>::GetLastObject()
171 {
172     if ((resultset_ == nullptr) || (resultset_->GoToLastRow() != 0)) {
173         MEDIA_ERR_LOG("resultset is null|go to last row failed");
174         return nullptr;
175     }
176 
177     return GetObject();
178 }
179 
180 template <class T>
IsAtLastRow()181 bool FetchResult<T>::IsAtLastRow()
182 {
183     if (resultset_ == nullptr) {
184         MEDIA_ERR_LOG("resultset null");
185         return false;
186     }
187 
188     bool retVal = false;
189     resultset_->IsAtLastRow(retVal);
190     return retVal;
191 }
192 
ReturnDefaultOnError(string errMsg,ResultSetDataType dataType)193 variant<int32_t, int64_t, string> ReturnDefaultOnError(string errMsg, ResultSetDataType dataType)
194 {
195     MEDIA_ERR_LOG("%{public}s", errMsg.c_str());
196     if (dataType == TYPE_STRING) {
197         return "";
198     } else if (dataType == TYPE_INT64) {
199         return static_cast<int64_t>(0);
200     } else {
201         return 0;
202     }
203 }
204 
205 template <class T>
GetRowValFromColumn(string columnName,ResultSetDataType dataType,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)206 variant<int32_t, int64_t, string> FetchResult<T>::GetRowValFromColumn(string columnName, ResultSetDataType dataType,
207     shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
208 {
209     if ((resultset_ == nullptr) && (resultSet == nullptr)) {
210         return ReturnDefaultOnError("Resultset is null", dataType);
211     }
212     int index;
213     int status;
214     if (resultSet) {
215         status = resultSet->GetColumnIndex(columnName, index);
216     } else {
217         status = resultset_->GetColumnIndex(columnName, index);
218     }
219     if (status != NativeRdb::E_OK) {
220         ReturnDefaultOnError("failed to obtain the index", dataType);
221     }
222     return GetValByIndex(index, dataType, resultSet);
223 }
224 
225 template <class T>
GetValByIndex(int32_t index,ResultSetDataType dataType,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)226 variant<int32_t, int64_t, string> FetchResult<T>::GetValByIndex(int32_t index, ResultSetDataType dataType,
227     shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
228 {
229     if ((resultset_ == nullptr) && (resultSet == nullptr)) {
230         return ReturnDefaultOnError("Resultset is null", dataType);
231     }
232 
233     variant<int32_t, int64_t, string> cellValue;
234     int integerVal = 0;
235     string stringVal = "";
236     int64_t longVal = 0;
237     int status;
238     switch (dataType) {
239         case TYPE_STRING:
240             if (resultSet) {
241                 status = resultSet->GetString(index, stringVal);
242             } else {
243                 status = resultset_->GetString(index, stringVal);
244             }
245             cellValue = stringVal;
246             break;
247         case TYPE_INT32:
248             if (resultSet) {
249                 status = resultSet->GetInt(index, integerVal);
250             } else {
251                 status = resultset_->GetInt(index, integerVal);
252             }
253             cellValue = integerVal;
254             break;
255         case TYPE_INT64:
256             if (resultSet) {
257                 status = resultSet->GetLong(index, longVal);
258             } else {
259                 status = resultset_->GetLong(index, longVal);
260             }
261             cellValue = longVal;
262             break;
263         default:
264             MEDIA_ERR_LOG("not match  dataType %{public}d", dataType);
265             break;
266     }
267 
268     return cellValue;
269 }
270 
GetFileMediaTypeUri(MediaType mediaType,const string & networkId)271 static string GetFileMediaTypeUri(MediaType mediaType, const string &networkId)
272 {
273     string uri = MEDIALIBRARY_DATA_ABILITY_PREFIX + networkId + MEDIALIBRARY_DATA_URI_IDENTIFIER;
274     switch (mediaType) {
275         case MEDIA_TYPE_AUDIO:
276             return uri + MEDIALIBRARY_TYPE_AUDIO_URI;
277         case MEDIA_TYPE_VIDEO:
278             return uri + MEDIALIBRARY_TYPE_VIDEO_URI;
279         case MEDIA_TYPE_IMAGE:
280             return uri + MEDIALIBRARY_TYPE_IMAGE_URI;
281         case MEDIA_TYPE_FILE:
282         default:
283             return uri + MEDIALIBRARY_TYPE_FILE_URI;
284     }
285 }
286 
MediaTypeToMask(MediaType mediaType,std::string & typeMask)287 static void MediaTypeToMask(MediaType mediaType, std::string &typeMask)
288 {
289     typeMask.resize(TYPE_MASK_STRING_SIZE, TYPE_MASK_BIT_DEFAULT);
290     if ((mediaType >= MEDIA_TYPE_FILE) && (mediaType <= MEDIA_TYPE_AUDIO)) {
291         typeMask[std::get<POS_TYPE_MASK_STRING_INDEX>(MEDIA_TYPE_TUPLE_VEC[mediaType])] = TYPE_MASK_BIT_SET;
292     }
293 }
294 
UriAddFragmentTypeMask(std::string & uri,const std::string & typeMask)295 static void UriAddFragmentTypeMask(std::string &uri, const std::string &typeMask)
296 {
297     if (!typeMask.empty()) {
298         uri += "#" + URI_PARAM_KEY_TYPE + ":" + typeMask;
299     }
300 }
301 
302 template<class T>
GetFileCount(const shared_ptr<DataShare::DataShareResultSet> & resultSet)303 int32_t FetchResult<T>::GetFileCount(const shared_ptr<DataShare::DataShareResultSet> &resultSet)
304 {
305     int32_t count = 1;
306     if (resultSet) {
307         string name;
308         resultSet->GetColumnName(0, name);
309         if (name.find("count(") != string::npos) {
310             resultSet->GetInt(0, count);
311         }
312     }
313     return count;
314 }
315 
316 template<class T>
SetFileAsset(FileAsset * fileAsset,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)317 void FetchResult<T>::SetFileAsset(FileAsset *fileAsset, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
318 {
319     if ((resultset_ == nullptr) && (resultSet == nullptr)) {
320         MEDIA_ERR_LOG("SetFileAsset fail, result is nullptr");
321         return;
322     }
323     vector<string> columnNames;
324     if (resultSet != nullptr) {
325         resultSet->GetAllColumnNames(columnNames);
326     } else {
327         resultset_->GetAllColumnNames(columnNames);
328     }
329     int32_t index = -1;
330     auto &map = fileAsset->GetMemberMap();
331     for (const auto &name : columnNames) {
332         index++;
333         if (RESULT_TYPE_MAP.count(name) == 0) {
334             continue;
335         }
336         auto memberType = RESULT_TYPE_MAP.at(name);
337         map.emplace(move(name), move(GetValByIndex(index, memberType, resultSet)));
338     }
339     fileAsset->SetResultNapiType(resultNapiType_);
340     fileAsset->SetCount(GetFileCount(resultset_));
341     string typeMask;
342     MediaTypeToMask(fileAsset->GetMediaType(), typeMask);
343     string uri = GetFileMediaTypeUri(fileAsset->GetMediaType(), networkId_) + "/" + to_string(fileAsset->GetId());
344     if (resultNapiType_ == ResultNapiType::TYPE_USERFILE_MGR) {
345         UriAddFragmentTypeMask(uri, typeMask);
346     }
347     fileAsset->SetUri(uri);
348 }
349 
350 template<class T>
GetObjectFromAsset(FileAsset * asset,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)351 void FetchResult<T>::GetObjectFromAsset(FileAsset *asset, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
352 {
353     SetFileAsset(asset, resultSet);
354 }
355 
356 template<class T>
GetObjectFromAsset(AlbumAsset * asset,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)357 void FetchResult<T>::GetObjectFromAsset(AlbumAsset *asset, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
358 {
359     SetAlbumAsset(asset, resultSet);
360 }
361 
362 template<class T>
GetObjectFromAsset(SmartAlbumAsset * asset,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)363 void FetchResult<T>::GetObjectFromAsset(SmartAlbumAsset *asset, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
364 {
365     SetSmartAlbumAsset(asset, resultSet);
366 }
367 
368 template<class T>
GetObject(shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)369 unique_ptr<T> FetchResult<T>::GetObject(shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
370 {
371     MediaLibraryTracer tracer;
372     tracer.Start("FetchResult::GetObject");
373     unique_ptr<T> asset = make_unique<T>();
374     GetObjectFromAsset(asset.get(), resultSet);
375     return asset;
376 }
377 
378 template <class T>
GetObject()379 unique_ptr<T> FetchResult<T>::GetObject()
380 {
381     shared_ptr<NativeRdb::AbsSharedResultSet> resultSet = nullptr;
382     return GetObject(resultSet);
383 }
384 
385 template <class T>
GetObjectFromRdb(shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,int idx)386 unique_ptr<T> FetchResult<T>::GetObjectFromRdb(shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet, int idx)
387 {
388     if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != 0) || (resultSet->GoTo(idx))) {
389         MEDIA_ERR_LOG("resultset is null|first row failed");
390         return nullptr;
391     }
392 
393     return GetObject(resultSet);
394 }
395 
396 template<class T>
SetAlbumAsset(AlbumAsset * albumData,shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)397 void FetchResult<T>::SetAlbumAsset(AlbumAsset *albumData, shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
398 {
399     // Get album id index and value
400     albumData->SetAlbumId(get<int32_t>(GetRowValFromColumn(MEDIA_DATA_DB_BUCKET_ID, TYPE_INT32, resultSet)));
401 
402     // Get album title index and value
403     albumData->SetAlbumName(get<string>(GetRowValFromColumn(MEDIA_DATA_DB_TITLE, TYPE_STRING, resultSet)));
404 
405     // Get album asset count index and value
406     albumData->SetCount(get<int32_t>(GetRowValFromColumn(MEDIA_DATA_DB_COUNT, TYPE_INT32, resultSet)));
407     albumData->SetAlbumUri(GetFileMediaTypeUri(MEDIA_TYPE_ALBUM, networkId_) + "/" +
408         to_string(albumData->GetAlbumId()));
409     // Get album relativePath index and value
410     albumData->SetAlbumRelativePath(get<string>(GetRowValFromColumn(MEDIA_DATA_DB_RELATIVE_PATH,
411         TYPE_STRING, resultSet)));
412     albumData->SetAlbumDateModified(get<int64_t>(GetRowValFromColumn(MEDIA_DATA_DB_DATE_MODIFIED,
413         TYPE_INT64, resultSet)));
414 
415     albumData->SetResultNapiType(resultNapiType_);
416     albumData->SetAlbumTypeMask(typeMask_);
417 }
418 
419 template<class T>
SetSmartAlbumAsset(SmartAlbumAsset * smartAlbumData,std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)420 void FetchResult<T>::SetSmartAlbumAsset(SmartAlbumAsset* smartAlbumData,
421     std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
422 {
423     smartAlbumData->SetAlbumId(get<int32_t>(GetRowValFromColumn(SMARTALBUM_DB_ID, TYPE_INT32, resultSet)));
424     smartAlbumData->SetAlbumName(get<string>(GetRowValFromColumn(SMARTALBUM_DB_NAME, TYPE_STRING, resultSet)));
425     smartAlbumData->SetAlbumCapacity(get<int32_t>(GetRowValFromColumn(SMARTALBUM_DB_CAPACITY, TYPE_INT32, resultSet)));
426     smartAlbumData->SetResultNapiType(resultNapiType_);
427     smartAlbumData->SetTypeMask(typeMask_);
428 }
429 
430 template class FetchResult<FileAsset>;
431 template class FetchResult<AlbumAsset>;
432 template class FetchResult<SmartAlbumAsset>;
433 }  // namespace Media
434 }  // namespace OHOS
435