• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "Scanner"
16 
17 #include "ringtone_scanner_db.h"
18 
19 #include "result_set_utils.h"
20 #include "rdb_errno.h"
21 #include "ringtone_errno.h"
22 #include "ringtone_file_utils.h"
23 #include "ringtone_log.h"
24 #include "ringtone_rdbstore.h"
25 
26 namespace OHOS {
27 namespace Media {
28 using namespace std;
29 using namespace OHOS::NativeRdb;
30 using namespace OHOS::DataShare;
GetFileBasicInfo(const string & path,unique_ptr<RingtoneMetadata> & ptr)31 int32_t RingtoneScannerDb::GetFileBasicInfo(const string &path, unique_ptr<RingtoneMetadata> &ptr)
32 {
33     vector<string> columns = {
34         RINGTONE_COLUMN_TONE_ID, RINGTONE_COLUMN_SIZE, RINGTONE_COLUMN_DATE_MODIFIED, RINGTONE_COLUMN_TITLE,
35         RINGTONE_COLUMN_DATE_ADDED
36     };
37     string whereClause = RINGTONE_COLUMN_DATA + " = ?";
38     vector<string> args = { path };
39 
40     Uri uri("");
41     RingtoneDataCommand cmd(uri, RINGTONE_TABLE, RingtoneOperationType::QUERY);
42     cmd.GetAbsRdbPredicates()->SetWhereClause(whereClause);
43     cmd.GetAbsRdbPredicates()->SetWhereArgs(args);
44 
45     shared_ptr<NativeRdb::ResultSet> resultSet;
46     int32_t ret = GetFileSet(cmd, columns, resultSet);
47     if (ret != E_OK) {
48         RINGTONE_ERR_LOG("Update operation failed. ret=%{public}d", ret);
49         return E_DB_FAIL;
50     }
51 
52     return FillMetadata(resultSet, ptr);
53 }
54 
QueryRingtoneRdb(string & whereClause,vector<string> & whereArgs,const vector<string> & columns,shared_ptr<NativeRdb::ResultSet> & resultSet)55 int32_t RingtoneScannerDb::QueryRingtoneRdb(string &whereClause, vector<string> &whereArgs,
56     const vector<string> &columns, shared_ptr<NativeRdb::ResultSet> &resultSet)
57 {
58     string tableName = RINGTONE_TABLE;
59     auto rawRdb = RingtoneRdbStore::GetInstance()->GetRaw();
60     if (rawRdb == nullptr) {
61         RINGTONE_ERR_LOG("get raw rdb failed");
62         return E_RDB;
63     }
64 
65     AbsRdbPredicates absRdbPredicates(tableName);
66     absRdbPredicates.SetWhereClause(whereClause);
67     absRdbPredicates.SetWhereArgs(whereArgs);
68     resultSet = rawRdb->Query(absRdbPredicates, columns);
69     if (resultSet == nullptr) {
70         RINGTONE_ERR_LOG("return nullptr when query rdb");
71         return E_RDB;
72     }
73 
74     return E_OK;
75 }
76 
UpdateRingtoneRdb(ValuesBucket & values,string & whereClause,vector<string> & whereArgs)77 int32_t RingtoneScannerDb::UpdateRingtoneRdb(ValuesBucket &values, string &whereClause, vector<string> &whereArgs)
78 {
79     string tableName = RINGTONE_TABLE;
80     auto rawRdb = RingtoneRdbStore::GetInstance()->GetRaw();
81     if (rawRdb == nullptr) {
82         RINGTONE_ERR_LOG("get raw rdb failed");
83         return E_RDB;
84     }
85     int32_t updateCount = 0;
86     int32_t result = rawRdb->Update(updateCount, tableName, values, whereClause, whereArgs);
87     if (result != NativeRdb::E_OK) {
88         RINGTONE_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, updateCount);
89         return E_DB_FAIL;
90     }
91     return updateCount;
92 }
93 
FillMetadata(const shared_ptr<NativeRdb::ResultSet> & resultSet,unique_ptr<RingtoneMetadata> & ptr)94 int32_t RingtoneScannerDb::FillMetadata(const shared_ptr<NativeRdb::ResultSet> &resultSet,
95     unique_ptr<RingtoneMetadata> &ptr)
96 {
97     std::vector<std::string> columnNames;
98     int32_t err = resultSet->GetAllColumnNames(columnNames);
99     if (err != NativeRdb::E_OK) {
100         RINGTONE_ERR_LOG("failed to get all column names");
101         return E_RDB;
102     }
103 
104     for (const auto &col : columnNames) {
105         ExtractMetaFromColumn(resultSet, ptr, col);
106     }
107 
108     return E_OK;
109 }
110 
ExtractMetaFromColumn(const shared_ptr<NativeRdb::ResultSet> & resultSet,unique_ptr<RingtoneMetadata> & metadata,const std::string & col)111 void RingtoneScannerDb::ExtractMetaFromColumn(const shared_ptr<NativeRdb::ResultSet> &resultSet,
112     unique_ptr<RingtoneMetadata> &metadata, const std::string &col)
113 {
114     RingtoneResultSetDataType dataType = RingtoneResultSetDataType::DATA_TYPE_NULL;
115     RingtoneMetadata::RingtoneMetadataFnPtr requestFunc = nullptr;
116     auto itr = metadata->memberFuncMap_.find(col);
117     if (itr != metadata->memberFuncMap_.end()) {
118         dataType = itr->second.first;
119         requestFunc = itr->second.second;
120     } else {
121         RINGTONE_ERR_LOG("invalid column name %{private}s", col.c_str());
122         return;
123     }
124 
125     std::variant<int32_t, std::string, int64_t, double> data =
126         ResultSetUtils::GetValFromColumn<const shared_ptr<NativeRdb::ResultSet>>(col, resultSet, dataType);
127 
128     // Use the function pointer from map and pass data to fn ptr
129     if (requestFunc != nullptr) {
130         (metadata.get()->*requestFunc)(data);
131     }
132 }
133 
GetFileSet(RingtoneDataCommand & cmd,const vector<string> & columns,shared_ptr<NativeRdb::ResultSet> & resultSet)134 int32_t RingtoneScannerDb::GetFileSet(RingtoneDataCommand &cmd, const vector<string> &columns,
135     shared_ptr<NativeRdb::ResultSet> &resultSet)
136 {
137     auto rawRdb = RingtoneRdbStore::GetInstance()->GetRaw();
138     if (rawRdb == nullptr) {
139         RINGTONE_ERR_LOG("get raw rdb failed");
140         return E_RDB;
141     }
142     resultSet = rawRdb->Query(*cmd.GetAbsRdbPredicates(), columns);
143     if (resultSet == nullptr) {
144         RINGTONE_ERR_LOG("return nullptr when query rdb");
145         return E_RDB;
146     }
147 
148     int32_t rowCount = 0;
149     int32_t ret = resultSet->GetRowCount(rowCount);
150     if (ret != NativeRdb::E_OK) {
151         RINGTONE_ERR_LOG("failed to get row count");
152         return E_RDB;
153     }
154     if (rowCount == 0) {
155         return E_OK;
156     }
157 
158     ret = resultSet->GoToFirstRow();
159     if (ret != NativeRdb::E_OK) {
160         RINGTONE_ERR_LOG("failed to go to first row");
161         return E_RDB;
162     }
163     return E_OK;
164 }
165 
InsertDateAdded(const RingtoneMetadata & metadata,ValuesBucket & outValues)166 static void InsertDateAdded(const RingtoneMetadata &metadata, ValuesBucket &outValues)
167 {
168     int64_t dateAdded = metadata.GetDateAdded();
169     if (dateAdded == 0) {
170         int64_t dateTaken = metadata.GetDateTaken();
171         if (dateTaken == 0) {
172             int64_t dateModified = metadata.GetDateModified();
173             if (dateModified == 0) {
174                 dateAdded = RingtoneFileUtils::UTCTimeMilliSeconds();
175                 RINGTONE_WARN_LOG("Invalid dateAdded time, use current time instead: %{public}" PRId64, dateAdded);
176             } else {
177                 dateAdded = dateModified;
178                 RINGTONE_WARN_LOG("Invalid dateAdded time, use dateModified instead: %{public}" PRId64, dateAdded);
179             }
180         } else {
181             dateAdded = dateTaken * MSEC_TO_SEC;
182             RINGTONE_WARN_LOG("Invalid dateAdded time, use dateTaken instead: %{public}" PRId64, dateAdded);
183         }
184     }
185     outValues.PutLong(RINGTONE_COLUMN_DATE_ADDED, dateAdded);
186 }
187 
SetValuesFromMetaData(const RingtoneMetadata & metadata,ValuesBucket & values,bool isInsert)188 static void SetValuesFromMetaData(const RingtoneMetadata &metadata, ValuesBucket &values, bool isInsert)
189 {
190     values.PutString(RINGTONE_COLUMN_DATA, metadata.GetData());
191     values.PutLong(RINGTONE_COLUMN_SIZE, metadata.GetSize());
192     values.PutString(RINGTONE_COLUMN_DISPLAY_NAME, metadata.GetDisplayName());
193     values.PutString(RINGTONE_COLUMN_TITLE, metadata.GetTitle());
194     values.PutInt(RINGTONE_COLUMN_MEDIA_TYPE, metadata.GetMediaType());
195     values.PutInt(RINGTONE_COLUMN_TONE_TYPE, metadata.GetToneType());
196     values.PutString(RINGTONE_COLUMN_MIME_TYPE, metadata.GetMimeType());
197     values.PutInt(RINGTONE_COLUMN_SOURCE_TYPE, metadata.GetSourceType());
198     values.PutLong(RINGTONE_COLUMN_DATE_MODIFIED, metadata.GetDateModified());
199     values.PutLong(RINGTONE_COLUMN_DATE_TAKEN, metadata.GetDateTaken());
200     values.PutInt(RINGTONE_COLUMN_DURATION, metadata.GetDuration());
201     values.PutInt(RINGTONE_COLUMN_SHOT_TONE_TYPE, metadata.GetShotToneType());
202     values.PutInt(RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, metadata.GetShotToneSourceType());
203     values.PutInt(RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE, metadata.GetNotificationToneType());
204     values.PutInt(RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, metadata.GetNotificationToneSourceType());
205     values.PutInt(RINGTONE_COLUMN_RING_TONE_TYPE, metadata.GetRingToneType());
206     values.PutInt(RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, metadata.GetRingToneSourceType());
207     values.PutInt(RINGTONE_COLUMN_ALARM_TONE_TYPE, metadata.GetAlarmToneType());
208     values.PutInt(RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE, metadata.GetAlarmToneSourceType());
209 
210     if (isInsert) {
211         InsertDateAdded(metadata, values);
212         return;
213     }
214 }
215 
UpdateMetadata(const RingtoneMetadata & metadata,string & tableName)216 int32_t RingtoneScannerDb::UpdateMetadata(const RingtoneMetadata &metadata, string &tableName)
217 {
218     int32_t updateCount = 0;
219     ValuesBucket values;
220     string whereClause = RINGTONE_COLUMN_TONE_ID + " = ?";
221     vector<string> whereArgs = { to_string(metadata.GetToneId()) };
222 
223     SetValuesFromMetaData(metadata, values, false);
224 
225     tableName = RINGTONE_TABLE;
226     auto rawRdb = RingtoneRdbStore::GetInstance()->GetRaw();
227     if (rawRdb == nullptr) {
228         RINGTONE_ERR_LOG("get raw rdb failed");
229         return E_RDB;
230     }
231     int32_t result = rawRdb->Update(updateCount, tableName, values, whereClause, whereArgs);
232     if (result != NativeRdb::E_OK || updateCount <= 0) {
233         RINGTONE_ERR_LOG("Update operation failed. Result %{public}d. Updated %{public}d", result, updateCount);
234         return E_DB_FAIL;
235     }
236     return updateCount;
237 }
238 
InsertMetadata(const RingtoneMetadata & metadata,string & tableName)239 int32_t RingtoneScannerDb::InsertMetadata(const RingtoneMetadata &metadata, string &tableName)
240 {
241     ValuesBucket values;
242     SetValuesFromMetaData(metadata, values, true);
243 
244     int64_t rowNum = 0;
245     tableName = RINGTONE_TABLE;
246     if (!InsertData(values, tableName, rowNum)) {
247         return E_DB_FAIL;
248     }
249     return static_cast<int32_t>(rowNum);
250 }
251 
InsertData(const ValuesBucket values,const string & tableName,int64_t & rowNum)252 bool RingtoneScannerDb::InsertData(const ValuesBucket values, const string &tableName, int64_t &rowNum)
253 {
254     auto rawRdb = RingtoneRdbStore::GetInstance()->GetRaw();
255     if (rawRdb == nullptr) {
256         RINGTONE_ERR_LOG("get raw rdb failed");
257         return E_RDB;
258     }
259     int32_t result = rawRdb->Insert(rowNum, tableName, values);
260     if (rowNum <= 0) {
261         RINGTONE_ERR_LOG("Ringtone library Insert functionality is failed, rowNum %{public}ld", (long) rowNum);
262         return false;
263     }
264 
265     if (result != NativeRdb::E_OK) {
266         RINGTONE_ERR_LOG("Ringtone library Insert functionality is failed, return %{public}d", result);
267         return false;
268     }
269 
270     return true;
271 }
272 } // namespace Media
273 } // namespace OHOS
274