• 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 #define MLOG_TAG "FileOperation"
16 
17 #include "medialibrary_file_operations.h"
18 
19 #include "datashare_predicates.h"
20 #include "datashare_values_bucket.h"
21 #include "file_asset.h"
22 #include "hitrace_meter.h"
23 #include "media_file_utils.h"
24 #include "media_log.h"
25 #include "medialibrary_db_const.h"
26 #include "medialibrary_errno.h"
27 #include "medialibrary_notify.h"
28 #include "medialibrary_object_utils.h"
29 #include "medialibrary_smartalbum_map_operations.h"
30 #include "medialibrary_tracer.h"
31 #include "medialibrary_unistore_manager.h"
32 #include "native_album_asset.h"
33 #include "rdb_utils.h"
34 
35 using namespace std;
36 using namespace OHOS::NativeRdb;
37 using namespace OHOS::DataShare;
38 using namespace OHOS::RdbDataShareAdapter;
39 
40 namespace OHOS {
41 namespace Media {
42 using ChangeType = AAFwk::ChangeInfo::ChangeType;
43 
HandleFileOperation(MediaLibraryCommand & cmd)44 int32_t MediaLibraryFileOperations::HandleFileOperation(MediaLibraryCommand &cmd)
45 {
46     int32_t errCode = E_FAIL;
47     auto values = cmd.GetValueBucket();
48     string actualUri;
49 
50     ValueObject valueObject;
51     if (values.GetObject(MEDIA_DATA_DB_URI, valueObject)) {
52         valueObject.GetString(actualUri);
53     }
54 
55     // only support CloseAsset when networkId is not empty
56     string networkId = MediaFileUtils::GetNetworkIdFromUri(actualUri);
57     if (!networkId.empty() && cmd.GetOprnType() != OperationType::CLOSE) {
58         return E_PERMISSION_DENIED;
59     }
60 
61     switch (cmd.GetOprnType()) {
62         case OperationType::CREATE:
63             errCode = CreateFileOperation(cmd);
64             break;
65         case OperationType::CLOSE:
66             errCode = CloseFileOperation(cmd);
67             break;
68         case OperationType::GETCAPACITY:
69             errCode = GetAlbumCapacityOperation(cmd);
70             break;
71         case OperationType::COPY:
72             errCode = CopyFileOperation(cmd);
73             break;
74         default:
75             MEDIA_ERR_LOG("unknown operation type %{public}d", cmd.GetOprnType());
76             break;
77     }
78     return errCode;
79 }
80 
CreateFileOperation(MediaLibraryCommand & cmd)81 int32_t MediaLibraryFileOperations::CreateFileOperation(MediaLibraryCommand &cmd)
82 {
83     return MediaLibraryObjectUtils::CreateFileObj(cmd);
84 }
85 
CloseFileOperation(MediaLibraryCommand & cmd)86 int32_t MediaLibraryFileOperations::CloseFileOperation(MediaLibraryCommand &cmd)
87 {
88     return MediaLibraryObjectUtils::CloseFile(cmd);
89 }
90 
QueryFavFiles(MediaLibraryCommand & cmd)91 shared_ptr<NativeRdb::ResultSet> MediaLibraryFileOperations::QueryFavFiles(MediaLibraryCommand &cmd)
92 {
93     cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_IS_FAV, "1");
94     cmd.GetAbsRdbPredicates()->And()->NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, std::to_string(MEDIA_TYPE_ALBUM));
95 
96     return MediaLibraryObjectUtils::QueryWithCondition(cmd, {});
97 }
98 
QueryTrashFiles(MediaLibraryCommand & cmd)99 shared_ptr<NativeRdb::ResultSet> MediaLibraryFileOperations::QueryTrashFiles(MediaLibraryCommand &cmd)
100 {
101     cmd.GetAbsRdbPredicates()
102         ->GreaterThan(MEDIA_DATA_DB_DATE_TRASHED, std::to_string(NOT_TRASHED))
103         ->And()
104         ->NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, std::to_string(MEDIA_TYPE_ALBUM));
105 
106     return MediaLibraryObjectUtils::QueryWithCondition(cmd, {});
107 }
108 
GetAlbumCapacityOperation(MediaLibraryCommand & cmd)109 int32_t MediaLibraryFileOperations::GetAlbumCapacityOperation(MediaLibraryCommand &cmd)
110 {
111     int32_t errorCode = E_FAIL;
112     shared_ptr<NativeRdb::ResultSet> resultSet = nullptr;
113 
114     auto values = cmd.GetValueBucket();
115     ValueObject valueObject;
116     int32_t isFavourite = 0;
117     bool isTrash = false;
118     if (values.GetObject(MEDIA_DATA_DB_IS_FAV, valueObject)) {
119         valueObject.GetInt(isFavourite);
120     }
121     if (values.GetObject(MEDIA_DATA_DB_IS_TRASH, valueObject)) {
122         valueObject.GetBool(isTrash);
123     }
124 
125     if (isFavourite != 0) {
126         resultSet = QueryFavFiles(cmd);
127     } else if (isTrash) {
128         resultSet = QueryTrashFiles(cmd);
129     }
130 
131     if (resultSet != nullptr) {
132         resultSet->GetRowCount(errorCode);
133         MEDIA_INFO_LOG("GetRowCount %{private}d", errorCode);
134     }
135 
136     return errorCode;
137 }
138 
ModifyFileOperation(MediaLibraryCommand & cmd)139 int32_t MediaLibraryFileOperations::ModifyFileOperation(MediaLibraryCommand &cmd)
140 {
141     string strFileId = cmd.GetOprnFileId();
142     if (strFileId.empty()) {
143         MEDIA_ERR_LOG("MediaLibraryFileOperations::ModifyFileOperation Get id from uri or valuesBucket failed!");
144         return E_INVALID_FILEID;
145     }
146 
147     string srcPath = MediaLibraryObjectUtils::GetPathByIdFromDb(strFileId);
148     if (srcPath.empty()) {
149         MEDIA_ERR_LOG("MediaLibraryFileOperations::ModifyFileOperation Get path of id %{private}s from database file!",
150             strFileId.c_str());
151         return E_INVALID_FILEID;
152     }
153 
154     string dstFileName;
155     string dstReFilePath;
156     auto values = cmd.GetValueBucket();
157     ValueObject valueObject;
158     if (values.GetObject(MEDIA_DATA_DB_NAME, valueObject)) {
159         valueObject.GetString(dstFileName);
160     }
161     if (values.GetObject(MEDIA_DATA_DB_RELATIVE_PATH, valueObject)) {
162         valueObject.GetString(dstReFilePath);
163     }
164     string dstFilePath = ROOT_MEDIA_DIR + dstReFilePath + dstFileName;
165 
166     if (srcPath.compare(dstFilePath) == 0) {
167         return E_SAME_PATH;
168     }
169     return MediaLibraryObjectUtils::RenameFileObj(cmd, srcPath, dstFilePath);
170 }
171 
172 constexpr bool START_PENDING = false;
SolvePendingInQuery(AbsRdbPredicates * predicates)173 static void SolvePendingInQuery(AbsRdbPredicates* predicates)
174 {
175     string whereClause = predicates->GetWhereClause();
176     size_t groupByPoint = whereClause.rfind("GROUP BY");
177     string groupBy;
178     if (groupByPoint != string::npos) {
179         groupBy = whereClause.substr(groupByPoint);
180         whereClause = whereClause.substr(0, groupByPoint);
181     }
182 
183     predicates->SetWhereClause(whereClause);
184     predicates->EqualTo(MEDIA_DATA_DB_TIME_PENDING, "0");
185     if (!groupBy.empty()) {
186         predicates->SetWhereClause(predicates->GetWhereClause() + groupBy);
187     }
188 }
189 
190 #ifdef MEDIALIBRARY_COMPATIBILITY
PhotosCompatColumns()191 static const vector<string> &PhotosCompatColumns()
192 {
193     /*
194      * Caution: Columns MUST KEEP SAME ORDER for sqlite UNION operation in:
195      *     o PHOTOS_COMPAT_COLUMNS
196      *     o AUDIOS_COMPAT_COLUMNS
197      *     o FILES_COMPAT_COLUMNS
198      */
199     static const vector<string> PHOTOS_COMPAT_COLUMNS = {
200         MEDIA_DATA_DB_ID,
201         MEDIA_DATA_DB_FILE_PATH,
202         COMPAT_COLUMN_URI,
203         MEDIA_DATA_DB_MIME_TYPE,
204         MEDIA_DATA_DB_MEDIA_TYPE,
205         MEDIA_DATA_DB_NAME,
206         MEDIA_DATA_DB_TITLE,
207         MEDIA_DATA_DB_RELATIVE_PATH,
208         MEDIA_DATA_DB_PARENT_ID,
209         MEDIA_DATA_DB_SIZE,
210         MEDIA_DATA_DB_DATE_ADDED,
211         MEDIA_DATA_DB_DATE_MODIFIED,
212         MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
213         MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND,
214         MEDIA_DATA_DB_DATE_TAKEN,
215         COMPAT_COLUMN_ARTIST,
216         COMPAT_COLUMN_AUDIO_ALBUM,
217         MEDIA_DATA_DB_WIDTH,
218         MEDIA_DATA_DB_HEIGHT,
219         MEDIA_DATA_DB_ORIENTATION,
220         MEDIA_DATA_DB_DURATION,
221         COMPAT_COLUMN_BUCKET_ID,
222         COMPAT_COLUMN_BUCKET_NAME,
223         COMPAT_COLUMN_IS_TRASH,
224         MEDIA_DATA_DB_IS_FAV,
225         MEDIA_DATA_DB_DATE_TRASHED,
226         MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND,
227 
228         MediaColumn::MEDIA_HIDDEN,
229         PhotoColumn::PHOTO_SYNC_STATUS,
230         PhotoColumn::PHOTO_SUBTYPE,
231     };
232     return PHOTOS_COMPAT_COLUMNS;
233 }
234 
AudiosCompatColumns()235 static const vector<string> &AudiosCompatColumns()
236 {
237     /*
238      * Caution: Columns MUST KEEP SAME ORDER for sqlite UNION operation in:
239      *     o PHOTOS_COMPAT_COLUMNS
240      *     o AUDIOS_COMPAT_COLUMNS
241      *     o FILES_COMPAT_COLUMNS
242      */
243     static const vector<string> AUDIOS_COMPAT_COLUMNS = {
244         MEDIA_DATA_DB_ID,
245         MEDIA_DATA_DB_FILE_PATH,
246         COMPAT_COLUMN_URI,
247         MEDIA_DATA_DB_MIME_TYPE,
248         MEDIA_DATA_DB_MEDIA_TYPE,
249         MEDIA_DATA_DB_NAME,
250         MEDIA_DATA_DB_TITLE,
251         MEDIA_DATA_DB_RELATIVE_PATH,
252         MEDIA_DATA_DB_PARENT_ID,
253         MEDIA_DATA_DB_SIZE,
254         MEDIA_DATA_DB_DATE_ADDED,
255         MEDIA_DATA_DB_DATE_MODIFIED,
256         MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
257         MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND,
258         MEDIA_DATA_DB_DATE_TAKEN,
259         MEDIA_DATA_DB_ARTIST,
260         MEDIA_DATA_DB_AUDIO_ALBUM,
261         COMPAT_COLUMN_WIDTH,
262         COMPAT_COLUMN_HEIGHT,
263         COMPAT_COLUMN_ORIENTATION,
264         MEDIA_DATA_DB_DURATION,
265         COMPAT_COLUMN_BUCKET_ID,
266         COMPAT_COLUMN_BUCKET_NAME,
267         COMPAT_COLUMN_IS_TRASH,
268         MEDIA_DATA_DB_IS_FAV,
269         MEDIA_DATA_DB_DATE_TRASHED,
270         MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND,
271 
272         DEFAULT_INT_COLUMN_AS + MediaColumn::MEDIA_HIDDEN,
273         DEFAULT_INT_COLUMN_AS + PhotoColumn::PHOTO_SYNC_STATUS,
274         DEFAULT_INT_COLUMN_AS + PhotoColumn::PHOTO_SUBTYPE,
275     };
276     return AUDIOS_COMPAT_COLUMNS;
277 }
278 
FilesCompatColumns()279 static const vector<string> &FilesCompatColumns()
280 {
281     /*
282      * Caution: KEEP SAME ORDER for sqlite UNION operation in columns below:
283      *     o PHOTOS_COMPAT_COLUMNS
284      *     o AUDIOS_COMPAT_COLUMNS
285      *     o FILES_COMPAT_COLUMNS
286      */
287     static const vector<string> FILES_COMPAT_COLUMNS = {
288         MEDIA_DATA_DB_ID,
289         MEDIA_DATA_DB_FILE_PATH,
290         MEDIA_DATA_DB_URI,
291         MEDIA_DATA_DB_MIME_TYPE,
292         MEDIA_DATA_DB_MEDIA_TYPE,
293         MEDIA_DATA_DB_NAME,
294         MEDIA_DATA_DB_TITLE,
295         MEDIA_DATA_DB_RELATIVE_PATH,
296         MEDIA_DATA_DB_PARENT_ID,
297         MEDIA_DATA_DB_SIZE,
298         MEDIA_DATA_DB_DATE_ADDED,
299         MEDIA_DATA_DB_DATE_MODIFIED,
300         MEDIA_DATA_DB_DATE_TAKEN,
301         MEDIA_DATA_DB_DATE_ADDED_TO_SECOND,
302         MEDIA_DATA_DB_DATE_MODIFIED_TO_SECOND,
303         MEDIA_DATA_DB_ARTIST,
304         COMPAT_COLUMN_AUDIO_ALBUM,
305         MEDIA_DATA_DB_WIDTH,
306         MEDIA_DATA_DB_HEIGHT,
307         MEDIA_DATA_DB_ORIENTATION,
308         MEDIA_DATA_DB_DURATION,
309         MEDIA_DATA_DB_BUCKET_ID,
310         MEDIA_DATA_DB_BUCKET_NAME,
311         MEDIA_DATA_DB_IS_TRASH,
312         MEDIA_DATA_DB_IS_FAV,
313         MEDIA_DATA_DB_DATE_TRASHED,
314         MEDIA_DATA_DB_DATE_TRASHED_TO_SECOND,
315 
316         DEFAULT_INT_COLUMN_AS + MediaColumn::MEDIA_HIDDEN,
317         PhotoColumn::PHOTO_SYNC_STATUS,
318         DEFAULT_INT_COLUMN_AS + PhotoColumn::PHOTO_SUBTYPE,
319     };
320 
321     return FILES_COMPAT_COLUMNS;
322 }
323 
BuildQueryColumns(const vector<string> & columns,string & sql)324 static void BuildQueryColumns(const vector<string> &columns, string &sql)
325 {
326     for (const auto &col : columns) {
327         sql += col + ',';
328     }
329     sql.pop_back();         // Remove last ','
330 }
331 
ReplaceAlbumName(const string & arg,string & argInstead)332 static void ReplaceAlbumName(const string &arg, string &argInstead)
333 {
334     if (arg == CAMERA_ALBUM_NAME) {
335         argInstead = to_string(static_cast<int32_t>(PhotoSubType::CAMERA));
336     } else if (arg == SCREEN_SHOT_ALBUM_NAME || arg == SCREEN_RECORD_ALBUM_NAME) {
337         argInstead = to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT));
338     } else {
339         argInstead = arg;
340     }
341 }
342 
ReplaceId(const string & fileId,string & idInstead,const string & tableName)343 static void ReplaceId(const string &fileId, string &idInstead, const string &tableName)
344 {
345     if (!all_of(fileId.begin(), fileId.end(), ::isdigit)) {
346         return;
347     }
348     int32_t id;
349     if (!StrToInt(fileId, id)) {
350         MEDIA_ERR_LOG("invalid fileuri %{private}s", fileId.c_str());
351         return;
352     }
353     idInstead = to_string(MediaFileUtils::GetRealIdByTable(id, tableName));
354 }
355 
ReplaceSelectionAndArgsInQuery(string & selection,vector<string> & selectionArgs,const string & tableName,const string & key,const string & keyInstead="")356 static void ReplaceSelectionAndArgsInQuery(string &selection, vector<string> &selectionArgs,
357     const string &tableName, const string &key, const string &keyInstead = "")
358 {
359     if (selection.empty()) {
360         return;
361     }
362 
363     for (size_t pos = 0; pos != string::npos;) {
364         pos = selection.find(key, pos);
365         if (pos == string::npos) {
366             break;
367         }
368         if (!keyInstead.empty()) {
369             selection.replace(pos, key.length(), keyInstead);
370         }
371         size_t argPos = selection.find('?', pos);
372         if (argPos == string::npos) {
373             break;
374         }
375         size_t argIndex = 0;
376         for (size_t i = 0; i < argPos; i++) {
377             if (selection[i] == '?') {
378                 argIndex++;
379             }
380         }
381         if (argIndex > selectionArgs.size() - 1) {
382             MEDIA_INFO_LOG("SelectionArgs size is not valid, selection format maybe incorrect: %{private}s",
383                 selection.c_str());
384             break;
385         }
386         const string &arg = selectionArgs[argIndex];
387         string argInstead = arg;
388         if (key == MEDIA_DATA_DB_BUCKET_NAME) {
389             ReplaceAlbumName(arg, argInstead);
390         } else if (key == MEDIA_DATA_DB_ID) {
391             ReplaceId(arg, argInstead, tableName);
392         }
393         selectionArgs[argIndex] = argInstead;
394         pos = argPos + 1;
395     }
396 }
397 
BuildCompatQuerySql(MediaLibraryCommand & cmd,const string table,const vector<string> & columns,vector<string> & selectionArgs,string & sql)398 static void BuildCompatQuerySql(MediaLibraryCommand &cmd, const string table, const vector<string> &columns,
399     vector<string> &selectionArgs, string &sql)
400 {
401     sql += "SELECT ";
402     BuildQueryColumns(columns, sql);
403     sql += " FROM " + table;
404 
405     string whereClause = cmd.GetAbsRdbPredicates()->GetWhereClause();
406     vector<string> whereArgs = cmd.GetAbsRdbPredicates()->GetWhereArgs();
407     if (table == PhotoColumn::PHOTOS_TABLE) {
408         ReplaceSelectionAndArgsInQuery(whereClause, whereArgs, table, MEDIA_DATA_DB_BUCKET_NAME,
409             PhotoColumn::PHOTO_SUBTYPE);
410     }
411     ReplaceSelectionAndArgsInQuery(whereClause, whereArgs, table, MEDIA_DATA_DB_ID);
412 
413     if (!whereClause.empty()) {
414         sql += " WHERE " + whereClause;
415     }
416 
417     if (!whereArgs.empty()) {
418         selectionArgs.insert(selectionArgs.end(), whereArgs.begin(), whereArgs.end());
419     }
420 }
421 
RemoveWhereSuffix(MediaLibraryCommand & cmd,const string & key)422 static string RemoveWhereSuffix(MediaLibraryCommand &cmd, const string &key)
423 {
424     string suffix;
425     string whereClause = cmd.GetAbsRdbPredicates()->GetWhereClause();
426     size_t keyPos = MediaFileUtils::FindIgnoreCase(whereClause, key);
427     if (keyPos != string::npos) {
428         suffix = whereClause.substr(keyPos);
429         whereClause = whereClause.substr(0, keyPos);
430     }
431     cmd.GetAbsRdbPredicates()->SetWhereClause(whereClause);
432     return suffix;
433 }
434 
BuildQueryFileSql(MediaLibraryCommand & cmd,vector<string> & selectionArgs,string & sql)435 static void BuildQueryFileSql(MediaLibraryCommand &cmd, vector<string> &selectionArgs, string &sql)
436 {
437     string groupBy = RemoveWhereSuffix(cmd, " GROUP BY ");
438     string having = RemoveWhereSuffix(cmd, " HAVING ");
439     string orderBy = RemoveWhereSuffix(cmd, " ORDER BY ");
440     string limit = RemoveWhereSuffix(cmd, " LIMIT ");
441 
442     sql = "SELECT ";
443     if (!groupBy.empty()) {
444         sql += "count(*),";
445     }
446     BuildQueryColumns(FILE_ASSET_COLUMNS, sql);
447 
448     sql += " FROM (";
449     BuildCompatQuerySql(cmd, PhotoColumn::PHOTOS_TABLE, PhotosCompatColumns(), selectionArgs, sql);
450     sql += " UNION ";
451     BuildCompatQuerySql(cmd, AudioColumn::AUDIOS_TABLE, AudiosCompatColumns(), selectionArgs, sql);
452     sql += " UNION ";
453     BuildCompatQuerySql(cmd, MEDIALIBRARY_TABLE, FilesCompatColumns(), selectionArgs, sql);
454     sql += ") ";
455 
456     if (!groupBy.empty()) {
457         sql += groupBy;
458     }
459     if (!having.empty()) {
460         sql += having;
461     }
462 
463     const string &order = cmd.GetAbsRdbPredicates()->GetOrder();
464     if ((!order.empty()) && (!orderBy.empty())) {
465         MEDIA_WARN_LOG("ORDER BY found both in whereClause and predicates, use the predicates one");
466         sql += " ORDER BY " + order;
467     } else if (!order.empty()) {
468         sql += " ORDER BY " + order;
469     } else if (!orderBy.empty()) {
470         sql += orderBy;
471     }
472 
473     if (!limit.empty()) {
474         sql += limit;
475     }
476 }
477 
CampatQueryDebug(const string & sql,const vector<string> & selectionArgs,const shared_ptr<MediaLibraryUnistore> & store)478 static void CampatQueryDebug(const string &sql, const vector<string> &selectionArgs,
479     const shared_ptr<MediaLibraryUnistore> &store)
480 {
481     constexpr int32_t printMax = 512;
482     for (size_t pos = 0; pos < sql.size(); pos += printMax) {
483         MEDIA_DEBUG_LOG("Quering file sql: %{private}s", sql.substr(pos, printMax).c_str());
484     }
485     for (const auto &arg : selectionArgs) {
486         MEDIA_DEBUG_LOG("Quering file, arg: %{private}s", arg.c_str());
487     }
488     auto resultSet = store->QuerySql(sql, selectionArgs);
489     if (resultSet == nullptr) {
490         MEDIA_ERR_LOG("Failed to query file!");
491         return;
492     }
493     int32_t count = -1;
494     int32_t err = resultSet->GetRowCount(count);
495     if (err != E_OK) {
496         MEDIA_ERR_LOG("Failed to get count, err: %{public}d", err);
497         return;
498     }
499     MEDIA_DEBUG_LOG("Quering file, count: %{public}d", count);
500 }
501 #endif
502 
QueryFileOperation(MediaLibraryCommand & cmd,const vector<string> & columns)503 shared_ptr<NativeRdb::ResultSet> MediaLibraryFileOperations::QueryFileOperation(
504     MediaLibraryCommand &cmd, const vector<string> &columns)
505 {
506     auto uniStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
507     if (uniStore == nullptr) {
508         MEDIA_ERR_LOG("uniStore is nullptr");
509         return nullptr;
510     }
511 
512     string fileId = cmd.GetOprnFileId();
513     if (cmd.GetAbsRdbPredicates()->GetWhereClause().empty() && !fileId.empty()) {
514         cmd.GetAbsRdbPredicates()->EqualTo(MEDIA_DATA_DB_ID, fileId);
515     }
516 
517     if (START_PENDING) {
518         SolvePendingInQuery(cmd.GetAbsRdbPredicates());
519     }
520     string networkId = cmd.GetOprnDevice();
521     if (!networkId.empty()) {
522         std::vector<string> devices;
523         devices.push_back(networkId);
524         cmd.GetAbsRdbPredicates()->InDevices(devices);
525     }
526     MediaLibraryTracer tracer;
527     tracer.Start("QueryFile RdbStore->Query");
528 
529 #ifdef MEDIALIBRARY_COMPATIBILITY
530     string sql;
531     vector<string> selectionArgs;
532     BuildQueryFileSql(cmd, selectionArgs, sql);
533     CampatQueryDebug(sql, selectionArgs, uniStore);
534     return uniStore->QuerySql(sql, selectionArgs);
535 #else
536     return uniStore->Query(cmd, columns);
537 #endif
538 }
539 
CopyFileOperation(MediaLibraryCommand & cmd)540 int32_t MediaLibraryFileOperations::CopyFileOperation(MediaLibraryCommand &cmd)
541 {
542     auto values = cmd.GetValueBucket();
543     auto assetId = cmd.GetOprnFileId();
544     ValueObject valueObject;
545     string relativePath;
546     if (values.GetObject(MEDIA_DATA_DB_RELATIVE_PATH, valueObject)) {
547         valueObject.GetString(relativePath);
548     }
549     Uri srcUri(MEDIALIBRARY_DATA_URI + "/" + assetId);
550     string srcUriString = srcUri.ToString();
551     shared_ptr<FileAsset> srcFileAsset = MediaLibraryObjectUtils::GetFileAssetFromUri(srcUriString);
552     if (srcFileAsset == nullptr) {
553         return E_INVALID_URI;
554     }
555     if (srcFileAsset->GetMediaType() == MEDIA_TYPE_ALBUM) {
556         return MediaLibraryObjectUtils::CopyDir(srcFileAsset, relativePath);
557     } else {
558         return MediaLibraryObjectUtils::CopyAsset(srcFileAsset, relativePath);
559     }
560 }
561 } // namespace Media
562 } // namespace OHOS
563