rs_impl.cpp

来自「ncbi源码」· C++ 代码 · 共 479 行

CPP
479
字号
/* * =========================================================================== * PRODUCTION $Log: rs_impl.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:18:42  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.32 * PRODUCTION * =========================================================================== *//* $Id: rs_impl.cpp,v 1000.3 2004/06/01 19:18:42 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.   ** ===========================================================================** File Name:  $Id: rs_impl.cpp,v 1000.3 2004/06/01 19:18:42 gouriano Exp $** Author:  Michael Kholodov*   * File Description:  Base class for database access*** $Log: rs_impl.cpp,v $* Revision 1000.3  2004/06/01 19:18:42  gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.32** Revision 1.32  2004/05/17 21:10:28  gorelenk* Added include of PCH ncbi_pch.hpp** Revision 1.31  2004/04/26 14:14:27  kholodov* Added: ExecteQuery() method** Revision 1.30  2004/04/12 14:25:33  kholodov* Modified: resultset caching scheme, fixed single connection handling** Revision 1.29  2004/04/08 15:56:58  kholodov* Multiple bug fixes and optimizations** Revision 1.28  2004/03/02 19:37:56  kholodov* Added: process close event from CStatement to CResultSet** Revision 1.27  2004/03/01 16:21:55  kholodov* Fixed: double deletion in calling subsequently CResultset::Close() and delete** Revision 1.26  2004/02/19 15:23:21  kholodov* Fixed: attempt to delete cached CDB_Result when it was already deleted by the CResultSet object** Revision 1.25  2004/02/10 18:50:44  kholodov* Modified: made Move() method const** Revision 1.24  2003/06/25 21:03:05  kholodov* Fixed: method name in error message** Revision 1.23  2003/05/05 18:32:50  kholodov* Added: LONGCHAR and LONGBINARY support** Revision 1.22  2003/02/12 15:52:32  kholodov* Added: WasNull() method** Revision 1.21  2003/02/06 19:59:22  kholodov* Fixed: CResultSet::GetColumnNo() never returned 1** Revision 1.20  2002/11/25 15:15:50  kholodov* Removed: dynamic array module (array.hpp, array.cpp), using* STL vector instead to keep bound column data.** Revision 1.19  2002/11/07 14:50:31  kholodov* Fixed: truncate BLOB buffer befor each successful read into CVariant object** Revision 1.18  2002/10/31 22:37:05  kholodov* Added: DisableBind(), GetColumnNo(), GetTotalColumns() methods* Fixed: minor errors, diagnostic messages** Revision 1.17  2002/10/21 20:38:08  kholodov* Added: GetParentConn() method to get the parent connection from IStatement,* ICallableStatement and ICursor objects.* Fixed: Minor fixes** Revision 1.16  2002/10/03 18:50:00  kholodov* Added: additional TRACE diagnostics about object deletion* Fixed: setting parameters in IStatement object is fully supported* Added: IStatement::ExecuteLast() to execute the last statement with* different parameters if any** Revision 1.15  2002/09/18 18:49:27  kholodov* Modified: class declaration and Action method to reflect* direct inheritance of CActiveObject from IEventListener** Revision 1.14  2002/09/16 19:34:41  kholodov* Added: bulk insert support** Revision 1.13  2002/09/09 20:48:57  kholodov* Added: Additional trace output about object life cycle* Added: CStatement::Failed() method to check command status** Revision 1.12  2002/08/26 15:35:56  kholodov* Added possibility to disable transaction log* while updating BLOBs** Revision 1.11  2002/07/08 16:08:19  kholodov* Modified: moved initialization code to Init() method** Revision 1.10  2002/07/02 13:46:05  kholodov* Fixed: Incorrect exception class used CDB_Exception** Revision 1.9  2002/07/01 13:15:11  kholodov* Added ITDescriptor diagnostics** Revision 1.8  2002/06/24 19:10:03  kholodov* Added more trace diagnostics** Revision 1.7  2002/06/11 16:22:54  kholodov* Fixed the incorrect declaration of GetMetaData() method** Revision 1.6  2002/05/16 22:09:19  kholodov* Fixed: incorrect start of BLOB column** Revision 1.5  2002/05/14 19:53:17  kholodov* Modified: Read() returns 0 to signal end of column** Revision 1.4  2002/05/13 19:07:33  kholodov* Modified: every call to GetBlobIStream() returns new istream& object. Changed to retrieve data from several BLOB columns.** Revision 1.3  2002/04/05 19:29:50  kholodov* Modified: GetBlobIStream() returns one and the same object, which is created* on the first call.* Added: GetVariant(const string& colName) to retrieve column value by* column name** Revision 1.2  2002/03/13 16:40:16  kholodov* Modified indent formatting** Revision 1.1  2002/01/30 14:51:21  kholodov* User DBAPI implementation, first commit** Revision 1.1  2001/11/30 16:30:06  kholodov* Snapshot of the first draft of dbapi lib****/#include <ncbi_pch.hpp>#include "stmt_impl.hpp"#include "cstmt_impl.hpp"#include "conn_impl.hpp"#include "cursor_impl.hpp"#include "rs_impl.hpp"#include "rsmeta_impl.hpp"#include "dbexception.hpp"#include <dbapi/driver/public.hpp>#include <dbapi/driver/exception.hpp>#include <corelib/ncbistr.hpp>#include <typeinfo>BEGIN_NCBI_SCOPECResultSet::CResultSet(CConnection* conn, CDB_Result *rs)    : m_conn(conn),      m_rs(rs), m_istr(0), m_ostr(0), m_column(-1),      m_bindBlob(false), m_disableBind(false), m_wasNull(true){    SetIdent("CResultSet");    if( m_rs == 0 ) {        _TRACE("CResultSet::ctor(): null CDB_Result* object");        _ASSERT(0);    }    else {        Init();    }}void CResultSet::Init() {    // Reserve storage for column data    EDB_Type type;    for(unsigned int i = 0; i < m_rs->NofItems(); ++i ) {        type = m_rs->ItemDataType(i);        switch( type ) {        case eDB_LongChar:            m_data.push_back(CVariant::LongChar(0, m_rs->ItemMaxSize(i)));            break;        case eDB_LongBinary:            m_data.push_back(CVariant::LongBinary(m_rs->ItemMaxSize(i), 0, 0));            break;        default:            m_data.push_back(CVariant(type));            break;        }    }    _TRACE("CResultSet::Init(): Space reserved for " << m_data.size()            << " columns");}CResultSet::~CResultSet(){    Notify(CDbapiClosedEvent(this));    FreeResources();    Notify(CDbapiDeletedEvent(this));    _TRACE(GetIdent() << " " << (void*)this << " deleted."); }const CVariant& CResultSet::GetVariant(unsigned int idx) {    CheckIdx(idx - 1);    return m_data[idx-1];}const CVariant& CResultSet::GetVariant(const string& name) {    int zIdx = GetColNum(name);    CheckIdx(zIdx);    return m_data[zIdx];}const IResultSetMetaData* CResultSet::GetMetaData() {    CResultSetMetaData *md = new CResultSetMetaData(m_rs);    md->AddListener(this);    AddListener(md);    return md;}EDB_ResType CResultSet::GetResultType() {    return m_rs->ResultType();}void CResultSet::BindBlobToVariant(bool b) {    m_bindBlob = b;}void CResultSet::DisableBind(bool b) {    m_disableBind = b;}bool CResultSet::Next() {    bool more = false;    EDB_Type type = eDB_UnsupportedType;    more = m_rs->Fetch();    if( more && !IsDisableBind() ) {        for(unsigned int i = 0; i < m_rs->NofItems(); ++i ) {                        type = m_rs->ItemDataType(i);                        if( !IsBindBlob() ) {                if( type == eDB_Text || type == eDB_Image )  {                    m_column = m_rs->CurrentItemNo();                    break;                }            }            else {                switch(type) {                case eDB_Text:                    ((CDB_Text*)m_data[i].GetNonNullData())->Truncate();                    break;                case eDB_Image:                    ((CDB_Image*)m_data[i].GetNonNullData())->Truncate();                    break;                }            }                        m_rs->GetItem(m_data[i].GetNonNullData());        }    }     if( !more ) {        if( m_ostr ) {            _TRACE("CResulstSet: deleting BLOB output stream...");                   delete m_ostr;                   m_ostr = 0;        }        if( m_istr ) {            _TRACE("CResulstSet: deleting BLOB input stream...");            delete m_istr;            m_istr = 0;        }    }      return more;}size_t CResultSet::Read(void* buf, size_t size){    if( m_column < 0 || m_column != m_rs->CurrentItemNo() ) {        if( m_column < 0 ) {            _TRACE("CResulstSet: Column for raw Read not set, current column: "                   << m_rs->CurrentItemNo());#ifdef _DEBUG            _ASSERT(0);#endif        }        else            _TRACE("Last column: " << m_column);        m_column = m_rs->CurrentItemNo();        return 0;    }    else {        return m_rs->ReadItem(buf, size, &m_wasNull);    }}bool CResultSet::WasNull(){    return m_wasNull;}int CResultSet::GetColumnNo(){    int col = m_rs->CurrentItemNo();    return col >= 0 ? col + 1 : -1;}unsigned int CResultSet::GetTotalColumns(){    return m_rs->NofItems();}istream& CResultSet::GetBlobIStream(size_t buf_size){#if 0    if( m_istr == 0 ) {        m_istr = new CBlobIStream(m_rs, buf_size);    }#endif    delete m_istr;    m_istr = new CBlobIStream(m_rs, buf_size);     return *m_istr;}ostream& CResultSet::GetBlobOStream(size_t blob_size,                                     EAllowLog log_it,                                    size_t buf_size){    // GetConnAux() returns pointer to pooled CDB_Connection.    // we need to delete it every time we request new one.    // The same with ITDescriptor    delete m_ostr;    // Call ReadItem(0, 0) before getting text/image descriptor    m_rs->ReadItem(0, 0);        I_ITDescriptor* desc = m_rs->GetImageOrTextDescriptor();    if( desc == 0 ) {        _TRACE("CResultSet::GetBlobOStream(): zero IT Descriptor");#ifdef _DEBUG        _ASSERT(0);#else        throw CDbapiException("CResultSet::GetBlobOStream(): Invalid IT Descriptor");#endif    }    m_ostr = new CBlobOStream(m_conn->CloneCDB_Conn(),                              desc,                              blob_size,                              buf_size,                              log_it == eEnableLog);    return *m_ostr;}void CResultSet::Close(){    Notify(CDbapiClosedEvent(this));    FreeResources();}void CResultSet::FreeResources(){    //_TRACE("CResultSet::Close(): deleting CDB_Result " << (void*)m_rs);    Invalidate();    delete m_istr;    m_istr = 0;    delete m_ostr;    m_ostr = 0;}  void CResultSet::Action(const CDbapiEvent& e) {    _TRACE(GetIdent() << " " << (void*)this               << ": '" << e.GetName()               << "' received from " << e.GetSource()->GetIdent());        if(dynamic_cast<const CDbapiClosedEvent*>(&e) != 0 ) {        if( dynamic_cast<CStatement*>(e.GetSource()) != 0            || dynamic_cast<CCallableStatement*>(e.GetSource()) != 0 ) {            if( m_rs != 0 ) {                _TRACE("Discarding old CDB_Result " << (void*)m_rs);                Invalidate();            }        }    }    else if(dynamic_cast<const CDbapiDeletedEvent*>(&e) != 0 ) {        RemoveListener(e.GetSource());        if(dynamic_cast<CStatement*>(e.GetSource()) != 0           || dynamic_cast<CCursor*>(e.GetSource()) != 0           || dynamic_cast<CCallableStatement*>(e.GetSource()) != 0 ) {            _TRACE("Deleting " << GetIdent() << " " << (void*)this);             delete this;        }    }}int CResultSet::GetColNum(const string& name) {        unsigned int i = 0;    for( ; i < m_rs->NofItems(); ++i ) {                if( !NStr::Compare(m_rs->ItemName(i), name) )            return i;    }    throw CDbapiException("CResultSet::GetColNum(): invalid column name ["                          + name + "]");}void CResultSet::CheckIdx(unsigned int idx) {    if( idx >= m_data.size() ) {#ifdef _DEBUG        NcbiCerr << "CResultSet::CheckIdx(): Column index "                  << idx << " out of range" << endl;        _ASSERT(0);#else        throw CDbapiException("CResultSet::CheckIdx(): Column index"                               + NStr::IntToString(idx) + " out of range");#endif    }}END_NCBI_SCOPE

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?