• 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_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