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