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