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

📄 statement.cpp

📁 絲路server源碼 Silk Road server source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*   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++/statement.h>#include <odbc++/resultset.h>#include <odbc++/connection.h>#include "driverinfo.h"#include "dtconv.h"using namespace odbc;using namespace std;Statement::Statement(Connection* con, SQLHSTMT hstmt,		     int resultSetType, int resultSetConcurrency)  :connection_(con),  hstmt_(hstmt),  lastExecute_(SQL_SUCCESS),  currentResultSet_(NULL),  fetchSize_(SQL_ROWSET_SIZE_DEFAULT),  resultSetType_(resultSetType),  resultSetConcurrency_(resultSetConcurrency),  state_(STATE_CLOSED){  try {    this->_applyResultSetType();  } catch(...) {    // avoid a statement handle leak (the destructor will not be called)#if ODBCVER < 0x0300    SQLFreeStmt(hstmt_,SQL_DROP);#else    SQLFreeHandle(SQL_HANDLE_STMT,hstmt_);#endif    throw;  }}Statement::~Statement(){  if(currentResultSet_!=NULL) {    currentResultSet_->ownStatement_=false;    delete currentResultSet_;    currentResultSet_=NULL;  }#if ODBCVER < 0x0300    SQLFreeStmt(hstmt_,SQL_DROP);#else    SQLFreeHandle(SQL_HANDLE_STMT,hstmt_);#endif  connection_->_unregisterStatement(this);}//privatevoid Statement::_registerResultSet(ResultSet* rs){  assert(currentResultSet_==NULL);  currentResultSet_=rs;}void Statement::_unregisterResultSet(ResultSet* rs){  assert(currentResultSet_==rs);  currentResultSet_=NULL;}//protectedSQLUINTEGER Statement::_getNumericOption(SQLINTEGER optnum){  SQLUINTEGER res;  SQLRETURN r;#if ODBCVER < 0x0300  r=SQLGetStmtOption(hstmt_,optnum,(SQLPOINTER)&res);#else  SQLINTEGER dummy;  r=SQLGetStmtAttr(hstmt_,optnum,(SQLPOINTER)&res,SQL_IS_UINTEGER,&dummy);#endif  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching numeric statement option"));  return res;}//protectedvoid Statement::_setNumericOption(SQLINTEGER optnum, SQLUINTEGER value){  SQLRETURN r;#if ODBCVER < 0x0300  r=SQLSetStmtOption(hstmt_,optnum,value);#else  r=SQLSetStmtAttr(hstmt_,optnum,(SQLPOINTER)value,SQL_IS_UINTEGER);#endif  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error setting numeric statement option"));}//protectedODBCXX_STRING Statement::_getStringOption(SQLINTEGER optnum){  SQLRETURN r;#if ODBCVER < 0x0300  ODBCXX_CHAR_TYPE buf[SQL_MAX_OPTION_STRING_LENGTH+1];  r=SQLGetStmtOption(hstmt_,optnum,(SQLPOINTER)buf);  this->_checkStmtError(hstmt_,r,"Error fetching string statement option");#else  ODBCXX_CHAR_TYPE buf[256];  SQLINTEGER dataSize;  r=SQLGetStmtAttr(hstmt_,optnum,(SQLPOINTER)buf,255,&dataSize);  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching string statement option"));  if(dataSize>255) {    // we have a longer attribute here    ODBCXX_CHAR_TYPE* tmp=new ODBCXX_CHAR_TYPE[dataSize+1];    odbc::Deleter<ODBCXX_CHAR_TYPE> _tmp(tmp,true);    r=SQLGetStmtAttr(hstmt_,optnum,(SQLPOINTER)tmp,dataSize,&dataSize);    this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching string statement option"));    return ODBCXX_STRING_C(tmp);  }#endif  return ODBCXX_STRING_C(buf);}//protectedvoid Statement::_setStringOption(SQLINTEGER optnum,				 const ODBCXX_STRING& value){  SQLRETURN r;#if ODBCVER < 0x0300  r=SQLSetStmtOption(hstmt_,optnum,		     (SQLUINTEGER) ODBCXX_STRING_CSTR(value));#else  r=SQLSetStmtAttr(hstmt_,optnum,		   (SQLPOINTER) ODBCXX_STRING_CSTR(value),		   ODBCXX_STRING_LEN(value));#endif  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error setting string statement option"));}#if ODBCVER >= 0x0300SQLPOINTER Statement::_getPointerOption(SQLINTEGER optnum){  SQLPOINTER ret;  SQLINTEGER len;  SQLRETURN r=SQLGetStmtAttr(hstmt_,optnum,(SQLPOINTER)&ret,			     SQL_IS_POINTER,&len);  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching pointer statement option"));			  return ret;}void Statement::_setPointerOption(SQLINTEGER optnum, SQLPOINTER value){  SQLRETURN r=SQLSetStmtAttr(hstmt_,optnum,value,SQL_IS_POINTER);  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error setting pointer statement option"));}#endifvoid Statement::_applyResultSetType(){  const DriverInfo* di=this->_getDriverInfo();  int ct;  switch(resultSetType_) {  case ResultSet::TYPE_FORWARD_ONLY:    ct=SQL_CURSOR_FORWARD_ONLY;    break;  case ResultSet::TYPE_SCROLL_INSENSITIVE:    if(di->supportsStatic()) {      ct=SQL_CURSOR_STATIC;    } else {      throw SQLException	(ODBCXX_STRING_CONST("[libodbc++]: Datasource does not support ResultSet::TYPE_SCROLL_INSENSITIVE"));    }    break;  case ResultSet::TYPE_SCROLL_SENSITIVE:    if(di->supportsScrollSensitive()) {      ct=di->getScrollSensitive();    } else {      throw SQLException	(ODBCXX_STRING_CONST("[libodbc++]: Datasource does not support ResultSet::TYPE_SCROLL_SENSITIVE"));    }    break;  default:    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Invalid ResultSet type"));  }  if(ct!=SQL_CURSOR_FORWARD_ONLY) {    this->_setNumericOption      (ODBC3_C(SQL_ATTR_CURSOR_TYPE,SQL_CURSOR_TYPE),ct);  }  // concurrency:  switch(resultSetConcurrency_) {  case ResultSet::CONCUR_READ_ONLY:    // we only apply this for non-default cursors    if(ct!=SQL_CURSOR_FORWARD_ONLY) {      if(di->supportsReadOnly(ct)) {	this->_setNumericOption	  (ODBC3_C(SQL_ATTR_CONCURRENCY,SQL_CONCURRENCY),SQL_CONCUR_READ_ONLY);      } else {	throw SQLException	  (ODBCXX_STRING_CONST("[libodbc++]: ResultSet::CONCUR_READ_ONLY not supported for given type"));      }    }    break;  case ResultSet::CONCUR_UPDATABLE:    if(di->supportsUpdatable(ct)) {      this->_setNumericOption	(ODBC3_C(SQL_ATTR_CONCURRENCY,SQL_CONCURRENCY),	 di->getUpdatable(ct));    } else {      throw SQLException	(ODBCXX_STRING_CONST("[libodbc++]: ResultSet::CONCUR_UPDATABLE not supported for given type"));    }    break;  default:    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Invalid concurrency level"));  }}//protectedbool Statement::_checkForResults(){  SQLSMALLINT nc;  SQLRETURN r=SQLNumResultCols(hstmt_,&nc);  return r==SQL_SUCCESS && nc>0;}//protectedResultSet* Statement::_getResultSet(bool hideMe){  ResultSet* rs=new ResultSet(this,hstmt_,hideMe);  this->_registerResultSet(rs);  return rs;}//protectedvoid Statement::_beforeExecute(){  this->clearWarnings();  if(currentResultSet_!=NULL) {    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Cannot re-execute; statement has an open resultset"));  }  if(state_==STATE_OPEN) {    SQLRETURN r=SQLFreeStmt(hstmt_,SQL_CLOSE);    this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error closing statement"));    state_=STATE_CLOSED;  }}//protectedvoid Statement::_afterExecute(){  state_=STATE_OPEN;}//private catalog stuff//this statement should be hidden behind a ResultSet//but since it can be obtained with ResultSet->getStatement()//we still track the state (before/afterExecute).inline ODBCXX_SQLCHAR* valueOrNull(const ODBCXX_STRING& str){  return (ODBCXX_SQLCHAR*)(ODBCXX_STRING_LEN(str)>0?		    ODBCXX_STRING_DATA(str):NULL);}ResultSet* Statement::_getTypeInfo(){  this->_beforeExecute();  SQLRETURN r=SQLGetTypeInfo(hstmt_,SQL_ALL_TYPES);  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching type information"));  this->_afterExecute();  ResultSet* rs=this->_getResultSet(true);  return rs;}ResultSet* Statement::_getColumns(const ODBCXX_STRING& catalog,				  const ODBCXX_STRING& schema,				  const ODBCXX_STRING& tableName,				  const ODBCXX_STRING& columnName){  this->_beforeExecute();  SQLRETURN r=SQLColumns(hstmt_,			 valueOrNull(catalog),			 ODBCXX_STRING_LEN(catalog),			 valueOrNull(schema),			 ODBCXX_STRING_LEN(schema),			 valueOrNull(tableName),			 ODBCXX_STRING_LEN(tableName),			 valueOrNull(columnName),			 ODBCXX_STRING_LEN(columnName));  this->_checkStmtError(hstmt_,r,ODBCXX_STRING_CONST("Error fetching column information"));  ResultSet* rs=this->_getResultSet(true);  return rs;}ResultSet* Statement::_getTables(const ODBCXX_STRING& catalog,				 const ODBCXX_STRING& schema,				 const ODBCXX_STRING& tableName,				 const ODBCXX_STRING& types){  this->_beforeExecute();  SQLRETURN r=SQLTables(hstmt_,			valueOrNull(catalog),			ODBCXX_STRING_LEN(catalog),			valueOrNull(schema),			ODBCXX_STRING_LEN(schema),			valueOrNull(tableName),			ODBCXX_STRING_LEN(tableName),

⌨️ 快捷键说明

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