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