// //////////////////////////////////////////////////////////////////////////// SQLRETURN GetAttrForHandle(SQLHANDLE Handle, SQLINTEGER Attribute, std::string &ValuePtr, const char *odbc_function_name, HandleGetAttrFunc get_attr_function, OdbcThrowFlags::Flags throw_flags) { CheckStringArgInLengthDomain<SQLINTEGER>(ValuePtr, "ValuePtr", odbc_function_name); SQLRETURN return_code; MLB::Utility::IncrementalBuffer<SQLCHAR, 4096> buffer; throw_flags = MLB::Utility::EnumFlagAnd(throw_flags, static_cast<OdbcThrowFlags::Flags>(~(OdbcThrowFlags::SuccessWithInfo))); for ( ; ; ) { SQLINTEGER actual_len; return_code = get_attr_function(Handle, Attribute, reinterpret_cast<SQLPOINTER>(buffer.GetPtr()), buffer.GetAllocationCountAsType<SQLINTEGER>(), &actual_len, throw_flags); if (return_code == SQL_SUCCESS) { std::string(reinterpret_cast<const char *>(buffer.GetPtr()), actual_len).swap(ValuePtr); break; } else if (return_code == SQL_SUCCESS_WITH_INFO) { if (!buffer.SetCount(actual_len, false)) throw OdbcException("Call to '" + std::string(odbc_function_name) + "' returned 'SQL_SUCCESS_WITH_INFO', but no returned lengths " "qualified for that return code."); } } return(return_code); }
// //////////////////////////////////////////////////////////////////////////// SQLRETURN DescribeCol(SQLHSTMT StatementHandle, SQLSMALLINT ColumnNumber, std::string &ColumnName, SQLSMALLINT *DataTypePtr, SQLUINTEGER *ColumnSizePtr, SQLSMALLINT *DecimalDigitsPtr, SQLSMALLINT *NullablePtr, OdbcThrowFlags::Flags throw_flags) { SQLRETURN return_code; MLB::Utility::IncrementalBuffer<SQLCHAR, 256> buffer; OdbcThrowFlags::Flags tmp_throw_flags; tmp_throw_flags = MLB::Utility::EnumFlagAnd(throw_flags, static_cast<OdbcThrowFlags::Flags>(~(OdbcThrowFlags::SuccessWithInfo))); for ( ; ; ) { SQLSMALLINT actual_len; return_code = DescribeCol(StatementHandle, ColumnNumber, reinterpret_cast<SQLCHAR *>(buffer.GetPtr()), buffer.GetAllocationCountAsType<SQLSMALLINT>(), &actual_len, DataTypePtr, ColumnSizePtr, DecimalDigitsPtr, NullablePtr, tmp_throw_flags); if (return_code == SQL_SUCCESS) { std::string(reinterpret_cast<const char *>(buffer.GetPtr()), actual_len).swap(ColumnName); break; } else if (return_code == SQL_SUCCESS_WITH_INFO) { if (!buffer.SetCount(actual_len, false)) { std::string(reinterpret_cast<const char *>(buffer.GetPtr()), actual_len).swap(ColumnName); if (throw_flags & OdbcThrowFlags::SuccessWithInfo) throw OdbcException("Call to '::SQLDescribeCol()' returned " "'SQL_SUCCESS_WITH_INFO', but no returned lengths qualified " "for that return code."); break; } } } return(return_code); }
// //////////////////////////////////////////////////////////////////////////// SQLRETURN DriverConnect(SQLHDBC ConnectionHandle, SQLHWND WindowHandle, const std::string &InConnectionString, std::string &OutConnectionString, SQLUSMALLINT DriverCompletion, OdbcThrowFlags::Flags throw_flags) { CheckStringArgInLengthDomain<SQLSMALLINT>(InConnectionString, "InConnectionString", "::SQLDriverConnect"); SQLRETURN return_code; MLB::Utility::IncrementalBuffer<SQLCHAR, 4096> buffer; throw_flags = MLB::Utility::EnumFlagAnd(throw_flags, static_cast<OdbcThrowFlags::Flags>(~(OdbcThrowFlags::SuccessWithInfo))); for ( ; ; ) { SQLSMALLINT actual_len; return_code = DriverConnect(ConnectionHandle, WindowHandle, reinterpret_cast<SQLCHAR *>( const_cast<char *>(InConnectionString.c_str())), static_cast<SQLSMALLINT>(InConnectionString.size()), reinterpret_cast<SQLCHAR *>(buffer.GetPtr()), buffer.GetAllocationCountAsType<SQLSMALLINT>(), &actual_len, DriverCompletion, throw_flags); if (return_code == SQL_SUCCESS) { std::string(reinterpret_cast<const char *>(buffer.GetPtr()), actual_len).swap(OutConnectionString); break; } else if (return_code == SQL_SUCCESS_WITH_INFO) { // ::SQLDriverConnect() returns 'SQL_SUCCESS_WITH_INFO' for reasons // other than to do with insufficient length of returned strings... if (!buffer.SetCount(actual_len, false)) break; } } return(return_code); }