diff options
Diffstat (limited to 'libodbcpp/param.cpp')
-rw-r--r-- | libodbcpp/param.cpp | 191 |
1 files changed, 60 insertions, 131 deletions
diff --git a/libodbcpp/param.cpp b/libodbcpp/param.cpp index ff10d3a..1992252 100644 --- a/libodbcpp/param.cpp +++ b/libodbcpp/param.cpp @@ -1,173 +1,102 @@ #include <sqlext.h> #include "param.h" #include "command.h" -#include "column.h" #include "error.h" #include <string.h> ODBC::Param::Param() : - bound(false) + paramCmd(NULL), + paramIdx(NULL), + paramBound(false) +{ +} + +ODBC::Param::Param(Command * c, unsigned int i) : + paramCmd(c), + paramIdx(i), + paramBound(false) { } ODBC::Param::~Param(){ } -template <class t> -ODBC::_Param<t>* -ODBC::Param::makeParam(ODBC::Param*& p) +template <class ParamType> +ParamType * +ODBC::Command::makeParam(unsigned int idx) { + if (idx >= params.size()) { + throw Error("%s: Bind out of bounds", __FUNCTION__); + } + Param * & p = params[idx]; if (p) { - _Param<t>* np = dynamic_cast<_Param<t>*>(p); + ParamType * np = dynamic_cast<ParamType *>(p); if (np) { return np; } delete p; } - _Param<t>* np = new _Param<t>(); + ParamType * np = new ParamType(this, idx); p = np; return np; } void -ODBC::Param::bind(SQLHANDLE hStmt, SQLUINTEGER col, SQLSMALLINT ctype, SQLSMALLINT stype, - SQLINTEGER colsize, SQLINTEGER dp, const void * value, size_t buflen) -{ - RETCODE rc = SQLBindParameter(hStmt, col, SQL_PARAM_INPUT, ctype, stype, - colsize, dp, const_cast<void*>(value), buflen, &bindLen); - if (rc != SQL_SUCCESS) { - throw Error(rc, SQL_HANDLE_STMT, hStmt, "%s: Bind for column %lu", - __FUNCTION__, col); - } -} - -void -ODBC::Command::bindParamI(unsigned int i, int val) -{ - if (i < params.size()) { - _Param<SQLINTEGER>* p = Param::makeParam<SQLINTEGER>(params[i]); - p->value = val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_SLONG, SQL_C_LONG, 0, 0, - &p->value, sizeof(SQLINTEGER)); - p->bound = true; - } - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); -} -void -ODBC::Command::bindParamI(unsigned int i, long val) -{ - if (i < params.size()) { - _Param<SQLINTEGER>* p = Param::makeParam<SQLINTEGER>(params[i]); - p->value = val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_SLONG, SQL_C_LONG, 0, 0, - &p->value, sizeof(SQLINTEGER)); - p->bound = true; - } - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); -} -void -ODBC::Command::bindParamI(unsigned int i, long long unsigned int val) -{ - if (i < params.size()) { - _Param<SQLUINTEGER>* p = Param::makeParam<SQLUINTEGER>(params[i]); - p->value = val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_ULONG, SQL_C_ULONG, 0, 0, - &p->value, sizeof(SQLUINTEGER)); - p->bound = true; - } - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); -} -void -ODBC::Command::bindParamF(unsigned int i, double val) -{ - if (i < params.size()) { - _Param<SQLDOUBLE>* p = Param::makeParam<SQLDOUBLE>(params[i]); - p->value = val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_DOUBLE, SQL_DOUBLE, 0, 0, - &p->value, sizeof(SQLDOUBLE)); - p->bound = true; - } - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); -} -void -ODBC::Command::bindParamS(unsigned int i, const Glib::ustring & val) +ODBC::Param::bind() const { - if (i < params.size()) { - _Param<Glib::ustring>* p = Param::makeParam<Glib::ustring>(params[i]); - p->value = val; - p->bindLen = p->value.bytes(); - p->bind(this->hStmt, i + 1, SQL_C_CHAR, SQL_CHAR, 0, 0, p->value.data(), p->value.bytes()); - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); -} -void -ODBC::Command::bindParamT(unsigned int i, const struct tm * val) -{ - if (i < params.size()) { - _Param<SQL_TIMESTAMP_STRUCT>* p = Param::makeParam<SQL_TIMESTAMP_STRUCT>(params[i]); - p->value << *val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_TIMESTAMP, SQL_TYPE_TIMESTAMP, - sizeof(SQL_TIMESTAMP_STRUCT), 0, &p->value, sizeof(SQL_TIMESTAMP_STRUCT)); - p->bound = true; + if (!paramBound) { + RETCODE rc = SQLBindParameter(paramCmd->hStmt, paramIdx + 1, SQL_PARAM_INPUT, ctype(), stype(), + size(), dp(), const_cast<void *>(dataAddress()), size(), &bindLen); + if (rc != SQL_SUCCESS) { + throw Error(rc, SQL_HANDLE_STMT, paramCmd->hStmt, "%s: Bind for parameter %u", + __FUNCTION__, paramIdx); } - return; + paramBound = true; } - throw Error("%s: Bind out of bounds", __FUNCTION__); } -void -ODBC::Command::bindParamT(unsigned int i, const SQL_TIMESTAMP_STRUCT & val) -{ - if (i < params.size()) { - _Param<SQL_TIMESTAMP_STRUCT>* p = Param::makeParam<SQL_TIMESTAMP_STRUCT>(params[i]); - p->value = val; - if (!p->bound) { - p->bind(this->hStmt, i + 1, SQL_C_TIMESTAMP, SQL_TIMESTAMP, - sizeof(SQL_TIMESTAMP_STRUCT), 0, &p->value, sizeof(SQL_TIMESTAMP_STRUCT)); - p->bound = true; - } - return; - } - throw Error("%s: Bind out of bounds", __FUNCTION__); + +#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(double, FloatingPointParam, F); +SIMPLEBINDER(float, FloatingPointParam, F); +SIMPLEBINDER(const Glib::ustring &, GlibUstringParam, S); -// Wrappers for all the roughly compatable types +SIMPLEBINDER(const struct tm *, TimeStampParam, T); +SIMPLEBINDER(const SQL_TIMESTAMP_STRUCT &, TimeStampParam, T); +SIMPLEBINDER(time_t, TimeStampParam, T); void -ODBC::Command::bindParamI(unsigned int i, long unsigned int val) -{ - bindParamI(i, (long long unsigned int)val); -} -void -ODBC::Command::bindParamI(unsigned int i, unsigned int val) +ODBC::GlibUstringParam::operator=(Glib::ustring const & d) { - bindParamI(i, (long long unsigned int)val); -} -void -ODBC::Command::bindParamF(unsigned int i, float val) -{ - bindParamF(i, (double)val); + const char * addr = data.data(); + data = d; + bindLen = d.bytes(); + paramBound &= (addr == data.data()); + if (!paramBound) { + paramBound = false; + bind(); + } } + void -ODBC::Command::bindParamT(unsigned int i, time_t val) +ODBC::TimeStampParam::operator=(long const & d) { struct tm t; - gmtime_r(&val, &t); - bindParamT(i, &t); + gmtime_r(&d, &t); + data << t; } |