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