📄 rpc.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: rpc.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 19:21:56 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9 * PRODUCTION * =========================================================================== *//* $Id: rpc.cpp,v 1000.3 2004/06/01 19:21:56 gouriano Exp $ * =========================================================================== * * 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 RPC command * */ #include <ncbi_pch.hpp>#include <dbapi/driver/odbc/interfaces.hpp>#include <dbapi/driver/util/numeric_convert.hpp>#include <stdio.h>BEGIN_NCBI_SCOPE///////////////////////////////////////////////////////////////////////////////// CODBC_RPCCmd:://CODBC_RPCCmd::CODBC_RPCCmd(CODBC_Connection* con, SQLHSTMT cmd, const string& proc_name, unsigned int nof_params) : m_Connect(con), m_Cmd(cmd), m_Query(proc_name), m_Params(nof_params), m_WasSent(false), m_HasFailed(false), m_Recompile(false), m_Res(0), m_RowCount(-1), m_Reporter(&con->m_MsgHandlers, SQL_HANDLE_STMT, cmd){ return;}bool CODBC_RPCCmd::BindParam(const string& param_name, CDB_Object* param_ptr, bool out_param){ return m_Params.BindParam(CDB_Params::kNoParamNumber, param_name, param_ptr, out_param);}bool CODBC_RPCCmd::SetParam(const string& param_name, CDB_Object* param_ptr, bool out_param){ return m_Params.SetParam(CDB_Params::kNoParamNumber, param_name, param_ptr, out_param);}bool CODBC_RPCCmd::Send(){ if (m_WasSent) Cancel(); m_HasFailed = false; m_HasStatus = false; // make a language command string main_exec_query("declare @STpROCrETURNsTATUS int;\nexec @STpROCrETURNsTATUS="); main_exec_query+= m_Query; string param_result_query; CMemPot bindGuard; string q_str; if(m_Params.NofParams() > 0) { SQLINTEGER* indicator= (SQLINTEGER*) bindGuard.Alloc(m_Params.NofParams()*sizeof(SQLINTEGER)); if (!x_AssignParams(q_str, main_exec_query, param_result_query, bindGuard, indicator)) { SQLFreeStmt(m_Cmd, SQL_RESET_PARAMS); m_HasFailed = true; throw CDB_ClientEx(eDB_Error, 420003, "CODBC_RPCCmd::Send", "cannot assign params"); } } if(m_Recompile) 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(m_Cmd, (SQLCHAR*)q_str.c_str(), SQL_NTS)) { case SQL_SUCCESS: m_hasResults= true; break; case SQL_NO_DATA: m_hasResults= 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: m_Reporter.ReportErrors(); SQLFreeStmt(m_Cmd, SQL_RESET_PARAMS); m_HasFailed = true; throw CDB_ClientEx(eDB_Fatal, 420001, "CODBC_RPCCmd::Send", "SQLExecDirect failed"); case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); m_hasResults= true; break; case SQL_STILL_EXECUTING: m_Reporter.ReportErrors(); SQLFreeStmt(m_Cmd, SQL_RESET_PARAMS); m_HasFailed = true; throw CDB_ClientEx(eDB_Fatal, 420002, "CODBC_RPCCmd::Send", "Some other query is executing on this connection"); case SQL_INVALID_HANDLE: m_HasFailed= true; throw CDB_ClientEx(eDB_Fatal, 420004, "CODBC_RPCCmd::Send", "The statement handler is invalid (memory corruption suspected)"); default: m_Reporter.ReportErrors(); SQLFreeStmt(m_Cmd, SQL_RESET_PARAMS); m_HasFailed = true; throw CDB_ClientEx(eDB_Fatal, 420005, "CODBC_RPCCmd::Send", "Unexpected error"); } m_WasSent = true; return true;}bool CODBC_RPCCmd::WasSent() const{ return m_WasSent;}bool CODBC_RPCCmd::Cancel(){ if (m_WasSent) { if (m_Res) { delete m_Res; m_Res = 0; } m_WasSent = false; switch(SQLFreeStmt(m_Cmd, SQL_CLOSE)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: m_Reporter.ReportErrors(); default: return false; } } SQLFreeStmt(m_Cmd, SQL_RESET_PARAMS); m_Query.erase(); return true;}bool CODBC_RPCCmd::WasCanceled() const{ return !m_WasSent;}CDB_Result* CODBC_RPCCmd::Result(){ if (m_Res) { delete m_Res; m_Res = 0; m_hasResults= xCheck4MoreResults(); } if (!m_WasSent) { throw CDB_ClientEx(eDB_Error, 420010, "CODBC_RPCCmd::Result", "a command has to be sent first"); } if(!m_hasResults) { m_WasSent= false; return 0; } SQLSMALLINT nof_cols= 0; char n_buff[64]; while(m_hasResults) { switch(SQLNumResultCols(m_Cmd, &nof_cols)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: m_Reporter.ReportErrors(); throw CDB_ClientEx(eDB_Error, 420011, "CODBC_RPCCmd::Result", "SQLNumResultCols failed"); default: throw CDB_ClientEx(eDB_Error, 420012, "CODBC_RPCCmd::Result", "SQLNumResultCols failed (memory corruption suspected)"); } if(nof_cols < 1) { // no data in this result set SQLINTEGER rc; switch(SQLRowCount(m_Cmd, &rc)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: m_Reporter.ReportErrors(); throw CDB_ClientEx(eDB_Error, 420013, "CODBC_RPCCmd::Result", "SQLRowCount failed"); default: throw CDB_ClientEx(eDB_Error, 420014, "CODBC_RPCCmd::Result", "SQLRowCount failed (memory corruption suspected)"); } m_RowCount = rc; m_hasResults= xCheck4MoreResults(); continue; } if(nof_cols == 1) { // it could be a status result SQLSMALLINT l; switch(SQLColAttribute(m_Cmd, 1, SQL_DESC_LABEL, n_buff, 64, &l, 0)) { case SQL_SUCCESS_WITH_INFO: m_Reporter.ReportErrors(); case SQL_SUCCESS: break; case SQL_ERROR: m_Reporter.ReportErrors(); throw CDB_ClientEx(eDB_Error, 420015, "CODBC_RPCCmd::Result", "SQLColAttribute failed"); default: throw CDB_ClientEx(eDB_Error, 420016, "CODBC_RPCCmd::Result", "SQLColAttribute failed (memory corruption suspected)"); } if(strcmp(n_buff, "STpROCrETURNsTATUS") == 0) {//this is a status result m_HasStatus= true; m_Res= new CODBC_StatusResult(m_Cmd, m_Reporter); } } if(!m_Res) { if(m_HasStatus) { m_HasStatus= false; m_Res= new CODBC_ParamResult(nof_cols, m_Cmd, m_Reporter); } else { m_Res = new CODBC_RowResult(nof_cols, m_Cmd, m_Reporter); } } return Create_Result(*m_Res); } m_WasSent = false; return 0;}bool CODBC_RPCCmd::HasMoreResults() const{ return m_hasResults;}void CODBC_RPCCmd::DumpResults(){ CDB_Result* dbres; while(m_WasSent) { dbres= Result(); if(dbres) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -