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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: stmt_impl.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:18:50  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.22
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: stmt_impl.cpp,v 1000.3 2004/06/01 19:18:50 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. * File Name:  $Id: stmt_impl.cpp,v 1000.3 2004/06/01 19:18:50 gouriano Exp $
  35. *
  36. * Author:  Michael Kholodov
  37. *   
  38. * File Description:  Statement implementation
  39. *
  40. *
  41. * $Log: stmt_impl.cpp,v $
  42. * Revision 1000.3  2004/06/01 19:18:50  gouriano
  43. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.22
  44. *
  45. * Revision 1.22  2004/05/17 21:10:28  gorelenk
  46. * Added include of PCH ncbi_pch.hpp
  47. *
  48. * Revision 1.21  2004/04/26 14:15:28  kholodov
  49. * Added: ExecuteQuery() method
  50. *
  51. * Revision 1.20  2004/04/22 15:14:53  kholodov
  52. * Added: PurgeResults()
  53. *
  54. * Revision 1.19  2004/04/12 14:25:33  kholodov
  55. * Modified: resultset caching scheme, fixed single connection handling
  56. *
  57. * Revision 1.18  2004/04/08 15:56:58  kholodov
  58. * Multiple bug fixes and optimizations
  59. *
  60. * Revision 1.17  2004/03/02 19:37:56  kholodov
  61. * Added: process close event from CStatement to CResultSet
  62. *
  63. * Revision 1.16  2004/03/01 16:21:55  kholodov
  64. * Fixed: double deletion in calling subsequently CResultset::Close() and delete
  65. *
  66. * Revision 1.15  2004/02/26 18:52:34  kholodov
  67. * Added: more trace messages
  68. *
  69. * Revision 1.14  2004/02/26 16:56:01  kholodov
  70. * Added: Trace message to HasMoreResults()
  71. *
  72. * Revision 1.13  2004/02/19 15:23:21  kholodov
  73. * Fixed: attempt to delete cached CDB_Result when it was already deleted by the CResultSet object
  74. *
  75. * Revision 1.12  2004/02/10 18:50:44  kholodov
  76. * Modified: made Move() method const
  77. *
  78. * Revision 1.11  2003/06/16 19:43:58  kholodov
  79. * Added: SQL command logging
  80. *
  81. * Revision 1.10  2002/12/16 18:56:50  kholodov
  82. * Fixed: memory leak in CStatement object
  83. *
  84. * Revision 1.9  2002/12/06 23:00:21  kholodov
  85. * Memory leak fix rolled back
  86. *
  87. * Revision 1.8  2002/12/05 17:37:23  kholodov
  88. * Fixed: potential memory leak in CStatement::HasMoreResults() method
  89. * Modified: getter and setter name for the internal CDB_Result pointer.
  90. *
  91. * Revision 1.7  2002/10/21 20:38:08  kholodov
  92. * Added: GetParentConn() method to get the parent connection from IStatement,
  93. * ICallableStatement and ICursor objects.
  94. * Fixed: Minor fixes
  95. *
  96. * Revision 1.6  2002/10/03 18:50:00  kholodov
  97. * Added: additional TRACE diagnostics about object deletion
  98. * Fixed: setting parameters in IStatement object is fully supported
  99. * Added: IStatement::ExecuteLast() to execute the last statement with
  100. * different parameters if any
  101. *
  102. * Revision 1.5  2002/09/18 18:49:27  kholodov
  103. * Modified: class declaration and Action method to reflect
  104. * direct inheritance of CActiveObject from IEventListener
  105. *
  106. * Revision 1.4  2002/09/09 20:48:57  kholodov
  107. * Added: Additional trace output about object life cycle
  108. * Added: CStatement::Failed() method to check command status
  109. *
  110. * Revision 1.3  2002/05/16 22:11:12  kholodov
  111. * Improved: using minimum connections possible
  112. *
  113. * Revision 1.2  2002/02/08 17:38:26  kholodov
  114. * Moved listener registration to parent objects
  115. *
  116. * Revision 1.1  2002/01/30 14:51:22  kholodov
  117. * User DBAPI implementation, first commit
  118. *
  119. *
  120. *
  121. *
  122. */
  123. #include <ncbi_pch.hpp>
  124. #include "conn_impl.hpp"
  125. #include "stmt_impl.hpp"
  126. #include "rs_impl.hpp"
  127. #include <dbapi/driver/public.hpp>
  128. BEGIN_NCBI_SCOPE
  129. // implementation
  130. CStatement::CStatement(CConnection* conn)
  131.     : m_conn(conn), m_cmd(0), m_rowCount(-1), m_failed(false),
  132.       m_irs(0)
  133. {
  134.     SetIdent("CStatement");
  135. }
  136. CStatement::~CStatement()
  137. {
  138.     Notify(CDbapiClosedEvent(this));
  139.     FreeResources();
  140.     Notify(CDbapiDeletedEvent(this));
  141.     _TRACE(GetIdent() << " " << (void*)this << " deleted."); 
  142. }
  143. IConnection* CStatement::GetParentConn() 
  144. {
  145.     return m_conn;
  146. }
  147. void CStatement::CacheResultSet(CDB_Result *rs) 
  148.     if( m_irs != 0 ) {
  149.         _TRACE("CStatement::CacheResultSet(): Invalidating cached CResultSet " << (void*)m_irs);
  150.         m_irs->Invalidate();
  151.     }
  152.     if( rs != 0 ) {
  153.         m_irs = new CResultSet(m_conn, rs);
  154.         m_irs->AddListener(this);
  155.         AddListener(m_irs);
  156.         _TRACE("CStatement::CacheResultSet(): Created new CResultSet " << (void*)m_irs
  157.             << " with CDB_Result " << (void*)rs);
  158.     }
  159.     else
  160.         m_irs = 0;
  161. }
  162. IResultSet* CStatement::GetResultSet()
  163. {
  164.    return m_irs;
  165. }
  166. bool CStatement::HasMoreResults() 
  167. {
  168.     bool more = GetBaseCmd()->HasMoreResults();
  169.     if( more ) {
  170.         if( GetBaseCmd()->HasFailed() ) {
  171.             SetFailed(true);
  172.             return false;
  173.         }
  174.         //Notify(CDbapiNewResultEvent(this));
  175.         CDB_Result *rs = GetBaseCmd()->Result();
  176.         CacheResultSet(rs); 
  177.         if( rs == 0 ) {
  178.             m_rowCount = GetBaseCmd()->RowCount();
  179.         }
  180.     }
  181.     return more;
  182. }
  183. void CStatement::SetParam(const CVariant& v, 
  184.                           const string& name)
  185. {
  186.     ParamList::iterator i = m_params.find(name);
  187.     if( i != m_params.end() ) {
  188.         *((*i).second) = v;
  189.     }
  190.     else {
  191.         m_params.insert(make_pair(name, new CVariant(v)));
  192.     }
  193. }
  194. void CStatement::ClearParamList()
  195. {
  196.     ParamList::iterator i = m_params.begin();
  197.     for( ; i != m_params.end(); ++i ) {
  198.         delete (*i).second;
  199.     }
  200.     m_params.clear();
  201. }
  202. void CStatement::Execute(const string& sql)
  203. {
  204.     if( m_cmd != 0 ) {
  205.         delete m_cmd;
  206.         m_cmd = 0;
  207.         m_rowCount = -1;
  208.     }
  209.     SetFailed(false);
  210.     _TRACE("Sending SQL: " + sql);
  211.     m_cmd = m_conn->GetCDB_Connection()->LangCmd(sql, m_params.size());
  212.     ExecuteLast();
  213. }
  214. IResultSet* CStatement::ExecuteQuery(const string& sql)
  215. {
  216.     Execute(sql);
  217.     while( HasMoreResults() ) {
  218.         if( HasRows() ) {
  219.             return GetResultSet();
  220.         }
  221.     }
  222.     return 0;
  223. }
  224. void CStatement::ExecuteUpdate(const string& sql)
  225. {
  226.     Execute(sql);
  227.     while( HasMoreResults() );
  228. }
  229. void CStatement::ExecuteLast()
  230. {
  231.     ParamList::iterator i = m_params.begin();
  232.     for( ; i != m_params.end(); ++i ) {
  233.         GetLangCmd()->SetParam((*i).first, (*i).second->GetData());
  234.     }
  235.     m_cmd->Send();
  236. }
  237. bool CStatement::HasRows() 
  238. {
  239.     return m_irs != 0;
  240. }
  241. CDB_Result* CStatement::GetCDB_Result() {
  242.     return m_irs == 0 ? 0 : m_irs->GetCDB_Result();
  243. }
  244. bool CStatement::Failed() 
  245. {
  246.     return m_failed;
  247. }
  248. int CStatement::GetRowCount() 
  249. {
  250.     return m_rowCount;
  251. }
  252. void CStatement::Close()
  253. {
  254.     Notify(CDbapiClosedEvent(this));
  255.     FreeResources();
  256. }
  257. void CStatement::FreeResources() 
  258. {
  259.     delete m_cmd;
  260.     m_cmd = 0;
  261.     m_rowCount = -1;
  262.     if( m_conn != 0 && m_conn->IsAux() ) {
  263.     delete m_conn;
  264.     m_conn = 0;
  265.     Notify(CDbapiAuxDeletedEvent(this));
  266.     }
  267.     ClearParamList();
  268. }
  269.   
  270. void CStatement::PurgeResults()
  271. {
  272.     if( GetBaseCmd() != 0 )
  273.         GetBaseCmd()->DumpResults();
  274. }
  275. void CStatement::Cancel()
  276. {
  277.     if( GetBaseCmd() != 0 )
  278.         GetBaseCmd()->Cancel();
  279.     m_rowCount = -1;
  280. }
  281. CDB_LangCmd* CStatement::GetLangCmd() 
  282. {
  283.     //if( m_cmd == 0 )
  284.     //throw CDbException("CStatementImpl::GetLangCmd(): no cmd structure");
  285.     return (CDB_LangCmd*)m_cmd;
  286. }
  287. void CStatement::Action(const CDbapiEvent& e) 
  288. {
  289.     _TRACE(GetIdent() << " " << (void*)this << ": '" << e.GetName() 
  290.            << "' received from " << e.GetSource()->GetIdent());
  291.     CResultSet *rs;
  292.     if(dynamic_cast<const CDbapiDeletedEvent*>(&e) != 0 ) {
  293.     RemoveListener(e.GetSource());
  294.         if(dynamic_cast<CConnection*>(e.GetSource()) != 0 ) {
  295.             _TRACE("Deleting " << GetIdent() << " " << (void*)this); 
  296.             delete this;
  297.         } 
  298.         else if( m_irs != 0 && (rs = dynamic_cast<CResultSet*>(e.GetSource())) != 0 ) {
  299.             if( rs == m_irs ) {
  300.                 _TRACE("Clearing cached CResultSet " << (void*)m_irs); 
  301.                 m_irs = 0;
  302.             }
  303.         } 
  304.     }
  305. }
  306. END_NCBI_SCOPE