diff --git a/rdbms/CMakeLists.txt b/rdbms/CMakeLists.txt index c6e926561262358a0dc6080292cd491f74d97f8e..a3fa9ad9df1423869bfd41044a83b795f10f201a 100644 --- a/rdbms/CMakeLists.txt +++ b/rdbms/CMakeLists.txt @@ -45,6 +45,7 @@ set(RDBMS_UNIT_TESTS_LIB_SRC_FILES ConnPoolTest.cpp LoginTest.cpp RdbmsTest.cpp + RsetTest.cpp StmtPoolTest.cpp) add_library (ctardbmsunittests SHARED diff --git a/rdbms/Rset.cpp b/rdbms/Rset.cpp index 1fab1e324be180804f847c8ee5e43b139dcd71fe..92750284af2365d165cbd18fbf67ec16bbce64b6 100644 --- a/rdbms/Rset.cpp +++ b/rdbms/Rset.cpp @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "rdbms/InvalidResultSet.hpp" #include "rdbms/NullDbValue.hpp" #include "rdbms/Rset.hpp" #include "rdbms/wrapper/RsetWrapper.hpp" @@ -62,8 +63,7 @@ Rset &Rset::operator=(Rset &&rhs) { //------------------------------------------------------------------------------ std::string Rset::columnBlob(const std::string &colName) const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->columnBlob(colName); } @@ -74,7 +74,7 @@ std::string Rset::columnBlob(const std::string &colName) const { std::string Rset::columnString(const std::string &colName) const { try { if(nullptr == m_impl) { - throw exception::Exception("This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const optional<std::string> col = columnOptionalString(colName); @@ -94,7 +94,7 @@ std::string Rset::columnString(const std::string &colName) const { uint64_t Rset::columnUint64(const std::string &colName) const { try { if(nullptr == m_impl) { - throw exception::Exception("This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const optional<uint64_t> col = columnOptionalUint64(colName); @@ -114,7 +114,7 @@ uint64_t Rset::columnUint64(const std::string &colName) const { bool Rset::columnBool(const std::string &colName) const { try { if(nullptr == m_impl) { - throw exception::Exception("This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const optional<bool> col = columnOptionalBool(colName); @@ -134,7 +134,7 @@ bool Rset::columnBool(const std::string &colName) const { optional<bool> Rset::columnOptionalBool(const std::string &colName) const { try { if(nullptr == m_impl) { - throw exception::Exception("This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const auto column = columnOptionalUint64(colName); @@ -153,8 +153,7 @@ optional<bool> Rset::columnOptionalBool(const std::string &colName) const { //------------------------------------------------------------------------------ const std::string &Rset::getSql() const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->getSql(); } @@ -164,8 +163,7 @@ const std::string &Rset::getSql() const { //------------------------------------------------------------------------------ bool Rset::next() { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const bool aRowHasBeenRetrieved = m_impl->next(); @@ -183,8 +181,7 @@ bool Rset::next() { //------------------------------------------------------------------------------ bool Rset::columnIsNull(const std::string &colName) const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->columnIsNull(colName); } @@ -194,8 +191,7 @@ bool Rset::columnIsNull(const std::string &colName) const { //------------------------------------------------------------------------------ optional<std::string> Rset::columnOptionalString(const std::string &colName) const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->columnOptionalString(colName); } @@ -205,8 +201,7 @@ optional<std::string> Rset::columnOptionalString(const std::string &colName) con //------------------------------------------------------------------------------ optional<uint64_t> Rset::columnOptionalUint64(const std::string &colName) const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->columnOptionalUint64(colName); } @@ -217,7 +212,7 @@ optional<uint64_t> Rset::columnOptionalUint64(const std::string &colName) const double Rset::columnDouble(const std::string &colName) const { try { if(nullptr == m_impl) { - throw exception::Exception("This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } const optional<double> col = columnOptionalDouble(colName); @@ -236,8 +231,7 @@ double Rset::columnDouble(const std::string &colName) const { //------------------------------------------------------------------------------ optional<double> Rset::columnOptionalDouble(const std::string &colName) const { if(nullptr == m_impl) { - throw exception::Exception(std::string(__FUNCTION__) + " failed: " - "This result set is invalid"); + throw InvalidResultSet(std::string(__FUNCTION__) + " failed: This result set is invalid"); } return m_impl->columnOptionalDouble(colName); } diff --git a/rdbms/Rset.hpp b/rdbms/Rset.hpp index 8dcb91b78bb2346bf44e127b88bf8adc8bd290b1..daf4c62f4f34384020e5fd4c1a7b3edeac7ab085 100644 --- a/rdbms/Rset.hpp +++ b/rdbms/Rset.hpp @@ -19,6 +19,7 @@ #pragma once #include "common/optional.hpp" +#include "rdbms/InvalidResultSet.hpp" #include <memory> #include <stdint.h> @@ -86,6 +87,7 @@ public: * * @return True if a row has been retrieved else false if there are no more * rows in the result set. + * @throw InvalidResultSet if the result is invalid. */ bool next(); @@ -94,6 +96,7 @@ public: * * @param colName The name of the column. * @return True if the specified column contains a null value. + * @throw InvalidResultSet if the result is invalid. */ bool columnIsNull(const std::string &colName) const; @@ -105,6 +108,7 @@ public: * * @param colName The name of the column. * @return The string value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ std::string columnBlob(const std::string &colName) const; @@ -116,6 +120,7 @@ public: * * @param colName The name of the column. * @return The string value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ std::string columnString(const std::string &colName) const; @@ -126,6 +131,7 @@ public: * * @param colName The name of the column. * @return The string value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ optional<std::string> columnOptionalString(const std::string &colName) const; @@ -137,6 +143,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ uint64_t columnUint64(const std::string &colName) const; @@ -151,6 +158,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ bool columnBool(const std::string &colName) const; @@ -161,6 +169,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ optional<uint64_t> columnOptionalUint64(const std::string &colName) const; @@ -174,6 +183,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ optional<bool> columnOptionalBool(const std::string &colName) const; @@ -185,6 +195,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ double columnDouble(const std::string &colName) const; @@ -195,6 +206,7 @@ public: * * @param colName The name of the column. * @return The value of the specified column. + * @throw InvalidResultSet if the result is invalid. */ optional<double> columnOptionalDouble(const std::string &colName) const; diff --git a/rdbms/RsetTest.cpp b/rdbms/RsetTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b9d4ff2fb1bc075c770fc5f4e6ad538ad2d5433 --- /dev/null +++ b/rdbms/RsetTest.cpp @@ -0,0 +1,72 @@ +/* + * The CERN Tape Archive (CTA) project + * Copyright (C) 2015 CERN + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "common/exception/Exception.hpp" +#include "rdbms/ConnPool.hpp" +#include "rdbms/Rset.hpp" +#include "rdbms/wrapper/ConnFactoryFactory.hpp" + +#include <gtest/gtest.h> +#include <sstream> + +namespace unitTests { + +class cta_rdbms_RsetTest : public ::testing::Test { +protected: + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + +TEST_F(cta_rdbms_RsetTest, next) { + using namespace cta::rdbms; + + const Login login(Login::DBTYPE_SQLITE, "", "", "file::memory:?cache=shared", "", 0); + auto connFactory = wrapper::ConnFactoryFactory::create(login); + auto conn = connFactory->create(); + StmtPool pool; + { + const std::string sql = "CREATE TABLE RSET_TEST(ID INTEGER)"; + Stmt stmt = pool.getStmt(*conn, sql); + stmt.executeNonQuery(); + } + + { + const std::string sql = "INSERT INTO RSET_TEST(ID) VALUES(1)"; + Stmt stmt = pool.getStmt(*conn, sql); + stmt.executeNonQuery(); + } + + { + const std::string sql = "SELECT ID AS ID FROM RSET_TEST ORDER BY ID"; + Stmt stmt = pool.getStmt(*conn, sql); + auto rset = stmt.executeQuery(); + + ASSERT_TRUE(rset.next()); + ASSERT_EQ(1, rset.columnUint64("ID")); + + ASSERT_FALSE(rset.next()); + + ASSERT_THROW(rset.next(), InvalidResultSet); + } +} + +} // namespace unitTests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b8a4bef379581ac64f0ba7b4216e62eeec154220..f9dd89e2ee5e45f9d47180b35718c21c219df13a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,6 +35,7 @@ target_link_libraries(cta-unitTests ctainmemorystmtunittests ctaobjectstore ctaobjectstoreunittests + ctardbmsunittests ctardbmswrapperunittests ctaschedulerunittests ctatapeserverdaemonunittests