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