From 0da3fb4c1bf5aa5f5255363ee8f12b0f97f1e5f4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 5 Jun 2017 12:28:42 +0100 Subject: Add support for blob type --- libdbpp/column.cpp | 8 ++++++++ libdbpp/column.h | 5 +++++ libdbpp/command.cpp | 6 ++++++ libdbpp/command.h | 4 ++++ libdbpp/testCore.cpp | 1 + libdbpp/types.cpp | 8 ++++++++ libdbpp/types.h | 31 ++++++++++++++++++++++++++++ libdbpp/unittests/testUtils.cpp | 45 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 108 insertions(+) create mode 100644 libdbpp/types.cpp create mode 100644 libdbpp/types.h diff --git a/libdbpp/column.cpp b/libdbpp/column.cpp index e7bbd21..f8eae65 100644 --- a/libdbpp/column.cpp +++ b/libdbpp/column.cpp @@ -23,6 +23,12 @@ InvalidConversion::message() const throw() return InvalidConversionMsg::get(from, to); } +void +DB::HandleField::blob(const DB::Blob &) +{ + throw DB::ColumnTypeNotSupported(); +} + template class Extract : public DB::HandleField { public: @@ -34,6 +40,7 @@ class Extract : public DB::HandleField { void string(const char * v, size_t len) override { (*this)(std::string(v, len)); } void timestamp(const boost::posix_time::ptime & v) override { (*this)(v); } void interval(const boost::posix_time::time_duration & v) override { (*this)(v); } + void blob(const Blob & v) override { (*this)(v); } void null() override { } template @@ -65,5 +72,6 @@ COLUMNINTO(double); COLUMNINTO(std::string); COLUMNINTO(boost::posix_time::ptime); COLUMNINTO(boost::posix_time::time_duration); +COLUMNINTO(Blob); } diff --git a/libdbpp/column.h b/libdbpp/column.h index 53e912a..acfb2f3 100644 --- a/libdbpp/column.h +++ b/libdbpp/column.h @@ -7,6 +7,7 @@ #include #include #include +#include "types.h" #include "error.h" namespace DB { @@ -27,6 +28,8 @@ namespace DB { virtual void interval(const boost::posix_time::time_duration &) = 0; /// The field is a timestamp/date/datetime. virtual void timestamp(const boost::posix_time::ptime &) = 0; + /// The field is a BLOB. + virtual void blob(const Blob &); }; class Command; @@ -54,6 +57,8 @@ namespace DB { void operator>>(boost::posix_time::time_duration &) const; /// STL like date time extractor. void operator>>(boost::posix_time::ptime &) const; + /// STL like BLOB extractor. + void operator>>(Blob &) const; /// STL like wrapper for optional types. template void operator>>(boost::optional & v) const { diff --git a/libdbpp/command.cpp b/libdbpp/command.cpp index 8957858..2751b54 100644 --- a/libdbpp/command.cpp +++ b/libdbpp/command.cpp @@ -53,3 +53,9 @@ DB::Command::bindParamS(unsigned int i, char * const o) bindNull(i); } +void +DB::Command::bindParamBLOB(unsigned int, const Blob &) +{ + throw ParameterTypeNotSupported(); +} + diff --git a/libdbpp/command.h b/libdbpp/command.h index 86e0a10..e80a523 100644 --- a/libdbpp/command.h +++ b/libdbpp/command.h @@ -8,6 +8,7 @@ #include #include #include +#include "types.h" #include "error.h" namespace DB { @@ -87,6 +88,9 @@ namespace DB { /// Bind a date time to parameter i. virtual void bindParamT(unsigned int i, const boost::posix_time::ptime &) = 0; + /// Bind a BLOB to parameter i. + virtual void bindParamBLOB(unsigned int i, const Blob &); + /// Bind null to parameter i. virtual void bindNull(unsigned int i) = 0; diff --git a/libdbpp/testCore.cpp b/libdbpp/testCore.cpp index 5029025..08b0e99 100644 --- a/libdbpp/testCore.cpp +++ b/libdbpp/testCore.cpp @@ -27,6 +27,7 @@ class Assert : public DB::HandleField { void string(const char * v, size_t len) override { (*this)(std::string(v, len)); } void timestamp(const boost::posix_time::ptime & v) override { (*this)(v); } void interval(const boost::posix_time::time_duration & v) override { (*this)(v); } + void blob(const Blob & v) override { (*this)(v); } void null() override { } template diff --git a/libdbpp/types.cpp b/libdbpp/types.cpp new file mode 100644 index 0000000..a663200 --- /dev/null +++ b/libdbpp/types.cpp @@ -0,0 +1,8 @@ +#include "types.h" + +DB::Blob::Blob(const void * d, size_t l) : + data(d), + len(l) +{ +} + diff --git a/libdbpp/types.h b/libdbpp/types.h new file mode 100644 index 0000000..3db6807 --- /dev/null +++ b/libdbpp/types.h @@ -0,0 +1,31 @@ +#ifndef DB_TYPES_H +#define DB_TYPES_H + +#include +#include +#include + +namespace DB { + class DLL_PUBLIC Blob { + public: + Blob(const void * data, size_t len); + template + Blob(const T * t) : + data(t), + len(sizeof(T)) + { + } + template + Blob(const std::vector & v) : + data(&v.front()), + len(sizeof(T) * v.size()) + { + } + + const void * data; + size_t len; + }; +} + +#endif + diff --git a/libdbpp/unittests/testUtils.cpp b/libdbpp/unittests/testUtils.cpp index 1435ad3..48a2801 100644 --- a/libdbpp/unittests/testUtils.cpp +++ b/libdbpp/unittests/testUtils.cpp @@ -259,3 +259,48 @@ BOOST_AUTO_TEST_CASE( bindIntPtr ) BOOST_REQUIRE_EQUAL(159, total); } +BOOST_AUTO_TEST_CASE( testBlobRaw ) +{ + DB::Blob ptr(this, 1); + BOOST_REQUIRE_EQUAL(ptr.data, this); + BOOST_REQUIRE_EQUAL(ptr.len, 1); +} + +BOOST_AUTO_TEST_CASE( testBlobObject ) +{ + int32_t x = 20; + DB::Blob obj(&x); + BOOST_REQUIRE_EQUAL(obj.data, &x); + BOOST_REQUIRE_EQUAL(obj.len, 4); +} + +BOOST_AUTO_TEST_CASE( testBlobVec ) +{ + std::vector buf(20, 0); + DB::Blob vec(buf); + BOOST_REQUIRE_EQUAL(vec.data, &buf[0]); + BOOST_REQUIRE_EQUAL(vec.len, 20); +} + +struct S { + int64_t a; + int64_t b; +}; +BOOST_STATIC_ASSERT(sizeof(S) == 16); + +BOOST_AUTO_TEST_CASE( testBlobStruct ) +{ + S s = { 8, 4 }; + DB::Blob str(&s); + BOOST_REQUIRE_EQUAL(str.data, &s); + BOOST_REQUIRE_EQUAL(str.len, 16); +} + +BOOST_AUTO_TEST_CASE( testBlobVecStruct ) +{ + std::vector buf(20, {4, 8}); + DB::Blob vec(buf); + BOOST_REQUIRE_EQUAL(vec.data, &buf[0]); + BOOST_REQUIRE_EQUAL(vec.len, 20 * 16); +} + -- cgit v1.2.3