From 7297648c278903589beebf6fbc7511e5c1ff421d Mon Sep 17 00:00:00 2001 From: randomdan Date: Thu, 16 Sep 2010 00:01:56 +0000 Subject: 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 --- libodbcpp/column.cpp | 284 +++++++++++++++++++++------------------------------ 1 file changed, 115 insertions(+), 169 deletions(-) (limited to 'libodbcpp/column.cpp') diff --git a/libodbcpp/column.cpp b/libodbcpp/column.cpp index 3d37e50..f8a9dfb 100644 --- a/libodbcpp/column.cpp +++ b/libodbcpp/column.cpp @@ -3,14 +3,16 @@ #include #include "column.h" #include "command.h" +#include "selectcommand.h" #include "error.h" -ODBC::Column::Column(const Glib::ustring & n, unsigned int i) : +ODBC::Column::Column(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : colNo(i), name(n), - composeCache(NULL), - bindSize(0) + selectCmd(sc), + composeCache(NULL) { + bindLen = 0; } ODBC::Column::~Column() @@ -24,196 +26,140 @@ ODBC::Column::resize(SQLHANDLE hStmt) } void -ODBC::StringColumn::resize(SQLHANDLE hStmt) +ODBC::CharArrayColumn::resize(SQLHANDLE hStmt) { - if (bindSize < bindLen) { - value.resize(bindLen + 1); - bindSize = bindLen; - bind(hStmt, colNo + 1, SQL_C_CHAR, &value[0], bindSize + 1); + const char * addr = &data.front(); + if (bindLen > SQLLEN(data.size())) { + data.resize(bindLen + 1); + if (addr != &data.front()) { + Column::bind(); + if (paramCmd) { + paramBound = false; + Param::bind(); + } + } } } +void +ODBC::Column::onScroll() +{ + delete composeCache; + composeCache = NULL; +} + bool ODBC::Column::isNull() const { return (bindLen == SQL_NULL_DATA); } -#define ODBC_DEFAULT_COLUMN_CAST(ctype, rtype) \ - ODBC::Column::operator rtype() const { \ - return (dynamic_cast& >(*this)).value; \ - } - -ODBC_DEFAULT_COLUMN_CAST(SQLINTEGER, unsigned int); -ODBC_DEFAULT_COLUMN_CAST(SQLINTEGER, unsigned long long); -ODBC_DEFAULT_COLUMN_CAST(SQLINTEGER, long long); -ODBC_DEFAULT_COLUMN_CAST(SQLINTEGER, int); -ODBC_DEFAULT_COLUMN_CAST(SQLDOUBLE, double); -ODBC_DEFAULT_COLUMN_CAST(SQLDOUBLE, float); -ODBC::Column::operator Glib::ustring() const { - return Glib::ustring((const char *)((dynamic_cast& >(*this)).value)); -} -ODBC::Column::operator std::string() const { - return (const char*)((dynamic_cast& >(*this)).value); -} -ODBC::Column::operator const char * () const { - return (const char*)((dynamic_cast& >(*this)).value); -} -ODBC::Column::operator struct tm () const { - const _Column& c = dynamic_cast& >(*this); - struct tm rtn; - rtn << c.value; - return rtn; +void +ODBC::Column::rebind(Command * cmd, unsigned int idx) const +{ + meAsAParam()->paramCmd = cmd; + meAsAParam()->paramIdx = idx; + meAsAParam()->bind(); } void -ODBC::Column::bind(SQLHANDLE hStmt, SQLUINTEGER col, SQLSMALLINT ctype, void * buf, size_t size) +ODBC::Column::bind() { - bindSize = size; - RETCODE rc = SQLBindCol(hStmt, col, ctype, buf, bindSize, &bindLen); + RETCODE rc = SQLBindCol(selectCmd->hStmt, colNo + 1, ctype(), rwDataAddress(), size(), &bindLen); if (rc != SQL_SUCCESS) { - throw Error(rc, SQL_HANDLE_STMT, hStmt, "%s: Bind column %lu", __FUNCTION__, col); + throw Error(rc, SQL_HANDLE_STMT, selectCmd->hStmt, "%s: Bind column %u", __FUNCTION__, colNo); } } -#define REBIND(t, p) \ - template<> void _Column::rebind(Command * cmd, unsigned int col) const \ +#define SIMPLEFORMATTER(ctype, deffmtstr) \ + int \ + ODBC::ctype::writeToBuf(char ** buf, const char * fmt) const \ + { \ + return asprintf(buf, fmt, data); \ + } \ + int \ + ODBC::ctype::writeToBuf(char ** buf) const \ + { \ + return writeToBuf(buf, deffmtstr); \ + } \ + const Glib::ustring & \ + ODBC::ctype::compose() const \ + { \ + if (!composeCache) { \ + composeCache = new Glib::ustring(Glib::ustring::compose("%1", data)); \ + } \ + return *composeCache; \ + } \ + Glib::ustring \ + ODBC::ctype::compose(const Glib::ustring & fmt) const \ { \ - cmd->p(col, value); \ + return Glib::ustring::compose(fmt, data); \ } -namespace ODBC { - REBIND(int, bindParamI) - REBIND(long, bindParamI) - REBIND(unsigned int, bindParamI) - REBIND(long unsigned int, bindParamI) - REBIND(long long unsigned int, bindParamI) - REBIND(double, bindParamF) - REBIND(float, bindParamF) - REBIND(SQL_TIMESTAMP_STRUCT, bindParamT) +SIMPLEFORMATTER(FloatingPointColumn, "%g"); +SIMPLEFORMATTER(SignedIntegerColumn, "%ld"); +#ifdef COMPLETENESS +SIMPLEFORMATTER(UnsignedIntegerColumn, "%lu"); +#endif - template<> - void - _Column::rebind(Command * cmd, unsigned int col) const \ - { - cmd->bindParamS(col, &value[0]); - } - template <> - int - _Column::writeToBuf(char ** buf, const char * fmt) const - { - return asprintf(buf, fmt, value); - } - template <> - int - _Column::writeToBuf(char ** buf) const - { - return writeToBuf(buf, "%g"); - } - template <> - const Glib::ustring & - _Column::compose() const - { - if (!composeCache) { - composeCache = new Glib::ustring(Glib::ustring::compose("%1", value)); - } - return *composeCache; - } - template <> - Glib::ustring - _Column::compose(const Glib::ustring & fmt) const - { - return Glib::ustring::compose(fmt, value); - } - template <> - int - _Column::writeToBuf(char ** buf, const char * fmt) const - { - return asprintf(buf, fmt, value); - } - template <> - int - _Column::writeToBuf(char ** buf) const - { - return writeToBuf(buf, "%ld"); - } - template <> - const Glib::ustring & - _Column::compose() const - { - if (!composeCache) { - composeCache = new Glib::ustring(Glib::ustring::compose("%1", value)); - } - return *composeCache; - } - template <> - Glib::ustring - _Column::compose(const Glib::ustring & fmt) const - { - return Glib::ustring::compose(fmt, value); - } - template <> - int - _Column::writeToBuf(char ** buf, const char * fmt) const - { - return asprintf(buf, fmt, &value[0]); - } - template <> - int - _Column::writeToBuf(char ** buf) const - { - return writeToBuf(buf, "%s"); - } - template <> - const Glib::ustring & - _Column::compose() const - { - if (!composeCache) { - composeCache = new Glib::ustring((const char *)&value[0]); - } - return *composeCache; - } - template <> - Glib::ustring - _Column::compose(const Glib::ustring & fmt) const - { - return Glib::ustring::compose(fmt, &value[0]); - } - template <> - int - _Column::writeToBuf(char ** buf, const char * fmt) const - { - *buf = (char *)malloc(300); - struct tm t; - t << value; - return strftime(*buf, 300, fmt, &t); - } - template <> - int - _Column::writeToBuf(char ** buf) const - { - return writeToBuf(buf, "%F %T"); - } - template <> - Glib::ustring - _Column::compose(const Glib::ustring & fmt) const - { - char buf[300]; - struct tm t; - t << value; - int len = strftime(buf, sizeof(buf), fmt.c_str(), &t); - return Glib::ustring(buf, len); +int +ODBC::CharArrayColumn::writeToBuf(char ** buf, const char * fmt) const +{ + return asprintf(buf, fmt, &data[0]); +} +int +ODBC::CharArrayColumn::writeToBuf(char ** buf) const +{ + return writeToBuf(buf, "%s"); +} +const Glib::ustring & +ODBC::CharArrayColumn::compose() const +{ + if (!composeCache) { + composeCache = new Glib::ustring(data.begin(), data.end()); } - template <> - const Glib::ustring & - _Column::compose() const - { - if (!composeCache) { - composeCache = new Glib::ustring(Glib::ustring(compose("%F %T"))); - } - return *composeCache; + return *composeCache; +} +Glib::ustring +ODBC::CharArrayColumn::compose(const Glib::ustring & fmt) const +{ + return Glib::ustring::compose(fmt, &data[0]); +} +int +ODBC::TimeStampColumn::writeToBuf(char ** buf, const char * fmt) const +{ + *buf = (char *)malloc(300); + struct tm t; + t << data; + return strftime(*buf, 300, fmt, &t); +} +int +ODBC::TimeStampColumn::writeToBuf(char ** buf) const +{ + return writeToBuf(buf, "%F %T"); +} +Glib::ustring +ODBC::TimeStampColumn::compose(const Glib::ustring & fmt) const +{ + char buf[300]; + struct tm t; + t << data; + int len = strftime(buf, sizeof(buf), fmt.c_str(), &t); + return Glib::ustring(buf, len); +} +const Glib::ustring & +ODBC::TimeStampColumn::compose() const +{ + if (!composeCache) { + composeCache = new Glib::ustring(Glib::ustring(compose("%F %T"))); } + return *composeCache; +} +ODBC::TimeStampColumn::operator tm() const +{ + struct tm t; + t << data; + return t; } - void operator << (SQL_TIMESTAMP_STRUCT & target, const struct tm & src) { target.year = src.tm_year + 1900; -- cgit v1.2.3