diff options
author | randomdan <randomdan@localhost> | 2010-09-16 00:01:56 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2010-09-16 00:01:56 +0000 |
commit | 7297648c278903589beebf6fbc7511e5c1ff421d (patch) | |
tree | a2686c7d458aad2c32bcb1ae61cb4e04702fd9d4 /libodbcpp/param.cpp | |
parent | Remove duplication in ODBC::Connection constructors (diff) | |
download | libdbpp-odbc-7297648c278903589beebf6fbc7511e5c1ff421d.tar.bz2 libdbpp-odbc-7297648c278903589beebf6fbc7511e5c1ff421d.tar.xz libdbpp-odbc-7297648c278903589beebf6fbc7511e5c1ff421d.zip |
Rewrite the whole of parameter and column binding almost from scratch
No more template rubbish, no more messy partial specialisation
Add copyless rebind of column to parameter
Changes in project2 to suit
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; } |