// 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 ); } } }
// Aux. for CDBL_RowResult::GetItem() CDB_Object* CDBL_Result::GetItemInternal( I_Result::EGetItem policy, int item_no, SDBL_ColDescr* fmt, CDB_Object* item_buff ) { EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType; const BYTE* d_ptr = Check(dbdata (GetCmd(), item_no)); DBINT d_len = Check(dbdatlen(GetCmd(), item_no)); CDB_Object* val = s_GenericGetItem(fmt->data_type, item_buff, b_type, d_ptr, d_len); if (val) return val; switch (fmt->data_type) { case eDB_BigInt: { DBNUMERIC* v = (DBNUMERIC*) d_ptr; if (item_buff) { if (v) { if (b_type == eDB_Numeric) { ((CDB_Numeric*) item_buff)->Assign ((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)); } else if (b_type == eDB_BigInt) { *((CDB_BigInt*) item_buff) = numeric_to_longlong ((unsigned int) v->precision, DBNUMERIC_val(v)); } else { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 230020 ); } } else item_buff->AssignNULL(); return item_buff; } return v ? new CDB_BigInt(numeric_to_longlong((unsigned int) v->precision, DBNUMERIC_val(v))) : new CDB_BigInt; } case eDB_Numeric: { DBNUMERIC* v = (DBNUMERIC*) d_ptr; if (item_buff) { if (v) { if (b_type == eDB_Numeric) { ((CDB_Numeric*) item_buff)->Assign ((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)); } else { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 230020 ); } } else item_buff->AssignNULL(); return item_buff; } return v ? new CDB_Numeric((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)) : new CDB_Numeric; } case eDB_Text: { if (item_buff && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CDB_Text* v = NULL; if (item_buff) { v = static_cast<CDB_Text*>(item_buff); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... v->Truncate(); } } else { v = new CDB_Text; } _ASSERT(v); v->Append((char*) d_ptr, (int) d_len); return v; } case eDB_Image: { if (item_buff && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CDB_Image* v = NULL; if (item_buff) { v = static_cast<CDB_Image*>(item_buff); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... v->Truncate(); } } else { v = new CDB_Image; } _ASSERT(v); v->Append((void*) d_ptr, (int) d_len); return v; } default: DATABASE_DRIVER_ERROR( "Unexpected result type." + GetDbgInfo(), 130004 ); } }