bool CTL_BCPInCmd::Cancel() { #ifndef FTDS_IN_USE DATABASE_DRIVER_ERROR("Cancelling is not available in ctlib.", 125000); #endif if(WasSent()) { if (IsDead()) { SetWasSent(false); return true; } CS_INT outrow = 0; size_t was_timeout = GetConnection().PrepareToCancel(); try { bool result = (CheckSentSFB(blk_done(x_GetSybaseCmd(), CS_BLK_CANCEL, &outrow), "blk_done failed", 123020) == CS_SUCCEED); GetConnection().CancelFinished(was_timeout); return result; } catch (CDB_Exception&) { GetConnection().CancelFinished(was_timeout); throw; } } return true; }
bool CTL_RowResult::Fetch() { SetCurrentItemNum(-1); if ( m_EOR ) { return false; } // Reset NullValue flags ... for (unsigned int nof_items = 0; nof_items < GetDefineParams().GetNum(); ++nof_items) { m_NullValue[nof_items] = eNullUnknown; } CheckIsDead(); switch ( Check(ct_fetch(x_GetSybaseCmd(), CS_UNUSED, CS_UNUSED, CS_UNUSED, 0)) ) { case CS_SUCCEED: SetCurrentItemNum(0); return true; case CS_END_DATA: m_EOR = true; return false; case CS_ROW_FAIL: DATABASE_DRIVER_ERROR( "Error while fetching the row." + GetDbgInfo(), 130003 ); case CS_FAIL: DATABASE_DRIVER_ERROR("ct_fetch has failed. " "You need to cancel the command." + GetDbgInfo(), 130006 ); case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "The connection is busy." + GetDbgInfo(), 130005 ); } }
void CTL_BCPInCmd::SetHints(CTempString hints) { #ifdef FTDS_IN_USE m_Hints.clear(); if (Check(blk_sethints(x_GetSybaseCmd(), (CS_CHAR*)hints.data(), CS_INT(hints.size()))) == CS_FAIL) { DATABASE_DRIVER_ERROR("blk_sethints failed." + GetDbgInfo(), 123018); } #else _ASSERT(false); #endif }
void CTL_RowResult::Close(void) { if (x_GetSybaseCmd()) { if (m_EOR || IsDead()) { return; } switch (Check(ct_cancel(NULL, x_GetSybaseCmd(), CS_CANCEL_CURRENT))) { case CS_SUCCEED: case CS_CANCELED: break; default: CS_INT err_code = 130007; Check(ct_cmd_props(x_GetSybaseCmd(), CS_SET, CS_USERDATA, &err_code, (CS_INT) sizeof(err_code), 0)); } m_Cmd = NULL; } }
CTL_CursorResult::~CTL_CursorResult() { try { if (m_EOR && !IsDead()) { // this is not a bug CS_INT res_type; while (Check(ct_results(x_GetSybaseCmd(), &res_type)) == CS_SUCCEED) { continue; } } else m_EOR= true; // to prevent ct_cancel call (close cursor will do a job) } NCBI_CATCH_ALL_X( 2, NCBI_CURRENT_FUNCTION ) }
void CTL_BCPInCmd::x_BlkSetHints(void) { #ifdef FTDS_IN_USE string hints; ITERATE(THintsMap, it, m_Hints) { if (!hints.empty()) hints += ","; hints += it->second; } if (Check(blk_sethints(x_GetSybaseCmd(), (CS_CHAR*)hints.data(), CS_INT(hints.size()))) == CS_FAIL) { DATABASE_DRIVER_ERROR("blk_sethints failed." + GetDbgInfo(), 123019); } #endif }
I_ITDescriptor* CTL_RowResult::GetImageOrTextDescriptor(int item_num) { bool is_null = false; if ((unsigned int) item_num >= GetDefineParams().GetNum() || item_num < 0) { return 0; } char dummy[4]; CS_INT outlen = 0; switch (my_ct_get_data(x_GetSybaseCmd(), item_num + 1, dummy, 0, &outlen, is_null) ) { case CS_END_ITEM: case CS_END_DATA: case CS_SUCCEED: break; case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } if (is_null) m_NullValue[item_num] = eIsNull; auto_ptr<CTL_ITDescriptor> desc(new CTL_ITDescriptor); bool rc = (Check(ct_data_info(x_GetSybaseCmd(), CS_GET, item_num + 1, &desc->m_Desc)) != CS_SUCCEED); CHECK_DRIVER_ERROR( rc, "ct_data_info failed." + GetDbgInfo(), 130010 ); return desc.release(); }
CTL_BCPInCmd::~CTL_BCPInCmd() { try { DetachInterface(); DropCmd(*this); Close(); if (!IsDead()) { Check(blk_drop(x_GetSybaseCmd())); } } NCBI_CATCH_ALL_X( 1, NCBI_CURRENT_FUNCTION ) }
bool CTL_BCPInCmd::EndBCP(void) { if(!WasSent()) return false; CheckIsDead(); CS_INT outrow = 0; if (CheckSentSFB(blk_done(x_GetSybaseCmd(), CS_BLK_ALL, &outrow), "blk_done failed", 123020) == CS_SUCCEED) { return (outrow > 0); } return false; }
CDB_Object* CTL_RowResult::GetItem(CDB_Object* item_buf, I_Result::EGetItem policy) { if ((unsigned int) CurrentItemNo() >= GetDefineParams().GetNum() || CurrentItemNo() == -1) { return 0; } CDB_Object* item = GetItemInternal( policy, x_GetSybaseCmd(), CurrentItemNo() + 1, m_ColFmt[CurrentItemNo()], item_buf); IncCurrentItemNum(); return item; }
bool CTL_BCPInCmd::CommitBCPTrans(void) { if(!WasSent()) return false; CheckIsDead(); CS_INT outrow = 0; switch( Check(blk_done(x_GetSybaseCmd(), CS_BLK_BATCH, &outrow)) ) { case CS_SUCCEED: return (outrow > 0); case CS_FAIL: SetHasFailed(); DATABASE_DRIVER_ERROR( "blk_done failed." + GetDbgInfo(), 123020 ); default: return false; } }
void CTL_BCPInCmd::Close(void) { if (x_GetSybaseCmd()) { // ???? DetachInterface(); try { #ifdef FTDS_IN_USE SetDead(!Cancel()); #else if (WasSent()) { SetDead(!EndBCP()); } #endif } catch (...) { SetDead(); throw; } } }
bool CTL_CursorResult::SkipItem() { if (GetCurrentItemNum() < (int) GetDefineParams().GetNum()) { IncCurrentItemNum(); char dummy[4]; bool is_null = false; switch ( my_ct_get_data(x_GetSybaseCmd(), GetCurrentItemNum(), dummy, 0, 0, is_null) ) { case CS_END_ITEM: case CS_END_DATA: case CS_SUCCEED: break; case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } return true; } return false; }
bool CTL_BCPInCmd::Send(void) { unsigned int i; CS_INT datalen = 0; size_t len = 0; char buff[2048]; CheckIsDead(); if ( !WasSent() ) { // we need to init the bcp CheckSFB(blk_init(x_GetSybaseCmd(), CS_BLK_IN, (CS_CHAR*) GetQuery().data(), GetQuery().size()), "blk_init failed", 123001); SetWasSent(); // check what needs to be default CS_DATAFMT fmt; for (i = 0; i < GetBindParamsImpl().NofParams(); i++) { if (GetBindParamsImpl().GetParamStatus(i) != 0) { continue; } SetHasFailed((Check(blk_describe(x_GetSybaseCmd(), i + 1, &fmt)) != CS_SUCCEED)); CHECK_DRIVER_ERROR( HasFailed(), "blk_describe failed (check the number of " "columns in a table)." + GetDbgInfo(), 123002 ); } } SetHasFailed(!x_AssignParams()); CHECK_DRIVER_ERROR( HasFailed(), "Cannot assign the params." + GetDbgInfo(), 123004 ); switch ( Check(blk_rowxfer(x_GetSybaseCmd())) ) { case CS_BLK_HAS_TEXT: for (i = 0; i < GetBindParamsImpl().NofParams(); i++) { if (GetBindParamsImpl().GetParamStatus(i) == 0) continue; CDB_Object& param = *GetBindParamsImpl().GetParam(i); if (param.IsNULL()) { continue; } else if (param.GetType() == eDB_Text || param.GetType() == eDB_Image) { CDB_Stream& par = dynamic_cast<CDB_Stream&> (param); for (datalen = (CS_INT) par.Size(); datalen > 0; datalen -= (CS_INT) len) { len = par.Read(buff, sizeof(buff)); SetHasFailed((Check(blk_textxfer(x_GetSybaseCmd(), (CS_BYTE*) buff, (CS_INT) len, 0) ) == CS_FAIL)); CHECK_DRIVER_ERROR( HasFailed(), "blk_textxfer failed for the text/image field." + GetDbgInfo(), 123005 ); } } } case CS_SUCCEED: ++m_RowCount; return true; default: SetHasFailed(); CHECK_DRIVER_ERROR( HasFailed(), "blk_rowxfer failed." + GetDbgInfo(), 123007 ); } return false; }
CTL_RowResult::CTL_RowResult(CS_COMMAND* cmd, CTL_Connection& conn) : m_Connect(&conn), m_Cmd(cmd), m_CurrItem(-1), m_EOR(false), m_BindedCols(0) { CheckIsDead(); CS_INT outlen; CS_INT nof_cols; bool rc = (Check(ct_res_info(x_GetSybaseCmd(), CS_NUMDATA, &nof_cols, CS_UNUSED, &outlen)) != CS_SUCCEED); CHECK_DRIVER_ERROR( rc, "ct_res_info(CS_NUMDATA) failed." + GetDbgInfo(), 130001 ); CS_INT bind_len = 0; m_BindedCols = 0; bool buff_is_full = false; m_ColFmt = AutoArray<CS_DATAFMT>(nof_cols); m_NullValue = AutoArray<ENullValue>(nof_cols); for (unsigned int nof_item = 0; nof_item < (unsigned int) nof_cols; nof_item++) { rc = (Check(ct_describe(x_GetSybaseCmd(), (CS_INT) nof_item + 1, &m_ColFmt[nof_item])) != CS_SUCCEED); CHECK_DRIVER_ERROR( rc, "ct_describe failed." + GetDbgInfo(), 130002 ); m_NullValue[nof_item] = eNullUnknown; #ifdef FTDS_IN_USE // Seems like FreeTDS reports wrong maxlength in // ct_describe() - fix this when binding to a buffer. if (m_ColFmt[nof_item].datatype == CS_NUMERIC_TYPE || m_ColFmt[nof_item].datatype == CS_DECIMAL_TYPE ) { m_ColFmt[nof_item].maxlength = sizeof(CS_NUMERIC); } #endif m_CachedRowInfo.Add( string(m_ColFmt[nof_item].name, m_ColFmt[nof_item].namelen), m_ColFmt[nof_item].maxlength, ConvDataType_Ctlib2DBAPI(m_ColFmt[nof_item]) ); if (!buff_is_full) { if (m_ColFmt[nof_item].maxlength > 2048 || m_ColFmt[nof_item].datatype == CS_IMAGE_TYPE) { buff_is_full = true; } else { bind_len += m_ColFmt[nof_item].maxlength; if (bind_len <= 2048) { m_BindedCols++; } else { buff_is_full = true; } } } } if(m_BindedCols) { m_BindItem = AutoArray<CS_VOID*>(m_BindedCols); m_Copied = AutoArray<CS_INT>(m_BindedCols); m_Indicator = AutoArray<CS_SMALLINT>(m_BindedCols); for(int i= 0; i < m_BindedCols; i++) { m_BindItem[i] = (i ? ((unsigned char*)(m_BindItem[i-1])) + m_ColFmt[i-1].maxlength : m_BindBuff); rc = (Check(ct_bind(x_GetSybaseCmd(), i+1, &m_ColFmt[i], m_BindItem[i], &m_Copied[i], &m_Indicator[i]) ) != CS_SUCCEED); CHECK_DRIVER_ERROR( rc, "ct_bind failed." + GetDbgInfo(), 130042 ); } } }
size_t CTL_RowResult::ReadItem(void* buffer, size_t buffer_size, bool* is_null) { if ((unsigned int) CurrentItemNo() >= GetDefineParams().GetNum() || CurrentItemNo() == -1) { return 0; } if (m_NullValue[GetCurrentItemNum()] == eIsNull) { if (is_null) *is_null = true; IncCurrentItemNum(); return 0; } CS_INT outlen = 0; if((buffer == 0) && (buffer_size == 0)) { buffer= (void*)(&buffer_size); } bool is_null_tmp; const CS_RETCODE rc = my_ct_get_data( x_GetSybaseCmd(), GetCurrentItemNum() + 1, buffer, (CS_INT) buffer_size, &outlen, is_null_tmp ); switch (rc) { case CS_END_ITEM: // This is not the last column in the row. case CS_END_DATA: // This is the last column in the row. if (m_NullValue[GetCurrentItemNum()] == eNullUnknown) { m_NullValue[GetCurrentItemNum()] = (is_null_tmp ? eIsNull : eIsNotNull); } if (is_null) { if (m_NullValue[GetCurrentItemNum()] != eNullUnknown) { *is_null = (m_NullValue[GetCurrentItemNum()] == eIsNull); } else { *is_null = (outlen == 0); } } #ifdef FTDS_IN_USE if (rc == CS_END_ITEM) { IncCurrentItemNum(); } #else IncCurrentItemNum(); // That won't work with the ftds64 driver #endif break; case CS_SUCCEED: // ct_get_data successfully retrieved a chunk of data that is // not the last chunk of data for this column. break; case CS_CANCELED: DATABASE_DRIVER_ERROR( "The command has been canceled." + GetDbgInfo(), 130004 ); default: DATABASE_DRIVER_ERROR( "ct_get_data failed." + GetDbgInfo(), 130000 ); } return (size_t) outlen; }