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 
16 #define LOG_TAG "CacheResultSet"
17 #include "cache_result_set.h"
18 
19 #include <algorithm>
20 #include <string>
21 
22 #include "abs_result_set.h"
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_trace.h"
26 namespace OHOS {
27 namespace NativeRdb {
CacheResultSet(std::vector<NativeRdb::ValuesBucket> && valueBuckets)28 CacheResultSet::CacheResultSet(std::vector<NativeRdb::ValuesBucket> &&valueBuckets)
29     : row_(0), maxCol_(0), valueBuckets_(std::move(valueBuckets))
30 {
31     maxRow_ = static_cast<int>(valueBuckets_.size());
32     if (maxRow_ > 0) {
33         for (auto it = valueBuckets_[0].values_.begin(); it != valueBuckets_[0].values_.end(); it++) {
34             colNames_.push_back(it->first);
35             colTypes_.push_back(it->second.GetType());
36         }
37         maxCol_ = static_cast<int>(colNames_.size());
38     }
39 }
40 
~CacheResultSet()41 CacheResultSet::~CacheResultSet()
42 {
43 }
44 
GetRowCount(int & count)45 int CacheResultSet::GetRowCount(int &count)
46 {
47     count = static_cast<int>(maxRow_);
48     return E_OK;
49 }
50 
GetAllColumnNames(std::vector<std::string> & columnNames)51 int CacheResultSet::GetAllColumnNames(std::vector<std::string> &columnNames)
52 {
53     columnNames = colNames_;
54     return E_OK;
55 }
56 
GetBlob(int columnIndex,std::vector<uint8_t> & blob)57 int CacheResultSet::GetBlob(int columnIndex, std::vector<uint8_t> &blob)
58 {
59     if (columnIndex < 0 || columnIndex >= maxCol_) {
60         return E_INVALID_ARGS;
61     }
62     auto name = colNames_[columnIndex];
63     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
64     if (row_ < 0 || row_ >= maxRow_) {
65         return E_ERROR;
66     }
67     return valueBuckets_[row_].values_[name].GetBlob(blob);
68 }
69 
GetString(int columnIndex,std::string & value)70 int CacheResultSet::GetString(int columnIndex, std::string &value)
71 {
72     if (columnIndex < 0 || columnIndex >= maxCol_) {
73         return E_INVALID_ARGS;
74     }
75     auto name = colNames_[columnIndex];
76     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
77     if (row_ < 0 || row_ >= maxRow_) {
78         return E_ERROR;
79     }
80     return valueBuckets_[row_].values_[name].GetString(value);
81 }
82 
GetInt(int columnIndex,int & value)83 int CacheResultSet::GetInt(int columnIndex, int &value)
84 {
85     if (columnIndex < 0 || columnIndex >= maxCol_) {
86         return E_INVALID_ARGS;
87     }
88     auto name = colNames_[columnIndex];
89     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
90     if (row_ < 0 || row_ >= maxRow_) {
91         return E_ERROR;
92     }
93     return valueBuckets_[row_].values_[name].GetInt(value);
94 }
95 
GetLong(int columnIndex,int64_t & value)96 int CacheResultSet::GetLong(int columnIndex, int64_t &value)
97 {
98     if (columnIndex < 0 || columnIndex >= maxCol_) {
99         return E_INVALID_ARGS;
100     }
101     auto name = colNames_[columnIndex];
102     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
103     if (row_ < 0 || row_ >= maxRow_) {
104         return E_ERROR;
105     }
106     return valueBuckets_[row_].values_[name].GetLong(value);
107 }
108 
GetDouble(int columnIndex,double & value)109 int CacheResultSet::GetDouble(int columnIndex, double &value)
110 {
111     if (columnIndex < 0 || columnIndex >= maxCol_) {
112         return E_INVALID_ARGS;
113     }
114     auto name = colNames_[columnIndex];
115     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
116     if (row_ < 0 || row_ >= maxRow_) {
117         return E_ERROR;
118     }
119     return valueBuckets_[row_].values_[name].GetDouble(value);
120 }
121 
IsColumnNull(int columnIndex,bool & isNull)122 int CacheResultSet::IsColumnNull(int columnIndex, bool &isNull)
123 {
124     if (columnIndex < 0 || columnIndex >= maxCol_) {
125         return E_INVALID_ARGS;
126     }
127     auto name = colNames_[columnIndex];
128     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
129     if (row_ < 0 || row_ >= maxRow_) {
130         return E_ERROR;
131     }
132     isNull = valueBuckets_[row_].values_[name].GetType() == ValueObject::TYPE_NULL;
133     return E_OK;
134 }
135 
GetRow(RowEntity & rowEntity)136 int CacheResultSet::GetRow(RowEntity &rowEntity)
137 {
138     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
139     if (row_ < 0 || row_ >= maxRow_) {
140         return E_ERROR;
141     }
142     rowEntity.Clear(colNames_.size());
143     int32_t index = 0;
144     for (auto &columnName : colNames_) {
145         ValueObject object;
146         if (!valueBuckets_[row_].GetObject(columnName, object)) {
147             return E_ERROR;
148         }
149         rowEntity.Put(columnName, index, std::move(object));
150         index++;
151     }
152     return E_OK;
153 }
154 
GoToRow(int position)155 int CacheResultSet::GoToRow(int position)
156 {
157     std::unique_lock<decltype(rwMutex_)> lock(rwMutex_);
158     if (position >= maxRow_) {
159         row_ = maxRow_;
160         return E_ERROR;
161     }
162     if (position < 0) {
163         row_ = -1;
164         return E_ERROR;
165     }
166     row_ = position;
167     return E_OK;
168 }
169 
GetColumnType(int columnIndex,ColumnType & columnType)170 int CacheResultSet::GetColumnType(int columnIndex, ColumnType &columnType)
171 {
172     if (columnIndex < 0 || columnIndex >= maxCol_) {
173         return E_INVALID_ARGS;
174     }
175     auto index = colTypes_[columnIndex];
176     if (index < ValueObject::TYPE_NULL || index >= ValueObject::TYPE_MAX) {
177         return E_INVALID_ARGS;
178     }
179     columnType = COLUMNTYPES[index];
180     return E_OK;
181 }
182 
GetRowIndex(int & position) const183 int CacheResultSet::GetRowIndex(int &position) const
184 {
185     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
186     position = row_;
187     return E_OK;
188 }
189 
GoTo(int offset)190 int CacheResultSet::GoTo(int offset)
191 {
192     int target = offset;
193     {
194         std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
195         target += row_;
196     }
197     return GoToRow(target);
198 }
199 
GoToFirstRow()200 int CacheResultSet::GoToFirstRow()
201 {
202     return GoToRow(0);
203 }
204 
GoToLastRow()205 int CacheResultSet::GoToLastRow()
206 {
207     return GoToRow(maxRow_ - 1);
208 }
209 
GoToNextRow()210 int CacheResultSet::GoToNextRow()
211 {
212     return GoTo(1);
213 }
214 
GoToPreviousRow()215 int CacheResultSet::GoToPreviousRow()
216 {
217     return GoTo(-1);
218 }
219 
IsAtFirstRow(bool & result) const220 int CacheResultSet::IsAtFirstRow(bool &result) const
221 {
222     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
223     result = row_ == 0;
224     return E_OK;
225 }
226 
IsAtLastRow(bool & result)227 int CacheResultSet::IsAtLastRow(bool &result)
228 {
229     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
230     result = row_ == maxRow_ - 1;
231     return E_OK;
232 }
233 
IsStarted(bool & result) const234 int CacheResultSet::IsStarted(bool &result) const
235 {
236     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
237     result = row_ == -1;
238     return E_OK;
239 }
240 
IsEnded(bool & result)241 int CacheResultSet::IsEnded(bool &result)
242 {
243     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
244     result = maxRow_ == 0 || row_ == maxRow_;
245     return E_OK;
246 }
247 
GetColumnCount(int & count)248 int CacheResultSet::GetColumnCount(int &count)
249 {
250     count = maxCol_;
251     return E_OK;
252 }
253 
GetColumnIndex(const std::string & columnName,int & columnIndex)254 int CacheResultSet::GetColumnIndex(const std::string &columnName, int &columnIndex)
255 {
256     for (int i = 0; i < maxCol_; ++i) {
257         if (colNames_[i] == columnName) {
258             columnIndex = i;
259             return E_OK;
260         }
261     }
262     return E_ERROR;
263 }
264 
GetColumnName(int columnIndex,std::string & columnName)265 int CacheResultSet::GetColumnName(int columnIndex, std::string &columnName)
266 {
267     if (columnIndex < 0 || columnIndex >= maxCol_) {
268         return E_INVALID_ARGS;
269     }
270     columnName = colNames_[columnIndex];
271     return E_OK;
272 }
273 
IsClosed() const274 bool CacheResultSet::IsClosed() const
275 {
276     return false;
277 }
278 
Close()279 int CacheResultSet::Close()
280 {
281     return E_NOT_SUPPORT;
282 }
283 
GetAsset(int32_t col,ValueObject::Asset & value)284 int CacheResultSet::GetAsset(int32_t col, ValueObject::Asset &value)
285 {
286     if (col < 0 || col >= maxCol_) {
287         return E_INVALID_ARGS;
288     }
289     auto name = colNames_[col];
290     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
291     if (row_ < 0 || row_ >= maxRow_) {
292         return E_ERROR;
293     }
294     return valueBuckets_[row_].values_[name].GetAsset(value);
295 }
296 
GetAssets(int32_t col,ValueObject::Assets & value)297 int CacheResultSet::GetAssets(int32_t col, ValueObject::Assets &value)
298 {
299     if (col < 0 || col >= maxCol_) {
300         return E_INVALID_ARGS;
301     }
302     auto name = colNames_[col];
303     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
304     if (row_ < 0 || row_ >= maxRow_) {
305         return E_ERROR;
306     }
307     return valueBuckets_[row_].values_[name].GetAssets(value);
308 }
309 
GetFloat32Array(int32_t index,ValueObject::FloatVector & vecs)310 int CacheResultSet::GetFloat32Array(int32_t index, ValueObject::FloatVector &vecs)
311 {
312     return E_NOT_SUPPORT;
313 }
314 
Get(int32_t col,ValueObject & value)315 int CacheResultSet::Get(int32_t col, ValueObject &value)
316 {
317     if (col < 0 || col >= maxCol_) {
318         return E_INVALID_ARGS;
319     }
320     auto name = colNames_[col];
321     std::shared_lock<decltype(rwMutex_)> lock(rwMutex_);
322     if (row_ < 0 || row_ >= maxRow_) {
323         return E_ERROR;
324     }
325     value = valueBuckets_[row_].values_[name];
326     return E_OK;
327 }
328 
GetSize(int columnIndex,size_t & size)329 int CacheResultSet::GetSize(int columnIndex, size_t &size)
330 {
331     return E_NOT_SUPPORT;
332 }
333 }
334 } // namespace OHOS