summaryrefslogtreecommitdiff
path: root/libodbcpp
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-02-18 12:58:59 +0000
committerrandomdan <randomdan@localhost>2011-02-18 12:58:59 +0000
commitc3f2a299a734494a61a49709a8e4cc335570b3d3 (patch)
treeb5bf5bb8e01ad1e41ff5957c17fb60e3c353cfd9 /libodbcpp
parentAdd check function for when a connection is finished with, but you don't want... (diff)
downloadlibdbpp-odbc-c3f2a299a734494a61a49709a8e4cc335570b3d3.tar.bz2
libdbpp-odbc-c3f2a299a734494a61a49709a8e4cc335570b3d3.tar.xz
libdbpp-odbc-c3f2a299a734494a61a49709a8e4cc335570b3d3.zip
Handle the case when the driver tries to save more data than the buffer is big enough, and doesn't bother to mention it
Use the driver's bindSize as a hint as to how much buffer to allocate up front
Diffstat (limited to 'libodbcpp')
-rw-r--r--libodbcpp/column.cpp16
-rw-r--r--libodbcpp/column.h10
-rw-r--r--libodbcpp/selectcommand.cpp16
3 files changed, 23 insertions, 19 deletions
diff --git a/libodbcpp/column.cpp b/libodbcpp/column.cpp
index b041bd4..a34946a 100644
--- a/libodbcpp/column.cpp
+++ b/libodbcpp/column.cpp
@@ -17,13 +17,14 @@ ODBC::Column::~Column()
{
}
-void
-ODBC::Column::resize(SQLHANDLE)
+bool
+ODBC::Column::resize()
{
+ return false;
}
-void
-ODBC::CharArrayColumn::resize(SQLHANDLE)
+bool
+ODBC::CharArrayColumn::resize()
{
if (bindLen >= SQLLEN(data.size())) {
data.resize(bindLen + 1);
@@ -32,12 +33,9 @@ ODBC::CharArrayColumn::resize(SQLHANDLE)
paramBound = false;
Param::bind();
}
+ return true;
}
-}
-
-void
-ODBC::Column::onScroll()
-{
+ return false;
}
bool
diff --git a/libodbcpp/column.h b/libodbcpp/column.h
index 71118f8..e981a14 100644
--- a/libodbcpp/column.h
+++ b/libodbcpp/column.h
@@ -4,6 +4,7 @@
#include "../libdbpp/column.h"
#include <typeinfo>
#include <glibmm/ustring.h>
+#include <algorithm>
#include "bind.h"
#include "param.h"
@@ -16,8 +17,7 @@ namespace ODBC {
void bind();
virtual void * rwDataAddress() = 0;
void rebind(DB::Command *, unsigned int idx) const;
- virtual void resize(SQLHANDLE);
- virtual void onScroll();
+ virtual bool resize();
virtual operator int () const { throw std::bad_cast(); }
virtual operator long () const { throw std::bad_cast(); }
@@ -45,11 +45,11 @@ namespace ODBC {
class CharArrayColumn : public Column, public Param {
public:
typedef std::vector<char> CharArray;
- CharArrayColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) :
+ CharArrayColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i, SQLULEN sizeHint) :
DB::Column(n, i),
Column(sc, n, i)
{
- data.resize(256);
+ data.resize(std::max<SQLULEN>(sizeHint, 64) + 1);
}
virtual SQLSMALLINT ctype() const { return SQL_C_CHAR; }
virtual SQLSMALLINT stype() const { return SQL_CHAR; }
@@ -58,7 +58,7 @@ namespace ODBC {
virtual const void * dataAddress() const { return &data.front(); }
virtual void * rwDataAddress() { return &data.front(); }
void operator=(const Glib::ustring & d);
- void resize(SQLHANDLE);
+ bool resize();
virtual operator std::string () const { return std::string(&data.front(), bindLen); }
virtual operator Glib::ustring () const { return std::string(&data.front(), bindLen); }
virtual void apply(DB::HandleField &) const;
diff --git a/libodbcpp/selectcommand.cpp b/libodbcpp/selectcommand.cpp
index 32978a4..f44472f 100644
--- a/libodbcpp/selectcommand.cpp
+++ b/libodbcpp/selectcommand.cpp
@@ -49,7 +49,7 @@ ODBC::SelectCommand::fetch(SQLSMALLINT orientation, SQLLEN offset)
if (SQL_SUCCEEDED(diagrc)) {
if (!strncmp((const char*)sqlstatus, "01004", 5)) {
for (Columns::iterator i = columns.begin(); i != columns.end(); i++) {
- (*i)->resize(hStmt);
+ (*i)->resize();
}
return fetch(SQL_FETCH_RELATIVE, 0);
}
@@ -59,10 +59,16 @@ ODBC::SelectCommand::fetch(SQLSMALLINT orientation, SQLLEN offset)
}
}
case SQL_SUCCESS:
- for (Columns::iterator i = columns.begin(); i != columns.end(); i++) {
- (*i)->onScroll();
+ {
+ bool resized = false;
+ for (Columns::iterator i = columns.begin(); i != columns.end(); i++) {
+ resized |= (*i)->resize();
+ }
+ if (resized) {
+ return fetch(SQL_FETCH_RELATIVE, 0);
+ }
+ return true;
}
- return true;
case SQL_NO_DATA:
return false;
}
@@ -115,7 +121,7 @@ ODBC::SelectCommand::execute()
columns[col] = new TimeStampColumn(this, colName, col);
break;
default:
- columns[col] = new CharArrayColumn(this, colName, col);
+ columns[col] = new CharArrayColumn(this, colName, col, bindSize);
break;
};
columns[col]->bind();