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
19 #include <sstream>
20
21 #include "adaptor.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 ClosedBlock();
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 AppDataFwk::SharedBlock::CellUnit *cellUnit =
113 sharedBlock_->GetCellUnit((uint32_t)rowPos_ - startRowPos_, (uint32_t)columnIndex);
114 if (!cellUnit) {
115 LOG_ERROR("cellUnit is null!");
116 return E_ERROR;
117 }
118 dataType = (DataType)cellUnit->type;
119 return E_OK;
120 }
121
GoToRow(int position)122 int DataShareResultSet::GoToRow(int position)
123 {
124 if (sharedBlock_ == nullptr) {
125 LOG_ERROR("sharedBlock_ is null!");
126 return E_ERROR;
127 }
128 int rowCnt = 0;
129 GetRowCount(rowCnt);
130 if (position >= rowCnt) {
131 rowPos_ = rowCnt;
132 return E_ERROR;
133 }
134 if (position < 0) {
135 rowPos_ = INITIAL_POS;
136 return E_ERROR;
137 }
138 if (position == rowPos_) {
139 return E_OK;
140 }
141 bool result = true;
142 if (position > endRowPos_ || position < startRowPos_) {
143 int endPos = -1;
144 result = OnGo(position, rowCnt - 1, &endPos);
145 if (result) {
146 startRowPos_ = position;
147 endRowPos_ = endPos;
148 }
149 }
150
151 if (!result) {
152 rowPos_ = INITIAL_POS;
153 startRowPos_ = INITIAL_POS;
154 endRowPos_ = INITIAL_POS;
155 return E_ERROR;
156 } else {
157 rowPos_ = position;
158 return E_OK;
159 }
160 }
161
GetBlob(int columnIndex,std::vector<uint8_t> & value)162 int DataShareResultSet::GetBlob(int columnIndex, std::vector<uint8_t> &value)
163 {
164 int errorCode = CheckState(columnIndex);
165 if (errorCode != E_OK) {
166 return errorCode;
167 }
168
169 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
170 if (!cellUnit) {
171 LOG_ERROR("cellUnit is null!");
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 int errorCode = CheckState(columnIndex);
203 if (errorCode != E_OK) {
204 return errorCode;
205 }
206 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
207 if (!cellUnit) {
208 LOG_ERROR("cellUnit is null!");
209 return E_ERROR;
210 }
211 int type = cellUnit->type;
212 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
213 size_t sizeIncludingNull;
214 value = std::string(sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull));
215 return E_OK;
216 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
217 return E_ERROR;
218 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
219 int64_t tempValue = cellUnit->cell.longValue;
220 value = std::to_string(tempValue);
221 return E_OK;
222 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
223 double tempValue = cellUnit->cell.doubleValue;
224 std::ostringstream os;
225 if (os << tempValue)
226 value = os.str();
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 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
239 if (!cellUnit) {
240 LOG_ERROR("cellUnit is null!");
241 return E_ERROR;
242 }
243 value = (int)cellUnit->cell.longValue;
244 return E_OK;
245 }
246
GetLong(int columnIndex,int64_t & value)247 int DataShareResultSet::GetLong(int columnIndex, int64_t &value)
248 {
249 int errorCode = CheckState(columnIndex);
250 if (errorCode != E_OK) {
251 return errorCode;
252 }
253 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
254 if (!cellUnit) {
255 LOG_ERROR("cellUnit is null!");
256 return E_ERROR;
257 }
258
259 int type = cellUnit->type;
260
261 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
262 value = cellUnit->cell.longValue;
263 return E_OK;
264 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
265 size_t sizeIncludingNull;
266 const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
267 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? long(strtoll(tempValue, nullptr, 0)) : 0L;
268 return E_OK;
269 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
270 value = (int64_t)cellUnit->cell.doubleValue;
271 return E_OK;
272 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
273 value = 0L;
274 return E_OK;
275 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
276 value = 0L;
277 return E_OK;
278 } else {
279 LOG_ERROR("Nothing !");
280 return E_INVALID_OBJECT_TYPE;
281 }
282 }
283
GetDouble(int columnIndex,double & value)284 int DataShareResultSet::GetDouble(int columnIndex, double &value)
285 {
286 int errorCode = CheckState(columnIndex);
287 if (errorCode != E_OK) {
288 return errorCode;
289 }
290 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
291 if (!cellUnit) {
292 LOG_ERROR("cellUnit is null!");
293 return E_ERROR;
294 }
295 int type = cellUnit->type;
296 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
297 value = cellUnit->cell.doubleValue;
298 return E_OK;
299 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
300 size_t sizeIncludingNull;
301 const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
302 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? strtod(tempValue, nullptr) : 0.0;
303 return E_OK;
304 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
305 value = cellUnit->cell.longValue;
306 return E_OK;
307 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
308 value = 0.0;
309 return E_OK;
310 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
311 value = 0.0;
312 return E_OK;
313 } else {
314 LOG_ERROR("AppDataFwk::SharedBlock::nothing !");
315 value = 0.0;
316 return E_INVALID_OBJECT_TYPE;
317 }
318 }
319
IsColumnNull(int columnIndex,bool & isNull)320 int DataShareResultSet::IsColumnNull(int columnIndex, bool &isNull)
321 {
322 int errorCode = CheckState(columnIndex);
323 if (errorCode != E_OK) {
324 return errorCode;
325 }
326 AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(rowPos_ - startRowPos_, columnIndex);
327 if (!cellUnit) {
328 LOG_ERROR("cellUnit is null!");
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 return E_OK;
345 }
346
347 /**
348 * Allocates a new shared block to an {@link DataShareResultSet}
349 */
SetBlock(AppDataFwk::SharedBlock * block)350 void DataShareResultSet::SetBlock(AppDataFwk::SharedBlock *block)
351 {
352 if (sharedBlock_ != block) {
353 ClosedBlock();
354 sharedBlock_ = block;
355 }
356 }
357
358 /**
359 * Checks whether an {@code DataShareResultSet} object contains shared blocks
360 */
HasBlock() const361 bool DataShareResultSet::HasBlock() const
362 {
363 return sharedBlock_ != nullptr;
364 }
365
366 /**
367 * Closes a shared block that is not empty in this {@code DataShareResultSet} object
368 */
ClosedBlock()369 void DataShareResultSet::ClosedBlock()
370 {
371 if (sharedBlock_ != nullptr) {
372 delete sharedBlock_;
373 sharedBlock_ = nullptr;
374 }
375 }
376
Finalize()377 void DataShareResultSet::Finalize()
378 {
379 Close();
380 }
381
382 /**
383 * Check current status
384 */
CheckState(int columnIndex)385 int DataShareResultSet::CheckState(int columnIndex)
386 {
387 if (sharedBlock_ == nullptr) {
388 LOG_ERROR("sharedBlock is null!");
389 return E_ERROR;
390 }
391 int cnt = 0;
392 GetColumnCount(cnt);
393 if (columnIndex >= cnt || columnIndex < 0) {
394 return E_INVALID_COLUMN_INDEX;
395 }
396 if (rowPos_ == INITIAL_POS) {
397 return E_INVALID_STATEMENT;
398 }
399 return E_OK;
400 }
401
Marshalling(MessageParcel & parcel)402 bool DataShareResultSet::Marshalling(MessageParcel &parcel)
403 {
404 if (sharedBlock_ == nullptr) {
405 LOG_ERROR("sharedBlock is null.");
406 return false;
407 }
408 return sharedBlock_->WriteMessageParcel(parcel);
409 }
410
Unmarshalling(MessageParcel & parcel)411 bool DataShareResultSet::Unmarshalling(MessageParcel &parcel)
412 {
413 if (sharedBlock_ != nullptr) {
414 return false;
415 }
416 int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock_);
417 if (result < 0) {
418 LOG_ERROR("create from parcel error is %{public}d.", result);
419 }
420 return true;
421 }
422 } // namespace DataShare
423 } // namespace OHOS