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