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