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

📄 connection.cpp

📁 絲路server源碼 Silk Road server source
💻 CPP
字号:
/*   This file is part of libodbc++.   Copyright (C) 1999-2000 Manush Dodunekov <manush@stendahls.net>   This library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public   License as published by the Free Software Foundation; either   version 2 of the License, or (at your option) any later version.   This library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public License   along with this library; see the file COPYING.  If not, write to   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.*/#include <odbc++/connection.h>#include <odbc++/databasemetadata.h>#include <odbc++/resultset.h>#include <odbc++/callablestatement.h>#include "driverinfo.h"#include <set>using namespace odbc;using namespace std;struct Connection::PD {  typedef std::set<Statement*,std::less<Statement*> > StatementList;  StatementList statements_;  SQLHDBC hdbc_;#ifdef ODBCXX_ENABLE_THREADS  Mutex access_;#endif};Connection::Connection(SQLHDBC h)  :pd_(new PD()),   hdbc_(h),   driverInfo_(NULL){  metaData_=new DatabaseMetaData(this);}Connection::~Connection(){  while(!pd_->statements_.empty()) {    PD::StatementList::iterator      i=pd_->statements_.begin();    delete *i;  }  delete metaData_;  delete driverInfo_;  //no error checking performed here  SQLDisconnect(hdbc_);#if ODBCVER < 0x0300  SQLFreeConnect(hdbc_);#else  SQLFreeHandle(SQL_HANDLE_DBC,hdbc_);#endif  delete pd_;}//private//We have a case where the calling statement won't be registered//with this connection. When a constructor in a subclass//of Statement fails, the Statement destructor will still//be called.void Connection::_unregisterStatement(Statement* stmt){  ODBCXX_LOCKER(pd_->access_);  PD::StatementList::iterator    i=pd_->statements_.find(stmt);  if(i!=pd_->statements_.end()) {    pd_->statements_.erase(i);  }}void Connection::_registerStatement(Statement* stmt){  ODBCXX_LOCKER(pd_->access_);  pd_->statements_.insert(pd_->statements_.end(),stmt);}//privateSQLUINTEGER Connection::_getNumericOption(SQLINTEGER optnum){#if ODBCVER < 0x0300  SQLUINTEGER res;  SQLRETURN r=SQLGetConnectOption(hdbc_,optnum,(SQLPOINTER)&res);  this->_checkConError(hdbc_,r,"Error fetching numeric connection option");  return res;#else  // ODBC 3  SQLUINTEGER res;  SQLINTEGER dummy;  SQLRETURN r=SQLGetConnectAttr(hdbc_,optnum,(SQLPOINTER)&res, sizeof(res),&dummy);  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error fetching numeric connection attribute"));  return res;#endif}//privateODBCXX_STRING Connection::_getStringOption(SQLINTEGER optnum){#if ODBCVER < 0x0300  ODBCXX_CHAR_TYPE buf[SQL_MAX_OPTION_STRING_LENGTH+1]; //paranoia  SQLRETURN r=SQLGetConnectOption(hdbc_,optnum,(ODBCXX_SQLCHAR*)buf);  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error fetching string connection option"));  return ODBCXX_STRING_C(buf);#else  ODBCXX_CHAR_TYPE buf[256];  SQLINTEGER optSize;  SQLRETURN r=SQLGetConnectAttr(hdbc_,optnum,(SQLPOINTER)buf, 255, &optSize);  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error fetching string connection attribute"));  if(optSize>255) {    ODBCXX_CHAR_TYPE* tmp=new ODBCXX_CHAR_TYPE[optSize+1];    odbc::Deleter<ODBCXX_CHAR_TYPE> _tmp(tmp,true);    r=SQLGetConnectAttr(hdbc_,optnum,(SQLPOINTER)tmp,optSize,&optSize);    this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error fetching string connection attribute"));    return ODBCXX_STRING_C(tmp);  }  return ODBCXX_STRING_C(buf);#endif}//privatevoid Connection::_setNumericOption(SQLINTEGER optnum, SQLUINTEGER value){  SQLRETURN r=#if ODBCVER < 0x0300    SQLSetConnectOption(hdbc_,optnum,value)#else    SQLSetConnectAttr(hdbc_,optnum,(SQLPOINTER)value,sizeof(value))#endif    ;  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error setting numeric connection option"));}//privatevoid Connection::_setStringOption(SQLINTEGER optnum, const ODBCXX_STRING& value){  SQLRETURN r=#if ODBCVER < 0x0300    SQLSetConnectOption(hdbc_,optnum,			(SQLUINTEGER)ODBCXX_STRING_CSTR(value))#else    SQLSetConnectAttr(hdbc_,optnum,		      (SQLPOINTER)ODBCXX_STRING_CSTR(value),		      ODBCXX_STRING_LEN(value));#endif    ;  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Error setting string connection option"));}//privatevoid Connection::_connect(const ODBCXX_STRING& dsn,			  const ODBCXX_STRING& user,			  const ODBCXX_STRING& password){  SQLRETURN r=SQLConnect(hdbc_,			 (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(dsn),			 ODBCXX_STRING_LEN(dsn),			 (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(user),			 ODBCXX_STRING_LEN(user),			 (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(password),			 ODBCXX_STRING_LEN(password));  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Failed to connect to datasource"));  driverInfo_=new DriverInfo(this);}void Connection::_connect(const ODBCXX_STRING& connectString){  ODBCXX_SQLCHAR dummy[256];  SQLSMALLINT dummySize;  SQLRETURN r=SQLDriverConnect(hdbc_,			       0,			       (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(connectString),			       ODBCXX_STRING_LEN(connectString),			       dummy,			       255,			       &dummySize,			       SQL_DRIVER_COMPLETE);  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Failed to connect to datasource"));  driverInfo_=new DriverInfo(this);}bool Connection::getAutoCommit(){  return this->_getNumericOption    (ODBC3_C(SQL_ATTR_AUTOCOMMIT,SQL_AUTOCOMMIT))==SQL_AUTOCOMMIT_ON;}void Connection::setAutoCommit(bool ac){  this->_setNumericOption    (ODBC3_C(SQL_ATTR_AUTOCOMMIT,SQL_AUTOCOMMIT),     ac?SQL_AUTOCOMMIT_ON:SQL_AUTOCOMMIT_OFF);}void Connection::commit(){  SQLRETURN r=#if ODBCVER >= 0x0300    SQLEndTran(SQL_HANDLE_DBC, hdbc_, SQL_COMMIT)#else    SQLTransact(SQL_NULL_HENV, hdbc_, SQL_COMMIT)#endif    ;  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Commit failed"));}void Connection::rollback(){  SQLRETURN r=#if ODBCVER >= 0x0300    SQLEndTran(SQL_HANDLE_DBC, hdbc_, SQL_ROLLBACK)#else    SQLTransact(SQL_NULL_HENV, hdbc_, SQL_ROLLBACK)#endif    ;  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Rollback failed"));}void Connection::setCatalog(const ODBCXX_STRING& catalog){  this->_setStringOption    (ODBC3_C(SQL_ATTR_CURRENT_CATALOG,	     SQL_CURRENT_QUALIFIER), catalog);}ODBCXX_STRING Connection::getCatalog(){  return this->_getStringOption    (ODBC3_C(SQL_ATTR_CURRENT_CATALOG,SQL_CURRENT_QUALIFIER));}Connection::TransactionIsolationConnection::getTransactionIsolation(){  if(metaData_->supportsTransactions()) {    SQLUINTEGER r=this->_getNumericOption      (ODBC3_C(SQL_ATTR_TXN_ISOLATION,SQL_TXN_ISOLATION));    switch(r) {    case SQL_TXN_READ_UNCOMMITTED:      return TRANSACTION_READ_UNCOMMITTED;    case SQL_TXN_READ_COMMITTED:      return TRANSACTION_READ_COMMITTED;    case SQL_TXN_REPEATABLE_READ:      return TRANSACTION_REPEATABLE_READ;    case SQL_TXN_SERIALIZABLE:#if ODBCVER < 0x0300 && defined SQL_TXN_VERSIONING    case SQL_TXN_VERSIONING:#endif      return TRANSACTION_SERIALIZABLE;    }  }  return TRANSACTION_NONE;}void Connection::setTransactionIsolation(TransactionIsolation i){  if(metaData_->supportsTransactions()) {    SQLUINTEGER l;    switch(i) {    case TRANSACTION_READ_UNCOMMITTED:      l=SQL_TXN_READ_UNCOMMITTED;      break;    case TRANSACTION_READ_COMMITTED:      l=SQL_TXN_READ_COMMITTED;      break;    case TRANSACTION_REPEATABLE_READ:      l=SQL_TXN_REPEATABLE_READ;      break;    case TRANSACTION_SERIALIZABLE:      l=SQL_TXN_SERIALIZABLE;      break;    default:      throw SQLException	(ODBCXX_STRING_CONST("[libodbc++]: Invalid transaction isolation"));    }    this->_setNumericOption      (ODBC3_C(SQL_ATTR_TXN_ISOLATION,SQL_TXN_ISOLATION),l);  } else {    throw SQLException(ODBCXX_STRING_CONST("[libodbc++]: Data source does not support transactions"));  }}void Connection::setReadOnly(bool readOnly){  this->_setNumericOption    (ODBC3_C(SQL_ATTR_ACCESS_MODE, SQL_ACCESS_MODE),     readOnly?SQL_MODE_READ_ONLY:SQL_MODE_READ_WRITE);}bool Connection::isReadOnly(){  return this->_getNumericOption    (ODBC3_C(SQL_ATTR_ACCESS_MODE,SQL_ACCESS_MODE))==SQL_MODE_READ_ONLY;}bool Connection::getTrace(){  return this->_getNumericOption    (ODBC3_C(SQL_ATTR_TRACE,SQL_OPT_TRACE))==SQL_OPT_TRACE_ON;}void Connection::setTrace(bool on){  this->_setNumericOption    (ODBC3_C(SQL_ATTR_TRACE,SQL_OPT_TRACE),     on?SQL_OPT_TRACE_ON:SQL_OPT_TRACE_OFF);}ODBCXX_STRING Connection::getTraceFile(){  return this->_getStringOption    (ODBC3_C(SQL_ATTR_TRACEFILE,SQL_OPT_TRACEFILE));}void Connection::setTraceFile(const ODBCXX_STRING& fn){  this->_setStringOption    (ODBC3_C(SQL_ATTR_TRACEFILE,SQL_OPT_TRACEFILE),     fn);}ODBCXX_STRING Connection::nativeSQL(const ODBCXX_STRING& sql){  ODBCXX_CHAR_TYPE buf[256];  SQLINTEGER dataSize;  SQLRETURN r;  r=SQLNativeSql(hdbc_,		 (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(sql),		 ODBCXX_STRING_LEN(sql),		 (ODBCXX_SQLCHAR*)buf,		 255,		 &dataSize);  ODBCXX_STRING msg(ODBCXX_STRING_CONST("Error converting ")+sql+ODBCXX_STRING_CONST(" to native SQL"));  this->_checkConError(hdbc_,r,		       ODBCXX_STRING_CSTR(msg));  if(dataSize>255) {    ODBCXX_CHAR_TYPE* tmp=new ODBCXX_CHAR_TYPE[dataSize+1];    odbc::Deleter<ODBCXX_CHAR_TYPE> _tmp(tmp,true);    r=SQLNativeSql(hdbc_,		   (ODBCXX_SQLCHAR*) ODBCXX_STRING_DATA(sql),		   ODBCXX_STRING_LEN(sql),		   (ODBCXX_SQLCHAR*)tmp,		   dataSize+1,		   &dataSize);    this->_checkConError(hdbc_, r, ODBCXX_STRING_CSTR(msg));    return ODBCXX_STRING_C(tmp);  }  return ODBCXX_STRING_C(buf);}DatabaseMetaData* Connection::getMetaData(){  return metaData_;}//privateSQLHSTMT Connection::_allocStmt(){  SQLHSTMT hstmt;  SQLRETURN r=#if ODBCVER < 0x0300    SQLAllocStmt(hdbc_,&hstmt)#else    SQLAllocHandle(SQL_HANDLE_STMT,hdbc_,&hstmt)#endif    ;  this->_checkConError(hdbc_,r,ODBCXX_STRING_CONST("Statement allocation failed"));  return hstmt;}Statement* Connection::createStatement(){  //default values  return this->createStatement(ResultSet::TYPE_FORWARD_ONLY,			       ResultSet::CONCUR_READ_ONLY);}Statement* Connection::createStatement(int resultSetType,				       int resultSetConcurrency){  SQLHSTMT hstmt=this->_allocStmt();  Statement* stmt=new Statement(this,hstmt,resultSetType,resultSetConcurrency);  this->_registerStatement(stmt);  return stmt;}PreparedStatement* Connection::prepareStatement(const ODBCXX_STRING& sql){  //default values  return this->prepareStatement(sql,				ResultSet::TYPE_FORWARD_ONLY,				ResultSet::CONCUR_READ_ONLY);}PreparedStatement* Connection::prepareStatement(const ODBCXX_STRING& sql,						int resultSetType,						int resultSetConcurrency){  SQLHSTMT hstmt=this->_allocStmt();  PreparedStatement* pstmt=new PreparedStatement(this,hstmt,sql,						 resultSetType,						 resultSetConcurrency);  this->_registerStatement(pstmt);  return pstmt;}CallableStatement* Connection::prepareCall(const ODBCXX_STRING& sql){  return this->prepareCall(sql,			   ResultSet::TYPE_FORWARD_ONLY,			   ResultSet::CONCUR_READ_ONLY);}CallableStatement* Connection::prepareCall(const ODBCXX_STRING& sql,					   int resultSetType,					   int resultSetConcurrency){  SQLHSTMT hstmt=this->_allocStmt();  CallableStatement* cstmt= new CallableStatement(this,hstmt,sql,						  resultSetType,						  resultSetConcurrency);  this->_registerStatement(cstmt);  return cstmt;}

⌨️ 快捷键说明

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