• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "abs_shared_result_set.h"
16 
17 #include <algorithm>
18 #include <codecvt>
19 #include <iostream>
20 #include <securec.h>
21 #include <sstream>
22 #include <string>
23 
24 #include "logger.h"
25 #include "parcel.h"
26 #include "rdb_errno.h"
27 #include "rdb_trace.h"
28 #include "shared_block.h"
29 #include "string_ex.h"
30 
31 namespace OHOS {
32 namespace NativeRdb {
AbsSharedResultSet(std::string name)33 AbsSharedResultSet::AbsSharedResultSet(std::string name)
34 {
35     AppDataFwk::SharedBlock::Create(name, DEFAULT_BLOCK_SIZE, sharedBlock_);
36 }
37 
AbsSharedResultSet()38 AbsSharedResultSet::AbsSharedResultSet()
39 {
40 }
41 
~AbsSharedResultSet()42 AbsSharedResultSet::~AbsSharedResultSet()
43 {
44     ClosedBlock();
45 }
46 
GetAllColumnNames(std::vector<std::string> & columnNames)47 int AbsSharedResultSet::GetAllColumnNames(std::vector<std::string> &columnNames)
48 {
49     return E_OK;
50 }
51 
GetRowCount(int & count)52 int AbsSharedResultSet::GetRowCount(int &count)
53 {
54     return E_OK;
55 }
56 
OnGo(int oldRowIndex,int newRowIndex)57 bool AbsSharedResultSet::OnGo(int oldRowIndex, int newRowIndex)
58 {
59     return true;
60 }
61 
FillBlock(int startRowIndex,AppDataFwk::SharedBlock * block)62 void AbsSharedResultSet::FillBlock(int startRowIndex, AppDataFwk::SharedBlock *block)
63 {
64     return;
65 }
66 
67 /**
68  * Get current shared block
69  */
GetBlock() const70 AppDataFwk::SharedBlock *AbsSharedResultSet::GetBlock() const
71 {
72     return sharedBlock_;
73 }
74 
GetColumnType(int columnIndex,ColumnType & columnType)75 int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType)
76 {
77     int errorCode = CheckState(columnIndex);
78     if (errorCode != E_OK) {
79         return errorCode;
80     }
81     AppDataFwk::SharedBlock::CellUnit *cellUnit =
82         sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), (uint32_t)columnIndex);
83     if (!cellUnit) {
84         LOG_ERROR("AbsSharedResultSet::GetColumnType cellUnit is null!");
85         return E_ERROR;
86     }
87     columnType = (ColumnType)cellUnit->type;
88     return E_OK;
89 }
90 
GoToRow(int position)91 int AbsSharedResultSet::GoToRow(int position)
92 {
93     if (position == rowPos_) {
94         return E_OK;
95     }
96 
97     if (position < 0) {
98         LOG_ERROR("Invalid position %{public}d!", position);
99         return E_ERROR;
100     }
101 
102     int rowCnt = 0;
103     GetRowCount(rowCnt);
104     if (rowCnt == 0) {
105         LOG_WARN("No data!");
106         return E_ERROR;
107     }
108 
109     if (position >= rowCnt) {
110         rowPos_ = rowCnt;
111         return E_ERROR;
112     }
113 
114     if (rowPos_ <= INIT_POS) {
115         rowPos_ = 0;
116     }
117 
118     bool result = true;
119     if (sharedBlock_ == nullptr || (uint32_t)position < sharedBlock_->GetStartPos() ||
120         (uint32_t)position >= sharedBlock_->GetLastPos() || rowPos_ == rowCnt) {
121         result = OnGo(rowPos_, position);
122     } else {
123         uint32_t blockPos = sharedBlock_->GetBlockPos();
124         if (position > rowPos_) {
125             blockPos += (uint32_t)(position - rowPos_);
126         } else {
127             uint32_t offset = (uint32_t)(rowPos_ - position);
128             if (blockPos >= offset) {
129                 blockPos -= offset;
130             } else {
131                 LOG_ERROR("GoToRow failed of position= %{public}d, rowPos= %{public}d", position, rowPos_);
132                 return E_ERROR;
133             }
134         }
135         sharedBlock_->SetBlockPos(blockPos);
136     }
137 
138     if (result) {
139         rowPos_ = position;
140         return E_OK;
141     }
142 
143     return E_ERROR;
144 }
145 
GetBlob(int columnIndex,std::vector<uint8_t> & value)146 int AbsSharedResultSet::GetBlob(int columnIndex, std::vector<uint8_t> &value)
147 {
148     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
149     int errorCode = CheckState(columnIndex);
150     if (errorCode != E_OK) {
151         return errorCode;
152     }
153 
154     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
155     if (!cellUnit) {
156         LOG_ERROR("AbsSharedResultSet::GetBlob cellUnit is null!");
157         return E_ERROR;
158     }
159 
160     value.resize(0);
161     int type = cellUnit->type;
162     if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB
163         || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
164         size_t size;
165         const auto *blob = static_cast<const uint8_t *>(sharedBlock_->GetCellUnitValueBlob(cellUnit, &size));
166         if (size == 0 || blob == nullptr) {
167             LOG_WARN("blob data is empty!");
168         } else {
169             value.resize(size);
170             value.assign(blob, blob + size);
171         }
172         return E_OK;
173     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
174         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER!");
175         return E_OK;
176     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
177         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL!");
178         return E_OK;
179     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
180         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT!");
181         return E_OK;
182     } else {
183         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::nothing !");
184         return E_INVALID_OBJECT_TYPE;
185     }
186 }
187 
GetString(int columnIndex,std::string & value)188 int AbsSharedResultSet::GetString(int columnIndex, std::string &value)
189 {
190     DISTRIBUTED_DATA_HITRACE("AbsSharedResultSet::GetString");
191     int errorCode = CheckState(columnIndex);
192     if (errorCode != E_OK) {
193         return errorCode;
194     }
195     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
196     if (!cellUnit) {
197         LOG_ERROR("AbsSharedResultSet::GetString cellUnit is null!");
198         return E_ERROR;
199     }
200     int type = cellUnit->type;
201     if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
202         size_t sizeIncludingNull;
203         const char *tempValue = sharedBlock_->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
204         if ((sizeIncludingNull <= 1) || (tempValue == nullptr)) {
205             value = "";
206             return E_OK;
207         }
208         value = tempValue;
209         return E_OK;
210     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
211         int64_t tempValue = cellUnit->cell.longValue;
212         value = std::to_string(tempValue);
213         return E_OK;
214     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
215         double tempValue = cellUnit->cell.doubleValue;
216         std::ostringstream os;
217         if (os << tempValue)
218             value = os.str();
219         return E_OK;
220     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
221         return E_OK;
222     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
223         return E_OK;
224     } else {
225         LOG_ERROR("AbsSharedResultSet::GetString is failed!");
226         return E_ERROR;
227     }
228 }
229 
GetInt(int columnIndex,int & value)230 int AbsSharedResultSet::GetInt(int columnIndex, int &value)
231 {
232     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
233     int errorCode = CheckState(columnIndex);
234     if (errorCode != E_OK) {
235         return errorCode;
236     }
237     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
238     if (!cellUnit) {
239         LOG_ERROR("AbsSharedResultSet::GetInt cellUnit is null!");
240         return E_ERROR;
241     }
242     value = (int)cellUnit->cell.longValue;
243     return E_OK;
244 }
245 
GetLong(int columnIndex,int64_t & value)246 int AbsSharedResultSet::GetLong(int columnIndex, int64_t &value)
247 {
248     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
249     int errorCode = CheckState(columnIndex);
250     if (errorCode != E_OK) {
251         return errorCode;
252     }
253     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
254     if (!cellUnit) {
255         LOG_ERROR("AbsSharedResultSet::GetLong 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)) ? int64_t(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("AbsSharedResultSet::GetLong Nothing !");
280         return E_INVALID_OBJECT_TYPE;
281     }
282 }
283 
GetDouble(int columnIndex,double & value)284 int AbsSharedResultSet::GetDouble(int columnIndex, double &value)
285 {
286     DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
287     int errorCode = CheckState(columnIndex);
288     if (errorCode != E_OK) {
289         return errorCode;
290     }
291     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
292     if (!cellUnit) {
293         LOG_ERROR("AbsSharedResultSet::GetDouble cellUnit is null!");
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 = cellUnit->cell.longValue;
307         return E_OK;
308     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
309         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL!");
310         value = 0.0;
311         return E_OK;
312     } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
313         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB!");
314         value = 0.0;
315         return E_OK;
316     } else {
317         LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::nothing !");
318         value = 0.0;
319         return E_INVALID_OBJECT_TYPE;
320     }
321 }
322 
IsColumnNull(int columnIndex,bool & isNull)323 int AbsSharedResultSet::IsColumnNull(int columnIndex, bool &isNull)
324 {
325     int errorCode = CheckState(columnIndex);
326     if (errorCode != E_OK) {
327         return errorCode;
328     }
329     AppDataFwk::SharedBlock::CellUnit *cellUnit = sharedBlock_->GetCellUnit(sharedBlock_->GetBlockPos(), columnIndex);
330     if (!cellUnit) {
331         LOG_ERROR("AbsSharedResultSet::IsColumnNull cellUnit is null!");
332         return E_ERROR;
333     }
334     if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
335         isNull = true;
336         return E_OK;
337     }
338     isNull = false;
339     return E_OK;
340 }
341 
Close()342 int AbsSharedResultSet::Close()
343 {
344     AbsResultSet::Close();
345     ClosedBlock();
346     return E_OK;
347 }
348 
349 /**
350  * Allocates a new shared block to an {@link AbsSharedResultSet}
351  */
SetBlock(AppDataFwk::SharedBlock * block)352 void AbsSharedResultSet::SetBlock(AppDataFwk::SharedBlock *block)
353 {
354     if (sharedBlock_ != block) {
355         ClosedBlock();
356         sharedBlock_ = block;
357     }
358 }
359 
360 /**
361  * Checks whether an {@code AbsSharedResultSet} object contains shared blocks
362  */
HasBlock() const363 bool AbsSharedResultSet::HasBlock() const
364 {
365     return sharedBlock_ != nullptr;
366 }
367 
368 /**
369  * Closes a shared block that is not empty in this {@code AbsSharedResultSet} object
370  */
ClosedBlock()371 void AbsSharedResultSet::ClosedBlock()
372 {
373     delete sharedBlock_;
374     sharedBlock_ = nullptr;
375 }
376 
ClearBlock()377 void AbsSharedResultSet::ClearBlock()
378 {
379     if (sharedBlock_ != nullptr) {
380         sharedBlock_->Clear();
381     }
382 }
383 
Finalize()384 void AbsSharedResultSet::Finalize()
385 {
386     Close();
387 }
388 
389 /**
390  * Check current status
391  */
CheckState(int columnIndex)392 int AbsSharedResultSet::CheckState(int columnIndex)
393 {
394     if (sharedBlock_ == nullptr) {
395         LOG_ERROR("AbsSharedResultSet::CheckState 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     int rowCnt = 0;
404     GetRowCount(rowCnt);
405     if (rowPos_ < 0 || rowPos_ >= rowCnt) {
406         return E_INVALID_STATEMENT;
407     }
408     return E_OK;
409 }
410 
Marshalling(MessageParcel & parcel)411 bool AbsSharedResultSet::Marshalling(MessageParcel &parcel)
412 {
413     if (sharedBlock_ == nullptr) {
414         LOG_ERROR("AbsSharedResultSet::Marshalling sharedBlock is null.");
415         return false;
416     }
417     LOG_DEBUG("AbsSharedResultSet::Marshalling sharedBlock.");
418     return sharedBlock_->WriteMessageParcel(parcel);
419 }
420 
Unmarshalling(MessageParcel & parcel)421 bool AbsSharedResultSet::Unmarshalling(MessageParcel &parcel)
422 {
423     if (sharedBlock_ != nullptr) {
424         return false;
425     }
426     int result = AppDataFwk::SharedBlock::ReadMessageParcel(parcel, sharedBlock_);
427     if (result < 0) {
428         LOG_ERROR("AbsSharedResultSet: create from parcel error is %{public}d.", result);
429     }
430     return true;
431 }
432 } // namespace NativeRdb
433 } // namespace OHOS
434