BEGIN_NCBI_SCOPE #define DBDATETIME4_days(x) ((x)->numdays) #define DBDATETIME4_mins(x) ((x)->nummins) #define DBNUMERIC_val(x) ((x)->val) #define SQL_VARLEN_DATA (-10) ///////////////////////////////////////////////////////////////////////////// // // CODBC_BCPInCmd:: // CODBC_BCPInCmd::CODBC_BCPInCmd(CODBC_Connection& conn, SQLHDBC cmd, const string& table_name) : CStatementBase(conn, table_name), m_Cmd(cmd), m_HasTextImage(false), m_WasBound(false) { string extra_msg = "Table Name: " + table_name; SetDbgInfo( extra_msg ); if (bcp_init(cmd, CODBCString(table_name, GetClientEncoding()).AsCWString(), 0, 0, DB_IN) != SUCCEED) { ReportErrors(); string err_message = "bcp_init failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 423001 ); } ++m_RowCount; }
CODBC_RowResult::CODBC_RowResult( CStatementBase& stmt, SQLSMALLINT nof_cols, SQLLEN* row_count ) : m_Stmt(stmt) , m_CurrItem(-1) , m_EOR(false) , m_RowCountPtr( row_count ) , m_HasMoreData(false) { odbc::TSqlChar column_name_buff[eODBC_Column_Name_Size]; if(m_RowCountPtr) *m_RowCountPtr = 0; SQLSMALLINT actual_name_size; SQLSMALLINT nullable; m_ColFmt = new SODBC_ColDescr[nof_cols]; for (unsigned int n = 0; n < (unsigned int)nof_cols; ++n) { // SQLDescribeCol takes a pointer to a buffer. switch(SQLDescribeCol(GetHandle(), n + 1, column_name_buff, eODBC_Column_Name_Size * sizeof(odbc::TSqlChar), &actual_name_size, &m_ColFmt[n].DataType, &m_ColFmt[n].ColumnSize, &m_ColFmt[n].DecimalDigits, &nullable)) { case SQL_SUCCESS_WITH_INFO: ReportErrors(); case SQL_SUCCESS: m_ColFmt[n].ColumnName = CODBCString(column_name_buff, actual_name_size).ConvertTo(GetClientEncoding()); break; case SQL_ERROR: ReportErrors(); { string err_message = "SQLDescribeCol failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420020 ); } default: { string err_message = "SQLDescribeCol failed (memory corruption suspected)." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420021 ); } } m_CachedRowInfo.Add( m_ColFmt[n].ColumnName, m_ColFmt[n].ColumnSize, s_GetDataType(m_ColFmt[n].DataType, m_ColFmt[n].DecimalDigits, m_ColFmt[n].ColumnSize) ); } }
bool CODBC_RowResult::CheckSIENoD_WText(CDB_Stream* val) { int rc = 0; SQLLEN f = 0; wchar_t buffer[4*1024]; rc = SQLGetData(GetHandle(), m_CurrItem + 1, SQL_C_WCHAR, buffer, sizeof(buffer), &f); switch( rc ) { case SQL_SUCCESS_WITH_INFO: if(f == SQL_NO_TOTAL) { f = sizeof(buffer) - 1; } else if(f < 0) { ReportErrors(); } case SQL_SUCCESS: if(f > 0) { if(f > SQLLEN(sizeof(buffer) - 1)) { f = sizeof(buffer)-1; } f = f / sizeof(wchar_t); string encoded_value = CODBCString(buffer, f).ConvertTo(GetClientEncoding()); val->Append(encoded_value.data(), encoded_value.size()); } return true; case SQL_NO_DATA: break; case SQL_ERROR: ReportErrors(); default: { DATABASE_DRIVER_ERROR( string("SQLGetData failed while retrieving BLOB into C") + CDB_Object::GetTypeName(val->GetType()) + '.', 430021); } } return false; }
size_t CODBC_RowResult::ReadItem(void* buffer,size_t buffer_size,bool* is_null) { if ((unsigned int) m_CurrItem >= GetDefineParams().GetNum() || m_CurrItem == -1 || buffer == 0 || buffer_size == 0) { return 0; } SQLLEN f = 0; if(is_null) *is_null= false; SQLSMALLINT data_type = m_ColFmt[m_CurrItem].DataType; while (m_HasMoreData && m_LastReadData.size() < buffer_size) { m_HasMoreData = false; string next_data; size_t next_len = 0; switch(SQLGetData(GetHandle(), m_CurrItem + 1, SQL_C_BINARY, buffer, buffer_size, &f)) { case SQL_SUCCESS_WITH_INFO: switch(f) { case SQL_NO_TOTAL: next_data.append((char*) buffer, buffer_size); m_HasMoreData = true; break; case SQL_NULL_DATA: if(is_null) *is_null= true; break; default: if ( f < 0 ) { ReportErrors(); return 0; } m_HasMoreData = true; next_len = static_cast<size_t>(f); if (next_len >= buffer_size) { next_len = buffer_size; } next_data.append((char*) buffer, next_len); break; } break; case SQL_SUCCESS: if(f == SQL_NULL_DATA) { if(is_null) *is_null= true; } else { next_len = (f >= 0)? ((size_t)f) : 0; next_data.append((char*) buffer, next_len); } break; case SQL_NO_DATA: if(f == SQL_NULL_DATA) { if(is_null) *is_null= true; } break; case SQL_ERROR: ReportErrors(); return 0; default: { string err_message = "SQLGetData failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430026 ); } } #ifdef HAVE_WSTRING if (data_type == SQL_WCHAR || data_type == SQL_WVARCHAR || data_type == SQL_WLONGVARCHAR) { string conv_data = (CODBCString((wchar_t*) next_data.data(), next_data.size() / sizeof(wchar_t)) .ConvertTo(GetClientEncoding())); m_LastReadData += conv_data; } else #endif { m_LastReadData += next_data; } } size_t return_len = m_LastReadData.size(); if (return_len > buffer_size) { return_len = buffer_size; } memcpy(buffer, m_LastReadData.data(), return_len); m_LastReadData = m_LastReadData.substr(return_len); if (!m_HasMoreData && return_len <= buffer_size) { ++m_CurrItem; m_HasMoreData = true; } return return_len; }
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 ); } } }
CDB_Object* CODBC_RowResult::x_LoadItem(I_Result::EGetItem policy, CDB_Object* item_buf) { char buffer[8*1024]; int outlen; switch(m_ColFmt[m_CurrItem].DataType) { case SQL_WCHAR: case SQL_WVARCHAR: switch (item_buf->GetType()) { case eDB_VarBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_VarBinary*)item_buf)->SetValue(buffer, outlen); break; case eDB_Binary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_Binary*)item_buf)->SetValue(buffer, outlen); break; case eDB_LongBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_LongBinary*)item_buf)->SetValue(buffer, outlen); break; #ifdef HAVE_WSTRING case eDB_VarChar: outlen = xGetData(SQL_C_WCHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_VarChar*)item_buf) = CODBCString((wchar_t*)buffer).ConvertTo(GetClientEncoding()); break; case eDB_Char: outlen = xGetData(SQL_C_WCHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_Char*)item_buf) = CODBCString((wchar_t*)buffer).ConvertTo(GetClientEncoding()); break; case eDB_LongChar: outlen = xGetData(SQL_C_WCHAR, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else *((CDB_LongChar*)item_buf) = CODBCString((wchar_t*)buffer).ConvertTo(GetClientEncoding()); break; #endif default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; case SQL_VARCHAR: case SQL_CHAR: { switch (item_buf->GetType()) { case eDB_VarBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_VarBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_Binary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_Binary*) item_buf)->SetValue(buffer, outlen); break; case eDB_LongBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_LongBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_VarChar: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen < 0) item_buf->AssignNULL(); else *((CDB_VarChar*) item_buf) = buffer; break; case eDB_Char: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen < 0) item_buf->AssignNULL(); else *((CDB_Char*) item_buf) = buffer; break; case eDB_LongChar: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if ( outlen < 0) item_buf->AssignNULL(); else *((CDB_LongChar*) item_buf) = buffer; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_BINARY: case SQL_VARBINARY: { switch ( item_buf->GetType() ) { case eDB_VarBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_VarBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_Binary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_Binary*) item_buf)->SetValue(buffer, outlen); break; case eDB_LongBinary: outlen = xGetData(SQL_C_BINARY, buffer, sizeof(buffer)); if ( outlen <= 0) item_buf->AssignNULL(); else ((CDB_LongBinary*) item_buf)->SetValue(buffer, outlen); break; case eDB_VarChar: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen < 0) item_buf->AssignNULL(); else *((CDB_VarChar*) item_buf) = buffer; break; case eDB_Char: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen < 0) item_buf->AssignNULL(); else *((CDB_Char*) item_buf) = buffer; break; case eDB_LongChar: outlen = xGetData(SQL_C_CHAR, buffer, sizeof(buffer)); if (outlen < 0) item_buf->AssignNULL(); else *((CDB_LongChar*) item_buf) = buffer; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_BIT: { SQLCHAR v; switch ( item_buf->GetType() ) { case eDB_Bit: outlen = xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Bit*) item_buf) = (int) v; break; case eDB_TinyInt: outlen = xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_TinyInt*) item_buf) = v ? 1 : 0; break; case eDB_SmallInt: outlen = xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_SmallInt*) item_buf) = v ? 1 : 0; break; case eDB_Int: outlen = xGetData(SQL_C_BIT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Int*) item_buf) = v ? 1 : 0; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_TYPE_TIMESTAMP: { SQL_TIMESTAMP_STRUCT v; switch ( item_buf->GetType() ) { case eDB_SmallDateTime: { outlen = xGetData(SQL_C_TYPE_TIMESTAMP, &v, sizeof(SQL_TIMESTAMP_STRUCT)); if (outlen <= 0) item_buf->AssignNULL(); else { CTime t((int)v.year, (int)v.month, (int)v.day, (int)v.hour, (int)v.minute, (int)v.second, (long)v.fraction); *((CDB_SmallDateTime*) item_buf)= t; } break; } case eDB_DateTime: { outlen = xGetData(SQL_C_TYPE_TIMESTAMP, &v, sizeof(SQL_TIMESTAMP_STRUCT)); if (outlen <= 0) item_buf->AssignNULL(); else { CTime t((int)v.year, (int)v.month, (int)v.day, (int)v.hour, (int)v.minute, (int)v.second, (long)v.fraction); *((CDB_DateTime*) item_buf)= t; } break; } default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_TINYINT: { SQLCHAR v; switch ( item_buf->GetType() ) { case eDB_TinyInt: outlen = xGetData(SQL_C_UTINYINT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_TinyInt*) item_buf) = (Uint1) v; break; case eDB_SmallInt: outlen = xGetData(SQL_C_UTINYINT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_SmallInt*) item_buf) = (Int2) v; break; case eDB_Int: outlen = xGetData(SQL_C_UTINYINT, &v, sizeof(SQLCHAR)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Int*) item_buf) = (Int4) v; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_SMALLINT: { SQLSMALLINT v; switch ( item_buf->GetType() ) { case eDB_SmallInt: outlen = xGetData(SQL_C_SSHORT, &v, sizeof(SQLSMALLINT)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_SmallInt*) item_buf) = (Int2) v; break; case eDB_Int: outlen = xGetData(SQL_C_SSHORT, &v, sizeof(SQLSMALLINT)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Int*) item_buf) = (Int4) v; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_INTEGER: { SQLINTEGER v; switch ( item_buf->GetType() ) { case eDB_Int: outlen = xGetData(SQL_C_SLONG, &v, sizeof(SQLINTEGER)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Int*) item_buf) = (Int4) v; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_DOUBLE: case SQL_FLOAT: { SQLDOUBLE v; switch ( item_buf->GetType() ) { case eDB_Double: outlen = xGetData(SQL_C_DOUBLE, &v, sizeof(SQLDOUBLE)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Double*) item_buf) = v; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_REAL: { SQLREAL v; switch ( item_buf->GetType() ) { case eDB_Float: outlen = xGetData(SQL_C_FLOAT, &v, sizeof(SQLREAL)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_Float*) item_buf) = v; break; default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_BIGINT: case SQL_DECIMAL: case SQL_NUMERIC: { switch ( item_buf->GetType() ) { case eDB_Numeric: { SQL_NUMERIC_STRUCT v; SQLHDESC hdesc; SQLGetStmtAttr(GetHandle(), SQL_ATTR_APP_ROW_DESC, &hdesc, 0, NULL); SQLSetDescField(hdesc, m_CurrItem + 1, SQL_DESC_TYPE, (VOID*)SQL_C_NUMERIC, 0); SQLSetDescField(hdesc, m_CurrItem + 1, SQL_DESC_PRECISION, (VOID*)(m_ColFmt[m_CurrItem].ColumnSize), 0); SQLSetDescField(hdesc, m_CurrItem + 1, SQL_DESC_SCALE, reinterpret_cast<VOID*>(m_ColFmt[m_CurrItem].DecimalDigits), 0); // outlen = xGetData(SQL_ARD_TYPE, &v, sizeof(SQL_NUMERIC_STRUCT)); outlen = xGetData(SQL_C_NUMERIC, &v, sizeof(SQL_NUMERIC_STRUCT)); if (outlen <= 0) item_buf->AssignNULL(); else xConvert2CDB_Numeric((CDB_Numeric*)item_buf, v); break; } case eDB_BigInt: { SQLBIGINT v; outlen = xGetData(SQL_C_SBIGINT, &v, sizeof(SQLBIGINT)); if (outlen <= 0) item_buf->AssignNULL(); else *((CDB_BigInt*) item_buf) = (Int8) v; break; } default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; } case SQL_WLONGVARCHAR: switch(item_buf->GetType()) { #ifdef HAVE_WSTRING case eDB_Text: { if (policy == I_Result::eAssignLOB) { static_cast<CDB_Stream*>(item_buf)->Truncate(); } while (CheckSIENoD_WText((CDB_Stream*)item_buf)) { continue; } break; } #endif case eDB_Image: { if (policy == I_Result::eAssignLOB) { static_cast<CDB_Stream*>(item_buf)->Truncate(); } while (CheckSIENoD_Binary((CDB_Stream*)item_buf)) { continue; } break; } default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; case SQL_LONGVARBINARY: case SQL_LONGVARCHAR: switch(item_buf->GetType()) { case eDB_Text: case eDB_VarCharMax: { if (policy == I_Result::eAssignLOB) { static_cast<CDB_Stream*>(item_buf)->Truncate(); } while (CheckSIENoD_Text((CDB_Stream*)item_buf)) { continue; } break; } case eDB_Image: case eDB_VarBinaryMax: { if (policy == I_Result::eAssignLOB) { static_cast<CDB_Stream*>(item_buf)->Truncate(); } while (CheckSIENoD_Binary((CDB_Stream*)item_buf)) { continue; } break; } default: { string err_message = wrong_type + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430020 ); } } break; default: { string err_message = "Unsupported column type." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430025 ); } } return item_buf; }
CDB_BlobDescriptor* CODBC_RowResult::GetBlobDescriptor(int item_no, const string& cond) { enum {eNameStrLen = 128}; SQLSMALLINT slp; odbc::TSqlChar buffer[eNameStrLen]; switch(SQLColAttribute(GetHandle(), item_no + 1, SQL_DESC_BASE_TABLE_NAME, (SQLPOINTER)buffer, sizeof(buffer), &slp, 0)) { case SQL_SUCCESS_WITH_INFO: ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: ReportErrors(); return 0; default: { string err_message = "SQLColAttribute failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430027 ); } } string base_table = CODBCString(buffer, GetClientEncoding()).ConvertTo(GetClientEncoding()); switch(SQLColAttribute(GetHandle(), item_no + 1, SQL_DESC_BASE_COLUMN_NAME, (SQLPOINTER)buffer, sizeof(buffer), &slp, 0)) { case SQL_SUCCESS_WITH_INFO: ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: ReportErrors(); return 0; default: { string err_message = "SQLColAttribute failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430027 ); } } string base_column = CODBCString(buffer, GetClientEncoding()).ConvertTo(GetClientEncoding()); SQLLEN column_type = 0; switch(SQLColAttribute(GetHandle(), item_no + 1, SQL_COLUMN_TYPE, NULL, sizeof(column_type), &slp, &column_type)) { case SQL_SUCCESS_WITH_INFO: ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: ReportErrors(); return 0; default: { string err_message = "SQLColAttribute failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 430027 ); } } CDB_BlobDescriptor::ETDescriptorType type = CDB_BlobDescriptor::eUnknown; switch (column_type) { case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: type = CDB_BlobDescriptor::eBinary; break; case SQL_LONGVARCHAR: type = CDB_BlobDescriptor::eText; break; }; return new CDB_BlobDescriptor(base_table, base_column, cond, type); }
bool CODBC_RPCCmd::Send() { Cancel(); SetHasFailed(false); m_HasStatus = false; // make a language command string main_exec_query("declare @STpROCrETURNsTATUS int;\nexec @STpROCrETURNsTATUS="); main_exec_query += GetQuery(); string param_result_query; CMemPot bindGuard; string q_str; if(GetBindParamsImpl().NofParams() > 0) { SQLLEN* indicator = (SQLLEN*) bindGuard.Alloc(GetBindParamsImpl().NofParams() * sizeof(SQLLEN)); if (!x_AssignParams(q_str, main_exec_query, param_result_query, bindGuard, indicator)) { ResetParams(); SetHasFailed(); string err_message = "Cannot assign params." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420003 ); } } if(NeedToRecompile()) main_exec_query += " with recompile"; q_str += main_exec_query + ";\nselect STpROCrETURNsTATUS=@STpROCrETURNsTATUS"; if(!param_result_query.empty()) { q_str += ";\nselect " + param_result_query; } switch(SQLExecDirect(GetHandle(), CODBCString(q_str, GetClientEncoding()), SQL_NTS)) { case SQL_SUCCESS: m_HasMoreResults = true; break; case SQL_NO_DATA: m_HasMoreResults = true; /* this is a bug in SQLExecDirect it returns SQL_NO_DATA if status result is the only result of RPC */ m_RowCount = 0; break; case SQL_ERROR: ReportErrors(); ResetParams(); SetHasFailed(); { string err_message = "SQLExecDirect failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420001 ); } case SQL_SUCCESS_WITH_INFO: ReportErrors(); m_HasMoreResults = true; break; case SQL_STILL_EXECUTING: ReportErrors(); ResetParams(); SetHasFailed(); { string err_message = "Some other query is executing on this connection." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420002 ); } case SQL_INVALID_HANDLE: SetHasFailed(); { string err_message = "The statement handler is invalid (memory corruption suspected)." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420004 ); } default: ReportErrors(); ResetParams(); SetHasFailed(); { string err_message = "Unexpected error." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420005 ); } } SetWasSent(); return true; }
bool CODBC_BCPInCmd::x_AssignParams(void* pb) { RETCODE r; if (!m_WasBound) { for (unsigned int i = 0; i < GetBindParamsImpl().NofParams(); ++i) { if (GetBindParamsImpl().GetParamStatus(i) == 0) { r = bcp_bind(GetHandle(), (BYTE*) pb, 0, SQL_VARLEN_DATA, 0, 0, 0, i + 1); } else { CDB_Object& param = *GetBindParamsImpl().GetParam(i); EDB_Type data_type = param.GetType(); r = bcp_bind(GetHandle(), static_cast<LPCBYTE>(const_cast<void*>(x_GetDataPtr(data_type, pb))), 0, static_cast<DBINT>(x_GetBCPDataSize(data_type)), static_cast<LPCBYTE>(x_GetDataTerminator(data_type)), static_cast<INT>(x_GetDataTermSize(data_type)), x_GetBCPDataType(data_type), i + 1); m_HasTextImage = m_HasTextImage || (data_type == eDB_Image || data_type == eDB_Text); } if (r != SUCCEED) { ReportErrors(); return false; } } GetBindParamsImpl().LockBinding(); m_WasBound = true; } for (unsigned int i = 0; i < GetBindParamsImpl().NofParams(); i++) { if (GetBindParamsImpl().GetParamStatus(i) == 0) { r = bcp_collen(GetHandle(), SQL_NULL_DATA, i + 1); } else { CDB_Object& param = *GetBindParamsImpl().GetParam(i); switch ( param.GetType() ) { case eDB_Bit: DATABASE_DRIVER_ERROR("Bit data type is not supported", 10005); break; case eDB_Int: { CDB_Int& val = dynamic_cast<CDB_Int&> (param); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(Int4), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_SmallInt: { CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param); // DBSMALLINT v = (DBSMALLINT) val.Value(); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(Int2), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_TinyInt: { CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param); // DBTINYINT v = (DBTINYINT) val.Value(); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(Uint1), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_BigInt: { CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(Int8), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_Char: case eDB_VarChar: case eDB_LongChar: { CDB_String& val = dynamic_cast<CDB_String&> (param); CTempString data; if (val.IsNULL()) { data.assign(static_cast<char*>(pb), 0); } else { if (IsMultibyteClientEncoding()) { const wstring& ws = val.AsWString(GetClientEncoding()); // hack data.assign((const char*)(ws.data()), ws.size() * sizeof(wchar_t)); } else { data = val.Value(); } } DBINT length; INT dummy; // Can't just supply NULL if (val.IsNULL()) { length = SQL_NULL_DATA; } else if (bcp_getcolfmt(GetHandle(), i + 1, BCP_FMT_DATA_LEN, &length, sizeof(length), &dummy) == FAIL || length < 0) { length = SQL_VARLEN_DATA; // Be conservative. } else if (static_cast<SIZE_TYPE>(length) > data.size()) { // Retain automatic truncation, which blindly supplying // data.size() could lose. length = data.size(); } r = bcp_colptr(GetHandle(), (BYTE*) data.data(), i + 1) == SUCCEED && bcp_collen(GetHandle(), length, i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_Binary: { CDB_Binary& val = dynamic_cast<CDB_Binary&> (param); r = bcp_colptr(GetHandle(), (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : (Int4) val.Size(), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_VarBinary: { CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param); r = bcp_colptr(GetHandle(), (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : (Int4) val.Size(), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_LongBinary: { CDB_LongBinary& val = dynamic_cast<CDB_LongBinary&> (param); r = bcp_colptr(GetHandle(), (!val.IsNULL())? ((BYTE*) val.Value()) : (BYTE*)pb, i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : (Int4) val.DataSize(), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_Float: { CDB_Float& val = dynamic_cast<CDB_Float&> (param); //DBREAL v = (DBREAL) val.Value(); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(float), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_Double: { CDB_Double& val = dynamic_cast<CDB_Double&> (param); //DBFLT8 v = (DBFLT8) val.Value(); r = bcp_colptr(GetHandle(), (BYTE*) val.BindVal(), i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(double), i + 1) == SUCCEED ? SUCCEED : FAIL; } break; case eDB_SmallDateTime: { CDB_SmallDateTime& val = dynamic_cast<CDB_SmallDateTime&> (param); DBDATETIM4* dt = (DBDATETIM4*) pb; DBDATETIME4_days(dt) = val.GetDays(); DBDATETIME4_mins(dt) = val.GetMinutes(); r = bcp_colptr(GetHandle(), (BYTE*) dt, i + 1) == SUCCEED && bcp_collen(GetHandle(), val.IsNULL() ? SQL_NULL_DATA : sizeof(DBDATETIM4), i + 1) == SUCCEED ? SUCCEED : FAIL; pb = (void*) (dt + 1); } break; case eDB_DateTime: { CDB_DateTime& val = dynamic_cast<CDB_DateTime&> (param); DBDATETIME* dt = (DBDATETIME*) pb; if (val.IsNULL()) { r = bcp_colptr(GetHandle(), (BYTE*) dt, i + 1) == SUCCEED && bcp_collen(GetHandle(), SQL_NULL_DATA, i + 1) == SUCCEED ? SUCCEED : FAIL; } else { dt->dtdays = val.GetDays(); dt->dttime = val.Get300Secs(); r = bcp_colptr(GetHandle(), (BYTE*) dt, i + 1) == SUCCEED && bcp_collen(GetHandle(), sizeof(DBDATETIME), i + 1) == SUCCEED ? SUCCEED : FAIL; } pb = (void*) (dt + 1); } break; case eDB_Text: { CDB_Text& val = dynamic_cast<CDB_Text&> (param); if (val.IsNULL()) { r = bcp_colptr(GetHandle(), (BYTE*) pb, i + 1) == SUCCEED && bcp_collen(GetHandle(), SQL_NULL_DATA, i + 1) == SUCCEED ? SUCCEED : FAIL; } else { r = bcp_bind(GetHandle(), (BYTE*) NULL, 0, (DBINT) val.Size(), static_cast<LPCBYTE>(x_GetDataTerminator(eDB_Text)), static_cast<INT>(x_GetDataTermSize(eDB_Text)), x_GetBCPDataType(eDB_Text), i + 1); } } break; case eDB_Image: { CDB_Image& val = dynamic_cast<CDB_Image&> (param); // Null images doesn't work in odbc // (at least in those tests that exists in dbapi_unit_test) r = bcp_collen(GetHandle(), (DBINT) val.Size(), i + 1); } break; default: return false; } } if (r != SUCCEED) { ReportErrors(); return false; } } return true; }