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