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