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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cursor.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:20:15  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: cursor.cpp,v 1000.1 2004/06/01 19:20:15 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:  Vladimir Soussov
  35.  *
  36.  * File Description:  DBLib cursor command
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #ifndef USE_MS_DBLIB
  41. #  include <dbapi/driver/dblib/interfaces.hpp>
  42. #  include <dbapi/driver/dblib/interfaces_p.hpp>
  43. #else
  44. #  include <dbapi/driver/msdblib/interfaces.hpp>
  45. #  include <dbapi/driver/msdblib/interfaces_p.hpp>
  46. #endif
  47. BEGIN_NCBI_SCOPE
  48. /////////////////////////////////////////////////////////////////////////////
  49. //
  50. //  CDBL_CursorCmd::
  51. //
  52. CDBL_CursorCmd::CDBL_CursorCmd(CDBL_Connection* con, DBPROCESS* cmd,
  53.                                const string& cursor_name, const string& query,
  54.                                unsigned int nof_params) :
  55.     m_Connect(con), m_Cmd(cmd), m_Name(cursor_name), m_LCmd(0), m_Query(query),
  56.     m_Params(nof_params), m_IsOpen(false), m_HasFailed(false),
  57.     m_IsDeclared(false), m_Res(0), m_RowCount(-1)
  58. {
  59. }
  60. bool CDBL_CursorCmd::BindParam(const string& param_name, CDB_Object* param_ptr)
  61. {
  62.     return
  63.         m_Params.BindParam(CDB_Params::kNoParamNumber, param_name, param_ptr);
  64. }
  65. CDB_Result* CDBL_CursorCmd::Open()
  66. {
  67.     if (m_IsOpen) { // need to close it first
  68.         Close();
  69.     }
  70.     m_HasFailed = false;
  71.     // declare the cursor
  72.     if (!x_AssignParams()) {
  73.         m_HasFailed = true;
  74.         throw CDB_ClientEx(eDB_Error, 222003, "CDBL_CursorCmd::Open",
  75.                            "cannot assign params");
  76.     }
  77.     m_LCmd = 0;
  78.     string buff = "declare " + m_Name + " cursor for " + m_Query;
  79.     try {
  80.         m_LCmd = m_Connect->LangCmd(buff);
  81.         m_LCmd->Send();
  82.         m_LCmd->DumpResults();
  83. #if 0
  84.         while (m_LCmd->HasMoreResults()) {
  85.             CDB_Result* r = m_LCmd->Result();
  86.             if (r) {
  87.                 while (r->Fetch())
  88.                     ;
  89.                 delete r;
  90.             }
  91.         }
  92. #endif
  93.         delete m_LCmd;
  94.     } catch (CDB_Exception& ) {
  95.         if (m_LCmd) {
  96.             delete m_LCmd;
  97.             m_LCmd = 0;
  98.         }
  99.         throw CDB_ClientEx(eDB_Error, 222001, "CDBL_CursorCmd::Open",
  100.                            "failed to declare cursor");
  101.     }
  102.     m_IsDeclared = true;
  103.     // open the cursor
  104.     m_LCmd = 0;
  105.     buff = "open " + m_Name;
  106.     try {
  107.         m_LCmd = m_Connect->LangCmd(buff);
  108.         m_LCmd->Send();
  109.         m_LCmd->DumpResults();
  110. #if 0
  111.         while (m_LCmd->HasMoreResults()) {
  112.             CDB_Result* r = m_LCmd->Result();
  113.             if (r) {
  114.                 while (r->Fetch())
  115.                     ;
  116.                 delete r;
  117.             }
  118.         }
  119. #endif
  120.         delete m_LCmd;
  121.     } catch (CDB_Exception& ) {
  122.         if (m_LCmd) {
  123.             delete m_LCmd;
  124.             m_LCmd = 0;
  125.         }
  126.         throw CDB_ClientEx(eDB_Error, 222002, "CDBL_CursorCmd::Open",
  127.                            "failed to open cursor");
  128.     }
  129.     m_IsOpen = true;
  130.     m_LCmd = 0;
  131.     buff = "fetch " + m_Name;
  132.     m_LCmd = m_Connect->LangCmd(buff);
  133.     m_Res = new CDBL_CursorResult(m_LCmd);
  134.     return Create_Result(*m_Res);
  135. }
  136. bool CDBL_CursorCmd::Update(const string&, const string& upd_query)
  137. {
  138.     if (!m_IsOpen)
  139.         return false;
  140.     CDB_LangCmd* cmd = 0;
  141.     try {
  142.         string buff = upd_query + " where current of " + m_Name;
  143.         cmd = m_Connect->LangCmd(buff);
  144.         cmd->Send();
  145.         cmd->DumpResults();
  146. #if 0
  147.         while (cmd->HasMoreResults()) {
  148.             CDB_Result* r = cmd->Result();
  149.             if (r) {
  150.                 while (r->Fetch())
  151.                     ;
  152.                 delete r;
  153.             }
  154.         }
  155. #endif
  156.         delete cmd;
  157.     } catch (CDB_Exception& ) {
  158.         if (cmd)
  159.             delete cmd;
  160.         throw CDB_ClientEx(eDB_Error, 222004, "CDBL_CursorCmd::Update",
  161.                            "update failed");
  162.     }
  163.     return true;
  164. }
  165. I_ITDescriptor* CDBL_CursorCmd::x_GetITDescriptor(unsigned int item_num)
  166. {
  167.     if(!m_IsOpen || (m_Res == 0)) {
  168.         return 0;
  169.     }
  170.     while(m_Res->CurrentItemNo() < item_num) {
  171.         if(!m_Res->SkipItem()) return 0;
  172.     }
  173.     
  174.     I_ITDescriptor* desc= new CDBL_ITDescriptor(m_Cmd, item_num+1);
  175.     return desc;
  176. }
  177. bool CDBL_CursorCmd::UpdateTextImage(unsigned int item_num, CDB_Stream& data, 
  178.                                      bool log_it)
  179. {
  180.     I_ITDescriptor* desc= x_GetITDescriptor(item_num);
  181.     C_ITDescriptorGuard g(desc);
  182.     
  183.     return (desc) ? m_Connect->x_SendData(*desc, data, log_it) : false;
  184. }
  185. CDB_SendDataCmd* CDBL_CursorCmd::SendDataCmd(unsigned int item_num, size_t size, 
  186.                                              bool log_it)
  187. {
  188.     I_ITDescriptor* desc= x_GetITDescriptor(item_num);
  189.     C_ITDescriptorGuard g(desc);
  190.     
  191.     return (desc) ? m_Connect->SendDataCmd(*desc, size, log_it) : 0;
  192. }     
  193. bool CDBL_CursorCmd::Delete(const string& table_name)
  194. {
  195.     if (!m_IsOpen)
  196.         return false;
  197.     CDB_LangCmd* cmd = 0;
  198.     try {
  199.         string buff = "delete " + table_name + " where current of " + m_Name;
  200.         cmd = m_Connect->LangCmd(buff);
  201.         cmd->Send();
  202.         cmd->DumpResults();
  203. #if 0
  204.         while (cmd->HasMoreResults()) {
  205.             CDB_Result* r = cmd->Result();
  206.             if (r) {
  207.                 while (r->Fetch())
  208.                     ;
  209.                 delete r;
  210.             }
  211.         }
  212. #endif
  213.         delete cmd;
  214.     } catch (CDB_Exception& ) {
  215.         if (cmd)
  216.             delete cmd;
  217.         throw CDB_ClientEx(eDB_Error, 222004, "CDBL_CursorCmd::Update",
  218.                            "update failed");
  219.     }
  220.     return true;
  221. }
  222. int CDBL_CursorCmd::RowCount() const
  223. {
  224.     return m_RowCount;
  225. }
  226. bool CDBL_CursorCmd::Close()
  227. {
  228.     if (!m_IsOpen)
  229.         return false;
  230.     if (m_Res) {
  231.         delete m_Res;
  232.         m_Res = 0;
  233.     }
  234.     if (m_LCmd)
  235.         delete m_LCmd;
  236.     if (m_IsOpen) {
  237.         string buff = "close " + m_Name;
  238.         m_LCmd = 0;
  239.         try {
  240.             m_LCmd = m_Connect->LangCmd(buff);
  241.             m_LCmd->Send();
  242.             m_LCmd->DumpResults();
  243. #if 0
  244.             while (m_LCmd->HasMoreResults()) {
  245.                 CDB_Result* r = m_LCmd->Result();
  246.                 if (r) {
  247.                     while (r->Fetch())
  248.                         ;
  249.                     delete r;
  250.                 }
  251.             }
  252. #endif
  253.             delete m_LCmd;
  254.         } catch (CDB_Exception& ) {
  255.             if (m_LCmd)
  256.                 delete m_LCmd;
  257.             m_LCmd = 0;
  258.             throw CDB_ClientEx(eDB_Error, 222003, "CDBL_CursorCmd::Close",
  259.                                "failed to close cursor");
  260.         }
  261.         m_IsOpen = false;
  262.         m_LCmd = 0;
  263.     }
  264.     if (m_IsDeclared) {
  265.         string buff = "deallocate cursor " + m_Name;
  266.         m_LCmd = 0;
  267.         try {
  268.             m_LCmd = m_Connect->LangCmd(buff);
  269.             m_LCmd->Send();
  270.             m_LCmd->DumpResults();
  271. #if 0
  272.             while (m_LCmd->HasMoreResults()) {
  273.                 CDB_Result* r = m_LCmd->Result();
  274.                 if (r) {
  275.                     while (r->Fetch())
  276.                         ;
  277.                     delete r;
  278.                 }
  279.             }
  280. #endif
  281.             delete m_LCmd;
  282.         } catch (CDB_Exception& ) {
  283.             if (m_LCmd)
  284.                 delete m_LCmd;
  285.             m_LCmd = 0;
  286.             throw CDB_ClientEx(eDB_Error, 222003, "CDBL_CursorCmd::Close",
  287.                                "failed to deallocate cursor");
  288.         }
  289.         m_IsDeclared = false;
  290.         m_LCmd = 0;
  291.     }
  292.     return true;
  293. }
  294. void CDBL_CursorCmd::Release()
  295. {
  296.     m_BR = 0;
  297.     if (m_IsOpen) {
  298.         Close();
  299.         m_IsOpen = false;
  300.     }
  301.     m_Connect->DropCmd(*this);
  302.     delete this;
  303. }
  304. CDBL_CursorCmd::~CDBL_CursorCmd()
  305. {
  306.     if (m_BR)
  307.         *m_BR = 0;
  308.     if (m_IsOpen)
  309.         Close();
  310. }
  311. bool CDBL_CursorCmd::x_AssignParams()
  312. {
  313.     static const char s_hexnum[] = "0123456789ABCDEF";
  314.     for (unsigned int n = 0; n < m_Params.NofParams(); n++) {
  315.         const string& name = m_Params.GetParamName(n);
  316.         if (name.empty())
  317.             continue;
  318.         CDB_Object& param = *m_Params.GetParam(n);
  319.         char val_buffer[1024];
  320.         if (!param.IsNULL()) {
  321.             switch (param.GetType()) {
  322.             case eDB_Int: {
  323.                 CDB_Int& val = dynamic_cast<CDB_Int&> (param);
  324.                 sprintf(val_buffer, "%d", val.Value());
  325.                 break;
  326.             }
  327.             case eDB_SmallInt: {
  328.                 CDB_SmallInt& val = dynamic_cast<CDB_SmallInt&> (param);
  329.                 sprintf(val_buffer, "%d", (int) val.Value());
  330.                 break;
  331.             }
  332.             case eDB_TinyInt: {
  333.                 CDB_TinyInt& val = dynamic_cast<CDB_TinyInt&> (param);
  334.                 sprintf(val_buffer, "%d", (int) val.Value());
  335.                 break;
  336.             }
  337.             case eDB_BigInt: {
  338.                 CDB_BigInt& val = dynamic_cast<CDB_BigInt&> (param);
  339.                 Int8 v8 = val.Value();
  340.                 sprintf(val_buffer, "%lld", v8);
  341.                 break;
  342.             }
  343.             case eDB_Char: {
  344.                 CDB_Char& val = dynamic_cast<CDB_Char&> (param);
  345.                 const char* c = val.Value(); // NB: 255 bytes at most
  346.                 size_t i = 0;
  347.                 val_buffer[i++] = '"';
  348.                 while (*c) {
  349.                     if (*c == '"')
  350.                         val_buffer[i++] = '"';
  351.                     val_buffer[i++] = *c++;
  352.                 }
  353.                 val_buffer[i++] = '"';
  354.                 val_buffer[i] = '';
  355.                 break;
  356.             }
  357.             case eDB_VarChar: {
  358.                 CDB_VarChar& val = dynamic_cast<CDB_VarChar&> (param);
  359.                 const char* c = val.Value(); // NB: 255 bytes at most
  360.                 size_t i = 0;
  361.                 val_buffer[i++] = '"';
  362.                 while (*c) {
  363.                     if (*c == '"')
  364.                         val_buffer[i++] = '"';
  365.                     val_buffer[i++] = *c++;
  366.                 }
  367.                 val_buffer[i++] = '"';
  368.                 val_buffer[i] = '';
  369.                 break;
  370.             }
  371.             case eDB_Binary: {
  372.                 CDB_Binary& val = dynamic_cast<CDB_Binary&> (param);
  373.                 const unsigned char* c = (const unsigned char*) val.Value();
  374.                 size_t i = 0, size = val.Size();
  375.                 val_buffer[i++] = '0';
  376.                 val_buffer[i++] = 'x';
  377.                 for (size_t j = 0; j < size; j++) {
  378.                     val_buffer[i++] = s_hexnum[c[j] >> 4];
  379.                     val_buffer[i++] = s_hexnum[c[j] & 0x0F];
  380.                 }
  381.                 val_buffer[i++] = '';
  382.                 break;
  383.             }
  384.             case eDB_VarBinary: {
  385.                 CDB_VarBinary& val = dynamic_cast<CDB_VarBinary&> (param);
  386.                 const unsigned char* c = (const unsigned char*) val.Value();
  387.                 size_t i = 0, size = val.Size();
  388.                 val_buffer[i++] = '0';
  389.                 val_buffer[i++] = 'x';
  390.                 for (size_t j = 0; j < size; j++) {
  391.                     val_buffer[i++] = s_hexnum[c[j] >> 4];
  392.                     val_buffer[i++] = s_hexnum[c[j] & 0x0F];
  393.                 }
  394.                 val_buffer[i++] = '';
  395.                 break;
  396.             }
  397.             case eDB_Float: {
  398.                 CDB_Float& val = dynamic_cast<CDB_Float&> (param);
  399.                 sprintf(val_buffer, "%E", (double) val.Value());
  400.                 break;
  401.             }
  402.             case eDB_Double: {
  403.                 CDB_Double& val = dynamic_cast<CDB_Double&> (param);
  404.                 sprintf(val_buffer, "%E", val.Value());
  405.                 break;
  406.             }
  407.             case eDB_SmallDateTime: {
  408.                 CDB_SmallDateTime& val =
  409.                     dynamic_cast<CDB_SmallDateTime&> (param);
  410.                 string t = val.Value().AsString("M/D/Y h:m");
  411.                 sprintf(val_buffer, "'%s'", t.c_str());
  412.                 break;
  413.             }
  414.             case eDB_DateTime: {
  415.                 CDB_DateTime& val =
  416.                     dynamic_cast<CDB_DateTime&> (param);
  417.                 string t = val.Value().AsString("M/D/Y h:m:s");
  418.                 sprintf(val_buffer, "'%s:%.3d'", t.c_str(),
  419. (int)(val.Value().NanoSecond()/1000000));
  420.                 break;
  421.             }
  422.             default:
  423.                 return false;
  424.             }
  425.         } else
  426.             strcpy(val_buffer, "NULL");
  427.         // substitute the param
  428.         g_SubstituteParam(m_Query, name, val_buffer);
  429.     }
  430.     return true;
  431. }
  432. END_NCBI_SCOPE
  433. /*
  434.  * ===========================================================================
  435.  * $Log: cursor.cpp,v $
  436.  * Revision 1000.1  2004/06/01 19:20:15  gouriano
  437.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  438.  *
  439.  * Revision 1.12  2004/05/18 18:30:36  gorelenk
  440.  * PCH <ncbi_pch.hpp> moved to correct place .
  441.  *
  442.  * Revision 1.11  2003/06/05 16:01:13  soussov
  443.  * adds code for DumpResults and for the dumped results processing
  444.  *
  445.  * Revision 1.10  2003/01/31 16:50:12  lavr
  446.  * Remove unused variable "e" from catch() clause
  447.  *
  448.  * Revision 1.9  2002/07/02 16:05:49  soussov
  449.  * splitting Sybase dblib and MS dblib
  450.  *
  451.  * Revision 1.8  2002/05/16 21:36:06  soussov
  452.  * fixes the memory leak in text/image processing
  453.  *
  454.  * Revision 1.7  2002/03/26 15:37:52  soussov
  455.  * new image/text operations added
  456.  *
  457.  * Revision 1.6  2002/01/08 18:10:18  sapojnik
  458.  * Syabse to MSSQL name translations moved to interface_p.hpp
  459.  *
  460.  * Revision 1.5  2001/12/18 19:29:22  soussov
  461.  * adds conversion from nanosecs to milisecs for datetime args
  462.  *
  463.  * Revision 1.4  2001/12/18 17:56:53  soussov
  464.  * copy-paste bug in datetime processing fixed
  465.  *
  466.  * Revision 1.3  2001/10/24 16:41:13  lavr
  467.  * File description changed to be of the same style as in other files
  468.  *
  469.  * Revision 1.2  2001/10/22 16:28:01  lavr
  470.  * Default argument values removed
  471.  * (mistakenly left while moving code from header files)
  472.  *
  473.  * Revision 1.1  2001/10/22 15:19:55  lavr
  474.  * This is a major revamp (by Anton Lavrentiev, with help from Vladimir
  475.  * Soussov and Denis Vakatov) of the DBAPI "driver" libs originally
  476.  * written by Vladimir Soussov. The revamp follows the one of CTLib
  477.  * driver, and it involved massive code shuffling and grooming, numerous
  478.  * local API redesigns, adding comments and incorporating DBAPI to
  479.  * the C++ Toolkit.
  480.  *
  481.  * ===========================================================================
  482.  */