diff options
-rw-r--r-- | libodbcpp/bind.h | 1 | ||||
-rw-r--r-- | libodbcpp/column.cpp | 17 | ||||
-rw-r--r-- | libodbcpp/column.h | 2 | ||||
-rw-r--r-- | libodbcpp/command.h | 3 | ||||
-rw-r--r-- | libodbcpp/connection.cpp | 12 | ||||
-rw-r--r-- | libodbcpp/connection.h | 7 | ||||
-rw-r--r-- | libodbcpp/error.cpp | 36 | ||||
-rw-r--r-- | libodbcpp/param.cpp | 14 | ||||
-rw-r--r-- | libodbcpp/selectcommand.cpp | 13 | ||||
-rw-r--r-- | libodbcpp/selectcommand.h | 1 | ||||
-rw-r--r-- | libodbcpp/ustring.cpp | 5 |
11 files changed, 95 insertions, 16 deletions
diff --git a/libodbcpp/bind.h b/libodbcpp/bind.h index d06dcb2..4465466 100644 --- a/libodbcpp/bind.h +++ b/libodbcpp/bind.h @@ -4,6 +4,7 @@ #include <sql.h> namespace ODBC { + class Command; class BindBase { public: BindBase(); diff --git a/libodbcpp/column.cpp b/libodbcpp/column.cpp index 58f9b31..0d0e6e2 100644 --- a/libodbcpp/column.cpp +++ b/libodbcpp/column.cpp @@ -1,4 +1,5 @@ #include "column.h" +#include "command.h" #include "error.h" #include "timetypepair.h" @@ -51,4 +52,20 @@ ODBC::Column::bind(SQLHANDLE hStmt, SQLUINTEGER col, SQLSMALLINT ctype, void * b } } +#define REBIND(t, p) \ + template<> void _Column<t>::rebind(Command * cmd, unsigned int col) const \ + { \ + cmd->p(col, value); \ + } +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(TimeTypePair, bindParamT) + REBIND(unsigned char *, bindParamS) +} diff --git a/libodbcpp/column.h b/libodbcpp/column.h index 87c7edf..acc6904 100644 --- a/libodbcpp/column.h +++ b/libodbcpp/column.h @@ -21,6 +21,7 @@ namespace ODBC { operator std::string () const; operator String () const; operator const struct tm & () const; + virtual void rebind(Command *, unsigned int col) const = 0; const unsigned int colNo; const String name; @@ -33,6 +34,7 @@ namespace ODBC { public: _Column(String, unsigned int); ~_Column() {} + void rebind(Command *, unsigned int col) const; }; } diff --git a/libodbcpp/command.h b/libodbcpp/command.h index 55e6703..9da291c 100644 --- a/libodbcpp/command.h +++ b/libodbcpp/command.h @@ -14,6 +14,7 @@ namespace ODBC { virtual ~Command() = 0; void bindParamI(unsigned int i, int val); + void bindParamI(unsigned int i, long val); void bindParamI(unsigned int i, unsigned int val); void bindParamI(unsigned int i, long unsigned int val); void bindParamI(unsigned int i, long long unsigned int val); @@ -26,9 +27,11 @@ namespace ODBC { void bindParamS(unsigned int i, String); void bindParamT(unsigned int i, struct tm *); void bindParamT(unsigned int i, time_t); + void bindParamT(unsigned int i, const TimeTypePair & p) { bindParamT(i, p.c()); } const String sql; protected: + friend class BindBase; SQLHSTMT hStmt; const Connection& connection; private: diff --git a/libodbcpp/connection.cpp b/libodbcpp/connection.cpp index ad1c2a7..d1c447d 100644 --- a/libodbcpp/connection.cpp +++ b/libodbcpp/connection.cpp @@ -95,7 +95,7 @@ ODBC::Connection::~Connection() } int -ODBC::Connection::beginTx() +ODBC::Connection::beginTx() const { SQLRETURN dberr = SQLSetConnectOption(conn, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); if ((dberr != SQL_SUCCESS)) { @@ -106,7 +106,7 @@ ODBC::Connection::beginTx() } int -ODBC::Connection::commitTx() +ODBC::Connection::commitTx() const { if (txDepth > 0) { if (txAborted) { @@ -130,7 +130,7 @@ ODBC::Connection::commitTx() } int -ODBC::Connection::rollbackTx() +ODBC::Connection::rollbackTx() const { if (txDepth > 0) { txDepth -= 1; @@ -162,3 +162,9 @@ ODBC::Connection::txIsAborted() const return txAborted; } +bool +ODBC::Connection::inTx() const +{ + return (txDepth > 0); +} + diff --git a/libodbcpp/connection.h b/libodbcpp/connection.h index a2a99cf..5fdce9e 100644 --- a/libodbcpp/connection.h +++ b/libodbcpp/connection.h @@ -13,11 +13,12 @@ namespace ODBC { SQLHENV env; SQLHDBC conn; - int beginTx(); - int commitTx(); - int rollbackTx(); + int beginTx() const; + int commitTx() const; + int rollbackTx() const; void abortTx() const; bool txIsAborted() const; + bool inTx() const; private: mutable unsigned int txDepth; mutable bool txAborted; diff --git a/libodbcpp/error.cpp b/libodbcpp/error.cpp index 5497f4d..3d55fc2 100644 --- a/libodbcpp/error.cpp +++ b/libodbcpp/error.cpp @@ -13,29 +13,45 @@ odbc_verror(RETCODE err, SQLSMALLINT handletype, SQLHANDLE handle, char const * SQLCHAR sqlerrmsg[12800]; char * action; - vasprintf(&action, actionfmt, ap); + if (vasprintf(&action, actionfmt, ap) < 0) { + syslog(LOG_WARNING, "%s: %d: %ld: %5.5s: \"%s\" : failed to malloc for vasprintf", + __FUNCTION__, err, sqlerr, sqlstatus, sqlerrmsg); + return; + } SQLRETURN rc = SQLGetDiagRec(handletype, handle, 1, sqlstatus, &sqlerr, sqlerrmsg, sizeof(sqlerrmsg), NULL); switch (rc) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: - asprintf(msg, "%d: %ld: %5.5s: \"%s\" while attempting to %s", - err, sqlerr, sqlstatus, sqlerrmsg, action); + if (msg) { + if (asprintf(msg, "%d: %ld: %5.5s: \"%s\" while attempting to %s", + err, sqlerr, sqlstatus, sqlerrmsg, action) < 1) { + *msg = NULL; + } + } syslog(LOG_WARNING, "%s: %d: %ld: %5.5s: \"%s\" while attempting to %s", __FUNCTION__, err, sqlerr, sqlstatus, sqlerrmsg, action); break; case SQL_INVALID_HANDLE: - asprintf(msg, "(%d) Invalid handle passed into function trying to %s.", - err, action); + if (msg) { + if (asprintf(msg, "(%d) Invalid handle passed into function trying to %s.", + err, action) < 1) { + *msg = NULL; + } + } syslog(LOG_ERR, "%s: (%d) Invalid handle passed into function trying to %s.", __FUNCTION__, err, action); break; case SQL_NO_DATA: - asprintf(msg, "(%d) No error data available for record trying to %s.", - err, action); + if (msg) { + if (asprintf(msg, "(%d) No error data available for record trying to %s.", + err, action) < 1) { + *msg = NULL; + } + } syslog(LOG_ERR, "%s: (%d) No error data available for record trying to %s.", __FUNCTION__, err, action); break; @@ -62,8 +78,10 @@ ODBC::Error::Error(char const * action, ...) va_list ap; va_start(ap, action); - vsyslog(LOG_ERR, action, ap); - vasprintf(&msg, action, ap); + vsyslog(LOG_ERR, action, ap); + if (vasprintf(&msg, action, ap) < 1) { + msg = NULL; + } va_end(ap); } diff --git a/libodbcpp/param.cpp b/libodbcpp/param.cpp index a2a90f0..7bfa415 100644 --- a/libodbcpp/param.cpp +++ b/libodbcpp/param.cpp @@ -69,6 +69,20 @@ ODBC::Command::bindParamI(unsigned int i, int val) 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)); + } + 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()) { diff --git a/libodbcpp/selectcommand.cpp b/libodbcpp/selectcommand.cpp index 9d385b9..92b4077 100644 --- a/libodbcpp/selectcommand.cpp +++ b/libodbcpp/selectcommand.cpp @@ -153,6 +153,19 @@ ODBC::SelectCommand::operator[](const String & colName) const } unsigned int +ODBC::SelectCommand::getOrdinal(const String & colName) const +{ + unsigned int n = 0; + for (Columns::const_iterator col = columns.begin(); col != columns.end(); col++) { + if ((*col)->name == colName) { + return n; + } + n += 1; + } + throw ODBC::Error("Column (%s) does not exist", colName.c_str()); +} + +unsigned int ODBC::SelectCommand::columnCount() const { return columns.size(); diff --git a/libodbcpp/selectcommand.h b/libodbcpp/selectcommand.h index 0294d07..5a00739 100644 --- a/libodbcpp/selectcommand.h +++ b/libodbcpp/selectcommand.h @@ -14,6 +14,7 @@ namespace ODBC { const Column & operator[](unsigned int col) const; const Column & operator[](const String &) const; unsigned int columnCount() const; + unsigned int getOrdinal(const String &) const; private: void execute(); Columns columns; diff --git a/libodbcpp/ustring.cpp b/libodbcpp/ustring.cpp index 07a1f44..dd8ee3b 100644 --- a/libodbcpp/ustring.cpp +++ b/libodbcpp/ustring.cpp @@ -1,4 +1,5 @@ #include <stdarg.h> +#include <stdio.h> #include "ustring.h" ODBC::String::String() @@ -32,7 +33,9 @@ ODBC::String::Format(const char * fmt, ...) char * buf; va_list va; va_start(va, fmt); - vasprintf(&buf, fmt, va); + if (vasprintf(&buf, fmt, va)) { + buf = NULL; + } va_end(va); return buf; } |