1 /*
2  * Copyright (c) 2023 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 #include "gtest/gtest.h"
17 #include "mock/cursor_mock.h"
18 #include "rdb_result_set_impl.h"
19 #include "store/cursor.h"
20 using namespace testing::ext;
21 using namespace OHOS;
22 using namespace OHOS::DistributedRdb;
23 using namespace OHOS::DistributedData;
24 
25 namespace OHOS::Test {
26 namespace DistributedRDBTest {
27 class RdbResultSetImplTest : public testing::Test {
28 public:
29     static void SetUpTestCase(void);
30     static void TearDownTestCase(void);
31     void SetUp();
32     void TearDown();
33     static inline const std::vector<std::pair<std::string, RdbResultSetImpl::ColumnType>> Names = {
34         { "1_id", RdbResultSetImpl::ColumnType::TYPE_INTEGER },
35         { "2_name", RdbResultSetImpl::ColumnType::TYPE_STRING },
36         { "3_price", RdbResultSetImpl::ColumnType::TYPE_FLOAT },
37         { "4_bool", RdbResultSetImpl::ColumnType::TYPE_INTEGER },
38         { "5_bytes", RdbResultSetImpl::ColumnType::TYPE_BLOB }
39     };
40     static std::map<std::string, Value> makeEntry(int i);
41     static RdbResultSetImpl::ColumnType getColumnType(std::string &name);
42     std::shared_ptr<CursorMock::ResultSet> cursor;
43     std::shared_ptr<RdbResultSetImpl> resultSet;
44     static inline constexpr int32_t SIZE = 50;
45 };
46 
SetUpTestCase(void)47 void RdbResultSetImplTest::SetUpTestCase(void) {}
48 
TearDownTestCase(void)49 void RdbResultSetImplTest::TearDownTestCase(void) {}
50 
SetUp()51 void RdbResultSetImplTest::SetUp()
52 {
53     cursor = std::make_shared<CursorMock::ResultSet>(SIZE);
54     for (int i = 0; i < SIZE; i++) {
55         (*cursor)[i] = makeEntry(i);
56     }
57     auto cursorMock = std::make_shared<CursorMock>(cursor);
58     resultSet = std::make_shared<RdbResultSetImpl>(cursorMock);
59 }
60 
TearDown()61 void RdbResultSetImplTest::TearDown() {}
62 
makeEntry(int i)63 std::map<std::string, Value> RdbResultSetImplTest::makeEntry(int i)
64 {
65     std::string str = "RdbResultSetImplTest";
66     Bytes bytes(str.begin(), str.end());
67     std::map<std::string, Value> entry = {
68         { Names[0].first, i },
69         { Names[1].first, "name_" + std::to_string(i) },
70         { Names[2].first, 1.65 },
71         { Names[3].first, i & 0x1 },
72         { Names[4].first, bytes}
73     };
74     return entry;
75 }
76 
getColumnType(string & name)77 RdbResultSetImpl::ColumnType RdbResultSetImplTest::getColumnType(string &name)
78 {
79     RdbResultSetImpl::ColumnType columnType = RdbResultSetImpl::ColumnType::TYPE_NULL;
80     std::find_if(Names.begin(), Names.end(), [&columnType, &name](auto &pr) {
81         if (pr.first == name) {
82             columnType = pr.second;
83             return true;
84         }
85         return false;
86     });
87     return columnType;
88 }
89 
90 /**
91 * @tc.name: RdbResultSetImplGetColumn
92 * @tc.desc: RdbResultSetImpl get col;
93 * @tc.type: FUNC
94 * @tc.require:
95 * @tc.author: ht
96 */
97 HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGetColumn, TestSize.Level0)
98 {
99     std::vector<std::string> names;
100     resultSet->GetAllColumnNames(names);
101     ASSERT_EQ(Names.size(), names.size());
102     for (int i = 0; i < Names.size(); i++) {
103         ASSERT_EQ(Names[i].first, names[i]);
104         std::string colName;
105         ASSERT_EQ(resultSet->GetColumnName(i, colName), NativeRdb::E_OK);
106         ASSERT_EQ(colName, names[i]);
107         RdbResultSetImpl::ColumnType columnType;
108         ASSERT_EQ(resultSet->GetColumnType(i, columnType), NativeRdb::E_OK);
109         ASSERT_EQ(columnType, getColumnType(colName));
110     }
111 }
112 
113 /**
114 * @tc.name: RdbResultSetImplGoTO
115 * @tc.desc: RdbResultSetImpl go to row;
116 * @tc.type: FUNC
117 * @tc.require:
118 * @tc.author: ht
119 */
120 HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGoTO, TestSize.Level0)
121 {
122     int count = 0;
123     ASSERT_EQ(resultSet->GetRowCount(count), NativeRdb::E_OK);
124     ASSERT_EQ(count, SIZE);
125 
126     int position = 0;
127     ASSERT_EQ(resultSet->GoToFirstRow(), NativeRdb::E_OK);
128     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
129     ASSERT_EQ(position, 0);
130 
131     bool result;
132     ASSERT_EQ(resultSet->IsStarted(result), NativeRdb::E_OK);
133     ASSERT_FALSE(result);
134 
135     ASSERT_EQ(resultSet->GoToPreviousRow(), NativeRdb::E_ERROR);
136     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
137     ASSERT_EQ(position, -1);
138 
139     ASSERT_EQ(resultSet->IsStarted(result), NativeRdb::E_OK);
140     ASSERT_TRUE(result);
141 
142     int absPosition = random() % SIZE;
143     ASSERT_EQ(resultSet->GoToRow(absPosition), NativeRdb::E_OK);
144     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
145     ASSERT_EQ(position, absPosition);
146 
147     ASSERT_EQ(resultSet->GoToLastRow(), NativeRdb::E_OK);
148     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
149     ASSERT_EQ(position, SIZE - 1);
150 
151     ASSERT_EQ(resultSet->IsEnded(result), NativeRdb::E_OK);
152     ASSERT_FALSE(result);
153 
154     ASSERT_EQ(resultSet->GoToNextRow(), NativeRdb::E_ERROR);
155     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
156     ASSERT_EQ(position, SIZE);
157 
158     ASSERT_EQ(resultSet->IsEnded(result), NativeRdb::E_OK);
159     ASSERT_TRUE(result);
160 
161     ASSERT_EQ(resultSet->GoTo(-10), NativeRdb::E_OK);
162     ASSERT_EQ(resultSet->GetRowIndex(position), NativeRdb::E_OK);
163     ASSERT_EQ(position, SIZE - 10);
164 }
165 
166 /**
167 * @tc.name: RdbResultSetImplGet
168 * @tc.desc: RdbResultSetImpl get data;
169 * @tc.type: FUNC
170 * @tc.require:
171 * @tc.author: ht
172 */
173 HWTEST_F(RdbResultSetImplTest, RdbResultSetImplGet, TestSize.Level0)
174 {
175     ASSERT_EQ(resultSet->GoToFirstRow(), NativeRdb::E_OK);
176     bool result = false;
177     int index = 0;
178     int64_t tmpInt;
179     double tmpFlo;
180     std::string tmpStr;
181     Bytes tmpBlob;
182     while (!result) {
183         for (int i = 0; i < Names.size(); i++) {
184             auto var = (*cursor)[index][Names[i].first];
185             ValueProxy::Value value = ValueProxy::Convert(std::move(var));
186             switch (Names[i].second) {
187                 case RdbResultSetImpl::ColumnType::TYPE_INTEGER:
188                     ASSERT_EQ(resultSet->GetLong(i, tmpInt), NativeRdb::E_OK);
189                     ASSERT_EQ(tmpInt, int64_t(value));
190                     break;
191                 case RdbResultSetImpl::ColumnType::TYPE_FLOAT:
192                     ASSERT_EQ(resultSet->GetDouble(i, tmpFlo), NativeRdb::E_OK);
193                     ASSERT_EQ(tmpFlo, double(value));
194                     break;
195                 case RdbResultSetImpl::ColumnType::TYPE_STRING:
196                     ASSERT_EQ(resultSet->GetString(i, tmpStr), NativeRdb::E_OK);
197                     ASSERT_EQ(tmpStr, std::string(value));
198                     break;
199                 case RdbResultSetImpl::ColumnType::TYPE_BLOB:
200                     ASSERT_EQ(resultSet->GetBlob(i, tmpBlob), NativeRdb::E_OK);
201                     ASSERT_EQ(tmpBlob.size(), Bytes(value).size());
202                     break;
203                 default:
204                     break;
205             }
206         }
207         resultSet->GoToNextRow();
208         index++;
209         resultSet->IsEnded(result);
210     }
211 }
212 
213 /**
214 * @tc.name: RdbResultSetImpl001
215 * @tc.desc: RdbResultSetImpl function test.
216 * @tc.type: FUNC
217 * @tc.require:
218 * @tc.author: SQL
219 */
220 HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl001, TestSize.Level0)
221 {
222     std::vector<std::string> names;
223     EXPECT_EQ(resultSet->GetAllColumnNames(names), NativeRdb::E_OK);
224     int count = 0;
225     EXPECT_EQ(resultSet->GetColumnCount(count), NativeRdb::E_OK);
226     std::string columnName = "columnName";
227     int columnIndex = 0;
228     EXPECT_EQ(resultSet->GetColumnIndex(columnName, columnIndex), NativeRdb::E_ERROR);
229     EXPECT_EQ(resultSet->GetColumnIndex(names[1], columnIndex), NativeRdb::E_OK);
230     EXPECT_EQ(resultSet->GetColumnName(columnIndex, columnName), NativeRdb::E_OK);
231     columnIndex = 10; // 10 > colNames_.size()
232     EXPECT_EQ(resultSet->GetColumnName(columnIndex, columnName), NativeRdb::E_ERROR);
233     EXPECT_EQ(resultSet->GetColumnName(-1, columnName), NativeRdb::E_ERROR);
234     bool result = false;
235     EXPECT_EQ(resultSet->IsAtFirstRow(result), NativeRdb::E_OK);
236     EXPECT_EQ(resultSet->IsAtLastRow(result), NativeRdb::E_OK);
237     int value = 1;
238     EXPECT_EQ(resultSet->GetInt(value, value), NativeRdb::E_OK);
239     EXPECT_EQ(resultSet->IsColumnNull(value, result), NativeRdb::E_OK);
240     int32_t col = 1;
241     NativeRdb::ValueObject::Asset asset;
242     NativeRdb::ValueObject::Assets assets;
243     EXPECT_EQ(resultSet->GetAsset(col, asset), NativeRdb::E_OK);
244     EXPECT_EQ(resultSet->GetAssets(col, assets), NativeRdb::E_OK);
245     NativeRdb::ValueObject::FloatVector vecs;
246     size_t size = 0;
247     EXPECT_EQ(resultSet->GetSize(col, size), NativeRdb::E_OK);
248     EXPECT_FALSE(resultSet->IsClosed());
249     EXPECT_EQ(resultSet->Close(), NativeRdb::E_OK);
250 }
251 
252 /**
253 * @tc.name: RdbResultSetImpl002
254 * @tc.desc: RdbResultSetImpl function error test.
255 * @tc.type: FUNC
256 * @tc.require:
257 * @tc.author: SQL
258 */
259 HWTEST_F(RdbResultSetImplTest, RdbResultSetImpl002, TestSize.Level0)
260 {
261     auto cursorMock = std::make_shared<CursorMock>(cursor);
262     cursorMock = nullptr;
263     std::shared_ptr<RdbResultSetImpl> result = std::make_shared<RdbResultSetImpl>(cursorMock);
264     std::vector<std::string> columnNames;
265     int columnIndex = 0;
266     RdbResultSetImpl::ColumnType columnType;
267     std::string columnName = "columnName";
268     bool ret = false;
269     std::vector<uint8_t> value;
270     int64_t value1 = 0;
271     double value2 = 0.0;
272     int32_t col = 0;
273     NativeRdb::ValueObject::Asset asset;
274     NativeRdb::ValueObject::Assets assets;
275     NativeRdb::ValueObject::FloatVector vecs;
276     NativeRdb::ValueObject valueObject;
277     size_t size = 0;
278     EXPECT_EQ(result->GetAllColumnNames(columnNames), NativeRdb::E_ALREADY_CLOSED);
279     EXPECT_EQ(result->GetColumnCount(columnIndex), NativeRdb::E_ALREADY_CLOSED);
280     EXPECT_EQ(result->GetColumnType(columnIndex, columnType), NativeRdb::E_ALREADY_CLOSED);
281     EXPECT_EQ(result->GetColumnIndex(columnName, columnIndex), NativeRdb::E_ALREADY_CLOSED);
282     EXPECT_EQ(result->GetColumnName(columnIndex, columnName), NativeRdb::E_ALREADY_CLOSED);
283     EXPECT_EQ(result->GetRowCount(columnIndex), NativeRdb::E_ALREADY_CLOSED);
284     EXPECT_EQ(result->GetRowIndex(columnIndex), NativeRdb::E_ALREADY_CLOSED);
285     EXPECT_EQ(result->GoToFirstRow(), NativeRdb::E_ALREADY_CLOSED);
286     EXPECT_EQ(result->GoToNextRow(), NativeRdb::E_ALREADY_CLOSED);
287     EXPECT_EQ(result->GoToPreviousRow(), NativeRdb::E_ALREADY_CLOSED);
288     EXPECT_EQ(result->IsEnded(ret), NativeRdb::E_ALREADY_CLOSED);
289     EXPECT_EQ(result->IsStarted(ret), NativeRdb::E_ALREADY_CLOSED);
290     EXPECT_EQ(result->IsAtFirstRow(ret), NativeRdb::E_ALREADY_CLOSED);
291     EXPECT_EQ(result->IsAtLastRow(ret), NativeRdb::E_ALREADY_CLOSED);
292     EXPECT_EQ(result->GetBlob(columnIndex, value), NativeRdb::E_ALREADY_CLOSED);
293     EXPECT_EQ(result->GetString(columnIndex, columnName), NativeRdb::E_ALREADY_CLOSED);
294     EXPECT_EQ(result->GetLong(columnIndex, value1), NativeRdb::E_ALREADY_CLOSED);
295     EXPECT_EQ(result->GetDouble(columnIndex, value2), NativeRdb::E_ALREADY_CLOSED);
296     EXPECT_EQ(result->IsColumnNull(columnIndex, ret), NativeRdb::E_ALREADY_CLOSED);
297     EXPECT_EQ(result->Close(), NativeRdb::E_OK);
298     EXPECT_EQ(result->GetAsset(col, asset), NativeRdb::E_ALREADY_CLOSED);
299     EXPECT_EQ(result->GetAssets(col, assets), NativeRdb::E_ALREADY_CLOSED);
300     EXPECT_EQ(result->Get(col, valueObject), NativeRdb::E_ALREADY_CLOSED);
301     EXPECT_EQ(result->GetSize(col, size), NativeRdb::E_ALREADY_CLOSED);
302 }
303 } // namespace DistributedRDBTest
304 } // namespace OHOS::Test