From 56899b602ec83b9f6e5c50ba652d0a74738c0016 Mon Sep 17 00:00:00 2001 From: Kacperos155 Date: Tue, 2 Aug 2022 03:18:01 +0200 Subject: [PATCH] Add Iterators tests --- CMakeLists.txt | 1 + include/SQLiteCpp/Row.h | 4 +- src/Row.cpp | 4 +- tests/Iterators.cpp | 128 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 tests/Iterators.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 23004e29..b6cabd9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ set(SQLITECPP_TESTS tests/VariadicBind_test.cpp tests/Exception_test.cpp tests/ExecuteMany_test.cpp + tests/Iterators.cpp ) source_group(tests FILES ${SQLITECPP_TESTS}) diff --git a/include/SQLiteCpp/Row.h b/include/SQLiteCpp/Row.h index 1f168790..e5f633c9 100644 --- a/include/SQLiteCpp/Row.h +++ b/include/SQLiteCpp/Row.h @@ -55,7 +55,7 @@ class Row * @throws SQLite::Exception when there is no column with given name */ Column at(const char* aName) const; - + /** * @return Column with given index * @@ -78,7 +78,7 @@ class Row { return at(aName); } - + /** * @return Column with given index * diff --git a/src/Row.cpp b/src/Row.cpp index 56116e4c..71c65ca5 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -20,9 +20,9 @@ namespace SQLite Row::Row(TStatementWeakPtr apStatement, std::size_t aID) : mpStatement(apStatement), mID(aID) { - checkStatement(); auto statement = mpStatement.lock(); - mColumnCount = statement->mColumnCount; + if (statement) + mColumnCount = statement->mColumnCount; } Column Row::at(int_fast16_t aIndex) const diff --git a/tests/Iterators.cpp b/tests/Iterators.cpp new file mode 100644 index 00000000..5d65f645 --- /dev/null +++ b/tests/Iterators.cpp @@ -0,0 +1,128 @@ +/** + * @file Iterators.cpp + * @ingroup tests + * @brief Test of Statement iterators + * + * Copyright (c) 2022 Kacper Zielinski (KacperZ155@gmail.com) + * + * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt + * or copy at http://opensource.org/licenses/MIT) + */ + +#include +#include + +#include + +#include +#include +#include + +SQLite::Database createDatabase() +{ + SQLite::Database db(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); + EXPECT_EQ(SQLite::OK, db.exec("CREATE TABLE test (number INTEGER, number_str TEXT)")); + + SQLite::Statement inserter(db, "INSERT INTO test VALUES(?,?)"); + for (int i = 10; i > 0; --i) + { + inserter.bind(1, i); + inserter.bind(2, std::to_string(i)); + EXPECT_EQ(1, inserter.exec()); + EXPECT_NO_THROW(inserter.reset()); + } + return db; +} + +TEST(Iterators, RowIterator) +{ + auto db = createDatabase(); + + SQLite::Statement query(db, "SELECT * FROM test"); + std::vector numbers; + + for (const auto& row : query) + { + numbers.push_back(row[0]); + } + + //TODO: EXPECT_TRUE(query.isDone()); + + const auto v_size = static_cast(numbers.size()); + for (int i = v_size; i > 0; --i) + { + EXPECT_EQ(i, numbers[v_size - i]); + } + + auto it = query.begin(); + ++it; + EXPECT_STREQ("number_str", it->getColumn(1).getName()); + EXPECT_EQ(1, it->getColumnIndex("number_str")); + + // getColumn aliases + EXPECT_EQ(9, it->at(0).getInt()); + EXPECT_EQ(9, it->getColumn(0).getInt()); + EXPECT_EQ(9, it->operator[](0).getInt()); + + auto it2 = query.begin(); + ++it2; + EXPECT_EQ(it, it2); + + // RowInterator is advancing common statement object + ++it; + EXPECT_EQ(it->at(0).getInt(), it2->at(0).getInt()); + // But iterators internal state is diffrent. + EXPECT_NE(it, it2); +} + +TEST(Iterators, RowIterator_STL_Algorithms) +{ + auto db = createDatabase(); + + SQLite::Statement query(db, "SELECT * FROM test"); + + for (auto it = query.begin(); it != query.end(); std::advance(it, 3)) + { + EXPECT_TRUE(it->getRowNumber() % 3 == 0); + } + + EXPECT_TRUE(std::all_of(query.begin(), query.end(), [](const SQLite::Row& row) + { + return row[0].getInt() > 0; + })); +} + +TEST(Iterators, ColumnIterator) +{ + auto db = createDatabase(); + + SQLite::Statement query_only1(db, "SELECT * FROM test LIMIT 1"); + std::vector numbers_str; + + for(const auto& row : query_only1) + for (const auto& column : row) + { + numbers_str.emplace_back(column.getText()); + } + + for (const auto& column : numbers_str) + { + EXPECT_EQ("10", column); + } +} + +TEST(Iterators, ColumnIterator_STL_Algorithms) +{ + auto db = createDatabase(); + + SQLite::Statement query_only1(db, "SELECT * FROM test LIMIT 1"); + std::vector numbers; + + for (const auto& row : query_only1) + { + EXPECT_EQ(2, std::count_if(row.begin(), row.end(), [i = 10](const SQLite::Column& column) + { + return column.getText() == std::to_string(i); + })); + } +}