⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 context.cpp

📁 ncbi源码
💻 CPP
字号:
/* * =========================================================================== * PRODUCTION $Log: context.cpp,v $ * PRODUCTION Revision 1000.4  2004/06/01 19:21:44  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14 * PRODUCTION * =========================================================================== *//* $Id: context.cpp,v 1000.4 2004/06/01 19:21:44 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:  Driver for ODBC server * */#include <ncbi_pch.hpp>#include <corelib/ncbimtx.hpp>#include <dbapi/driver/odbc/interfaces.hpp>#include <dbapi/driver/util/numeric_convert.hpp>#ifdef HAVE_ODBCSS_H#include <odbcss.h>#endifBEGIN_NCBI_SCOPE/////////////////////////////////////////////////////////////////////////////////  CODBC_Reporter:://void CODBC_Reporter::ReportErrors(){    SQLINTEGER NativeError;    SQLSMALLINT MsgLen;    SQLCHAR SqlState[6];    SQLCHAR Msg[1024];    if(!m_HStack) return;    for(SQLSMALLINT i= 1; i < 128; i++) {        switch(SQLGetDiagRec(m_HType, m_Handle, i, SqlState, &NativeError,                              Msg, sizeof(Msg), &MsgLen)) {        case SQL_SUCCESS:            if(strncmp((const char*)SqlState, "HYT", 3) == 0) { // timeout                CDB_TimeoutEx to(NativeError, "odbc", (const char*)Msg);                m_HStack->PostMsg(&to);            }            else if(strncmp((const char*)SqlState, "40001", 5) == 0) { // deadlock                CDB_DeadlockEx dl("odbc", (const char*)Msg);                m_HStack->PostMsg(&dl);            }            else if(NativeError != 5701 && NativeError != 5703){                CDB_SQLEx se(eDB_Unknown, NativeError, "odbc", (const char*)Msg, 					(const char*)SqlState, 0);                m_HStack->PostMsg(&se);            }            continue;        case SQL_NO_DATA: break;        case SQL_SUCCESS_WITH_INFO:            {                CDB_DSEx dse(eDB_Unknown, 777, "odbc", "Message is too long to be retrieved");                m_HStack->PostMsg(&dse);            }            continue;        default:            {                CDB_ClientEx ce(eDB_Warning, 420016, "CODBC_Reporter::ReportErrors",                                "SQLGetDiagRec failed (memory corruption suspected)");                m_HStack->PostMsg(&ce);            }            break;        }        break;    }}/////////////////////////////////////////////////////////////////////////////////  CODBCContext:://CODBCContext::CODBCContext(SQLINTEGER version, bool use_dsn) : m_Reporter(0, SQL_HANDLE_ENV, 0){    if(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_Context) != SQL_SUCCESS) {        throw CDB_ClientEx(eDB_Fatal, 400001, "CODBCContext::CODBCContext",                           "Can not allocate a context");    }    m_Reporter.SetHandle(m_Context);    m_Reporter.SetHandlerStack(&m_CntxHandlers);    SQLSetEnvAttr(m_Context, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)version, 0);	        m_PacketSize= 0;    m_LoginTimeout= 0;    m_Timeout= 0;    m_TextImageSize= 0;    m_UseDSN= use_dsn;}bool CODBCContext::SetLoginTimeout(unsigned int nof_secs){    m_LoginTimeout= (SQLUINTEGER)nof_secs;    return true;}bool CODBCContext::SetTimeout(unsigned int nof_secs){    m_Timeout= (SQLUINTEGER)nof_secs;    for (int i = m_NotInUse.NofItems(); i--;) {        CODBC_Connection* t_con            = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));        t_con->ODBC_SetTimeout(m_Timeout);    }    for (int i = m_InUse.NofItems(); i--;) {        CODBC_Connection* t_con            = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));        t_con->ODBC_SetTimeout(m_Timeout);    }    return true;}bool CODBCContext::SetMaxTextImageSize(size_t nof_bytes){    m_TextImageSize = (SQLUINTEGER) nof_bytes;    for (int i = m_NotInUse.NofItems(); i--;) {        CODBC_Connection* t_con            = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));        t_con->ODBC_SetTextImageSize(m_TextImageSize);    }        for (int i = m_InUse.NofItems(); i--;) {        CODBC_Connection* t_con            = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));        t_con->ODBC_SetTextImageSize(m_TextImageSize);    }    return true;}CDB_Connection* CODBCContext::Connect(const string&   srv_name,                                      const string&   user_name,                                      const string&   passwd,                                      TConnectionMode mode,                                      bool            reusable,                                      const string&   pool_name){    // static CFastMutex xMutex;    CFastMutexGuard mg(m_Mtx);    if (reusable  &&  m_NotInUse.NofItems() > 0) {        // try to get a connection from the pot        if ( !pool_name.empty() ) {            // use a pool name            for (int i = m_NotInUse.NofItems();  i--; ) {                CODBC_Connection* t_con                    = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));                if (pool_name.compare(t_con->PoolName()) == 0) {                    m_NotInUse.Remove(i);                    if(t_con->Refresh()) {                        m_InUse.Add((TPotItem) t_con);                        return Create_Connection(*t_con);                    }                    delete t_con;                }            }        }        else {            if ( srv_name.empty() )                return 0;                        // try to use a server name            for (int i = m_NotInUse.NofItems();  i--; ) {                CODBC_Connection* t_con                    = static_cast<CODBC_Connection*> (m_NotInUse.Get(i));                                if (srv_name.compare(t_con->ServerName()) == 0) {                    m_NotInUse.Remove(i);                    if(t_con->Refresh()) {                        m_InUse.Add((TPotItem) t_con);                        return Create_Connection(*t_con);                    }                    delete t_con;                }            }        }    }    if((mode & fDoNotConnect) != 0) return 0;    // new connection needed    if (srv_name.empty()  ||  user_name.empty()  ||  passwd.empty()) {        throw CDB_ClientEx(eDB_Error, 100010, "CODBCContext::Connect",                           "You have to provide server name, user name and "                           "password to connect to the server");    }    SQLHDBC con = x_ConnectToServer(srv_name, user_name, passwd, mode);    if (con == 0) {        throw CDB_ClientEx(eDB_Error, 100011, "CODBCContext::Connect",                           "Cannot connect to the server");    }    CODBC_Connection* t_con = new CODBC_Connection(this, con, reusable, pool_name);    t_con->m_MsgHandlers = m_ConnHandlers;    t_con->m_Server      = srv_name;    t_con->m_User        = user_name;    t_con->m_Passwd      = passwd;//    t_con->m_BCPAble     = (mode & fBcpIn) != 0;    t_con->m_SecureLogin = (mode & fPasswordEncrypted) != 0;    m_InUse.Add((TPotItem) t_con);    return Create_Connection(*t_con);}CODBCContext::~CODBCContext(){    if ( !m_Context ) {        return;    }    // close all connections first    for (int i = m_NotInUse.NofItems();  i--; ) {        CODBC_Connection* t_con = static_cast<CODBC_Connection*>(m_NotInUse.Get(i));        delete t_con;    }    for (int i = m_InUse.NofItems();  i--; ) {        CODBC_Connection* t_con = static_cast<CODBC_Connection*> (m_InUse.Get(i));        delete t_con;    }	SQLFreeHandle(SQL_HANDLE_ENV, m_Context);}void CODBCContext::ODBC_SetPacketSize(SQLUINTEGER packet_size){    m_PacketSize = packet_size;}SQLHENV CODBCContext::ODBC_GetContext() const{    return m_Context;}SQLHDBC CODBCContext::x_ConnectToServer(const string&   srv_name,                                               const string&   user_name,                                               const string&   passwd,                                               TConnectionMode mode){    SQLHDBC con;    SQLRETURN r;    r= SQLAllocHandle(SQL_HANDLE_DBC, m_Context, &con);    if((r != SQL_SUCCESS) && (r != SQL_SUCCESS_WITH_INFO))        return 0;    if(m_Timeout) {        SQLSetConnectAttr(con, SQL_ATTR_CONNECTION_TIMEOUT, (void*)m_Timeout, 0);    }        if(m_LoginTimeout) {        SQLSetConnectAttr(con, SQL_ATTR_LOGIN_TIMEOUT, (void*)m_LoginTimeout, 0);    }        if(m_PacketSize) {        SQLSetConnectAttr(con, SQL_ATTR_PACKET_SIZE, (void*)m_PacketSize, 0);    }    #ifdef SQL_COPT_SS_BCP    if((mode & fBcpIn) != 0) {        SQLSetConnectAttr(con, SQL_COPT_SS_BCP, (void*) SQL_BCP_ON, SQL_IS_INTEGER);    }#endif    if(!m_UseDSN) {#ifdef NCBI_OS_MSWIN      string connect_str("DRIVER={SQL Server};SERVER=");#else      string connect_str("DSN=");#endif        connect_str+= srv_name;        connect_str+= ";UID=";        connect_str+= user_name;        connect_str+= ";PWD=";        connect_str+= passwd;        r= SQLDriverConnect(con, 0, (SQLCHAR*) connect_str.c_str(), SQL_NTS,                             0, 0, 0, SQL_DRIVER_NOPROMPT);    }    else {        r= SQLConnect(con, (SQLCHAR*) srv_name.c_str(), SQL_NTS,                   (SQLCHAR*) user_name.c_str(), SQL_NTS,                   (SQLCHAR*) passwd.c_str(), SQL_NTS);    }    switch(r) {    case SQL_SUCCESS_WITH_INFO:        xReportConError(con);    case SQL_SUCCESS: return con;            case SQL_ERROR:        xReportConError(con);        SQLFreeHandle(SQL_HANDLE_DBC, con);        break;    default:        m_Reporter.ReportErrors();        break;    }        return 0;}void CODBCContext::xReportConError(SQLHDBC con){	m_Reporter.SetHandleType(SQL_HANDLE_DBC);    m_Reporter.SetHandle(con);	m_Reporter.ReportErrors();	m_Reporter.SetHandleType(SQL_HANDLE_ENV);    m_Reporter.SetHandle(m_Context);}/////////////////////////////////////////////////////////////////////////////////  Miscellaneous/////////////////////////////////////////////////////////////////////////// Driver manager related functions//I_DriverContext* ODBC_CreateContext(map<string,string>* attr = 0){    SQLINTEGER version= SQL_OV_ODBC3;    bool use_dsn= false;    if(attr) {        string vers= (*attr)["version"];        if(vers.find("3") != string::npos)            version= SQL_OV_ODBC3;        else if(vers.find("2") != string::npos)            version= SQL_OV_ODBC2;        use_dsn= (*attr)["use_dsn"] == "true";    }    CODBCContext* cntx=  new CODBCContext(version, use_dsn);    if(cntx && attr) {      string page_size= (*attr)["packet"];      if(!page_size.empty()) {	SQLUINTEGER s= atoi(page_size.c_str());	cntx->ODBC_SetPacketSize(s);      }    }    return cntx;}NCBI_DBAPIDRIVER_ODBC_EXPORTvoid DBAPI_RegisterDriver_ODBC(I_DriverMgr& mgr){    mgr.RegisterDriver("odbc", ODBC_CreateContext);}extern "C" {    NCBI_DBAPIDRIVER_ODBC_EXPORT    void* DBAPI_E_odbc()    {        return (void*)DBAPI_RegisterDriver_ODBC;    }}END_NCBI_SCOPE/* * =========================================================================== * $Log: context.cpp,v $ * Revision 1000.4  2004/06/01 19:21:44  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14 * * Revision 1.14  2004/05/17 21:16:05  gorelenk * Added include of PCH ncbi_pch.hpp * * Revision 1.13  2004/04/07 13:41:48  gorelenk * Added export prefix to implementations of DBAPI_E_* functions. * * Revision 1.12  2004/03/17 19:25:38  gorelenk * Added NCBI_DBAPIDRIVER_ODBC_EXPORT export prefix for definition of * DBAPI_RegisterDriver_ODBC . * * Revision 1.11  2003/11/14 20:46:51  soussov * implements DoNotConnect mode * * Revision 1.10  2003/10/27 17:00:53  soussov * adds code to prevent the return of broken connection from the pool * * Revision 1.9  2003/07/21 21:58:08  soussov * fixes bug whith pool name mismatch in Connect() * * Revision 1.8  2003/07/18 19:20:34  soussov * removes SetPacketSize function * * Revision 1.7  2003/07/17 20:47:10  soussov * connections pool improvements * * Revision 1.6  2003/05/08 20:48:33  soussov * adding datadirect-odbc type of connecting string. Rememner that you need ODBCINI environment variable to make it works * * Revision 1.5  2003/05/05 20:48:29  ucko * Check HAVE_ODBCSS_H; fix some typos in an error message. * * Revision 1.4  2003/04/01 21:51:17  soussov * new attribute 'packet=XXX' (where XXX is a packet size) added to ODBC_CreateContext * * Revision 1.3  2002/07/03 21:48:50  soussov * adds DSN support if needed * * Revision 1.2  2002/07/02 20:52:54  soussov * adds RegisterDriver for ODBC * * Revision 1.1  2002/06/18 22:06:24  soussov * initial commit * * * =========================================================================== */

⌨️ 快捷键说明

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