CDB_Object* CDBL_BlobResult::GetItem(CDB_Object* item_buff, I_Result::EGetItem policy) { if (m_CurrItem) return 0; EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType; if (item_buff && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 230020 ); } CDB_Stream* val = NULL; if (item_buff) { val = static_cast<CDB_Stream*>(item_buff); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... val->Truncate(); } } else if (m_ColFmt.data_type == eDB_Text) { val = new CDB_Text; } else { val = new CDB_Image; } _ASSERT(val); // check if we do have something in buffer if(m_ReadedBytes < m_BytesInBuffer) { val->Append(m_Buff + m_ReadedBytes, m_BytesInBuffer - m_ReadedBytes); m_ReadedBytes= m_BytesInBuffer; } if(m_BytesInBuffer == 0) { return item_buff; } STATUS s; while ((s = Check(dbreadtext(GetCmd(), m_Buff, (DBINT) sizeof(m_Buff)))) > 0) { val->Append(m_Buff, (size_t(s) < sizeof(m_Buff))? size_t(s) : sizeof(m_Buff)); } switch (s) { case NO_MORE_ROWS: m_EOR = true; case 0: m_CurrItem = 1; break; default: DATABASE_DRIVER_ERROR( "dbreadtext failed." + GetDbgInfo(), 280003 ); } return item_buff; }
// Aux. for CTL_RowResult::GetItem() CDB_Object* CTL_RowResult::GetItemInternal( I_Result::EGetItem policy, CS_COMMAND* cmd, CS_INT item_no, CS_DATAFMT& fmt, CDB_Object* item_buf ) { CS_INT outlen = 0; char buffer[2048]; EDB_Type b_type = item_buf ? item_buf->GetType() : eDB_UnsupportedType; bool is_null = false; switch ( fmt.datatype ) { #ifdef FTDS_IN_USE case CS_UNIQUE_TYPE: #endif case CS_VARBINARY_TYPE: case CS_BINARY_TYPE: { if (item_buf && b_type != eDB_VarBinary && b_type != eDB_Binary && b_type != eDB_VarChar && b_type != eDB_Char && b_type != eDB_LongChar && b_type != eDB_LongBinary) { DATABASE_DRIVER_ERROR("Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } char* v = (fmt.maxlength < (CS_INT) sizeof(buffer)) ? buffer : new char[fmt.maxlength + 1]; switch ( my_ct_get_data(cmd, item_no, v, fmt.maxlength, &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { switch ( b_type ) { case eDB_VarBinary: ((CDB_VarBinary*) item_buf)->SetValue(v, outlen); break; case eDB_Binary: ((CDB_Binary*) item_buf)->SetValue(v, outlen); break; case eDB_VarChar: v[outlen] = '\0'; *((CDB_VarChar*) item_buf) = v; break; case eDB_Char: v[outlen] = '\0'; *((CDB_Char*) item_buf) = v; break; case eDB_LongChar: v[outlen] = '\0'; *((CDB_LongChar*) item_buf) = v; break; case eDB_LongBinary: ((CDB_LongBinary*) item_buf)->SetValue(v, outlen); break; default: break; } if (v != buffer) delete[] v; return item_buf; } CDB_VarBinary* val = is_null ? new CDB_VarBinary() : new CDB_VarBinary(v, outlen); if ( v != buffer) delete[] v; return val; } case CS_CANCELED: if (v != buffer) delete[] v; DATABASE_DRIVER_ERROR("The command has been canceled." + GetDbgInfo(), 130004 ); default: if (v != buffer) delete[] v; DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_LONGBINARY_TYPE: { if (item_buf && b_type != eDB_LongChar && b_type != eDB_LongBinary) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } char* v = (fmt.maxlength < (CS_INT) sizeof(buffer)) ? buffer : new char[fmt.maxlength + 1]; switch ( my_ct_get_data(cmd, item_no, v, fmt.maxlength, &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { switch ( b_type ) { case eDB_LongBinary: ((CDB_LongBinary*) item_buf)->SetValue(v, outlen); break; case eDB_LongChar: v[outlen] = '\0'; *((CDB_LongChar*) item_buf) = v; default: break; } if (v != buffer) delete[] v; return item_buf; } CDB_LongBinary* val = is_null ? new CDB_LongBinary(fmt.maxlength) : new CDB_LongBinary(fmt.maxlength, v, outlen); if ( v != buffer) delete[] v; return val; } case CS_CANCELED: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_BIT_TYPE: { if (item_buf && b_type != eDB_Bit && b_type != eDB_TinyInt && b_type != eDB_SmallInt && b_type != eDB_Int) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_BIT v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { switch ( b_type ) { case eDB_Bit: *((CDB_Bit*) item_buf) = (int) v; break; case eDB_TinyInt: *((CDB_TinyInt*) item_buf) = v ? 1 : 0; break; case eDB_SmallInt: *((CDB_SmallInt*) item_buf) = v ? 1 : 0; break; case eDB_Int: *((CDB_Int*) item_buf) = v ? 1 : 0; break; default: break; } } return item_buf; } return is_null ? new CDB_Bit() : new CDB_Bit((int) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_VARCHAR_TYPE: case CS_CHAR_TYPE: { if (item_buf && b_type != eDB_VarBinary && b_type != eDB_Binary && b_type != eDB_VarChar && b_type != eDB_Char && b_type != eDB_LongChar && b_type != eDB_LongBinary) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } char* v = static_cast<unsigned int>(fmt.maxlength) < sizeof(buffer) ? buffer : new char[fmt.maxlength + 1]; switch ( my_ct_get_data(cmd, item_no, v, fmt.maxlength, &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { v[outlen] = '\0'; if ( item_buf) { if (is_null) { item_buf->AssignNULL(); } else { switch ( b_type ) { case eDB_VarChar: *((CDB_VarChar*) item_buf) = v; break; case eDB_Char: *((CDB_Char*) item_buf) = v; break; case eDB_LongChar: *((CDB_LongChar*) item_buf) = v; break; case eDB_VarBinary: ((CDB_VarBinary*) item_buf)->SetValue(v, outlen); break; case eDB_Binary: ((CDB_Binary*) item_buf)->SetValue(v, outlen); break; case eDB_LongBinary: ((CDB_LongBinary*) item_buf)->SetValue(v, outlen); break; default: break; } } if ( v != buffer) delete[] v; return item_buf; } CDB_VarChar* val = is_null ? new CDB_VarChar() : new CDB_VarChar(v, (size_t) outlen); if (v != buffer) delete[] v; return val; } case CS_CANCELED: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_LONGCHAR_TYPE: { char* v = static_cast<unsigned int>(fmt.maxlength) < sizeof(buffer) ? buffer : new char[fmt.maxlength + 1]; switch ( my_ct_get_data(cmd, item_no, v, fmt.maxlength, &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { v[outlen] = '\0'; if ( item_buf) { if (is_null) { item_buf->AssignNULL(); } else { switch ( b_type ) { case eDB_LongChar: *((CDB_LongChar*) item_buf) = v; break; case eDB_LongBinary: ((CDB_LongBinary*) item_buf)->SetValue(v, outlen); break; case eDB_VarChar: if (outlen <= MAX_VARCHAR_SIZE) { ((CDB_VarChar*) item_buf)->SetValue(v, outlen, eEncoding_Unknown); } else { DATABASE_DRIVER_ERROR( "Invalid conversion to CDB_VarChar type", 230021 ); } break; default: DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); break; } } if ( v != buffer) delete[] v; return item_buf; } CDB_LongChar* val = is_null ? new CDB_LongChar(fmt.maxlength) : new CDB_LongChar((size_t) outlen, v); if (v != buffer) delete[] v; return val; } case CS_CANCELED: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: if (v != buffer) { delete[] v; } DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_DATETIME_TYPE: { if (item_buf && b_type != eDB_DateTime) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_DATETIME v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf) { if (!is_null) { ((CDB_DateTime*)item_buf)->Assign(v.dtdays, v.dttime); } else { item_buf->AssignNULL(); } return item_buf; } CDB_DateTime* val; if (!is_null) { val = new CDB_DateTime(v.dtdays, v.dttime); } else { val = new CDB_DateTime; } return val; } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_DATETIME4_TYPE: { if (item_buf && b_type != eDB_SmallDateTime && b_type != eDB_DateTime) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_DATETIME4 v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf) { if (!is_null) { switch ( b_type ) { case eDB_SmallDateTime: ((CDB_SmallDateTime*) item_buf)->Assign (v.days, v.minutes); break; case eDB_DateTime: ((CDB_DateTime*) item_buf)->Assign (v.days, v.minutes * 60 * 300); break; default: break; } } else { item_buf->AssignNULL(); } return item_buf; } return is_null ? new CDB_SmallDateTime : new CDB_SmallDateTime(v.days, v.minutes); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_TINYINT_TYPE: { if (item_buf && b_type != eDB_TinyInt && b_type != eDB_SmallInt && b_type != eDB_Int) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_TINYINT v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { switch ( b_type ) { case eDB_TinyInt: *((CDB_TinyInt*) item_buf) = (Uint1) v; break; case eDB_SmallInt: *((CDB_SmallInt*) item_buf) = (Int2) v; break; case eDB_Int: *((CDB_Int*) item_buf) = (Int4) v; break; default: break; } } return item_buf; } return is_null ? new CDB_TinyInt() : new CDB_TinyInt((Uint1) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_SMALLINT_TYPE: { if (item_buf && b_type != eDB_SmallInt && b_type != eDB_Int) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_SMALLINT v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { switch ( b_type ) { case eDB_SmallInt: *((CDB_SmallInt*) item_buf) = (Int2) v; break; case eDB_Int: *((CDB_Int*) item_buf) = (Int4) v; break; default: break; } } return item_buf; } return is_null ? new CDB_SmallInt() : new CDB_SmallInt((Int2) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_INT_TYPE: { if (item_buf && b_type != eDB_Int) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_INT v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { *((CDB_Int*) item_buf) = (Int4) v; } return item_buf; } return is_null ? new CDB_Int() : new CDB_Int((Int4) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_LONG_TYPE: { if (item_buf && b_type != eDB_BigInt) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } Int8 v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { *((CDB_BigInt*) item_buf) = (Int8) v; } return item_buf; } return is_null ? new CDB_BigInt() : new CDB_BigInt(v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_DECIMAL_TYPE: case CS_NUMERIC_TYPE: { if (item_buf && b_type != eDB_BigInt && b_type != eDB_Numeric) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_NUMERIC v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (outlen < 3) { /* it used to be == 0 but ctlib on windows returns 2 even for NULL numeric */ item_buf->AssignNULL(); } else if (is_null) { item_buf->AssignNULL(); } else { if (b_type == eDB_Numeric) { ((CDB_Numeric*) item_buf)->Assign ((unsigned int) v.precision, (unsigned int) v.scale, (const unsigned char*) v.array); } else { *((CDB_BigInt*) item_buf) = numeric_to_longlong((unsigned int) v.precision, v.array); } } return item_buf; } if (fmt.scale == 0 && fmt.precision < 20) { return (outlen == 0) ? new CDB_BigInt : new CDB_BigInt(numeric_to_longlong((unsigned int) v.precision,v.array)); } else { return is_null ? new CDB_Numeric : new CDB_Numeric((unsigned int) v.precision, (unsigned int) v.scale, (const unsigned char*) v.array); } } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_FLOAT_TYPE: { if (item_buf && b_type != eDB_Double) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_FLOAT v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { *((CDB_Double*) item_buf) = (double) v; } return item_buf; } return is_null ? new CDB_Double() : new CDB_Double((double) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_REAL_TYPE: { if (item_buf && b_type != eDB_Float) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CS_REAL v; switch ( my_ct_get_data(cmd, item_no, &v, (CS_INT) sizeof(v), &outlen, is_null) ) { case CS_SUCCEED: case CS_END_ITEM: case CS_END_DATA: { if ( item_buf ) { if (is_null) { item_buf->AssignNULL(); } else { *((CDB_Float*) item_buf) = (float) v; } return item_buf; } return is_null ? new CDB_Float() : new CDB_Float((float) v); } case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } case CS_TEXT_TYPE: case CS_IMAGE_TYPE: { if (item_buf && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CDB_Stream* val = NULL; if (item_buf) { val = static_cast<CDB_Stream*>(item_buf); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... val->Truncate(); } } else if (fmt.datatype == CS_TEXT_TYPE) { val = new CDB_Text; } else { val = new CDB_Image; } _ASSERT(val); if (m_NullValue[GetCurrentItemNum()] == eIsNull) return val; for (;;) { switch ( my_ct_get_data(cmd, item_no, buffer, sizeof(buffer), &outlen, is_null) ) { case CS_SUCCEED: if (outlen != 0) val->Append(buffer, outlen); continue; case CS_END_ITEM: case CS_END_DATA: if (outlen != 0) val->Append(buffer, outlen); return val; case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } } } default: { // Not handled data types ... // CS_MONEY_TYPE // CS_MONEY4_TYPE // CS_SENSITIVITY_TYPE // CS_BOUNDARY_TYPE // CS_VOID_TYPE // CS_USHORT_TYPE // CS_UNICHAR_TYPE DATABASE_DRIVER_ERROR( "Unexpected result type." + GetDbgInfo(), 130004 ); } } }