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