📄 context.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: context.cpp,v $ * PRODUCTION Revision 1000.5 2004/06/01 19:19:38 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.32 * PRODUCTION * =========================================================================== *//* $Id: context.cpp,v 1000.5 2004/06/01 19:19:38 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 CTLib server * */#include <ncbi_pch.hpp>#include <dbapi/driver/ctlib/interfaces.hpp>#include <dbapi/driver/util/numeric_convert.hpp>#if defined(NCBI_OS_MSWIN)# include <winsock.h>#else# include <unistd.h>#endifBEGIN_NCBI_SCOPE///////////////////////////////////////////////////////////////////////////////// CTLibContext:://CS_START_EXTERN_C CS_RETCODE CS_PUBLIC s_CTLIB_cserr_callback(CS_CONTEXT* context, CS_CLIENTMSG* msg) { return CTLibContext::CTLIB_cserr_handler(context, msg) ? CS_SUCCEED : CS_FAIL; } CS_RETCODE CS_PUBLIC s_CTLIB_cterr_callback(CS_CONTEXT* context, CS_CONNECTION* con, CS_CLIENTMSG* msg) { return CTLibContext::CTLIB_cterr_handler(context, con, msg) ? CS_SUCCEED : CS_FAIL; } CS_RETCODE CS_PUBLIC s_CTLIB_srverr_callback(CS_CONTEXT* context, CS_CONNECTION* con, CS_SERVERMSG* msg) { return CTLibContext::CTLIB_srverr_handler(context, con, msg) ? CS_SUCCEED : CS_FAIL; }CS_END_EXTERN_CCTLibContext::CTLibContext(bool reuse_context, CS_INT version){ DEFINE_STATIC_FAST_MUTEX(xMutex); CFastMutexGuard mg(xMutex); m_Context = 0; m_AppName = "CTLibDriver"; m_LoginRetryCount = 0; m_LoginLoopDelay = 0; m_PacketSize = 2048; CS_RETCODE r = reuse_context ? cs_ctx_global(version, &m_Context) : cs_ctx_alloc(version, &m_Context); if (r != CS_SUCCEED) { m_Context = 0; throw CDB_ClientEx(eDB_Fatal, 100001, "CTLibContext::CTLibContext", "Can not allocate a context"); } CS_VOID* cb; CS_INT outlen; CPointerPot* p_pot = 0; // check if cs message callback is already installed r = cs_config(m_Context, CS_GET, CS_MESSAGE_CB, &cb, CS_UNUSED, &outlen); if (r != CS_SUCCEED) { m_Context = 0; throw CDB_ClientEx(eDB_Error, 100006, "CTLibContext::CTLibContext", "cs_config failed"); } if (cb == (CS_VOID*) s_CTLIB_cserr_callback) { // we did use this context already r = cs_config(m_Context, CS_GET, CS_USERDATA, (CS_VOID*) &p_pot, (CS_INT) sizeof(p_pot), &outlen); if (r != CS_SUCCEED) { m_Context = 0; throw CDB_ClientEx(eDB_Error, 100006, "CTLibContext::CTLibContext", "cs_config failed"); } } else { // this is a brand new context r = cs_config(m_Context, CS_SET, CS_MESSAGE_CB, (CS_VOID*) s_CTLIB_cserr_callback, CS_UNUSED, NULL); if (r != CS_SUCCEED) { cs_ctx_drop(m_Context); m_Context = 0; throw CDB_ClientEx(eDB_Error, 100005, "CTLibContext::CTLibContext", "Can not install the cslib message callback"); } p_pot = new CPointerPot; r = cs_config(m_Context, CS_SET, CS_USERDATA, (CS_VOID*) &p_pot, (CS_INT) sizeof(p_pot), NULL); if (r != CS_SUCCEED) { cs_ctx_drop(m_Context); m_Context = 0; delete p_pot; throw CDB_ClientEx(eDB_Error, 100007, "CTLibContext::CTLibContext", "Can not install the user data"); } r = ct_init(m_Context, version); if (r != CS_SUCCEED) { cs_ctx_drop(m_Context); m_Context = 0; delete p_pot; throw CDB_ClientEx(eDB_Error, 100002, "CTLibContext::CTLibContext", "ct_init failed"); } r = ct_callback(m_Context, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID*) s_CTLIB_cterr_callback); if (r != CS_SUCCEED) { ct_exit(m_Context, CS_FORCE_EXIT); cs_ctx_drop(m_Context); m_Context = 0; delete p_pot; throw CDB_ClientEx(eDB_Error, 100003, "CTLibContext::CTLibContext", "Can not install the client message callback"); } r = ct_callback(m_Context, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID*) s_CTLIB_srverr_callback); if (r != CS_SUCCEED) { ct_exit(m_Context, CS_FORCE_EXIT); cs_ctx_drop(m_Context); m_Context = 0; delete p_pot; throw CDB_ClientEx(eDB_Error, 100004, "CTLibContext::CTLibContext", "Can not install the server message callback"); } } if ( p_pot ) { p_pot->Add((TPotItem) this); }}bool CTLibContext::SetLoginTimeout(unsigned int nof_secs){ CS_INT t_out = (CS_INT) nof_secs; return ct_config(m_Context, CS_SET, CS_LOGIN_TIMEOUT, &t_out, CS_UNUSED, NULL) == CS_SUCCEED;}bool CTLibContext::SetTimeout(unsigned int nof_secs){ CS_INT t_out = (CS_INT) nof_secs; return ct_config(m_Context, CS_SET, CS_TIMEOUT, &t_out, CS_UNUSED, NULL) == CS_SUCCEED;}bool CTLibContext::SetMaxTextImageSize(size_t nof_bytes){ CS_INT ti_size = (CS_INT) nof_bytes; return ct_config(m_Context, CS_SET, CS_TEXTLIMIT, &ti_size, CS_UNUSED, NULL) == CS_SUCCEED;}CDB_Connection* CTLibContext::Connect(const string& srv_name, const string& user_name, const string& passwd, TConnectionMode mode, bool reusable, const string& pool_name){ //DEFINE_STATIC_FAST_MUTEX(xMutex); // CFastMutexGuard mg(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--; ) { CTL_Connection* t_con = static_cast<CTL_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 { // using server name as a pool name if ( srv_name.empty() ) return 0; // try to use a server name for (int i = m_NotInUse.NofItems(); i--; ) { CTL_Connection* t_con = static_cast<CTL_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, "CTLibContext::Connect", "You have to provide server name, user name and " "password to connect to the server"); } CS_CONNECTION* con = x_ConnectToServer(srv_name, user_name, passwd, mode); if (con == 0) { throw CDB_ClientEx(eDB_Error, 100011, "CTLibContext::Connect", "Can not connect to the server"); } CTL_Connection* t_con = new CTL_Connection(this, con, reusable, pool_name); t_con->m_MsgHandlers = m_ConnHandlers; m_InUse.Add((TPotItem) t_con); return Create_Connection(*t_con);}bool CTLibContext::IsAbleTo(ECapability cpb) const{ switch(cpb) { case eBcp: case eReturnITDescriptors: case eReturnComputeResults: return true; default: break; } return false;}CTLibContext::~CTLibContext(){ CFastMutexGuard mg(m_Mtx); if ( !m_Context ) { return; } // close all connections first for (int i = m_NotInUse.NofItems(); i--; ) { CTL_Connection* t_con = static_cast<CTL_Connection*>(m_NotInUse.Get(i)); delete t_con; } for (int i = m_InUse.NofItems(); i--; ) { CTL_Connection* t_con = static_cast<CTL_Connection*> (m_InUse.Get(i)); delete t_con; } CS_INT outlen; CPointerPot* p_pot = 0; if (cs_config(m_Context, CS_GET, CS_USERDATA, (void*) &p_pot, (CS_INT) sizeof(p_pot), &outlen) == CS_SUCCEED && p_pot != 0) { p_pot->Remove(this); if (p_pot->NofItems() == 0) { // this is a last driver for this context delete p_pot; if (ct_exit(m_Context, CS_UNUSED) != CS_SUCCEED) { ct_exit(m_Context, CS_FORCE_EXIT); } cs_ctx_drop(m_Context); } }}void CTLibContext::CTLIB_SetApplicationName(const string& a_name){ m_AppName = a_name;}void CTLibContext::CTLIB_SetHostName(const string& host_name){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -