From 45c23ec13e3a7322cb446207e6994ae0d932bb94 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 7 Nov 2015 23:56:14 +0000 Subject: Add utility function for passing each row of a result set to a function accepting one parameter per column --- libdbpp/selectcommand.h | 4 ++++ libdbpp/selectcommandUtil.impl.h | 35 +++++++++++++++++++++++++++++++++++ libdbpp/unittests/Jamfile.jam | 14 ++++++++++++++ libdbpp/unittests/testUtils.cpp | 37 +++++++++++++++++++++++++++++++++++++ libdbpp/unittests/util.sql | 8 ++++++++ 5 files changed, 98 insertions(+) create mode 100644 libdbpp/selectcommandUtil.impl.h create mode 100644 libdbpp/unittests/testUtils.cpp create mode 100644 libdbpp/unittests/util.sql diff --git a/libdbpp/selectcommand.h b/libdbpp/selectcommand.h index 31ef9ca..1586357 100644 --- a/libdbpp/selectcommand.h +++ b/libdbpp/selectcommand.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,9 @@ namespace DB { unsigned int columnCount() const; /// Get the index of a column by name. unsigned int getOrdinal(const Glib::ustring &) const; + /// Push each row through a function accepting one value per column + template> + void forEachRow(const Func & func); protected: /// Helper function so clients need not know about boost::multi_index_container. diff --git a/libdbpp/selectcommandUtil.impl.h b/libdbpp/selectcommandUtil.impl.h new file mode 100644 index 0000000..26ff1b7 --- /dev/null +++ b/libdbpp/selectcommandUtil.impl.h @@ -0,0 +1,35 @@ +#ifndef DB_SELECTCOMMANDUTIL_IMPL_H +#define DB_SELECTCOMMANDUTIL_IMPL_H + +#include "selectcommand.h" +#include +#include + +namespace DB { + template + inline typename boost::disable_if_c::value>::type + forEachField(DB::SelectCommand *, const Func & func, const Fn & ... args) + { + func(args...); + } + + template + inline typename boost::enable_if_c::value>::type + forEachField(DB::SelectCommand * sel, const Func & func, const Args & ... args) + { + typename std::tuple_element::type a; + (*sel)[field] >> a; + forEachField(sel, func, args..., a); + } + + template + inline void SelectCommand::forEachRow(const Func & func) + { + while (fetch()) { + forEachField, Func, 0>(this, func); + } + } +} + +#endif + diff --git a/libdbpp/unittests/Jamfile.jam b/libdbpp/unittests/Jamfile.jam index 0739af1..ad90ec6 100644 --- a/libdbpp/unittests/Jamfile.jam +++ b/libdbpp/unittests/Jamfile.jam @@ -17,3 +17,17 @@ run testConnection ; +run + testUtils.cpp + : : : + ROOT=\"$(me)\" + BOOST_TEST_DYN_LINK + ..//dbppcore + ..//adhocutil + ../../libpqpp//dbpp-postgresql + boost_utf + util.sql + : + testUtils + ; + diff --git a/libdbpp/unittests/testUtils.cpp b/libdbpp/unittests/testUtils.cpp new file mode 100644 index 0000000..79506cf --- /dev/null +++ b/libdbpp/unittests/testUtils.cpp @@ -0,0 +1,37 @@ +#define BOOST_TEST_MODULE DbUtil +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class StandardMockDatabase : public PQ::Mock { + public: + StandardMockDatabase() : PQ::Mock("user=postgres dbname=postgres", "pqmock", { + rootDir / "util.sql" }) + { + } +}; + +BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); + +BOOST_AUTO_TEST_CASE( forEachRow ) +{ + auto db = DB::ConnectionPtr(DB::MockDatabase::openConnectionTo("pqmock")); + auto sel = DB::SelectCommandPtr(db->newSelectCommand("SELECT a, b, c, d, e FROM forEachRow ORDER BY a LIMIT 1")); + sel->forEachRow( + [](auto a, auto b, auto c, auto d, auto e) { + BOOST_REQUIRE_EQUAL(1, a); + BOOST_REQUIRE_EQUAL(2.3, b); + BOOST_REQUIRE_EQUAL("Some text", c); + BOOST_REQUIRE_EQUAL(boost::posix_time::ptime_from_tm({ 17, 39, 13, 7, 10, 115, 0, 0, 0, 0, 0}), d); + BOOST_REQUIRE_EQUAL(boost::posix_time::time_duration(4, 3, 2), e); + }); +} + diff --git a/libdbpp/unittests/util.sql b/libdbpp/unittests/util.sql new file mode 100644 index 0000000..a3c5ac8 --- /dev/null +++ b/libdbpp/unittests/util.sql @@ -0,0 +1,8 @@ +CREATE TABLE foreachrow ( + a int, + b numeric(4,2), + c text, + d timestamp without time zone, + e interval); +INSERT INTO foreachrow(a, b, c, d, e) VALUES(1, 2.3, 'Some text', '2015-11-07 13:39:17', '04:03:02'); + -- cgit v1.2.3