📄 context.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: context.cpp,v $ * PRODUCTION Revision 1000.3 2004/06/01 19:20:45 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.26 * PRODUCTION * =========================================================================== *//* $Id: context.cpp,v 1000.3 2004/06/01 19:20:45 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 TDS server * */#include <ncbi_pch.hpp>#include <corelib/ncbimtx.hpp>#include <dbapi/driver/ftds/interfaces.hpp>#include <dbapi/driver/util/numeric_convert.hpp>BEGIN_NCBI_SCOPE///////////////////////////////////////////////////////////////////////////////// CTDSContext:://extern "C" { static int s_TDS_err_callback(DBPROCESS* dblink, int severity, int dberr, int oserr, char* dberrstr, char* oserrstr) { return CTDSContext::TDS_dberr_handler (dblink, severity, dberr, oserr, dberrstr? dberrstr : "", oserrstr? oserrstr : ""); } static int s_TDS_msg_callback(DBPROCESS* dblink, DBINT msgno, int msgstate, int severity, char* msgtxt, char* srvname, char* procname, int line) { CTDSContext::TDS_dbmsg_handler (dblink, msgno, msgstate, severity, msgtxt? msgtxt : "", srvname? srvname : "", procname? procname : "", line); return 0; }}CTDSContext* CTDSContext::m_pTDSContext = 0;CTDSContext::CTDSContext(DBINT version) : m_AppName("TDSDriver"), m_HostName(""), m_PacketSize(0){ DEFINE_STATIC_FAST_MUTEX(xMutex); CFastMutexGuard mg(xMutex); if (m_pTDSContext != 0) { throw CDB_ClientEx(eDB_Error, 200000, "CTDSContext::CTDSContext", "You cannot use more than one ftds contexts " "concurrently"); } char hostname[256]; if(gethostname(hostname, 256) == 0) { hostname[255]= '\0'; m_HostName= hostname; } if (dbinit() != SUCCEED) { throw CDB_ClientEx(eDB_Fatal, 200001, "CTDSContext::CTDSContext", "dbinit failed"); } m_Timeout= m_LoginTimeout= 0; dberrhandle(s_TDS_err_callback); dbmsghandle(s_TDS_msg_callback); m_pTDSContext = this; m_Login = dblogin();}bool CTDSContext::SetLoginTimeout(unsigned int nof_secs){ m_LoginTimeout= nof_secs; return true; // return dbsetlogintime(nof_secs) == SUCCEED;}bool CTDSContext::SetTimeout(unsigned int nof_secs){ m_Timeout= nof_secs; return true; // return dbsettime(nof_secs) == SUCCEED;}bool CTDSContext::SetMaxTextImageSize(size_t nof_bytes){ char s[64]; sprintf(s, "%lu", (unsigned long) nof_bytes); return dbsetopt(0, DBTEXTLIMIT, s, -1) == SUCCEED /* && dbsetopt(0, DBTEXTSIZE, s, -1) == SUCCEED */;}CDB_Connection* CTDSContext::Connect(const string& srv_name, const string& user_name, const string& passwd, TConnectionMode mode, bool reusable, const string& pool_name){ CTDS_Connection* t_con; // static CFastMutex xMutex; CFastMutexGuard mg(m_Mtx); if (reusable && m_NotInUse.NofItems() > 0) { // try to reuse connection if (!pool_name.empty()) { // try to use pool name int n = m_NotInUse.NofItems(); while (n--) { t_con = static_cast<CTDS_Connection*> (m_NotInUse.Get(n)); if (pool_name.compare(t_con->PoolName()) == 0) { m_NotInUse.Remove(n); 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; int n = m_NotInUse.NofItems(); // try to use server name while (n--) { t_con = static_cast<CTDS_Connection*> (m_NotInUse.Get(n)); if (srv_name.compare(t_con->ServerName()) == 0) { m_NotInUse.Remove(n); 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, 200010, "CTDSContext::Connect", "Insufficient info/credentials to connect"); } DBPROCESS* dbcon = x_ConnectToServer(srv_name, user_name, passwd, mode); if (!dbcon) { throw CDB_ClientEx(eDB_Error, 200011, "CTDSContext::Connect", "Cannot connect to server"); } t_con = new CTDS_Connection(this, dbcon, 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);}bool CTDSContext::IsAbleTo(ECapability cpb) const{ switch(cpb) { case eReturnITDescriptors: return true; case eReturnComputeResults: case eBcp: default: break; } return false;}CTDSContext::~CTDSContext(){ CTDS_Connection* t_con; // close all connections first for (int i = m_NotInUse.NofItems(); i--; ) { t_con = static_cast<CTDS_Connection*> (m_NotInUse.Get(i)); delete t_con; } for (int i = m_InUse.NofItems(); i--; ) { t_con = static_cast<CTDS_Connection*> (m_InUse.Get(i)); delete t_con; } dbloginfree(m_Login); dbexit(); m_pTDSContext = 0;}void CTDSContext::TDS_SetApplicationName(const string& app_name){ m_AppName = app_name;}void CTDSContext::TDS_SetHostName(const string& host_name){ m_HostName = host_name;}void CTDSContext::TDS_SetPacketSize(int p_size){ m_PacketSize = (short) p_size;}bool CTDSContext::TDS_SetMaxNofConns(int n){ return dbsetmaxprocs(n) == SUCCEED;}int CTDSContext::TDS_dberr_handler(DBPROCESS* dblink, int severity, int dberr, int oserr, const string& dberrstr, const string& oserrstr){ CTDS_Connection* link = dblink ? reinterpret_cast<CTDS_Connection*> (dbgetuserdata(dblink)) : 0; CDBHandlerStack* hs = link ? &link->m_MsgHandlers : &m_pTDSContext->m_CntxHandlers; switch (dberr) { case SYBETIME: case SYBEFCON: case SYBECONN: { CDB_TimeoutEx to(dberr, "dblib", dberrstr); hs->PostMsg(&to);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -