summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libodbcpp/bind.h1
-rw-r--r--libodbcpp/column.cpp17
-rw-r--r--libodbcpp/column.h2
-rw-r--r--libodbcpp/command.h3
-rw-r--r--libodbcpp/connection.cpp12
-rw-r--r--libodbcpp/connection.h7
-rw-r--r--libodbcpp/error.cpp36
-rw-r--r--libodbcpp/param.cpp14
-rw-r--r--libodbcpp/selectcommand.cpp13
-rw-r--r--libodbcpp/selectcommand.h1
-rw-r--r--libodbcpp/ustring.cpp5
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;
}