#include #include "sqlTest.h" #include "scriptLoader.h" #include "selectcommand.h" #include "column.h" #include "rdbmsDataSource.h" #include "commonObjects.h" #include "sqlVariableBinder.h" #include DECLARE_LOADER("sqltest", SqlTest); class CantCompareNulls : public std::exception { }; SqlTest::SqlTest(ScriptNodePtr p) : SourceObject(p), Test(p), dataSource(p, "datasource"), filter(p, "filter", ""), testOp(p, "testOp", "=="), testValue(p, "testValue"), sqlCommand(p->child("sql")), db(NULL) { } SqlTest::~SqlTest() { } void SqlTest::loadComplete(const CommonObjects * co) { db = co->dataSource(dataSource(NULL)); } class HandleDoCompare : public DB::HandleField { public: HandleDoCompare(const VariableType & tV, const std::string & tO) : retVal(false), testValue(tV), testOp(tO) { } void null() { throw CantCompareNulls(); } void string(const char *c , size_t l) { doTest(Glib::ustring(c, c + l)); } void integer(int64_t val) { doTest(val); } void boolean(bool val) { doTest(val); } void floatingpoint(double val) { doTest(val); } void interval(const boost::posix_time::time_duration & val) { doTest(val); } void timestamp(const boost::posix_time::ptime & val) { doTest(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 < tv) { retVal = true; } else if (testOp == ">" && val > tv) { retVal = true; } else if (testOp == "!=" && val != tv) { retVal = true; } else if ((testOp == "<=" || testOp == "=<") && val <= tv) { retVal = true; } else if ((testOp == ">=" || testOp == "=>") && val >= tv) { retVal = true; } } bool retVal; const VariableType & testValue; std::string testOp; }; bool SqlTest::passes(ExecContext * ec) const { auto con = db->getReadonly(); boost::shared_ptr query = boost::shared_ptr( con->newSelectCommand(sqlCommand.getSqlFor(filter(NULL)))); unsigned int offset = 0; sqlCommand.bindParams(ec, query.get(), offset); HandleDoCompare h(testValue(ec), testOp(ec)); while (query->fetch()) { (*query)[0].apply(h); } return h(); }