diff options
Diffstat (limited to 'libodbcpp/odbc-param.cpp')
-rw-r--r-- | libodbcpp/odbc-param.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/libodbcpp/odbc-param.cpp b/libodbcpp/odbc-param.cpp new file mode 100644 index 0000000..cd78940 --- /dev/null +++ b/libodbcpp/odbc-param.cpp @@ -0,0 +1,124 @@ +#include <sqlext.h> +#include "odbc-param.h" +#include "odbc-command.h" +#include "odbc-error.h" +#include <string.h> + +ODBC::Param::Param() : + paramCmd(NULL), + paramIdx(0), + paramBound(false) +{ +} + +ODBC::Param::Param(Command * c, unsigned int i) : + paramCmd(c), + paramIdx(i), + paramBound(false) +{ +} + +ODBC::Param::~Param(){ +} + +template <class ParamType> +ParamType * +ODBC::Command::makeParam(unsigned int idx) +{ + if (idx >= params.size()) { + throw Error("ODBC::Command::makeParam Bind out of bounds"); + } + Param * & p = params[idx]; + if (p) { + ParamType * np = dynamic_cast<ParamType *>(p); + if (np) { + return np; + } + delete p; + } + ParamType * np = new ParamType(this, idx); + p = np; + return np; +} + +void +ODBC::Param::bind() const +{ + if (!paramBound) { + RETCODE rc = SQLBindParameter(paramCmd->hStmt, paramIdx + 1, SQL_PARAM_INPUT, ctype(), stype(), + size(), dp(), const_cast<void *>(dataAddress()), size(), &bindLen); + if (!SQL_SUCCEEDED(rc)) { + throw Error(rc, SQL_HANDLE_STMT, paramCmd->hStmt, "ODBC::Param::bind Bind parameter"); + } + paramBound = true; + } +} + +#define SIMPLEBINDER(ctype, otype, suf) \ +void \ +ODBC::Command::bindParam##suf(unsigned int i, ctype val) \ +{ \ + ODBC::otype * p = makeParam<ODBC::otype>(i); \ + *p = val; \ + p->bind(); \ +} +SIMPLEBINDER(int, SignedIntegerParam, I); +SIMPLEBINDER(long, SignedIntegerParam, I); +SIMPLEBINDER(long long, SignedIntegerParam, I); +SIMPLEBINDER(unsigned int, UnsignedIntegerParam, I); +SIMPLEBINDER(unsigned long int, UnsignedIntegerParam, I); +SIMPLEBINDER(unsigned long long int, UnsignedIntegerParam, I); + +SIMPLEBINDER(bool, BooleanParam, B); + +SIMPLEBINDER(double, FloatingPointParam, F); +SIMPLEBINDER(float, FloatingPointParam, F); + +SIMPLEBINDER(const Glib::ustring &, GlibUstringParam, S); + +SIMPLEBINDER(const boost::posix_time::ptime &, TimeStampParam, T); +SIMPLEBINDER(const boost::posix_time::time_duration &, IntervalParam, T); + +void +ODBC::Command::bindNull(unsigned int i) +{ + makeParam<NullParam>(i)->bind(); +} + +void +ODBC::GlibUstringParam::operator=(Glib::ustring const & d) +{ + const char * addr = data.data(); + data = d; + bindLen = d.bytes(); + paramBound &= (addr == data.data()); + if (!paramBound) { + paramBound = false; + bind(); + } +} + +void +ODBC::TimeStampParam::operator=(const boost::posix_time::ptime & d) +{ + data.year = d.date().year(); + data.month = d.date().month(); + data.day = d.date().day(); + data.hour = d.time_of_day().hours(); + data.minute = d.time_of_day().minutes(); + data.second = d.time_of_day().seconds(); + data.fraction = d.time_of_day().fractional_seconds(); +} + +void +ODBC::IntervalParam::operator=(const boost::posix_time::time_duration & d) +{ + data.interval_type = SQL_IS_DAY_TO_SECOND; + data.interval_sign = d.is_negative(); + data.intval.day_second.day = d.hours() / 24; + data.intval.day_second.hour = d.hours() % 24; + data.intval.day_second.minute = d.minutes(); + data.intval.day_second.second = d.seconds(); + data.intval.day_second.fraction = d.fractional_seconds(); +} + |