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
16 #include "abs_shared_result_set.h"
17
18 #include <securec.h>
19
20 #include <algorithm>
21 #include <codecvt>
22 #include <iostream>
23 #include <sstream>
24 #include <string>
25
26 #include "logger.h"
27 #include "raw_data_parser.h"
28 #include "rdb_errno.h"
29 #include "rdb_trace.h"
30 #include "shared_block.h"
31
32 namespace OHOS {
33 namespace NativeRdb {
34 using namespace OHOS::Rdb;
35
AbsSharedResultSet(std::string name)36 AbsSharedResultSet::AbsSharedResultSet(std::string name) : sharedBlock_(nullptr), sharedBlockName_(name)
37 {
38 }
39
AbsSharedResultSet()40 AbsSharedResultSet::AbsSharedResultSet()
41 {
42 }
43
~AbsSharedResultSet()44 AbsSharedResultSet::~AbsSharedResultSet()
45 {
46 ClosedBlock();
47 }
48
GetAllColumnNames(std::vector<std::string> & columnNames)49 int AbsSharedResultSet::GetAllColumnNames(std::vector<std::string> &columnNames)
50 {
51 return E_OK;
52 }
53
GetRowCount(int & count)54 int AbsSharedResultSet::GetRowCount(int &count)
55 {
56 return E_OK;
57 }
58
OnGo(int oldRowIndex,int newRowIndex)59 bool AbsSharedResultSet::OnGo(int oldRowIndex, int newRowIndex)
60 {
61 return true;
62 }
63
FillBlock(int startRowIndex,AppDataFwk::SharedBlock * block)64 void AbsSharedResultSet::FillBlock(int startRowIndex, AppDataFwk::SharedBlock *block)
65 {
66 return;
67 }
68
69 /**
70 * Get current shared block
71 */
GetBlock()72 AppDataFwk::SharedBlock *AbsSharedResultSet::GetBlock()
73 {
74 if (sharedBlock_ != nullptr) {
75 return sharedBlock_;
76 }
77 AppDataFwk::SharedBlock::Create(sharedBlockName_, DEFAULT_BLOCK_SIZE, sharedBlock_);
78 return sharedBlock_;
79 }
80
GetColumnType(int columnIndex,ColumnType & columnType)81 int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType)
82 {
83 int errorCode = CheckState(columnIndex);
84 if (errorCode != E_OK) {
85 return errorCode;
86 }
87 AppDataFwk::SharedBlock::CellUnit *cellUnit =
88 GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), (uint32_t)columnIndex);
89 if (!cellUnit) {
90 LOG_ERROR("AbsSharedResultSet::GetColumnType cellUnit is null!");
91 return E_ERROR;
92 }
93 columnType = (ColumnType)cellUnit->type;
94 return E_OK;
95 }
96
GoToRow(int position)97 int AbsSharedResultSet::GoToRow(int position)
98 {
99 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
100 if (position == rowPos_) {
101 return E_OK;
102 }
103
104 if (position < 0) {
105 LOG_ERROR("Invalid position %{public}d!", position);
106 return E_ERROR;
107 }
108
109 int rowCnt = 0;
110 GetRowCount(rowCnt);
111 if (rowCnt == 0) {
112 LOG_DEBUG("No data!");
113 return E_ERROR;
114 }
115
116 if (position >= rowCnt) {
117 rowPos_ = rowCnt;
118 return E_ERROR;
119 }
120
121 if (rowPos_ <= INIT_POS) {
122 rowPos_ = 0;
123 }
124
125 bool result = true;
126 if (GetBlock() == nullptr || (uint32_t)position < GetBlock()->GetStartPos() ||
127 (uint32_t)position >= GetBlock()->GetLastPos() || rowPos_ == rowCnt) {
128 result = OnGo(rowPos_, position);
129 } else {
130 uint32_t blockPos = GetBlock()->GetBlockPos();
131 if (position > rowPos_) {
132 blockPos += (uint32_t)(position - rowPos_);
133 } else {
134 uint32_t offset = (uint32_t)(rowPos_ - position);
135 if (blockPos >= offset) {
136 blockPos -= offset;
137 } else {
138 LOG_ERROR("GoToRow failed of position= %{public}d, rowPos= %{public}d", position, rowPos_);
139 return E_ERROR;
140 }
141 }
142 GetBlock()->SetBlockPos(blockPos);
143 }
144
145 if (result) {
146 rowPos_ = position;
147 return E_OK;
148 }
149 return E_ERROR;
150 }
151
GetBlob(int columnIndex,std::vector<uint8_t> & value)152 int AbsSharedResultSet::GetBlob(int columnIndex, std::vector<uint8_t> &value)
153 {
154 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
155 int errorCode = CheckState(columnIndex);
156 if (errorCode != E_OK) {
157 return errorCode;
158 }
159
160 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
161 if (!cellUnit) {
162 LOG_ERROR("AbsSharedResultSet::GetBlob cellUnit is null!");
163 return E_ERROR;
164 }
165
166 value.resize(0);
167 int type = cellUnit->type;
168 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB
169 || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
170 size_t size;
171 const auto *blob = static_cast<const uint8_t *>(GetBlock()->GetCellUnitValueBlob(cellUnit, &size));
172 if (size == 0 || blob == nullptr) {
173 LOG_WARN("blob data is empty!");
174 } else {
175 value.resize(size);
176 value.assign(blob, blob + size);
177 }
178 return E_OK;
179 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
180 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER!");
181 return E_OK;
182 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
183 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL!");
184 return E_OK;
185 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
186 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT!");
187 return E_OK;
188 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) {
189 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET!");
190 return E_INVALID_OBJECT_TYPE;
191 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS) {
192 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS!");
193 return E_INVALID_OBJECT_TYPE;
194 } else {
195 LOG_ERROR("AbsSharedResultSet::GetBlob AppDataFwk::SharedBlock::nothing !");
196 return E_INVALID_OBJECT_TYPE;
197 }
198 }
199
GetString(int columnIndex,std::string & value)200 int AbsSharedResultSet::GetString(int columnIndex, std::string &value)
201 {
202 DISTRIBUTED_DATA_HITRACE("AbsSharedResultSet::GetString");
203 int errorCode = CheckState(columnIndex);
204 if (errorCode != E_OK) {
205 return errorCode;
206 }
207 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
208 if (!cellUnit) {
209 LOG_ERROR("AbsSharedResultSet::GetString 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 const char *tempValue = GetBlock()->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
216 if ((sizeIncludingNull <= 1) || (tempValue == nullptr)) {
217 value = "";
218 return E_OK;
219 }
220 value = tempValue;
221 return E_OK;
222 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
223 int64_t tempValue = cellUnit->cell.longValue;
224 value = std::to_string(tempValue);
225 return E_OK;
226 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
227 double tempValue = cellUnit->cell.doubleValue;
228 std::ostringstream os;
229 if (os << tempValue)
230 value = os.str();
231 return E_OK;
232 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
233 return E_OK;
234 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
235 return E_OK;
236 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) {
237 LOG_ERROR("AbsSharedResultSet::GetString AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET !");
238 return E_INVALID_OBJECT_TYPE;
239 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS) {
240 LOG_ERROR("AbsSharedResultSet::GetString AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS !");
241 return E_INVALID_OBJECT_TYPE;
242 } else {
243 LOG_ERROR("AbsSharedResultSet::GetString is failed!");
244 return E_ERROR;
245 }
246 }
247
GetInt(int columnIndex,int & value)248 int AbsSharedResultSet::GetInt(int columnIndex, int &value)
249 {
250 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
251 int errorCode = CheckState(columnIndex);
252 if (errorCode != E_OK) {
253 return errorCode;
254 }
255 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
256 if (!cellUnit) {
257 LOG_ERROR("AbsSharedResultSet::GetInt cellUnit is null!");
258 return E_ERROR;
259 }
260 value = (int)cellUnit->cell.longValue;
261 return E_OK;
262 }
263
GetLong(int columnIndex,int64_t & value)264 int AbsSharedResultSet::GetLong(int columnIndex, int64_t &value)
265 {
266 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
267 int errorCode = CheckState(columnIndex);
268 if (errorCode != E_OK) {
269 return errorCode;
270 }
271 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
272 if (!cellUnit) {
273 LOG_ERROR("AbsSharedResultSet::GetLong cellUnit is null!");
274 return E_ERROR;
275 }
276
277 int type = cellUnit->type;
278
279 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
280 value = cellUnit->cell.longValue;
281 return E_OK;
282 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
283 size_t sizeIncludingNull;
284 const char *tempValue = GetBlock()->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
285 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? int64_t(strtoll(tempValue, nullptr, 0)) : 0L;
286 return E_OK;
287 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
288 value = (int64_t)cellUnit->cell.doubleValue;
289 return E_OK;
290 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
291 value = 0L;
292 return E_OK;
293 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
294 value = 0L;
295 return E_OK;
296 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) {
297 LOG_ERROR("AbsSharedResultSet::GetLong AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET !");
298 return E_INVALID_OBJECT_TYPE;
299 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS) {
300 LOG_ERROR("AbsSharedResultSet::GetLong AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS !");
301 return E_INVALID_OBJECT_TYPE;
302 } else {
303 LOG_ERROR("AbsSharedResultSet::GetLong Nothing !");
304 return E_INVALID_OBJECT_TYPE;
305 }
306 }
307
GetDouble(int columnIndex,double & value)308 int AbsSharedResultSet::GetDouble(int columnIndex, double &value)
309 {
310 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
311 int errorCode = CheckState(columnIndex);
312 if (errorCode != E_OK) {
313 return errorCode;
314 }
315 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
316 if (!cellUnit) {
317 LOG_ERROR("AbsSharedResultSet::GetDouble cellUnit is null!");
318 return E_ERROR;
319 }
320 int type = cellUnit->type;
321 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_FLOAT) {
322 value = cellUnit->cell.doubleValue;
323 return E_OK;
324 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING) {
325 size_t sizeIncludingNull;
326 const char *tempValue = GetBlock()->GetCellUnitValueString(cellUnit, &sizeIncludingNull);
327 value = ((sizeIncludingNull > 1) && (tempValue != nullptr)) ? strtod(tempValue, nullptr) : 0.0;
328 return E_OK;
329 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_INTEGER) {
330 value = cellUnit->cell.longValue;
331 return E_OK;
332 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
333 LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL!");
334 value = 0.0;
335 return E_OK;
336 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB) {
337 LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB!");
338 value = 0.0;
339 return E_OK;
340 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) {
341 LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET!");
342 return E_INVALID_OBJECT_TYPE;
343 } else if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS) {
344 LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS!");
345 return E_INVALID_OBJECT_TYPE;
346 } else {
347 LOG_ERROR("AbsSharedResultSet::GetDouble AppDataFwk::SharedBlock::nothing !");
348 value = 0.0;
349 return E_INVALID_OBJECT_TYPE;
350 }
351 }
352
GetAsset(int32_t col,ValueObject::Asset & value)353 int AbsSharedResultSet::GetAsset(int32_t col, ValueObject::Asset &value)
354 {
355 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
356 int errorCode = CheckState(col);
357 if (errorCode != E_OK) {
358 return errorCode;
359 }
360
361 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), col);
362 if (!cellUnit) {
363 LOG_ERROR("GetAsset cellUnit is null!");
364 return E_ERROR;
365 }
366
367 if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
368 LOG_ERROR("GetAsset the type of cell is null !");
369 return E_NULL_OBJECT;
370 }
371
372 if (cellUnit->type != AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSET) {
373 LOG_ERROR("GetAssets the type of cell is not assets, type is %{public}d, col is %{public}d!", cellUnit->type,
374 col);
375 return E_INVALID_OBJECT_TYPE;
376 }
377
378 size_t size = 0;
379 auto data = reinterpret_cast<const uint8_t *>(GetBlock()->GetCellUnitValueBlob(cellUnit, &size));
380 ValueObject::Asset asset;
381 RawDataParser::ParserRawData(data, size, asset);
382 value = std::move(asset);
383 return E_OK;
384 }
385
GetAssets(int32_t col,ValueObject::Assets & value)386 int AbsSharedResultSet::GetAssets(int32_t col, ValueObject::Assets &value)
387 {
388 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
389 int errorCode = CheckState(col);
390 if (errorCode != E_OK) {
391 return errorCode;
392 }
393
394 auto *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), col);
395 if (!cellUnit) {
396 LOG_ERROR("GetAssets cellUnit is null!");
397 return E_ERROR;
398 }
399
400 if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
401 LOG_ERROR("GetAssets the type of cell is null !");
402 return E_NULL_OBJECT;
403 }
404
405 if (cellUnit->type != AppDataFwk::SharedBlock::CELL_UNIT_TYPE_ASSETS) {
406 LOG_ERROR("GetAssets the type of cell is not assets, type is %{public}d, col is %{public}d!", cellUnit->type,
407 col);
408 return E_INVALID_OBJECT_TYPE;
409 }
410
411 size_t size = 0;
412 auto data = reinterpret_cast<const uint8_t *>(GetBlock()->GetCellUnitValueBlob(cellUnit, &size));
413 ValueObject::Assets assets;
414 RawDataParser::ParserRawData(data, size, assets);
415 value = std::move(assets);
416 return E_OK;
417 }
418
GetSize(int columnIndex,size_t & size)419 int AbsSharedResultSet::GetSize(int columnIndex, size_t &size)
420 {
421 size = 0;
422 int errorCode = CheckState(columnIndex);
423 if (errorCode != E_OK) {
424 return errorCode;
425 }
426
427 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
428 if (cellUnit == nullptr) {
429 LOG_ERROR("cellUnit is null!");
430 return E_ERROR;
431 }
432
433 int type = cellUnit->type;
434 if (type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_STRING
435 || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_BLOB
436 || type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
437 GetBlock()->GetCellUnitValueBlob(cellUnit, &size);
438 return E_OK;
439 }
440
441 return E_INVALID_OBJECT_TYPE;
442 }
443
IsColumnNull(int columnIndex,bool & isNull)444 int AbsSharedResultSet::IsColumnNull(int columnIndex, bool &isNull)
445 {
446 int errorCode = CheckState(columnIndex);
447 if (errorCode != E_OK) {
448 return errorCode;
449 }
450 AppDataFwk::SharedBlock::CellUnit *cellUnit = GetBlock()->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
451 if (!cellUnit) {
452 LOG_ERROR("AbsSharedResultSet::IsColumnNull cellUnit is null!");
453 return E_ERROR;
454 }
455 if (cellUnit->type == AppDataFwk::SharedBlock::CELL_UNIT_TYPE_NULL) {
456 isNull = true;
457 return E_OK;
458 }
459 isNull = false;
460 return E_OK;
461 }
462
Close()463 int AbsSharedResultSet::Close()
464 {
465 if (!isClosed) {
466 AbsResultSet::Close();
467 ClosedBlock();
468 }
469 return E_OK;
470 }
471
472 /**
473 * Allocates a new shared block to an {@link AbsSharedResultSet}
474 */
SetBlock(AppDataFwk::SharedBlock * block)475 void AbsSharedResultSet::SetBlock(AppDataFwk::SharedBlock *block)
476 {
477 if (GetBlock() != block) {
478 ClosedBlock();
479 sharedBlock_ = block;
480 }
481 }
482
483 /**
484 * Checks whether an {@code AbsSharedResultSet} object contains shared blocks
485 */
HasBlock()486 bool AbsSharedResultSet::HasBlock()
487 {
488 return GetBlock() != nullptr;
489 }
490
491 /**
492 * Closes a shared block that is not empty in this {@code AbsSharedResultSet} object
493 */
ClosedBlock()494 void AbsSharedResultSet::ClosedBlock()
495 {
496 if (sharedBlock_ != nullptr) {
497 delete sharedBlock_;
498 sharedBlock_ = nullptr;
499 }
500 }
501
ClearBlock()502 void AbsSharedResultSet::ClearBlock()
503 {
504 if (GetBlock() != nullptr) {
505 GetBlock()->Clear();
506 }
507 }
508
Finalize()509 void AbsSharedResultSet::Finalize()
510 {
511 Close();
512 }
513
514 /**
515 * Check current status
516 */
CheckState(int columnIndex)517 int AbsSharedResultSet::CheckState(int columnIndex)
518 {
519 if (GetBlock() == nullptr) {
520 LOG_ERROR("AbsSharedResultSet::CheckState sharedBlock is null!");
521 return E_ERROR;
522 }
523 int count = 0;
524 GetRowCount(count);
525 if (rowPos_ < 0 || rowPos_ >= count) {
526 return E_INVALID_STATEMENT;
527 }
528
529 GetColumnCount(count);
530 if (columnIndex >= count || columnIndex < 0) {
531 return E_INVALID_COLUMN_INDEX;
532 }
533
534 return E_OK;
535 }
536 } // namespace NativeRdb
537 } // namespace OHOS
538