1 /*
2 * Copyright (c) 2022 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 #include "datashare_result_set.h"
16
17 #include <securec.h>
18 #include <sstream>
19
20 #include "adaptor.h"
21 #include "datashare_block_writer_impl.h"
22 #include "datashare_errno.h"
23 #include "datashare_log.h"
24 #include "parcel.h"
25 #include "shared_block.h"
26 #include "string_ex.h"
27
28 namespace OHOS {
29 namespace DataShare {
30 namespace {
31 // The default position of the cursor
32 static const int INITIAL_POS = -1;
33 static const size_t DEFAULT_SHARE_BLOCK_SIZE = 2 * 1024 * 1024;
34 } // namespace
35 int DataShareResultSet::blockId_ = 0;
DataShareResultSet()36 DataShareResultSet::DataShareResultSet()
37 {
38 }
39
DataShareResultSet(std::shared_ptr<ResultSetBridge> & bridge)40 DataShareResultSet::DataShareResultSet(std::shared_ptr<ResultSetBridge> &bridge)
41 : bridge_(bridge)
42 {
43 std::string name = "DataShare" + std::to_string(blockId_++);
44 blockWriter_ = std::make_shared<DataShareBlockWriterImpl>(name, DEFAULT_SHARE_BLOCK_SIZE);
45 if (blockWriter_ == nullptr) {
46 return;
47 }
48 sharedBlock_ = blockWriter_->GetBlock();
49 if (sharedBlock_ == nullptr) {
50 return;
51 }
52 }
53
~DataShareResultSet()54 DataShareResultSet::~DataShareResultSet()
55 {
56 Close();
57 }
58
GetAllColumnNames(std::vector<std::string> & columnNames)59 int DataShareResultSet::GetAllColumnNames(std::vector<std::string> &columnNames)
60 {
61 if (bridge_ == nullptr) {
62 LOG_ERROR("bridge_ is null!");
63 return E_ERROR;
64 }
65 return bridge_->GetAllColumnNames(columnNames);
66 }
67
GetRowCount(int & count)68 int DataShareResultSet::GetRowCount(int &count)
69 {
70 if (bridge_ == nullptr) {
71 LOG_ERROR("bridge_ is null!");
72 return E_ERROR;
73 }
74 return bridge_->GetRowCount(count);
75 }
76
OnGo(int startRowIndex,int targetRowIndex,int * cachedIndex)77 bool DataShareResultSet::OnGo(int startRowIndex, int targetRowIndex, int *cachedIndex)
78 {
79 if (bridge_ == nullptr || blockWriter_ == nullptr || sharedBlock_ == nullptr) {
80 LOG_ERROR("bridge_ or blockWriter_ or sharedBlock_ is null!");
81 return false;
82 }
83 std::vector<std::string> columnNames;
84 GetAllColumnNames(columnNames);
85 sharedBlock_->Clear();
86 sharedBlock_->SetColumnNum(columnNames.size());
87 int result = bridge_->OnGo(startRowIndex, targetRowIndex, *blockWriter_);
88 if (cachedIndex != nullptr) {
89 *cachedIndex = result;
90 }
91 if (result < 0) {
92 return false;
93 }
94 return true;
95 }
96
FillBlock(int startRowIndex,AppDataFwk::SharedBlock * block)97 void DataShareResultSet::FillBlock(int startRowIndex, AppDataFwk::SharedBlock *block)
98 {
99 return;
100 }
101
102 /**
103 * Get current shared block
104 */
GetBlock() const105 AppDataFwk::SharedBlock *DataShareResultSet::GetBlock() const
106 {
107 return sharedBlock_;
108 }
109
GetDataType(int columnIndex,DataType & dataType)110 int DataShareResultSet::GetDataType(int columnIndex, DataType &dataType)
111 {
112 int rowCount = 0;
113 GetRowCount(rowCount);
114 AppDataFwk::SharedBlock::CellUnit *cellUnit =
115 sharedBlock_->GetCellUnit(static_cast<uint32_t>(rowPos_) - startRowPos_, static_cast<uint32_t>(columnIndex));
116 if (!cellUnit) {
117 return E_ERROR;
118 }
119 dataType = (DataType)cellUnit->type;
120 return E_OK;
121 }
122
GoToRow(int position)123 int DataShareResultSet::GoToRow(int position)
124 {
125 if (sharedBlock_ == nullptr) {
126 LOG_ERROR("sharedBlock_ is null!");
127 return E_ERROR;
128 }
129 int rowCnt = 0;
130 GetRowCount(rowCnt);
131 if (position >= rowCnt) {
132 rowPos_ = rowCnt;
133 return E_ERROR;
134 }
135 if (position < 0) {
136 rowPos_ = INITIAL_POS;
137 return E_ERROR;
138 }
139 if (position == rowPos_) {
140 return E_OK;
141 }
142 bool result = true;
143 if (position > endRowPos_ || position < startRowPos_) {
144 int endPos = -1;
145 result = OnGo(position, rowCnt - 1, &endPos);
146 if (result) {
147 startRowPos_ = position;
148 endRowPos_ = endPos;
149 }
150 }
151
152 if (!result) {
153 rowPos_ = INITIAL_POS;
154 startRowPos_ = INITIAL_POS;
155 endRowPos_ = INITIAL_POS;
156 return E_ERROR;
157 } else {
158 rowPos_ = position;
159 return E_OK;
160 }
161 }
162
GetBlob(int columnIndex,std::vector<uint8_t> & value)163 int DataShareResultSet::GetBlob(int columnIndex, std::vector<uint8_t> &value)
164 {
165 int errorCode = CheckState(columnIndex);
166 if (errorCode != E_OK) {
167 return errorCode;
168 }
169
170 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
171 if (!cellUnit) {
172 return E_ERROR;
173 }
174
175 value.resize(0);
176 int type = cellUnit->type;
177 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB
178 || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
179 size_t size;
180 const auto *blob = static_cast<const uint8_t *>(sharedBlock_->GetCellUnitValueBlob(cellUnit, &size));
181 if (size == 0 || blob == nullptr) {
182 LOG_WARN("blob data is empty!");
183 } else {
184 value.resize(size);
185 value.assign(blob, blob + size);
186 }
187 return E_OK;
188 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
189 return E_OK;
190 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
191 return E_OK;
192 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
193 return E_OK;
194 } else {
195 LOG_ERROR("AppDataFwk::SharedBlock::nothing !");
196 return E_INVALID_OBJECT_TYPE;
197 }
198 }
199
GetString(int columnIndex,std::string & value)200 int DataShareResultSet::GetString(int columnIndex, std::string &value)
201 {
202 if (sharedBlock_ == nullptr) {
203 LOG_ERROR("sharedBlock is null!");
204 return E_ERROR;
205 }
206 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
207 if (!cellUnit) {
208 return E_ERROR;
209 }
210 int type = cellUnit->type;
211 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
212 size_t sizeIncludingNull;
213 value = std::string(sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull));
214 return E_OK;
215 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
216 return E_OK;
217 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
218 int64_t tempValue = cellUnit->cell.longValue;
219 value = std::to_string(tempValue);
220 return E_OK;
221 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
222 double tempValue = cellUnit->cell.doubleValue;
223 std::ostringstream os;
224 if (os << tempValue) {
225 value = os.str();
226 }
227 return E_OK;
228 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
229 return E_ERROR;
230 } else {
231 LOG_ERROR("GetString is failed!");
232 return E_ERROR;
233 }
234 }
235
GetInt(int columnIndex,int & value)236 int DataShareResultSet::GetInt(int columnIndex, int &value)
237 {
238 if (sharedBlock_ == nullptr) {
239 LOG_ERROR("sharedBlock is null!");
240 return E_ERROR;
241 }
242 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
243 if (!cellUnit) {
244 return E_ERROR;
245 }
246 value = (int)cellUnit->cell.longValue;
247 return E_OK;
248 }
249
GetLong(int columnIndex,int64_t & value)250 int DataShareResultSet::GetLong(int columnIndex, int64_t &value)
251 {
252 if (sharedBlock_ == nullptr) {
253 LOG_ERROR("sharedBlock is null!");
254 return E_ERROR;
255 }
256 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
257 if (!cellUnit) {
258 return E_ERROR;
259 }
260
261 int type = cellUnit->type;
262
263 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
264 value = cellUnit->cell.longValue;
265 return E_OK;
266 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
267 size_t sizeIncludingNull;
268 const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
269 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? long(strtoll(tempValue, nullptr, 0)) : 0L;
270 return E_OK;
271 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
272 value = (int64_t)cellUnit->cell.doubleValue;
273 return E_OK;
274 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
275 value = 0L;
276 return E_OK;
277 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
278 value = 0L;
279 return E_OK;
280 } else {
281 LOG_ERROR("Nothing !");
282 return E_INVALID_OBJECT_TYPE;
283 }
284 }
285
GetDouble(int columnIndex,double & value)286 int DataShareResultSet::GetDouble(int columnIndex, double &value)
287 {
288 int errorCode = CheckState(columnIndex);
289 if (errorCode != E_OK) {
290 return errorCode;
291 }
292 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
293 if (!cellUnit) {
294 return E_ERROR;
295 }
296 int type = cellUnit->type;
297 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
298 value = cellUnit->cell.doubleValue;
299 return E_OK;
300 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
301 size_t sizeIncludingNull;
302 const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
303 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? strtod(tempValue, nullptr) : 0.0;
304 return E_OK;
305 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
306 value = static_cast<double>(cellUnit->cell.longValue);
307 return E_OK;
308 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
309 value = 0.0;
310 return E_OK;
311 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
312 value = 0.0;
313 return E_OK;
314 } else {
315 LOG_ERROR("AppDataFwk::SharedBlock::nothing !");
316 value = 0.0;
317 return E_INVALID_OBJECT_TYPE;
318 }
319 }
320
IsColumnNull(int columnIndex,bool & isNull)321 int DataShareResultSet::IsColumnNull(int columnIndex, bool &isNull)
322 {
323 int errorCode = CheckState(columnIndex);
324 if (errorCode != E_OK) {
325 return errorCode;
326 }
327 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
328 if (!cellUnit) {
329 return E_ERROR;
330 }
331 if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
332 isNull = true;
333 return E_OK;
334 }
335 isNull = false;
336 return E_OK;
337 }
338
Close()339 int DataShareResultSet::Close()
340 {
341 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
342 DataShareAbsResultSet::Close();
343 ClosedBlock();
344 bridge_ = nullptr;
345 return E_OK;
346 }
347
348 /**
349 * Allocates a new shared block to an {@link DataShareResultSet}
350 */
SetBlock(AppDataFwk::SharedBlock * block)351 void DataShareResultSet::SetBlock(AppDataFwk::SharedBlock *block)
352 {
353 if (sharedBlock_ != block) {
354 ClosedBlock();
355 sharedBlock_ = block;
356 }
357 }
358
359 /**
360 * Checks whether an {@code DataShareResultSet} object contains shared blocks
361 */
HasBlock() const362 bool DataShareResultSet::HasBlock() const
363 {
364 return sharedBlock_ != nullptr;
365 }
366
367 /**
368 * Closes a shared block that is not empty in this {@code DataShareResultSet} object
369 */
ClosedBlock()370 void DataShareResultSet::ClosedBlock()
371 {
372 if (sharedBlock_ != nullptr) {
373 delete sharedBlock_;
374 sharedBlock_ = nullptr;
375 }
376 }
377
Finalize()378 void DataShareResultSet::Finalize()
379 {
380 Close();
381 }
382
383 /**
384 * Check current status
385 */
CheckState(int columnIndex)386 int DataShareResultSet::CheckState(int columnIndex)
387 {
388 if (sharedBlock_ == nullptr) {
389 LOG_ERROR("sharedBlock is null!");
390 return E_ERROR;
391 }
392 int cnt = 0;
393 GetColumnCount(cnt);
394 if (columnIndex >= cnt || columnIndex < 0) {
395 return E_INVALID_COLUMN_INDEX;
396 }
397 if (rowPos_ == INITIAL_POS) {
398 return E_INVALID_STATEMENT;
399 }
400 return E_OK;
401 }
402
Marshalling(MessageParcel & parcel)403 bool DataShareResultSet::Marshalling(MessageParcel &parcel)
404 {
405 if (sharedBlock_ == nullptr) {
406 LOG_ERROR("sharedBlock is null.");
407 return false;
408 }
409 return sharedBlock_->WriteMessageParcel(parcel);
410 }
411
Unmarshalling(MessageParcel & parcel)412 bool DataShareResultSet::Unmarshalling(MessageParcel &parcel)
413 {
414 if (sharedBlock_ != nullptr) {
415 return false;
416 }
417 int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock_);
418 if (result < 0) {
419 LOG_ERROR("create from parcel error is %{public}d.", result);
420 }
421 return true;
422 }
423 } // namespace DataShare
424 } // namespace OHOS