NCBI C++ Toolkit Cross Reference

  C++/src/dbapi/driver/odbc/lang_cmd.cpp


/* $Id: lang_cmd.cpp 63610 2014-07-14 19:00:33Z ucko $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Vladimir Soussov * * File Description: ODBC language command * */ #include <ncbi_pch.hpp> #include <dbapi/driver/odbc/interfaces.hpp> #include <dbapi/error_codes.hpp> #include "odbc_utils.hpp" #include <stdio.h> #define NCBI_USE_ERRCODE_X Dbapi_Odbc_Cmds #undef NCBI_DATABASE_THROW #define NCBI_DATABASE_THROW(ex_class, message, err_code, severity) \ NCBI_ODBC_THROW(ex_class, message, err_code, severity) // No use of NCBI_DATABASE_RETHROW or DATABASE_DRIVER_*_EX here. // Accommodate all the code of the form // string err_message = "..." + GetDbgInfo(); // DATABASE_DRIVER_ERROR(err_message, ...); // which will still pick up the desired context due to // NCBI_DATABASE_THROW's above redefinition. #define GetDbgInfo() 0 BEGIN_NCBI_SCOPE ///////////////////////////////////////////////////////////////////////////// // // CODBC_LangCmd:: // CODBC_LangCmd::CODBC_LangCmd( CODBC_Connection& conn, const string& lang_query ) : CStatementBase(conn, lang_query), m_Res(NULL) { /* This logic is not working for some reason if ( SQLSetStmtAttr(m_Cmd, SQL_ATTR_ROWS_FETCHED_PTR, &m_RowCount, sizeof(m_RowCount)) != SQL_SUCCESS ) { DATABASE_DRIVER_ERROR( "SQLSetStmtAttr failed (memory corruption suspected)", 420014 ); } */ SetDbgInfo("SQL Command: \"" + lang_query + "\""); } bool CODBC_LangCmd::Send(void) { Cancel(); SetHasFailed(false); CMemPot bindGuard; string q_str; if(GetBindParamsImpl().NofParams() > 0) { SQLLEN* indicator = (SQLLEN*) bindGuard.Alloc(GetBindParamsImpl().NofParams() * sizeof(SQLLEN)); if (!x_AssignParams(q_str, bindGuard, indicator)) { ResetParams(); SetHasFailed(); string err_message = "Cannot assign params." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420003 ); } } const string* real_query; if(!q_str.empty()) { q_str.append(GetQuery()); real_query = &q_str; } else { real_query = &GetQuery(); } TSqlString ss = x_MakeTSqlString(*real_query, GetClientEncoding()); switch (SQLExecDirect(GetHandle(), const_cast<TSqlChar*>(ss.data()), ss.size())) { // switch(SQLExecDirect(GetHandle(), tchar_str, odbc_str.GetSymbolNum())) { case SQL_SUCCESS: m_HasMoreResults = true; break; case SQL_NO_DATA: m_HasMoreResults = false; 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(true); return true; } bool CODBC_LangCmd::Cancel() { if (WasSent()) { if (m_Res) { delete m_Res; m_Res = 0; } SetWasSent(false); if ( !Close() ) { return false; } ResetParams(); // GetQuery().erase(); } return true; } CDB_Result* CODBC_LangCmd::Result() { if (m_Res) { delete m_Res; m_Res = 0; m_HasMoreResults = xCheck4MoreResults(); } if ( !WasSent() ) { string err_message = "A command has to be sent first." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420010 ); } if(!m_HasMoreResults) { SetWasSent(false); return 0; } SQLSMALLINT nof_cols= 0; while(m_HasMoreResults) { CheckSIE(SQLNumResultCols(GetHandle(), &nof_cols), "SQLNumResultCols failed", 420011); if(nof_cols < 1) { // no data in this result set SQLLEN rc; CheckSIE(SQLRowCount(GetHandle(), &rc), "SQLRowCount failed", 420013); m_RowCount = rc; m_HasMoreResults = xCheck4MoreResults(); continue; } m_Res = new CODBC_RowResult(*this, nof_cols, &m_RowCount); return Create_Result(*m_Res); } SetWasSent(false); return 0; } bool CODBC_LangCmd::HasMoreResults() const { return m_HasMoreResults; } int CODBC_LangCmd::RowCount() const { return static_cast<int>(m_RowCount); } CODBC_LangCmd::~CODBC_LangCmd() { try { DetachInterface(); GetConnection().DropCmd(*this); Cancel(); } NCBI_CATCH_ALL_X( 4, NCBI_CURRENT_FUNCTION ) } bool CODBC_LangCmd::x_AssignParams(string& cmd, CMemPot& bind_guard, SQLLEN* indicator) { for (unsigned int n = 0; n < GetBindParamsImpl().NofParams(); ++n) { if(GetBindParamsImpl().GetParamStatus(n) == 0) continue; const string& name = GetBindParamsImpl().GetParamName(n); if (name.empty()) { DATABASE_DRIVER_ERROR( "Binding by position is not supported." + GetDbgInfo(), 420110 ); } const CDB_Object& param = *GetBindParamsImpl().GetParam(n); const string type = Type2String(param); if (!x_BindParam_ODBC(param, bind_guard, indicator, n)) { return false; } cmd += "declare " + name + ' ' + type + ";select " + name + " = ?;"; if(param.IsNULL()) { indicator[n] = SQL_NULL_DATA; } } GetBindParamsImpl().LockBinding(); return true; } bool CODBC_LangCmd::xCheck4MoreResults() { // int rc = CheckSIE(SQLMoreResults(GetHandle()), "SQLBindParameter failed", 420066); // // return (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS); switch(SQLMoreResults(GetHandle())) { case SQL_SUCCESS_WITH_INFO: ReportErrors(); case SQL_SUCCESS: return true; case SQL_NO_DATA: return false; case SQL_ERROR: { ReportErrors(); string err_message = "SQLMoreResults failed." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420014 ); } default: { string err_message = "SQLMoreResults failed (memory corruption suspected)." + GetDbgInfo(); DATABASE_DRIVER_ERROR( err_message, 420015 ); } } } void CODBC_LangCmd::SetCursorName(const string& name) const { // Set statement attributes so server-side cursor is generated // The default ODBC cursor attributes are: // SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_FORWARD_ONLY); // SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY, SQL_CONCUR_READ_ONLY); // SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE, 1); // CheckSIE(SQLSetStmtAttr(GetHandle(), SQL_ROWSET_SIZE, (void*)2, SQL_NTS), // "SQLSetStmtAttr(SQL_ROWSET_SIZE) failed", 420015); CheckSIE(SQLSetStmtAttr(GetHandle(), SQL_ATTR_CONCURRENCY, (void*)SQL_CONCUR_VALUES, SQL_NTS), "SQLSetStmtAttr(SQL_ATTR_CONCURRENCY) failed", 420017); CheckSIE(SQLSetStmtAttr(GetHandle(), SQL_ATTR_CURSOR_TYPE, (void*)SQL_CURSOR_FORWARD_ONLY, SQL_NTS), "SQLSetStmtAttr(SQL_ATTR_CURSOR_TYPE) failed", 420018); TSqlString ss = x_MakeTSqlString(name, GetClientEncoding()); CheckSIE(SQLSetCursorName(GetHandle(), const_cast<TSqlChar*>(ss.data()), static_cast<SQLSMALLINT>(ss.size())), "SQLSetCursorName failed", 420016); } bool CODBC_LangCmd::CloseCursor(void) { bool result = true; try { CheckSIE(SQLCloseCursor(GetHandle()), "SQLCloseCursor failed", 420017); } catch (...) { result = false; } return result; } END_NCBI_SCOPE

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.