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 "RingtoneFetchResult"
16
17 #include "ringtone_fetch_result.h"
18
19 #include "ringtone_log.h"
20
21 namespace OHOS {
22 namespace Media {
23 using namespace std;
24 using ResultTypeMap = unordered_map<string, RingtoneResultSetDataType>;
25
GetResultTypeMap()26 static const ResultTypeMap &GetResultTypeMap()
27 {
28 static const ResultTypeMap RESULT_TYPE_MAP = {
29 { RINGTONE_COLUMN_TONE_ID, DATA_TYPE_INT32 },
30 { RINGTONE_COLUMN_DATA, DATA_TYPE_STRING },
31 { RINGTONE_COLUMN_SIZE, DATA_TYPE_INT64 },
32 { RINGTONE_COLUMN_DISPLAY_NAME, DATA_TYPE_STRING },
33 { RINGTONE_COLUMN_TITLE, DATA_TYPE_STRING },
34 { RINGTONE_COLUMN_MEDIA_TYPE, DATA_TYPE_INT32 },
35 { RINGTONE_COLUMN_TONE_TYPE, DATA_TYPE_INT32 },
36 { RINGTONE_COLUMN_MIME_TYPE, DATA_TYPE_STRING },
37 { RINGTONE_COLUMN_SOURCE_TYPE, DATA_TYPE_INT32 },
38 { RINGTONE_COLUMN_DATE_ADDED, DATA_TYPE_INT64 },
39 { RINGTONE_COLUMN_DATE_MODIFIED, DATA_TYPE_INT64 },
40 { RINGTONE_COLUMN_DATE_TAKEN, DATA_TYPE_INT64 },
41 { RINGTONE_COLUMN_DURATION, DATA_TYPE_INT32 },
42 { RINGTONE_COLUMN_SHOT_TONE_TYPE, DATA_TYPE_INT32 },
43 { RINGTONE_COLUMN_SHOT_TONE_SOURCE_TYPE, DATA_TYPE_INT32 },
44 { RINGTONE_COLUMN_NOTIFICATION_TONE_TYPE, DATA_TYPE_INT32 },
45 { RINGTONE_COLUMN_NOTIFICATION_TONE_SOURCE_TYPE, DATA_TYPE_INT32 },
46 { RINGTONE_COLUMN_RING_TONE_TYPE, DATA_TYPE_INT32 },
47 { RINGTONE_COLUMN_RING_TONE_SOURCE_TYPE, DATA_TYPE_INT32 },
48 { RINGTONE_COLUMN_ALARM_TONE_TYPE, DATA_TYPE_INT32 },
49 { RINGTONE_COLUMN_ALARM_TONE_SOURCE_TYPE, DATA_TYPE_INT32 },
50 { SIMCARD_SETTING_COLUMN_MODE, DATA_TYPE_INT32 },
51 { SIMCARD_SETTING_COLUMN_RINGTONE_TYPE, DATA_TYPE_INT32},
52 { SIMCARD_SETTING_COLUMN_TONE_FILE, DATA_TYPE_STRING },
53 { SIMCARD_SETTING_COLUMN_VIBRATE_FILE, DATA_TYPE_STRING },
54 { SIMCARD_SETTING_COLUMN_VIBRATE_MODE, DATA_TYPE_INT32 },
55 { SIMCARD_SETTING_COLUMN_RING_MODE, DATA_TYPE_INT32 },
56 { RINGTONE_COLUMN_SCANNER_FLAG, DATA_TYPE_INT32 },
57 // vibrate data
58 { VIBRATE_COLUMN_VIBRATE_ID, DATA_TYPE_INT32 },
59 { VIBRATE_COLUMN_DATA, DATA_TYPE_STRING },
60 { VIBRATE_COLUMN_SIZE, DATA_TYPE_INT64 },
61 { VIBRATE_COLUMN_DISPLAY_NAME, DATA_TYPE_STRING },
62 { VIBRATE_COLUMN_TITLE, DATA_TYPE_STRING },
63 { VIBRATE_COLUMN_DISPLAY_LANGUAGE, DATA_TYPE_STRING },
64 { VIBRATE_COLUMN_VIBRATE_TYPE, DATA_TYPE_INT32 },
65 { VIBRATE_COLUMN_SOURCE_TYPE, DATA_TYPE_INT32 },
66 { VIBRATE_COLUMN_DATE_ADDED, DATA_TYPE_INT64 },
67 { VIBRATE_COLUMN_DATE_MODIFIED, DATA_TYPE_INT64 },
68 { VIBRATE_COLUMN_DATE_TAKEN, DATA_TYPE_INT64 },
69 { VIBRATE_COLUMN_PLAY_MODE, DATA_TYPE_INT32 },
70 { VIBRATE_COLUMN_SCANNER_FLAG, DATA_TYPE_INT32 },
71 };
72 return RESULT_TYPE_MAP;
73 }
74
75 template <class T>
RingtoneFetchResult(const shared_ptr<DataShare::DataShareResultSet> & resultset)76 RingtoneFetchResult<T>::RingtoneFetchResult(const shared_ptr<DataShare::DataShareResultSet> &resultset)
77 {
78 resultset_ = resultset;
79 GetCount();
80 }
81
82 template <class T>
83 // empty constructor napi
RingtoneFetchResult()84 RingtoneFetchResult<T>::RingtoneFetchResult() : resultset_(nullptr)
85 {
86 }
87
88 template <class T>
~RingtoneFetchResult()89 RingtoneFetchResult<T>::~RingtoneFetchResult()
90 {
91 resultset_.reset();
92 }
93
94 template <class T>
Close()95 void RingtoneFetchResult<T>::Close()
96 {
97 if (resultset_ != nullptr) {
98 resultset_->Close();
99 resultset_ = nullptr;
100 }
101 }
102
103 template <class T>
GetCount()104 int32_t RingtoneFetchResult<T>::GetCount()
105 {
106 int32_t count = 0;
107 if (resultset_ == nullptr || resultset_->GetRowCount(count) != NativeRdb::E_OK) {
108 return 0;
109 }
110 return count < 0 ? 0 : count;
111 }
112
113 template<class T>
GetDataShareResultSet()114 shared_ptr<DataShare::DataShareResultSet> &RingtoneFetchResult<T>::GetDataShareResultSet()
115 {
116 return resultset_;
117 }
118
119 template <class T>
GetObjectAtPosition(int32_t index)120 unique_ptr<T> RingtoneFetchResult<T>::GetObjectAtPosition(int32_t index)
121 {
122 if (resultset_ == nullptr) {
123 RINGTONE_ERR_LOG("rs is null");
124 return nullptr;
125 }
126
127 int32_t count = GetCount();
128 if ((index < 0) || (index > (count - 1))) {
129 RINGTONE_ERR_LOG("index not proper");
130 return nullptr;
131 }
132
133 if (resultset_->GoToRow(index) != 0) {
134 RINGTONE_ERR_LOG("failed to go to row at index pos");
135 return nullptr;
136 }
137
138 return GetObject();
139 }
140
141 template <class T>
GetFirstObject()142 unique_ptr<T> RingtoneFetchResult<T>::GetFirstObject()
143 {
144 if ((resultset_ == nullptr) || (resultset_->GoToFirstRow() != 0)) {
145 RINGTONE_DEBUG_LOG("resultset is null|first row failed");
146 return nullptr;
147 }
148
149 return GetObject();
150 }
151
152 template <class T>
GetNextObject()153 unique_ptr<T> RingtoneFetchResult<T>::GetNextObject()
154 {
155 if ((resultset_ == nullptr) || (resultset_->GoToNextRow() != 0)) {
156 RINGTONE_DEBUG_LOG("resultset is null|go to next row failed");
157 return nullptr;
158 }
159
160 return GetObject();
161 }
162
163 template <class T>
GetLastObject()164 unique_ptr<T> RingtoneFetchResult<T>::GetLastObject()
165 {
166 if ((resultset_ == nullptr) || (resultset_->GoToLastRow() != 0)) {
167 RINGTONE_ERR_LOG("resultset is null|go to last row failed");
168 return nullptr;
169 }
170
171 return GetObject();
172 }
173
174 template <class T>
IsAtLastRow()175 bool RingtoneFetchResult<T>::IsAtLastRow()
176 {
177 if (resultset_ == nullptr) {
178 RINGTONE_ERR_LOG("resultset null");
179 return false;
180 }
181
182 bool retVal = false;
183 resultset_->IsAtLastRow(retVal);
184 return retVal;
185 }
186
ReturnDefaultOnError(string errMsg,RingtoneResultSetDataType dataType)187 variant<int32_t, int64_t, string, double> ReturnDefaultOnError(string errMsg, RingtoneResultSetDataType dataType)
188 {
189 if (dataType == DATA_TYPE_STRING) {
190 return "";
191 } else if (dataType == DATA_TYPE_INT64) {
192 return static_cast<int64_t>(0);
193 } else {
194 return 0;
195 }
196 }
197
198 template <class T>
GetRowValFromColumn(string columnName,RingtoneResultSetDataType dataType,shared_ptr<NativeRdb::ResultSet> & resultSet)199 variant<int32_t, int64_t, string, double> RingtoneFetchResult<T>::GetRowValFromColumn(string columnName,
200 RingtoneResultSetDataType dataType, shared_ptr<NativeRdb::ResultSet> &resultSet)
201 {
202 if ((resultset_ == nullptr) && (resultSet == nullptr)) {
203 return ReturnDefaultOnError("Resultset is null", dataType);
204 }
205 int index;
206 int status;
207 if (resultSet) {
208 status = resultSet->GetColumnIndex(columnName, index);
209 } else {
210 status = resultset_->GetColumnIndex(columnName, index);
211 }
212 if (status != NativeRdb::E_OK) {
213 return ReturnDefaultOnError("failed to obtain the index", dataType);
214 }
215 return GetValByIndex(index, dataType, resultSet);
216 }
217
218 template <class T>
GetValByIndex(int32_t index,RingtoneResultSetDataType dataType,shared_ptr<NativeRdb::ResultSet> & resultSet)219 variant<int32_t, int64_t, string, double> RingtoneFetchResult<T>::GetValByIndex(int32_t index,
220 RingtoneResultSetDataType dataType, shared_ptr<NativeRdb::ResultSet> &resultSet)
221 {
222 if ((resultset_ == nullptr) && (resultSet == nullptr)) {
223 return ReturnDefaultOnError("Resultset is null", dataType);
224 }
225 variant<int32_t, int64_t, string, double> cellValue;
226 int integerVal = 0;
227 string stringVal = "";
228 int64_t longVal = 0;
229 int status;
230 double doubleVal = 0.0;
231 switch (dataType) {
232 case DATA_TYPE_STRING:
233 if (resultSet) {
234 status = resultSet->GetString(index, stringVal);
235 } else {
236 status = resultset_->GetString(index, stringVal);
237 }
238 cellValue = move(stringVal);
239 break;
240 case DATA_TYPE_INT32:
241 if (resultSet) {
242 status = resultSet->GetInt(index, integerVal);
243 } else {
244 status = resultset_->GetInt(index, integerVal);
245 }
246 cellValue = integerVal;
247 break;
248 case DATA_TYPE_INT64:
249 if (resultSet) {
250 status = resultSet->GetLong(index, longVal);
251 } else {
252 status = resultset_->GetLong(index, longVal);
253 }
254 cellValue = longVal;
255 break;
256 case DATA_TYPE_DOUBLE:
257 if (resultSet) {
258 status = resultSet->GetDouble(index, doubleVal);
259 } else {
260 status = resultset_->GetDouble(index, doubleVal);
261 }
262 cellValue = doubleVal;
263 break;
264 default:
265 break;
266 }
267 return cellValue;
268 }
269
270 template<class T>
SetRingtoneAsset(unique_ptr<T> & asset,shared_ptr<NativeRdb::ResultSet> & resultSet)271 void RingtoneFetchResult<T>::SetRingtoneAsset(unique_ptr<T>& asset, shared_ptr<NativeRdb::ResultSet> &resultSet)
272 {
273 if ((resultset_ == nullptr) && (resultSet == nullptr)) {
274 RINGTONE_ERR_LOG("SetRingtoneAsset fail, result is nullptr");
275 return;
276 }
277 vector<string> columnNames;
278 if (resultSet != nullptr) {
279 resultSet->GetAllColumnNames(columnNames);
280 } else {
281 resultset_->GetAllColumnNames(columnNames);
282 }
283 int32_t index = -1;
284 auto &map = asset->GetMemberMap();
285 for (const auto &name : columnNames) {
286 index++;
287 if (GetResultTypeMap().count(name) == 0) {
288 continue;
289 }
290 auto memberType = GetResultTypeMap().at(name);
291 map.emplace(move(name), move(GetValByIndex(index, memberType, resultSet)));
292 }
293 }
294
295 template<class T>
GetObjectFromResultSet(unique_ptr<T> & asset,shared_ptr<NativeRdb::ResultSet> & resultSet)296 void RingtoneFetchResult<T>::GetObjectFromResultSet(unique_ptr<T>& asset, shared_ptr<NativeRdb::ResultSet> &resultSet)
297 {
298 SetRingtoneAsset(asset, resultSet);
299 }
300
301 template<class T>
GetObject(shared_ptr<NativeRdb::ResultSet> & resultSet)302 unique_ptr<T> RingtoneFetchResult<T>::GetObject(shared_ptr<NativeRdb::ResultSet> &resultSet)
303 {
304 unique_ptr<T> asset = make_unique<T>();
305
306 GetObjectFromResultSet(asset, resultSet);
307 return asset;
308 }
309
310 template <class T>
GetObject()311 unique_ptr<T> RingtoneFetchResult<T>::GetObject()
312 {
313 shared_ptr<NativeRdb::ResultSet> resultSet = nullptr;
314 return GetObject(resultSet);
315 }
316
317 template <class T>
GetObjectFromRdb(shared_ptr<NativeRdb::ResultSet> & resultSet,int idx)318 unique_ptr<T> RingtoneFetchResult<T>::GetObjectFromRdb(shared_ptr<NativeRdb::ResultSet> &resultSet, int idx)
319 {
320 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != 0) || (resultSet->GoTo(idx))) {
321 RINGTONE_ERR_LOG("resultset is null|first row failed");
322 return nullptr;
323 }
324
325 return GetObject(resultSet);
326 }
327
328 template class RingtoneFetchResult<RingtoneAsset>;
329 template class RingtoneFetchResult<SimcardSettingAsset>;
330 template class RingtoneFetchResult<VibrateAsset>;
331 } // namespace Media
332 } // namespace OHOS
333