CDB_Object* CODBC_RowResult::x_MakeItem() { char buffer[8*1024]; int outlen; switch(m_ColFmt[m_CurrItem].DataType) { case SQL_WCHAR: case SQL_WVARCHAR: #ifdef HAVE_WSTRING { wchar_t buffer[4*1024]; outlen = xGetData(SQL_C_WCHAR, buffer, sizeof(buffer)); CODBCString odbc_str(buffer, outlen); if(m_ColFmt[m_CurrItem].ColumnSize < 256) { CDB_VarChar* val = (outlen < 0) ? new CDB_VarChar() : new CDB_VarChar(odbc_str.ConvertTo(GetClientEncoding())); return val; } else { CDB_LongChar* val = (outlen < 0) ? new CDB_LongChar(m_ColFmt[m_CurrItem].ColumnSize) : new CDB_LongChar(m_ColFmt[m_CurrItem].ColumnSize, odbc_str.ConvertTo(GetClientEncoding())); return val; } } #endif case SQL_VARCHAR: case SQL_CHAR: { outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if(m_ColFmt[m_CurrItem].ColumnSize < 256) { CDB_VarChar* val = (outlen < 0) ? new CDB_VarChar() : new CDB_VarChar(buffer, (size_t) outlen); return val; } else { CDB_LongChar* val = (outlen < 0) ? new CDB_LongChar(m_ColFmt[m_CurrItem].ColumnSize) : new CDB_LongChar(m_ColFmt[m_CurrItem].ColumnSize, buffer); return val; } } case SQL_BINARY: case SQL_VARBINARY: { outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if(m_ColFmt[m_CurrItem].ColumnSize < 256) { CDB_VarBinary* val = (outlen <= 0) ? new CDB_VarBinary() : new CDB_VarBinary(buffer, (size_t)outlen); return val; } else { CDB_LongBinary* val = (outlen < 0) ? new CDB_LongBinary(m_ColFmt[m_CurrItem].ColumnSize) : new CDB_LongBinary(m_ColFmt[m_CurrItem].ColumnSize, buffer, (size_t) outlen); return val; } } case SQL_BIT: { SQLCHAR v; outlen = xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); return (outlen <= 0) ? new CDB_Bit() : new CDB_Bit((int) v); } case SQL_TYPE_TIMESTAMP: { SQL_TIMESTAMP_STRUCT v; outlen = xGetData(SQL_C_TYPE_TIMESTAMP, &v, sizeof(SQL_TIMESTAMP_STRUCT)); if (outlen <= 0) { return (m_ColFmt[m_CurrItem].ColumnSize > 16 || m_ColFmt[m_CurrItem].DecimalDigits > 0)? (CDB_Object*)(new CDB_DateTime()) : (CDB_Object*)(new CDB_SmallDateTime()); } else { CTime t((int)v.year, (int)v.month, (int)v.day, (int)v.hour, (int)v.minute, (int)v.second, (long)v.fraction); return (m_ColFmt[m_CurrItem].ColumnSize > 16 || m_ColFmt[m_CurrItem].DecimalDigits > 0)? (CDB_Object*)(new CDB_DateTime(t)) : (CDB_Object*)(new CDB_SmallDateTime(t)); } } case SQL_TINYINT: { SQLCHAR v; outlen = xGetData(SQL_C_UTINYINT, &v, sizeof(SQLCHAR)); return (outlen <= 0) ? new CDB_TinyInt() : new CDB_TinyInt((Uint1) v); } case SQL_SMALLINT: { SQLSMALLINT v; outlen = xGetData(SQL_C_SSHORT, &v, sizeof(SQLSMALLINT)); return (outlen <= 0) ? new CDB_SmallInt() : new CDB_SmallInt((Int2) v); } case SQL_INTEGER: { SQLINTEGER v; outlen = xGetData(SQL_C_SLONG, &v, sizeof(SQLINTEGER)); return (outlen <= 0) ? new CDB_Int() : new CDB_Int((Int4) v); } case SQL_DOUBLE: case SQL_FLOAT: { SQLDOUBLE v; outlen = xGetData(SQL_C_DOUBLE, &v, sizeof(SQLDOUBLE)); return (outlen <= 0) ? new CDB_Double() : new CDB_Double(v); } case SQL_REAL: { SQLREAL v; outlen = xGetData(SQL_C_FLOAT, &v, sizeof(SQLREAL)); return (outlen <= 0) ? new CDB_Float() : new CDB_Float(v); } case SQL_DECIMAL: case SQL_NUMERIC: { if((m_ColFmt[m_CurrItem].DecimalDigits > 0) || (m_ColFmt[m_CurrItem].ColumnSize > 20)) { // It should be numeric SQL_NUMERIC_STRUCT v; outlen = xGetData(SQL_C_NUMERIC, &v, sizeof(SQL_NUMERIC_STRUCT)); CDB_Numeric* r= new CDB_Numeric; if(outlen > 0) { xConvert2CDB_Numeric(r, v); } return r; } else { // It should be bigint SQLBIGINT v; outlen = xGetData(SQL_C_SBIGINT, &v, sizeof(SQLBIGINT)); return (outlen <= 0) ? new CDB_BigInt() : new CDB_BigInt((Int8) v); } } case SQL_WLONGVARCHAR: #ifdef HAVE_WSTRING { CDB_Text* val = new CDB_Text; // Code below looks strange, but it completely matches original logic. for(;;) { CheckSIENoD_WText(val); } return val; } #endif case SQL_LONGVARCHAR: { CDB_Text* val = new CDB_Text; // Code below looks strange, but it completely matches original logic. for(;;) { CheckSIENoD_Text(val); } return val; } case SQL_LONGVARBINARY: { CDB_Image* val = new CDB_Image; // Code below looks strange, but it completely matches original logic. for(;;) { CheckSIENoD_Binary(val); } return val; } default: { string err_message = "Unsupported column type." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430025 ); } } }
bool CODBC_BCPInCmd::Send(void) { char param_buff[2048]; // maximal row size, assured of buffer overruns if (!x_AssignParams(param_buff)) { SetHasFailed(); string err_message = "Cannot assign params." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 423004 ); } SetWasSent(); if (bcp_sendrow(GetHandle()) != SUCCEED) { SetHasFailed(); ReportErrors(); string err_message = "bcp_sendrow failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 423005 ); } if (m_HasTextImage) { // send text/image data char buff[1800]; // text/image page size for (unsigned int i = 0; i < GetBindParamsImpl().NofParams(); ++i) { if (GetBindParamsImpl().GetParamStatus(i) == 0) continue; CDB_Object& param = *GetBindParamsImpl().GetParam(i); if (param.GetType() != eDB_Image && (param.GetType() != eDB_Text || param.IsNULL())) continue; CDB_Stream& val = dynamic_cast<CDB_Stream&> (param); size_t left_bytes = val.Size(); size_t len = 0; size_t valid_len = 0; size_t invalid_len = 0; do { invalid_len = len - valid_len; if (valid_len < len) { memmove(buff, buff + valid_len, invalid_len); } len = val.Read(buff + invalid_len, sizeof(buff) - invalid_len); if (len > left_bytes) { len = left_bytes; } valid_len = CUtf8::GetValidBytesCount( CTempString(buff, len)); CODBCString odbc_str(buff, len); // !!! TODO: Decode to UCS2 if needed !!!! if (bcp_moretext(GetHandle(), (DBINT) valid_len, (LPCBYTE)static_cast<const char*>(odbc_str) ) != SUCCEED) { SetHasFailed(); ReportErrors(); string err_text; if (param.GetType() == eDB_Text) { err_text = "bcp_moretext for text failed."; } else { err_text = "bcp_moretext for image failed."; } err_text += GetDbgInfo(); DATABASE_DRIVER_ERROR( err_text, 423006 ); } if (!valid_len) { break; } left_bytes -= valid_len; } while (left_bytes); } } return true; }