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