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