From 615627e9472686fd6b45e753b1c4aab83e88913b Mon Sep 17 00:00:00 2001 From: randomdan Date: Sat, 19 Feb 2011 21:16:44 +0000 Subject: Add conversions for floats, ints and datetimes for variables > Use them to fully implement the rest of sqlCheck --- project2/sqlCheck.cpp | 46 +++++++++++---------- project2/sqlCheck.h | 2 +- project2/variableConvert.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++- project2/variables.h | 3 ++ 4 files changed, 126 insertions(+), 23 deletions(-) diff --git a/project2/sqlCheck.cpp b/project2/sqlCheck.cpp index 766f16d..f7c4c8c 100644 --- a/project2/sqlCheck.cpp +++ b/project2/sqlCheck.cpp @@ -7,11 +7,10 @@ #include "commonObjects.h" #include "sqlVariableBinder.h" #include +#include DECLARE_LOADER("sqlcheck", SqlCheck); -class CantCompareStrings : public std::exception { }; -class CantCompareDateTimes : public std::exception { }; class CantCompareNulls : public std::exception { }; SqlCheck::SqlCheck(const xmlpp::Element * p) : @@ -39,7 +38,7 @@ SqlCheck::loadComplete(const CommonObjects * co) class HandleDoCompare : public DB::HandleField { public: - HandleDoCompare(double tV, const std::string & tO) : + HandleDoCompare(const VariableType & tV, const std::string & tO) : retVal(false), testValue(tV), testOp(tO) { @@ -47,41 +46,46 @@ class HandleDoCompare : public DB::HandleField { void null() { throw CantCompareNulls(); } - void string(const char *, size_t) { - throw CantCompareStrings(); + void string(const char *c , size_t l) { + doTest(Glib::ustring(c, c + l)); } - void integer(int64_t i) { - floatingpoint(i); + void integer(int64_t val) { + doTest(val); } void floatingpoint(double val) { - if ((testOp == "==" || testOp == "=") && val == testValue) { + doTest(val); + } + void timestamp(const struct tm & val) { + doTest(boost::posix_time::ptime_from_tm(val)); + } + bool operator()() const { + return retVal; + } + private: + template + void doTest(const TV & val) { + TV tv = testValue; + if ((testOp == "==" || testOp == "=") && val == tv) { retVal = true; } - else if (testOp == "<" && val < testValue) { + else if (testOp == "<" && val < tv) { retVal = true; } - else if (testOp == ">" && val > testValue) { + else if (testOp == ">" && val > tv) { retVal = true; } - else if (testOp == "!=" && val != testValue) { + else if (testOp == "!=" && val != tv) { retVal = true; } - else if ((testOp == "<=" || testOp == "=<") && val <= testValue) { + else if ((testOp == "<=" || testOp == "=<") && val <= tv) { retVal = true; } - else if ((testOp == ">=" || testOp == "=>") && val >= testValue) { + else if ((testOp == ">=" || testOp == "=>") && val >= tv) { retVal = true; } } - void timestamp(const struct tm &) { - throw CantCompareDateTimes(); - } - bool operator()() const { - return retVal; - } - private: bool retVal; - double testValue; + const VariableType & testValue; std::string testOp; }; bool diff --git a/project2/sqlCheck.h b/project2/sqlCheck.h index 50132c1..8557dce 100644 --- a/project2/sqlCheck.h +++ b/project2/sqlCheck.h @@ -17,7 +17,7 @@ class SqlCheck : public IHaveParameters, public ParamChecker { const Variable dataSource; const Glib::ustring sql; const std::string testOp; - const double testValue; + const VariableType testValue; private: DB::SelectCommand * query; }; diff --git a/project2/variableConvert.cpp b/project2/variableConvert.cpp index 1ac2253..8797ef7 100644 --- a/project2/variableConvert.cpp +++ b/project2/variableConvert.cpp @@ -1,5 +1,7 @@ #include "variables.h" +#include "exceptions.h" #include +#include #include template @@ -25,6 +27,8 @@ set(const VariableType * var, const T * t) return set(var, t, deleter); } +SimpleMessageException(InvalidConversionTo); + class NullVariable : std::runtime_error { public: NullVariable() : std::runtime_error("Variable has null value where one is required") { @@ -141,6 +145,87 @@ class ConvertVisitorUCharStar : public boost::static_visitor { + public: + ConvertVisitorInt(const VariableType * v) : var(v) { + } + int64_t operator()(const Glib::ustring & r) const { + return boost::lexical_cast(r); + } + int64_t operator()(const boost::shared_ptr & r) const { + return boost::lexical_cast(*r); + } + int64_t operator()(const boost::posix_time::ptime &) const { + throw InvalidConversionTo("Integer"); + } + int64_t operator()(const boost::shared_ptr &) const { + throw InvalidConversionTo("Integer"); + } + int64_t operator()(const Null &) const { + throw NullVariable(); + } + template + int64_t operator()(const T & r) const { + return boost::numeric_cast(r); + } + private: + const VariableType * var; +}; +// Convert to double +class ConvertVisitorDouble : public boost::static_visitor { + public: + ConvertVisitorDouble(const VariableType * v) : var(v) { + } + double operator()(const Glib::ustring & r) const { + return boost::lexical_cast(r); + } + double operator()(const boost::shared_ptr & r) const { + return boost::lexical_cast(*r); + } + double operator()(const boost::posix_time::ptime &) const { + throw InvalidConversionTo("Floating point"); + } + double operator()(const boost::shared_ptr &) const { + throw InvalidConversionTo("Floating point"); + } + double operator()(const Null &) const { + throw NullVariable(); + } + template + double operator()(const T & r) const { + return boost::numeric_cast(r); + } + private: + const VariableType * var; +}; +// Convert to ptime +class ConvertVisitorDateTime : public boost::static_visitor { + public: + ConvertVisitorDateTime(const VariableType * v) : var(v) { + } + const boost::posix_time::ptime & operator()(const Glib::ustring & r) const { + return *set(var, new boost::posix_time::ptime(boost::posix_time::time_from_string(r)), deleter); + } + const boost::posix_time::ptime & operator()(const boost::shared_ptr & r) const { + return *set(var, new boost::posix_time::ptime(boost::posix_time::time_from_string(*r)), deleter); + } + const boost::posix_time::ptime & operator()(const boost::posix_time::ptime & r) const { + return r; + } + const boost::posix_time::ptime & operator()(const boost::shared_ptr & r) const { + return *r; + } + const boost::posix_time::ptime & operator()(const Null &) const { + throw NullVariable(); + } + template + const boost::posix_time::ptime & operator()(const T &) const { + throw InvalidConversionTo("DateTime"); + } + private: + const VariableType * var; +}; VariableType::operator const Glib::ustring &() const { return boost::apply_visitor(ConvertVisitorGlibUstring(this), *this); @@ -157,4 +242,15 @@ VariableType::operator const unsigned char *() const { return boost::apply_visitor(ConvertVisitorUCharStar(this), *this); } - +VariableType::operator int64_t() const +{ + return boost::apply_visitor(ConvertVisitorInt(this), *this); +} +VariableType::operator double() const +{ + return boost::apply_visitor(ConvertVisitorDouble(this), *this); +} +VariableType::operator const boost::posix_time::ptime &() const +{ + return boost::apply_visitor(ConvertVisitorDateTime(this), *this); +} diff --git a/project2/variables.h b/project2/variables.h index 71171b3..7dcccc2 100644 --- a/project2/variables.h +++ b/project2/variables.h @@ -49,6 +49,9 @@ class VariableType : public _VT { operator const std::string &() const; operator const char *() const; operator const unsigned char *() const; + operator int64_t() const; + operator double() const; + operator const boost::posix_time::ptime &() const; private: template friend const T * set(const VariableType * var, const T * t, Freer); -- cgit v1.2.3