1 /*
2 * Copyright (c) 2022 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 #define LOG_TAG "RdbResultSetImpl"
17
18 #include "rdb_result_set_impl.h"
19
20 #include <mutex>
21
22 #include "log_print.h"
23 #include "store/cursor.h"
24 #include "store_types.h"
25
26 using DistributedDB::DBStatus;
27 using OHOS::NativeRdb::ColumnType;
28
29 namespace OHOS::DistributedRdb {
30 using OHOS::DistributedData::GeneralError;
31 using Cursor = OHOS::DistributedData::Cursor;
32 using namespace OHOS::NativeRdb;
RdbResultSetImpl(std::shared_ptr<Cursor> resultSet)33 RdbResultSetImpl::RdbResultSetImpl(std::shared_ptr<Cursor> resultSet) : resultSet_(std::move(resultSet))
34 {
35 if (resultSet_ != nullptr) {
36 count_ = resultSet_->GetCount();
37 resultSet_->GetColumnNames(colNames_);
38 }
39 }
40
GetAllColumnNames(std::vector<std::string> &columnNames)41 int RdbResultSetImpl::GetAllColumnNames(std::vector<std::string> &columnNames)
42 {
43 std::shared_lock<std::shared_mutex> lock(mutex_);
44 if (resultSet_ == nullptr) {
45 return NativeRdb::E_ALREADY_CLOSED;
46 }
47 columnNames = colNames_;
48 return NativeRdb::E_OK;
49 }
50
GetColumnCount(int &count)51 int RdbResultSetImpl::GetColumnCount(int &count)
52 {
53 std::shared_lock<std::shared_mutex> lock(mutex_);
54 if (resultSet_ == nullptr) {
55 return NativeRdb::E_ALREADY_CLOSED;
56 }
57 count = static_cast<int>(colNames_.size());
58 return NativeRdb::E_OK;
59 }
60
GetColumnType(int columnIndex, ColumnType &columnType)61 int RdbResultSetImpl::GetColumnType(int columnIndex, ColumnType &columnType)
62 {
63 std::shared_lock<std::shared_mutex> lock(mutex_);
64 if (resultSet_ == nullptr) {
65 return NativeRdb::E_ALREADY_CLOSED;
66 }
67 columnType = ConvertColumnType(resultSet_->GetColumnType(columnIndex));
68 return NativeRdb::E_OK;
69 }
70
GetColumnIndex(const std::string &columnName, int &columnIndex)71 int RdbResultSetImpl::GetColumnIndex(const std::string &columnName, int &columnIndex)
72 {
73 std::shared_lock<std::shared_mutex> lock(mutex_);
74 if (resultSet_ == nullptr) {
75 return NativeRdb::E_ALREADY_CLOSED;
76 }
77 for (size_t i = 0; i < colNames_.size(); i++) {
78 if (colNames_[i] == columnName) {
79 columnIndex = static_cast<int>(i);
80 return NativeRdb::E_OK;
81 }
82 }
83 return NativeRdb::E_ERROR;
84 }
85
GetColumnName(int columnIndex, std::string &columnName)86 int RdbResultSetImpl::GetColumnName(int columnIndex, std::string &columnName)
87 {
88 std::shared_lock<std::shared_mutex> lock(mutex_);
89 if (resultSet_ == nullptr) {
90 return NativeRdb::E_ALREADY_CLOSED;
91 }
92 if (colNames_.size() <= static_cast<uint32_t>(columnIndex) || columnIndex < 0) {
93 return NativeRdb::E_ERROR;
94 }
95 columnName = colNames_[columnIndex];
96 return NativeRdb::E_OK;
97 }
98
GetRowCount(int &count)99 int RdbResultSetImpl::GetRowCount(int &count)
100 {
101 std::shared_lock<std::shared_mutex> lock(mutex_);
102 if (resultSet_ == nullptr) {
103 return NativeRdb::E_ALREADY_CLOSED;
104 }
105 count = count_;
106 return NativeRdb::E_OK;
107 }
108
GetRowIndex(int &position) const109 int RdbResultSetImpl::GetRowIndex(int &position) const
110 {
111 std::shared_lock<std::shared_mutex> lock(mutex_);
112 if (resultSet_ == nullptr) {
113 return NativeRdb::E_ALREADY_CLOSED;
114 }
115 position = current_;
116 return NativeRdb::E_OK;
117 }
118
GoTo(int offset)119 int RdbResultSetImpl::GoTo(int offset)
120 {
121 int ret = NativeRdb::E_OK;
122 while (offset != 0 && ret == NativeRdb::E_OK) {
123 if (offset > 0) {
124 ret = GoToNextRow();
125 offset--;
126 } else {
127 ret = GoToPreviousRow();
128 offset++;
129 }
130 }
131 return ret;
132 }
133
GoToRow(int position)134 int RdbResultSetImpl::GoToRow(int position)
135 {
136 return GoTo(position - current_);
137 }
138
GoToFirstRow()139 int RdbResultSetImpl::GoToFirstRow()
140 {
141 std::unique_lock<std::shared_mutex> lock(mutex_);
142 if (resultSet_ == nullptr) {
143 return NativeRdb::E_ALREADY_CLOSED;
144 }
145 auto ret = resultSet_->MoveToFirst();
146 current_ = 0;
147 return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR;
148 }
149
GoToLastRow()150 int RdbResultSetImpl::GoToLastRow()
151 {
152 return GoToRow(count_ - 1);
153 }
154
GoToNextRow()155 int RdbResultSetImpl::GoToNextRow()
156 {
157 std::unique_lock<std::shared_mutex> lock(mutex_);
158 if (resultSet_ == nullptr) {
159 return NativeRdb::E_ALREADY_CLOSED;
160 }
161 if (current_ >= count_ - 1) {
162 current_ = count_;
163 return NativeRdb::E_ERROR;
164 }
165
166 auto ret = resultSet_->MoveToNext();
167 current_++;
168 return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR;
169 }
170
GoToPreviousRow()171 int RdbResultSetImpl::GoToPreviousRow()
172 {
173 std::unique_lock<std::shared_mutex> lock(mutex_);
174 if (resultSet_ == nullptr) {
175 return NativeRdb::E_ALREADY_CLOSED;
176 }
177 if (current_ <= 0) {
178 current_ = -1;
179 return NativeRdb::E_ERROR;
180 }
181
182 auto ret = resultSet_->MoveToPrev();
183 current_--;
184 return ret == GeneralError::E_OK ? NativeRdb::E_OK : NativeRdb::E_ERROR;
185 }
186
IsEnded(bool &result)187 int RdbResultSetImpl::IsEnded(bool &result)
188 {
189 std::shared_lock<std::shared_mutex> lock(mutex_);
190 if (resultSet_ == nullptr) {
191 return NativeRdb::E_ALREADY_CLOSED;
192 }
193 result = current_ >= count_ || count_ <= 0;
194 return NativeRdb::E_OK;
195 }
196
IsStarted(bool &result) const197 int RdbResultSetImpl::IsStarted(bool &result) const
198 {
199 std::shared_lock<std::shared_mutex> lock(mutex_);
200 if (resultSet_ == nullptr) {
201 return NativeRdb::E_ALREADY_CLOSED;
202 }
203 result = current_ < 0 || count_ <= 0;
204 return NativeRdb::E_OK;
205 }
206
207 int RdbResultSetImpl::IsAtFirstRow(bool &result) const
208 {
209 std::shared_lock<std::shared_mutex> lock(mutex_);
210 if (resultSet_ == nullptr) {
211 return NativeRdb::E_ALREADY_CLOSED;
212 }
213 result = count_ > 0 && current_ == 0;
214 return NativeRdb::E_OK;
215 }
216
217 int RdbResultSetImpl::IsAtLastRow(bool &result)
218 {
219 std::shared_lock<std::shared_mutex> lock(mutex_);
220 if (resultSet_ == nullptr) {
221 return NativeRdb::E_ALREADY_CLOSED;
222 }
223 result = count_ > 0 && current_ == count_ - 1;
224 return NativeRdb::E_OK;
225 }
226
GetBlob(int columnIndex, std::vector<uint8_t> &value)227 int RdbResultSetImpl::GetBlob(int columnIndex, std::vector<uint8_t> &value)
228 {
229 std::shared_lock<std::shared_mutex> lock(mutex_);
230 if (resultSet_ == nullptr) {
231 return NativeRdb::E_ALREADY_CLOSED;
232 }
233 return Get(columnIndex, value);
234 }
235
GetString(int columnIndex, std::string &value)236 int RdbResultSetImpl::GetString(int columnIndex, std::string &value)
237 {
238 std::shared_lock<std::shared_mutex> lock(mutex_);
239 if (resultSet_ == nullptr) {
240 return NativeRdb::E_ALREADY_CLOSED;
241 }
242 return Get(columnIndex, value);
243 }
244
GetInt(int columnIndex, int &value)245 int RdbResultSetImpl::GetInt(int columnIndex, int &value)
246 {
247 int64_t tmpValue;
248 int status = GetLong(columnIndex, tmpValue);
249 if (status == NativeRdb::E_OK) {
250 if (tmpValue < INT32_MIN || tmpValue > INT32_MAX) {
251 ZLOGE("Get int value overflow.");
252 return NativeRdb::E_ERROR;
253 }
254 value = static_cast<int32_t>(tmpValue);
255 }
256 return status;
257 }
258
GetLong(int columnIndex, int64_t &value)259 int RdbResultSetImpl::GetLong(int columnIndex, int64_t &value)
260 {
261 std::shared_lock<std::shared_mutex> lock(mutex_);
262 if (resultSet_ == nullptr) {
263 return NativeRdb::E_ALREADY_CLOSED;
264 }
265 return Get(columnIndex, value);
266 }
267
GetDouble(int columnIndex, double &value)268 int RdbResultSetImpl::GetDouble(int columnIndex, double &value)
269 {
270 std::shared_lock<std::shared_mutex> lock(mutex_);
271 if (resultSet_ == nullptr) {
272 return NativeRdb::E_ALREADY_CLOSED;
273 }
274 return Get(columnIndex, value);
275 }
276
IsColumnNull(int columnIndex, bool &isNull)277 int RdbResultSetImpl::IsColumnNull(int columnIndex, bool &isNull)
278 {
279 std::shared_lock<std::shared_mutex> lock(mutex_);
280 if (resultSet_ == nullptr) {
281 return NativeRdb::E_ALREADY_CLOSED;
282 }
283 DistributedData::Value var;
284 auto status = resultSet_->Get(columnIndex, var);
285 if (status != DistributedData::GeneralError::E_OK) {
286 return NativeRdb::E_ERROR;
287 }
288 isNull = var.index() == DistributedData::TYPE_INDEX<std::monostate>;
289 return NativeRdb::E_OK;
290 }
291
IsClosed() const292 bool RdbResultSetImpl::IsClosed() const
293 {
294 std::shared_lock<std::shared_mutex> lock(mutex_);
295 return resultSet_ == nullptr;
296 }
297
Close()298 int RdbResultSetImpl::Close()
299 {
300 std::unique_lock<std::shared_mutex> lock(mutex_);
301 if (resultSet_ == nullptr) {
302 ZLOGW("Result set has been closed.");
303 return NativeRdb::E_OK;
304 }
305 resultSet_->Close();
306 resultSet_ = nullptr;
307 return NativeRdb::E_OK;
308 }
309
ConvertColumnType(int32_t columnType) const310 ColumnType RdbResultSetImpl::ConvertColumnType(int32_t columnType) const
311 {
312 if (static_cast<uint32_t>(columnType) >= DistributedData::TYPE_MAX || columnType < 0) {
313 return ColumnType::TYPE_NULL;
314 }
315 return COLUMNTYPES[columnType];
316 }
317
GetAsset(int32_t col, NativeRdb::ValueObject::Asset& value)318 int RdbResultSetImpl::GetAsset(int32_t col, NativeRdb::ValueObject::Asset& value)
319 {
320 std::shared_lock<std::shared_mutex> lock(mutex_);
321 if (resultSet_ == nullptr) {
322 return NativeRdb::E_ALREADY_CLOSED;
323 }
324 return Get(col, value);
325 }
326
GetAssets(int32_t col, NativeRdb::ValueObject::Assets& value)327 int RdbResultSetImpl::GetAssets(int32_t col, NativeRdb::ValueObject::Assets& value)
328 {
329 std::shared_lock<std::shared_mutex> lock(mutex_);
330 if (resultSet_ == nullptr) {
331 return NativeRdb::E_ALREADY_CLOSED;
332 }
333 return Get(col, value);
334 }
335
GetFloat32Array(int32_t index, NativeRdb::ValueObject::FloatVector& vecs)336 int RdbResultSetImpl::GetFloat32Array(int32_t index, NativeRdb::ValueObject::FloatVector& vecs)
337 {
338 std::shared_lock<std::shared_mutex> lock(mutex_);
339 if (resultSet_ == nullptr) {
340 return NativeRdb::E_ALREADY_CLOSED;
341 }
342 return NativeRdb::E_NOT_SUPPORT;
343 }
344
Get(int32_t col, NativeRdb::ValueObject& value)345 int RdbResultSetImpl::Get(int32_t col, NativeRdb::ValueObject& value)
346 {
347 std::shared_lock<std::shared_mutex> lock(mutex_);
348 if (resultSet_ == nullptr) {
349 return NativeRdb::E_ALREADY_CLOSED;
350 }
351 auto [errCode, object] = GetValue(col);
352 value = std::move(object);
353 return errCode;
354 }
355
GetRow(NativeRdb::RowEntity& rowEntity)356 int RdbResultSetImpl::GetRow(NativeRdb::RowEntity& rowEntity)
357 {
358 return NativeRdb::E_NOT_SUPPORT;
359 }
360
GetSize(int col, size_t& size)361 int RdbResultSetImpl::GetSize(int col, size_t& size)
362 {
363 std::shared_lock<std::shared_mutex> lock(mutex_);
364 if (resultSet_ == nullptr) {
365 return NativeRdb::E_ALREADY_CLOSED;
366 }
367 auto [errCode, value] = GetValue(col);
368 if (errCode != NativeRdb::E_OK) {
369 return errCode;
370 }
371 auto object = static_cast<ValueObject>(value);
372 if (object.GetType() == ValueObject::TYPE_STRING) {
373 auto val = std::get_if<std::string>(&object.value);
374 if (val != nullptr) {
375 size = val->size();
376 }
377 } else if (object.GetType() == ValueObject::TYPE_BLOB) {
378 auto val = std::get_if<std::vector<uint8_t>>(&object.value);
379 if (val != nullptr) {
380 size = val->size();
381 }
382 }
383 return NativeRdb::E_OK;
384 }
385 } // namespace OHOS::DistributedRdb
386