connection_cli.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:14k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: connection_cli.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:21:06  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: connection_cli.cpp,v 1000.1 2004/06/01 19:21:06 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Victor Sapojnikov
  35.  *
  36.  * File Description:
  37.  *   A comprot client proxies for remote I_Connection objects (CGW_Connection)
  38.  *   and internal gateway functions/classes (sendITDescriptor, C_GWLib_TextImageCallback,
  39.  *   C_GWLib_ObjectGetter).
  40.  *
  41.  */
  42. #include <ncbi_pch.hpp>
  43. #include <dbapi/driver/gateway/internal_cli.hpp>
  44. BEGIN_NCBI_SCOPE
  45. /////////////////////////////////////////////////////////////////////////////
  46. //
  47. //  CGWContext::
  48. //
  49. CDB_Connection* CGWContext::Connect(
  50.   const string& srv_name, const string& user_name, const string& passwd,
  51.   TConnectionMode mode, bool reusable, const string&   pool_name)
  52. {
  53.   IGate* pGate = conn->getProtocol();
  54.   pGate->set_RPC_call  ( "GWLib:Context:Connect" );
  55.   pGate->set_output_arg( "object"   , &remoteObj   );
  56.   pGate->set_output_arg( "srv_name" , srv_name .c_str() );
  57.   pGate->set_output_arg( "user_name", user_name.c_str() );
  58.   pGate->set_output_arg( "passwd"   , passwd   .c_str() );
  59.   pGate->set_output_arg( "mode"     , (int*)&mode       );
  60.   int iReusable = (int)reusable;
  61.   pGate->set_output_arg( "reusable" , &iReusable   );
  62.   pGate->set_output_arg( "pool_name", pool_name.c_str() );
  63.   pGate->send_data();
  64.   // cerr << "CGWContext::Connectn";
  65.   int res;
  66.   if( pGate->get_input_arg("result", &res) != IGate::eGood ) {
  67.     comprot_errmsg();
  68.     return NULL;
  69.   }
  70.   if(res) {
  71.     CGW_Connection* p = new CGW_Connection(this,res);
  72.     return Create_Connection( *p );
  73.   }
  74.   else{
  75.     return NULL;
  76.   }
  77. }
  78. CDB_RPCCmd* CGW_Connection::RPC( const string&  rpc_name, unsigned int nof_args )
  79. {
  80.   int cmdObj = comprot_int2(
  81.     "GWLib:Connection:RPC", remoteObj,
  82.     "rpc_name", rpc_name.c_str(),
  83.     "nof_args", (int*)&nof_args);
  84.   if(cmdObj) {
  85.     CGW_RPCCmd* p = new CGW_RPCCmd(this, cmdObj);
  86.     return Create_RPCCmd( *p );
  87.   }
  88.   else{
  89.     return NULL;
  90.   }
  91. }
  92. CDB_LangCmd* CGW_Connection::LangCmd( const string& lang_query, unsigned int nof_params)
  93. {
  94.   int cmdObj = comprot_int2(
  95.     "GWLib:Connection:LangCmd", remoteObj,
  96.     "lang_query", lang_query.c_str(),
  97.     "nof_params", (int*)&nof_params);
  98.   if(cmdObj) {
  99.     CGW_LangCmd* p = new CGW_LangCmd(this, cmdObj);
  100.     return Create_LangCmd( *p );
  101.   }
  102.   else{
  103.     return NULL;
  104.   }
  105. }
  106. CDB_BCPInCmd* CGW_Connection::BCPIn(const string&  table_name, unsigned int   nof_columns)
  107. {
  108.   int cmdObj = comprot_int2(
  109.     "GWLib:Connection:BCPIn", remoteObj,
  110.     "table_name", table_name.c_str(),
  111.     "nof_columns", (int*)&nof_columns);
  112.   if(cmdObj) {
  113.     CGW_BCPInCmd* p = new CGW_BCPInCmd(this, cmdObj);
  114.     return Create_BCPInCmd( *p );
  115.   }
  116.   else{
  117.     return NULL;
  118.   }
  119. }
  120. CDB_CursorCmd* CGW_Connection::Cursor( const string& cursor_name, const string& query,
  121.   unsigned int nof_params, unsigned int batch_size)
  122. {
  123.   IGate* pGate = conn->getProtocol();
  124.   pGate->set_RPC_call  ( "GWLib:Connection:Cursor" );
  125.   pGate->set_output_arg( "object"     , &remoteObj          );
  126.   pGate->set_output_arg( "cursor_name", cursor_name.c_str() );
  127.   pGate->set_output_arg( "query"      , query.c_str()       );
  128.   pGate->set_output_arg( "nof_params" , (int*)&nof_params   );
  129.   pGate->set_output_arg( "batch_size" , (int*)&batch_size   );
  130.   pGate->send_data();
  131.   int res;
  132.   if( pGate->get_input_arg("result", &res) != IGate::eGood ) {
  133.     comprot_errmsg();
  134.     return NULL;
  135.   }
  136.   if(res) {
  137.     CGW_CursorCmd* p = new CGW_CursorCmd(this,res);
  138.     return Create_CursorCmd( *p );
  139.   }
  140.   else{
  141.     return NULL;
  142.   }
  143. }
  144. bool sendITDescriptor(IGate* pGate, I_ITDescriptor& desc)
  145. {
  146.   int i = 0;
  147.   CGW_ITDescriptor* gwDesc = dynamic_cast<CGW_ITDescriptor*>(&desc);
  148.   if(gwDesc==NULL) {
  149.     CDB_ITDescriptor* cdbDesc = dynamic_cast<CDB_ITDescriptor*>(&desc);
  150.     if(cdbDesc==NULL) {
  151.       cerr << "Error: dynamic_cast(s)<CGW/CDB_ITDescriptor*> both return NULLn";
  152.       return false;
  153.     }
  154.     else {
  155.       pGate->set_output_arg( "desc_table" , cdbDesc->TableName       ().c_str() );
  156.       pGate->set_output_arg( "desc_column", cdbDesc->ColumnName      ().c_str() );
  157.       pGate->set_output_arg( "desc_where" , cdbDesc->SearchConditions().c_str() );
  158.     }
  159.   }
  160.   else {
  161.     i = gwDesc->getRemoteObj();
  162.   }
  163.   pGate->set_output_arg( "desc", &i );
  164.   pGate->send_data();
  165.   return true;
  166. }
  167. CDB_SendDataCmd* CGW_Connection::SendDataCmd(
  168.   I_ITDescriptor& desc, size_t data_size, bool log_it)
  169. {
  170.   IGate* pGate = conn->getProtocol();
  171.   pGate->set_RPC_call  ( "GWLib:Connection:SendDataCmd" );
  172.   pGate->set_output_arg( "object"    , &remoteObj       );
  173.   pGate->set_output_arg( "data_size" , (int*)&data_size );
  174.   pGate->set_output_arg( "log_it"    , (int*)&log_it    );
  175.   if( !sendITDescriptor(pGate, desc) ) return NULL; // invokes pGate->send_data();
  176.   int res;
  177.   if( pGate->get_input_arg("result", &res) != IGate::eGood ) {
  178.     comprot_errmsg();
  179.     return NULL;
  180.   }
  181.   if(res) {
  182.     CGW_SendDataCmd* p = new CGW_SendDataCmd(this,res);
  183.     return Create_SendDataCmd( *p );
  184.   }
  185.   else{
  186.     return NULL;
  187.   }
  188. }
  189. void C_GWLib_TextImageCallback::exec(IGate* pGate)
  190. {
  191.   SContext* pContext = (SContext*) pGate->get_user_data();
  192.   CDB_Stream* pStream; //= pContext->pStream;
  193.   int i=0;
  194.   if( pGate->get_input_arg( "cmd", &i ) != IGate::eGood  ) {
  195.     cerr << "  cannot get_input_arg("cmd")n";
  196.     pContext->bError = true;
  197.     const char* pchAnswer;
  198.     unsigned sz;
  199.     if( pGate->get_input_arg("Error", &pchAnswer, &sz) == IGate::eGood ) {
  200.       cerr << "  C_GWLib_TextImageCallback::exec comprot_errmsg=" << pchAnswer << "n";
  201.     }
  202.     else {
  203.       cerr << "  C_GWLib_TextImageCallback::exec comprot_errmsg - no Error message from servern";
  204.     }
  205.     pGate->send_cancel();
  206.     return;
  207.   }
  208.   void* mem = 0;
  209.   switch(i){
  210.     case CDB_Stream_Read: // void* buff, size_t nof_bytes
  211.     {
  212.       if( pGate->get_input_arg( "nof_bytes", &i          ) != IGate::eGood || i<0 ||
  213.           pGate->get_input_arg( "object", (int*)&pStream ) != IGate::eGood || pStream==NULL )
  214.       {
  215.         pGate->send_cancel();
  216.         pContext->bError = true;
  217.         return;
  218.       }
  219.       mem = new char[i+1];
  220.       size_t sz = pStream->Read(mem,i);
  221.       if( sz>i ) {
  222.         // Probably, an error flag
  223.         string sTmp = NStr::IntToString(sz);
  224.         pGate->send_message( 0, "CGW_Stream:Read_", sTmp.c_str(), sTmp.size()+1  );
  225.       }
  226.       else{
  227.         pGate->send_message( 0, "CGW_Stream:Read" , (const char*)mem, sz );
  228.       }
  229.     }
  230.     break;
  231.     case 0: // server function finished
  232.       if( pGate->get_input_arg( "result", &i ) != IGate::eGood  ) {
  233.         pContext->bError = true;
  234.         pGate->send_cancel();
  235.         return;
  236.       }
  237.       pContext->result=i;
  238.       break;
  239.     default:
  240.       pContext->bError = true;
  241.       pGate->send_cancel();
  242.       return;
  243.   }
  244.   pGate->send_done();
  245.   if(mem) {
  246.     delete mem;
  247.   }
  248. }
  249. bool CGW_Connection::xSendData(I_ITDescriptor& desc, CDB_Stream* data, bool log_it)
  250. {
  251.   IGate* pGate = conn->getProtocol();
  252.   void* pOldUserData = pGate->get_user_data();
  253.   C_GWLib_TextImageCallback::SContext callback_args; //(data);
  254.   pGate->set_user_data((void*)&callback_args);
  255.   pGate->set_RPC_call  ( "GWLib:Connection:SendData" );
  256.   pGate->set_output_arg( "object"    , &remoteObj    );
  257.   int type = (int)data->GetType();
  258.   int sz   = (int)data->Size();
  259.   pGate->set_output_arg( "type", &type);
  260.   pGate->set_output_arg( "size", &sz);
  261.   pGate->set_output_arg( "stream", (int*)&data);
  262.   pGate->set_output_arg( "log_it"    , (int*)&log_it    );
  263.   if( !sendITDescriptor(pGate, desc) ) return NULL; // invokes pGate->send_data();
  264.   int res;
  265.   if( pGate->get_input_arg("result", &res) != IGate::eGood ) {
  266.     comprot_errmsg();
  267.     return false;
  268.   }
  269.   pGate->set_user_data(pOldUserData);
  270.   if( callback_args.bError ) {
  271.     comprot_errmsg();
  272.     return false;
  273.   }
  274.   return callback_args.result;
  275. }
  276. bool CGW_Connection::SendData(I_ITDescriptor& desc, CDB_Image& data, bool log_it)
  277. {
  278.   return xSendData(desc, &data, log_it);
  279. }
  280. bool CGW_Connection::SendData(I_ITDescriptor& desc, CDB_Text&  data, bool log_it)
  281. {
  282.   return xSendData(desc, &data, log_it);
  283. }
  284. const string& CGW_Connection::ServerName() const
  285. {
  286.   char buf[1024];
  287.   char* p = comprot_chars(
  288.       "GWLib:Connection:ServerName", remoteObj,
  289.       buf, sizeof(buf)-1 );
  290.   vars->m_Server = p?p:"";
  291.   return vars->m_Server;
  292. }
  293. const string& CGW_Connection::UserName()   const
  294. {
  295.   char buf[1024];
  296.   char* p = comprot_chars(
  297.       "GWLib:Connection:UserName", remoteObj,
  298.       buf, sizeof(buf)-1 );
  299.   vars->m_User =  p?p:"";
  300.   return vars->m_User;
  301. }
  302. const string& CGW_Connection::Password()   const
  303. {
  304.   char buf[1024];
  305.   char* p = comprot_chars(
  306.       "GWLib:Connection:Password", remoteObj,
  307.       buf, sizeof(buf)-1 );
  308.   vars->m_Password =  p?p:"";
  309.   return vars->m_Password;
  310. }
  311. const string& CGW_Connection::PoolName()   const
  312. {
  313.   char buf[1024];
  314.   char* p = comprot_chars(
  315.       "GWLib:Connection:PoolName", remoteObj,
  316.       buf, sizeof(buf)-1 );
  317.   vars->m_PoolName =  p?p:"";
  318.   return vars->m_PoolName;
  319. }
  320. /*
  321. void CGW_Connection::DropCmd(CDB_BaseEnt& cmd)
  322. {
  323.   CGW_Base* p = dynamic_cast<CGW_Base*>(&cmd);
  324.   if(p==NULL) {
  325.     cerr << "Error: dynamic_cast<CGW_Base*> returns NULLn";
  326.     return;
  327.   }
  328.   comprot_void("GWLib:Connection:DropCmd",p->remoteObj);
  329.   // << also delete local proxy object?? >>
  330. }
  331. */
  332. void C_GWLib_Result_ReadItem::exec(IGate* pGate)
  333. {
  334.   SContext* pContext = (SContext*) pGate->get_user_data();
  335.   //cerr << "C_GWLib_Result_ReadItem::exec() pContext==" << (int)pContext << "n";
  336.   if(pContext->is_null) {
  337.     int i=0;
  338.     if(  pGate->get_input_arg( "is_null", &i ) != IGate::eGood  ) {
  339.       pContext->bError = true;
  340.       pGate->send_cancel();
  341.       return;
  342.     }
  343.     *(pContext->is_null) = i;
  344.   }
  345.   unsigned chunkSize;
  346.   char* chunkData;
  347.   if( pGate->take_bin_arg("value", (void**)&chunkData, &chunkSize ) != IGate::eGood  ) {
  348.       pContext->bError = true;
  349.       pGate->send_cancel();
  350.       return;
  351.   }
  352.   /*
  353.   if(pContext->stream) {
  354.     stream->Append( (const void*)chunkData, (size_t)chunkSize );
  355.     delete chunkData;
  356.     pGate->send_done();
  357.   }
  358.   else{
  359.   */
  360.     if( pContext->bytesReceived+chunkSize <= pContext->buffer_size ) {
  361.       memcpy(pContext->buffer+pContext->bytesReceived,chunkData,chunkSize);
  362.       pContext->bytesReceived+=chunkSize;
  363.       delete chunkData;
  364.       pGate->send_done();
  365.     }
  366.     else{
  367.       pContext->bError = true;
  368.       delete chunkData;
  369.       pGate->send_cancel();
  370.     }
  371.   //}
  372. }
  373. void C_GWLib_ObjectGetter::exec(IGate* pGate)
  374. {
  375.   SContext* pContext = (SContext*) pGate->get_user_data();
  376.   if(!pContext->bStreamAppend) {
  377.     int type;
  378.     if (pGate->get_input_arg("type", &type) != IGate::eGood) {
  379.       cerr << "C_GWLib_ObjectGetter::exec() - cannot get_input_arg(type)n";
  380.       pContext->bError = true;
  381.       pGate->send_cancel();
  382.       return;
  383.     }
  384.     if( (EDB_Type)type!=eDB_Text && (EDB_Type)type!=eDB_Image ) {
  385.       // Regular small object - we are finished in one call.
  386.       pContext->obj = read_CDB_Object(pGate, pContext->obj, type);
  387.       pGate->send_done();
  388.       return;
  389.     }
  390.     // Prepare the stream for receiving data
  391.     if(pContext->obj) {
  392.       ((CDB_Stream*)pContext->obj)->Truncate(0);
  393.     }
  394.     else{
  395.       pContext->obj = CDB_Object::Create((EDB_Type)type);
  396.     }
  397.     int isNull;
  398.     if(pGate->get_input_arg("is_null", &isNull) == IGate::eGood && isNull) {
  399.       // Empty stream - we are finished in one call.
  400.       pGate->send_done();
  401.       return;
  402.     }
  403.     pContext->bStreamAppend=true;
  404.   }
  405.   // Receive a chunk of stream data
  406.   unsigned chunkSize;
  407.   char* chunkData;
  408.   if( pGate->take_bin_arg("value", (void**)&chunkData, &chunkSize ) != IGate::eGood  ) {
  409.     cerr << "C_GWLib_ObjectGetter::exec() - cannot take_bin_arg(value)n";
  410.     pContext->bError = true;
  411.     pGate->send_cancel();
  412.     return;
  413.   }
  414.   ((CDB_Stream*)pContext->obj)->Append( (const void*)chunkData, (size_t)chunkSize );
  415.   delete chunkData;
  416.   pGate->send_done();
  417. }
  418. void C_GWLib_MsgCallback::exec(IGate* pGate)
  419. {
  420.   CGW_Connection* pConnection;
  421.   if( pGate->get_input_arg("connection", (int*)&pConnection) != IGate::eGood ) {
  422.     cerr << "C_GWLib_MsgCallback::exec() - cannot get_input_arg(connection)n";
  423.   }
  424.   else {
  425.     CDB_Exception* ex = read_CDB_Exception(pGate);
  426.     pConnection->m_MsgHandlers.PostMsg(ex);
  427.     delete ex;
  428.   }
  429.   pGate->send_done();
  430. }
  431. void CGW_Connection::PushMsgHandler(CDB_UserHandler* h)
  432. {
  433.   m_MsgHandlers.Push(h);
  434.   // Make sure there is a server-side handler listening to messages
  435.   int i=(int)this;
  436.   comprot_void1("GWLib:Connection:MsgHandler", remoteObj, &i);
  437. }
  438. void CGW_Connection::PopMsgHandler(CDB_UserHandler* h)
  439. {
  440.   m_MsgHandlers.Pop(h);
  441. }
  442. END_NCBI_SCOPE