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