1 /*
2 * Copyright (c) 2023 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
16 #include "data_convertor.h"
17
18 #include "rdb_errno.h"
19
20 #include "dfs_error.h"
21 #include "gallery_file_const.h"
22 #include "utils_log.h"
23 #include "sdk_helper.h"
24
25 namespace OHOS {
26 namespace FileManagement {
27 namespace CloudSync {
28 using namespace std;
29 using namespace NativeRdb;
30
ResultSetToRecords(const shared_ptr<NativeRdb::ResultSet> resultSet,std::vector<DriveKit::DKRecord> & records)31 int32_t DataConvertor::ResultSetToRecords(const shared_ptr<NativeRdb::ResultSet> resultSet,
32 std::vector<DriveKit::DKRecord> &records)
33 {
34 /* reserve to avoid repeatedly alloc and copy */
35 int32_t rowCount = 0;
36 int ret = resultSet->GetRowCount(rowCount);
37 if (ret != 0 || rowCount < 0) {
38 LOGE("result set get row count err %{public}d", ret);
39 return E_RDB;
40 }
41 records.reserve(rowCount);
42
43 /* iterate all rows */
44 while (resultSet->GoToNextRow() == 0) {
45 DriveKit::DKRecord record;
46 ret = Convert(record, *resultSet);
47 if (ret != E_OK) {
48 LOGE("covert result to record err %{public}d", ret);
49 continue;
50 }
51 records.emplace_back(move(record));
52 }
53
54 return E_OK;
55 }
56
GetInt(const string & key,int32_t & val,NativeRdb::ResultSet & resultSet)57 int32_t DataConvertor::GetInt(const string &key, int32_t &val, NativeRdb::ResultSet &resultSet)
58 {
59 int32_t index;
60 int32_t err = resultSet.GetColumnIndex(key, index);
61 if (err != NativeRdb::E_OK) {
62 LOGE("result set get column index err %{public}d", err);
63 return E_RDB;
64 }
65
66 err = resultSet.GetInt(index, val);
67 if (err != 0) {
68 LOGE("result set get int err %{public}d", err);
69 return E_RDB;
70 }
71
72 return E_OK;
73 }
74
GetLong(const string & key,int64_t & val,NativeRdb::ResultSet & resultSet)75 int32_t DataConvertor::GetLong(const string &key, int64_t &val, NativeRdb::ResultSet &resultSet)
76 {
77 int32_t index;
78 int32_t err = resultSet.GetColumnIndex(key, index);
79 if (err != NativeRdb::E_OK) {
80 LOGE("result set get column index err %{public}d", err);
81 return E_RDB;
82 }
83
84 err = resultSet.GetLong(index, val);
85 if (err != 0) {
86 LOGE("result set get int err %{public}d", err);
87 return E_RDB;
88 }
89
90 return E_OK;
91 }
92
GetDouble(const string & key,double & val,NativeRdb::ResultSet & resultSet)93 int32_t DataConvertor::GetDouble(const string &key, double &val, NativeRdb::ResultSet &resultSet)
94 {
95 int32_t index;
96 int32_t err = resultSet.GetColumnIndex(key, index);
97 if (err != NativeRdb::E_OK) {
98 LOGE("result set get column index err %{public}d", err);
99 return E_RDB;
100 }
101
102 err = resultSet.GetDouble(index, val);
103 if (err != 0) {
104 LOGE("result set get double err %{public}d", err);
105 return E_RDB;
106 }
107
108 return E_OK;
109 }
110
GetString(const string & key,string & val,NativeRdb::ResultSet & resultSet)111 int32_t DataConvertor::GetString(const string &key, string &val, NativeRdb::ResultSet &resultSet)
112 {
113 int32_t index;
114 int32_t err = resultSet.GetColumnIndex(key, index);
115 if (err != NativeRdb::E_OK) {
116 LOGE("result set get column index err %{public}d", err);
117 return E_RDB;
118 }
119
120 err = resultSet.GetString(index, val);
121 if (err != 0) {
122 LOGE("result set get string err %{public}d", err);
123 return E_RDB;
124 }
125
126 return E_OK;
127 }
128
GetBool(const string & key,bool & val,NativeRdb::ResultSet & resultSet)129 int32_t DataConvertor::GetBool(const string &key, bool &val, NativeRdb::ResultSet &resultSet)
130 {
131 int32_t index;
132 int32_t err = resultSet.GetColumnIndex(key, index);
133 if (err != NativeRdb::E_OK) {
134 LOGE("result set get column index err %{public}d", err);
135 return E_RDB;
136 }
137
138 int32_t tmpValue;
139 err = resultSet.GetInt(index, tmpValue);
140 if (err != 0) {
141 LOGE("result set get bool err %{public}d", err);
142 return E_RDB;
143 }
144 val = !!tmpValue;
145
146 return E_OK;
147 }
148
GetIntComp(const DriveKit::DKRecordField & field,int & val)149 static int32_t GetIntComp(const DriveKit::DKRecordField &field, int &val)
150 {
151 if (field.GetInt(val) != DriveKit::DKLocalErrorCode::NO_ERROR) {
152 string str;
153 if (field.GetString(str) != DriveKit::DKLocalErrorCode::NO_ERROR) {
154 LOGE("record filed bad type %{public}d", static_cast<int>(field.GetType()));
155 return E_INVAL_ARG;
156 }
157 try {
158 val = std::stoi(str);
159 } catch (const std::out_of_range &e) {
160 LOGE("record filed convert to int failed");
161 return E_INVAL_ARG;
162 }
163 return E_OK;
164 }
165 return E_OK;
166 }
167
GetLongComp(const DriveKit::DKRecordField & field,int64_t & val)168 int32_t DataConvertor::GetLongComp(const DriveKit::DKRecordField &field, int64_t &val)
169 {
170 if (field.GetLong(val) != DriveKit::DKLocalErrorCode::NO_ERROR) {
171 string str;
172 if (field.GetString(str) != DriveKit::DKLocalErrorCode::NO_ERROR) {
173 LOGE("record filed bad type %{public}d", static_cast<int>(field.GetType()));
174 return E_INVAL_ARG;
175 }
176 try {
177 val = std::stoll(str);
178 } catch (const std::out_of_range &e) {
179 LOGE("record filed convert to int64 failed");
180 return E_INVAL_ARG;
181 }
182 return E_OK;
183 }
184 return E_OK;
185 }
186
GetDoubleComp(const DriveKit::DKRecordField & field,double & val)187 static int32_t GetDoubleComp(const DriveKit::DKRecordField &field, double &val)
188 {
189 if (field.GetDouble(val) != DriveKit::DKLocalErrorCode::NO_ERROR) {
190 string str;
191 if (field.GetString(str) != DriveKit::DKLocalErrorCode::NO_ERROR) {
192 LOGE("record filed bad type %{public}d", static_cast<int>(field.GetType()));
193 return E_INVAL_ARG;
194 }
195 try {
196 val = std::stod(str);
197 } catch (const std::out_of_range &e) {
198 LOGE("record filed convert to double failed");
199 return E_INVAL_ARG;
200 }
201 return E_OK;
202 }
203 return E_OK;
204 }
205
GetBoolComp(const DriveKit::DKRecordField & field,bool & val)206 static int32_t GetBoolComp(const DriveKit::DKRecordField &field, bool &val)
207 {
208 if (field.GetBool(val) != DriveKit::DKLocalErrorCode::NO_ERROR) {
209 string str;
210 if (field.GetString(str) != DriveKit::DKLocalErrorCode::NO_ERROR) {
211 LOGE("record filed bad type %{public}d", static_cast<int>(field.GetType()));
212 return E_INVAL_ARG;
213 }
214 if (str == "true") {
215 val = true;
216 } else if (str == "false") {
217 val = false;
218 } else {
219 return E_INVAL_ARG;
220 }
221 return E_OK;
222 }
223 return E_OK;
224 }
225
226 const std::unordered_map<DataType,
227 std::function<int(const DriveKit::DKRecordField &, NativeRdb::ValuesBucket &, const std::string &)>>
228 TYPE_HANDLERS = {
229 {DataType::INT,
__anonc3597b390102() 230 [](const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket, const std::string &field) {
231 int intValue;
232 if (GetIntComp(value, intValue) != E_OK) {
233 return E_INVAL_ARG;
234 }
235 bucket.PutInt(field, intValue);
236 return E_OK;
237 }},
238 {DataType::LONG,
__anonc3597b390202() 239 [](const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket, const std::string &field) {
240 int64_t longValue;
241 if (DataConvertor::GetLongComp(value, longValue) != E_OK) {
242 return E_INVAL_ARG;
243 }
244 bucket.PutLong(field, longValue);
245 return E_OK;
246 }},
247 {DataType::STRING,
__anonc3597b390302() 248 [](const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket, const std::string &field) {
249 std::string stringValue;
250 if (value.GetString(stringValue) != DriveKit::DKLocalErrorCode::NO_ERROR) {
251 return E_INVAL_ARG;
252 }
253 if (stringValue == "") {
254 return E_OK;
255 }
256 bucket.PutString(field, stringValue);
257 return E_OK;
258 }},
259 {DataType::DOUBLE,
__anonc3597b390402() 260 [](const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket, const std::string &field) {
261 double doubleValue;
262 if (GetDoubleComp(value, doubleValue) != E_OK) {
263 return E_INVAL_ARG;
264 }
265 bucket.PutDouble(field, doubleValue);
266 return E_OK;
267 }},
268 {DataType::BOOL,
__anonc3597b390502() 269 [](const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket, const std::string &field) {
270 bool boolValue;
271 if (GetBoolComp(value, boolValue) != E_OK) {
272 return E_INVAL_ARG;
273 }
274 bucket.PutInt(field, static_cast<int>(boolValue));
275 return E_OK;
276 }}};
277
HandleField(const DriveKit::DKRecordField & value,NativeRdb::ValuesBucket & bucket,const std::string & field,DataType type)278 int DataConvertor::HandleField(const DriveKit::DKRecordField &value, NativeRdb::ValuesBucket &bucket,
279 const std::string &field, DataType type)
280 {
281 auto it = TYPE_HANDLERS.find(type);
282 if (it == TYPE_HANDLERS.end()) {
283 LOGE("invalid data type %d", static_cast<int>(type));
284 return E_INVAL_ARG;
285 }
286 return it->second(value, bucket, field);
287 }
288
RecordToValueBucket(DriveKit::DKRecord & record,NativeRdb::ValuesBucket & valueBucket)289 int32_t DataConvertor::RecordToValueBucket(DriveKit::DKRecord &record, NativeRdb::ValuesBucket &valueBucket)
290 {
291 return Convert(record, valueBucket);
292 }
293
294 } // namespace CloudSync
295 } // namespace FileManagement
296 } // namespace OHOS
297