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