• 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 #define LOG_TAG "AbsSharedResultSet"
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 using SharedBlock = AppDataFwk::SharedBlock;
AbsSharedResultSet(std::string name)36 AbsSharedResultSet::AbsSharedResultSet(std::string name)
37     : AbsResultSet(true), sharedBlock_(nullptr), sharedBlockName_(std::move(name))
38 {
39 }
40 
AbsSharedResultSet()41 AbsSharedResultSet::AbsSharedResultSet()
42 {
43 }
44 
~AbsSharedResultSet()45 AbsSharedResultSet::~AbsSharedResultSet()
46 {
47     ClosedBlock();
48 }
49 
GetRowCount(int & count)50 int AbsSharedResultSet::GetRowCount(int &count)
51 {
52     return AbsResultSet::GetRowCount(count);
53 }
54 
OnGo(int oldRowIndex,int newRowIndex)55 int32_t AbsSharedResultSet::OnGo(int oldRowIndex, int newRowIndex)
56 {
57     return E_OK;
58 }
59 
60 /**
61  * Get current shared block
62  */
GetBlock()63 std::shared_ptr<SharedBlock> AbsSharedResultSet::GetBlock()
64 {
65     std::lock_guard<decltype(globalMtx_)> lockGuard(globalMtx_);
66     if (sharedBlock_ != nullptr || isClosed_ || lowMem_) {
67         return sharedBlock_;
68     }
69     SharedBlock *block = nullptr;
70     auto errcode = SharedBlock::Create(sharedBlockName_, DEFAULT_BLOCK_SIZE, block);
71     if (errcode != SharedBlock::SHARED_BLOCK_OK) {
72         lowMem_ = true;
73         return nullptr;
74     }
75     sharedBlock_ = std::shared_ptr<SharedBlock>(block);
76     return sharedBlock_;
77 }
78 
GetColumnType(int columnIndex,ColumnType & columnType)79 int AbsSharedResultSet::GetColumnType(int columnIndex, ColumnType &columnType)
80 {
81     auto block = GetBlock();
82     int errorCode = CheckState(columnIndex);
83     if (errorCode != E_OK) {
84         return errorCode;
85     }
86     SharedBlock::CellUnit *cellUnit = block->GetCellUnit(block->GetBlockPos(), (uint32_t)columnIndex);
87     if (!cellUnit) {
88         LOG_ERROR("AbsSharedResultSet::GetColumnType cellUnit is null!");
89         return E_ERROR;
90     }
91     columnType = (ColumnType)cellUnit->type;
92     return E_OK;
93 }
94 
UpdateBlockPos(int position,int rowCnt)95 int AbsSharedResultSet::UpdateBlockPos(int position, int rowCnt)
96 {
97     auto block = GetBlock();
98     auto ret = OnGo(rowPos_, position);
99     if (ret == E_OK) {
100         uint32_t startPos = block->GetStartPos();
101         uint32_t blockPos = block->GetBlockPos();
102         if (static_cast<uint32_t>(position) != startPos + blockPos) {
103             block->SetBlockPos(position - startPos);
104         }
105     }
106     return ret;
107 }
108 
GoToRow(int position)109 int AbsSharedResultSet::GoToRow(int position)
110 {
111     if (isClosed_) {
112         return E_ALREADY_CLOSED;
113     }
114 
115     int rowCnt = 0;
116     auto ret = GetRowCount(rowCnt);
117     if (ret != E_OK) {
118         LOG_ERROR("GetRowCount ret is %{public}d, rowCount is %{public}d", ret, rowCnt);
119         return ret;
120     }
121 
122     if (position >= rowCnt || position < 0) {
123         rowPos_ = (position >= rowCnt && rowCnt != 0) ? rowCnt : rowPos_;
124         LOG_DEBUG("position[%{public}d] rowCnt[%{public}d] rowPos[%{public}d]!", position, rowCnt, rowPos_);
125         return E_ROW_OUT_RANGE;
126     }
127 
128     if (position == rowPos_) {
129         return E_OK;
130     }
131 
132     ret = UpdateBlockPos(position, rowCnt);
133     if (ret == E_OK) {
134         rowPos_ = position;
135     }
136     return ret;
137 }
138 
GetString(int columnIndex,std::string & value)139 int AbsSharedResultSet::GetString(int columnIndex, std::string &value)
140 {
141     return AbsResultSet::GetString(columnIndex, value);
142 }
143 
Get(int32_t col,ValueObject & value)144 int AbsSharedResultSet::Get(int32_t col, ValueObject &value)
145 {
146     auto block = GetBlock();
147     int errorCode = CheckState(col);
148     if (errorCode != E_OK || block == nullptr) {
149         return errorCode;
150     }
151 
152     auto *cellUnit = block->GetCellUnit(block->GetBlockPos(), col);
153     if (cellUnit == nullptr) {
154         LOG_ERROR("cellUnit is null, col is %{public}d!", col);
155         return E_ERROR;
156     }
157     switch (cellUnit->type) {
158         case SharedBlock::CELL_UNIT_TYPE_NULL:
159             break;
160         case SharedBlock::CELL_UNIT_TYPE_INTEGER:
161             value = cellUnit->cell.longValue;
162             break;
163         case SharedBlock::CELL_UNIT_TYPE_FLOAT:
164             value = cellUnit->cell.doubleValue;
165             break;
166         case SharedBlock::CELL_UNIT_TYPE_STRING:
167             value = cellUnit->GetString(block.get());
168             break;
169         case SharedBlock::CELL_UNIT_TYPE_BLOB:
170             value = cellUnit->GetBlob(block.get());
171             break;
172         default:
173             return GetCustomerValue(col, value, block.get());
174     }
175     return E_OK;
176 }
177 
GetSize(int columnIndex,size_t & size)178 int AbsSharedResultSet::GetSize(int columnIndex, size_t &size)
179 {
180     size = 0;
181     auto block = GetBlock();
182     int errorCode = CheckState(columnIndex);
183     if (errorCode != E_OK) {
184         return errorCode;
185     }
186 
187     auto *cellUnit = block->GetCellUnit(GetBlock()->GetBlockPos(), columnIndex);
188     if (cellUnit == nullptr) {
189         LOG_ERROR("cellUnit is null!");
190         return E_ERROR;
191     }
192 
193     int type = cellUnit->type;
194     if (type == SharedBlock::CELL_UNIT_TYPE_STRING
195         || type == SharedBlock::CELL_UNIT_TYPE_BLOB
196         || type == SharedBlock::CELL_UNIT_TYPE_NULL) {
197         size = cellUnit->cell.stringOrBlobValue.size;
198         return E_OK;
199     }
200 
201     return E_INVALID_OBJECT_TYPE;
202 }
203 
Close()204 int AbsSharedResultSet::Close()
205 {
206     if (!isClosed_) {
207         AbsResultSet::Close();
208         ClosedBlock();
209         auto name = std::move(sharedBlockName_);
210     }
211     return E_OK;
212 }
213 
214 /**
215  * Allocates a new shared block to an {@link AbsSharedResultSet}
216  */
SetBlock(SharedBlock * block)217 void AbsSharedResultSet::SetBlock(SharedBlock *block)
218 {
219     std::lock_guard<decltype(globalMtx_)> lockGuard(globalMtx_);
220     if (sharedBlock_.get() != block) {
221         sharedBlock_ = std::shared_ptr<SharedBlock>(block);
222     }
223 }
224 
225 /**
226  * Checks whether an {@code AbsSharedResultSet} object contains shared blocks
227  */
HasBlock()228 bool AbsSharedResultSet::HasBlock()
229 {
230     return GetBlock() != nullptr;
231 }
232 
233 /**
234  * Closes a shared block that is not empty in this {@code AbsSharedResultSet} object
235  */
ClosedBlock()236 void AbsSharedResultSet::ClosedBlock()
237 {
238     std::lock_guard<decltype(globalMtx_)> lockGuard(globalMtx_);
239     sharedBlock_ = nullptr;
240 }
241 
ClearBlock()242 void AbsSharedResultSet::ClearBlock()
243 {
244     auto block = GetBlock();
245     if (block != nullptr) {
246         block->Clear();
247     }
248 }
249 
Finalize()250 void AbsSharedResultSet::Finalize()
251 {
252     Close();
253 }
254 
GetCustomerValue(int index,ValueObject & value,SharedBlock * block)255 int AbsSharedResultSet::GetCustomerValue(int index, ValueObject &value, SharedBlock *block)
256 {
257     auto *cellUnit = block->GetCellUnit(block->GetBlockPos(), index);
258     if (cellUnit == nullptr) {
259         LOG_ERROR("cellUnit is null, col is %{public}d!", index);
260         return E_ERROR;
261     }
262 
263     size_t size = cellUnit->cell.stringOrBlobValue.size;
264     auto data = cellUnit->GetRawData(block);
265     switch (cellUnit->type) {
266         case SharedBlock::CELL_UNIT_TYPE_ASSET: {
267             ValueObject::Asset asset;
268             RawDataParser::ParserRawData(data, size, asset);
269             value = std::move(asset);
270             break;
271         }
272         case SharedBlock::CELL_UNIT_TYPE_ASSETS: {
273             ValueObject::Assets assets;
274             RawDataParser::ParserRawData(data, size, assets);
275             value = std::move(assets);
276             break;
277         }
278         case SharedBlock::CELL_UNIT_TYPE_FLOATS: {
279             ValueObject::FloatVector floats;
280             RawDataParser::ParserRawData(data, size, floats);
281             value = std::move(floats);
282             break;
283         }
284         case SharedBlock::CELL_UNIT_TYPE_BIGINT: {
285             ValueObject::BigInt bigInt;
286             RawDataParser::ParserRawData(data, size, bigInt);
287             value = std::move(bigInt);
288             break;
289         }
290         default:
291             LOG_ERROR("Invalid type is %{public}d, col is %{public}d!", cellUnit->type, index);
292             return E_INVALID_OBJECT_TYPE;
293     }
294     return E_OK;
295 }
296 
297 /**
298  * Check current status
299  */
CheckState(int columnIndex)300 int AbsSharedResultSet::CheckState(int columnIndex)
301 {
302     if (isClosed_) {
303         return E_ALREADY_CLOSED;
304     }
305     if (GetBlock() == nullptr) {
306         LOG_ERROR("SharedBlock is null!");
307         return E_ERROR;
308     }
309     int count = 0;
310     GetRowCount(count);
311     if (rowPos_ < 0 || rowPos_ >= count) {
312         return E_ROW_OUT_RANGE;
313     }
314 
315     GetColumnCount(count);
316     if (columnIndex >= count || columnIndex < 0) {
317         return E_COLUMN_OUT_RANGE;
318     }
319 
320     return E_OK;
321 }
322 } // namespace NativeRdb
323 } // namespace OHOS
324