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