diff --git a/src/connection.cpp b/src/connection.cpp index d061fbe..1054f8e 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -304,13 +304,15 @@ int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, ExecuteBaton } void Connection::CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, ExecuteBaton* baton, vector &columns) { - vector metadata = rs->getColumnListMetaData(); - for (vector::iterator iterator = metadata.begin(), end = metadata.end(); iterator != end; ++iterator) { + vector metadata = rs->getColumnListMetaData(); + int colIndex = 1; + for (vector::iterator iterator = metadata.begin(), end = metadata.end(); iterator != end; ++iterator, colIndex++) { oracle::occi::MetaData metadata = *iterator; column_t* col = new column_t(); col->name = metadata.getString(oracle::occi::MetaData::ATTR_NAME); int type = metadata.getInt(oracle::occi::MetaData::ATTR_DATA_TYPE); col->charForm = metadata.getInt(oracle::occi::MetaData::ATTR_CHARSET_FORM); + col->bufferSize = 0; switch(type) { case oracle::occi::OCCI_TYPECODE_NUMBER: case oracle::occi::OCCI_TYPECODE_FLOAT: @@ -325,6 +327,9 @@ void Connection::CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, Execute case oracle::occi::OCCI_TYPECODE_VARCHAR: case oracle::occi::OCCI_TYPECODE_CHAR: col->type = VALUE_TYPE_STRING; + col->bufferSize = metadata.getInt(oracle::occi::MetaData::ATTR_CHAR_SIZE) * 4; // allocate enough for UTF-8 + col->buffer = new char[col->bufferSize]; + rs->setDataBuffer(colIndex, col->buffer, oracle::occi::OCCI_SQLT_STR, col->bufferSize, &col->bufferLen, &col->bufferInd); break; case oracle::occi::OCCI_TYPECODE_CLOB: col->type = VALUE_TYPE_CLOB; @@ -366,12 +371,20 @@ row_t* Connection::CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs, int colIndex = 1; for (vector::iterator iterator = columns.begin(), end = columns.end(); iterator != end; ++iterator, colIndex++) { column_t* col = *iterator; - if(rs->isNull(colIndex)) { + if(!col->bufferSize && rs->isNull(colIndex)) { row->values.push_back(NULL); } else { switch(col->type) { case VALUE_TYPE_STRING: - row->values.push_back(new string(rs->getString(colIndex))); + if (col->bufferSize) { + if (col->bufferInd == -1) { + row->values.push_back(NULL); + } else { + row->values.push_back(new string((char*)col->buffer, col->bufferLen)); + } + } else { + row->values.push_back(new string(rs->getString(colIndex))); + } break; case VALUE_TYPE_NUMBER: row->values.push_back(new oracle::occi::Number(rs->getNumber(colIndex))); diff --git a/src/executeBaton.cpp b/src/executeBaton.cpp index 87779da..f5c6b90 100644 --- a/src/executeBaton.cpp +++ b/src/executeBaton.cpp @@ -24,6 +24,9 @@ ExecuteBaton::~ExecuteBaton() { for (std::vector::iterator iterator = columns.begin(), end = columns.end(); iterator != end; ++iterator) { column_t* col = *iterator; + if (col->bufferSize > 0) { + delete col->buffer; + } delete col; } diff --git a/src/executeBaton.h b/src/executeBaton.h index 451c45b..79547e6 100644 --- a/src/executeBaton.h +++ b/src/executeBaton.h @@ -31,6 +31,10 @@ struct column_t { int type; int charForm; std::string name; + void* buffer; + sb4 bufferSize; + ub2 bufferLen; + sb2 bufferInd; }; struct row_t {