summaryrefslogtreecommitdiff
path: root/libodbcpp/param.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libodbcpp/param.cpp')
-rw-r--r--libodbcpp/param.cpp191
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;
}