• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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