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

📄 databasemetadata.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/*   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++/databasemetadata.h>#include <odbc++/connection.h>#include <odbc++/resultset.h>#include <odbc++/statement.h>#include "dtconv.h"#include "driverinfo.h"using namespace odbc;using namespace std;#define FETCH_STEP 64namespace odbc {  // returns the actual ODBC cursor type this datasource would  // use for a given ResultSet typeinline int getODBCCursorTypeFor(int rsType, const DriverInfo* di){  int r;  switch(rsType) {  case ResultSet::TYPE_FORWARD_ONLY:    r=SQL_CURSOR_FORWARD_ONLY;    break;  case ResultSet::TYPE_SCROLL_INSENSITIVE:    r=SQL_CURSOR_STATIC;    break;  case ResultSet::TYPE_SCROLL_SENSITIVE:    if(di->getCursorMask()&SQL_SO_DYNAMIC) {      r=SQL_CURSOR_DYNAMIC;    } else {      r=SQL_CURSOR_KEYSET_DRIVEN;    }    break;  default:    throw SQLException(ODBCXX_STRING_CONST("[libodbc++]: Invalid ResultSet type ")+intToString(rsType));  }  return r;}#if ODBCVER >= 0x0300inline int getCursorAttributes1For(int odbcType){  int infoType;  switch(odbcType) {  case SQL_CURSOR_FORWARD_ONLY:    infoType=SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1;    break;  case SQL_CURSOR_STATIC:    infoType=SQL_STATIC_CURSOR_ATTRIBUTES1;    break;  case SQL_CURSOR_KEYSET_DRIVEN:    infoType=SQL_KEYSET_CURSOR_ATTRIBUTES1;    break;  case SQL_CURSOR_DYNAMIC:  default:    infoType=SQL_DYNAMIC_CURSOR_ATTRIBUTES1;    break;  }  return infoType;}inline int getCursorAttributes2For(int odbcType){  int infoType;  switch(odbcType) {  case SQL_CURSOR_FORWARD_ONLY:    infoType=SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2;    break;  case SQL_CURSOR_STATIC:    infoType=SQL_STATIC_CURSOR_ATTRIBUTES2;    break;  case SQL_CURSOR_KEYSET_DRIVEN:    infoType=SQL_KEYSET_CURSOR_ATTRIBUTES2;    break;  case SQL_CURSOR_DYNAMIC:  default:    infoType=SQL_DYNAMIC_CURSOR_ATTRIBUTES2;    break;  }  return infoType;}#endif // ODBCVER >= 0x0300// for _ownXXXAreVisibleenum {  INSERTS,UPDATES,DELETES};}; // namespace odbcDatabaseMetaData::DatabaseMetaData(Connection* c)  :connection_(c){}DatabaseMetaData::~DatabaseMetaData(){}SQLUSMALLINT DatabaseMetaData::_getNumeric16(int what){  SQLUSMALLINT res;  SQLSMALLINT t;  SQLRETURN r=SQLGetInfo(connection_->hdbc_,			 (SQLUSMALLINT)what,			 &res,			 sizeof(res), //ignored, but what the heck..			 &t);  connection_->_checkConError(connection_->hdbc_,			      r,ODBCXX_STRING_CONST("Error fetching information"));  return res;}SQLUINTEGER DatabaseMetaData::_getNumeric32(int what){  SQLUINTEGER res;  SQLSMALLINT t;  SQLRETURN r=SQLGetInfo(connection_->hdbc_,			 (SQLUSMALLINT)what,			 &res,			 sizeof(res), //ignored, but what the heck..			 &t);  connection_->_checkConError(connection_->hdbc_,r,ODBCXX_STRING_CONST("Error fetching information"));  return res;}//privateODBCXX_STRING DatabaseMetaData::_getStringInfo(int what){  ODBCXX_STRING res;  SQLSMALLINT len1;  SQLSMALLINT len2=FETCH_STEP;  ODBCXX_CHAR_TYPE* buf=NULL;  // ODBCXX_CERR << ODBCXX_STRING_CONST("Entering _getStringInfo()") << endl;  do {    len1=len2;    buf=new ODBCXX_CHAR_TYPE[len1+1];    //    ODBCXX_CERR << ODBCXX_STRING_CONST("Calling SQLGetInfo: len1=")    //                << len1 << ODBCXX_STRING_CONST(", len2=") << len2 << endl;    SQLRETURN r=SQLGetInfo(connection_->hdbc_,			   (SQLUSMALLINT)what,			   buf,			   len1+1,			   &len2);    try {      connection_->_checkConError(connection_->hdbc_,r,ODBCXX_STRING_CONST("Error fetching information"));    } catch(...) {      delete[] buf;      throw;    }  } while(len2>len1);  // ODBCXX_CERR << ODBCXX_STRING_CONST("Exiting _getStringInfo()") << endl;  res=ODBCXX_STRING_C(buf);  delete[] buf;  return res;}#if ODBCVER >= 0x0300SQLUINTEGER DatabaseMetaData::_getAllCursorAttributes1(){  SQLUINTEGER r=0;  int cm=this->_getDriverInfo()->getCursorMask();  if(cm&SQL_SO_FORWARD_ONLY) {    r|=this->_getNumeric32(SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1);  }  if(cm&SQL_SO_STATIC) {    r|=this->_getNumeric32(SQL_STATIC_CURSOR_ATTRIBUTES1);  }  if(cm&SQL_SO_KEYSET_DRIVEN) {    r|=this->_getNumeric32(SQL_KEYSET_CURSOR_ATTRIBUTES1);  }  if(cm&SQL_SO_DYNAMIC) {    r|=this->_getNumeric32(SQL_DYNAMIC_CURSOR_ATTRIBUTES1);  }  return r;}#endifbool DatabaseMetaData::supportsBatchUpdates(){  // we don't, yet  return false;}bool DatabaseMetaData::supportsIntegrityEnhancementFacility(){  return this->_getStringInfo(SQL_ODBC_SQL_OPT_IEF)==ODBCXX_STRING_CONST("Y");}bool DatabaseMetaData::supportsPositionedDelete(){  // with ODBC 2, we can simply check SQL_POSITIONED_STATEMENTS  // for ODBC 3, we have to check if any cursor type supports this#if ODBCVER >= 0x0300  if(this->_getDriverInfo()->getMajorVersion()<3) {#endif    return (this->_getNumeric32	    (SQL_POSITIONED_STATEMENTS)&SQL_PS_POSITIONED_DELETE)!=0;#if ODBCVER >= 0x0300  }  // the ODBC 3 way  return (this->_getAllCursorAttributes1()&SQL_CA1_POSITIONED_DELETE)!=0;#endif}bool DatabaseMetaData::supportsPositionedUpdate(){#if ODBCVER >= 0x0300  if(this->_getDriverInfo()->getMajorVersion()<3) {#endif    return (this->_getNumeric32	    (SQL_POSITIONED_STATEMENTS)&SQL_PS_POSITIONED_UPDATE)!=0;#if ODBCVER >= 0x0300  }  // the ODBC 3 way  return (this->_getAllCursorAttributes1()&SQL_CA1_POSITIONED_UPDATE)!=0;#endif}bool DatabaseMetaData::supportsSelectForUpdate(){#if ODBCVER >= 0x0300  if(this->_getDriverInfo()->getMajorVersion()<3) {#endif    return (this->_getNumeric32	    (SQL_POSITIONED_STATEMENTS)&SQL_PS_SELECT_FOR_UPDATE)!=0;#if ODBCVER >= 0x0300  }  // the ODBC 3 way  return (this->_getAllCursorAttributes1()&SQL_CA1_SELECT_FOR_UPDATE)!=0;#endif}bool DatabaseMetaData::supportsTransactions(){  return this->_getNumeric16(SQL_TXN_CAPABLE)!=SQL_TC_NONE;}bool DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions(){  return this->_getNumeric16    (SQL_TXN_CAPABLE)==SQL_TC_ALL;}bool DatabaseMetaData::supportsDataManipulationTransactionsOnly(){  return this->_getNumeric16    (SQL_TXN_CAPABLE)==SQL_TC_DML;}bool DatabaseMetaData::dataDefinitionCausesTransactionCommit(){  return this->_getNumeric16    (SQL_TXN_CAPABLE)==SQL_TC_DDL_COMMIT;}bool DatabaseMetaData::dataDefinitionIgnoredInTransactions(){  return this->_getNumeric16    (SQL_TXN_CAPABLE)==SQL_TC_DDL_IGNORE;}ODBCXX_STRING DatabaseMetaData::getDatabaseProductName(){  return this->_getStringInfo(SQL_DBMS_NAME);}ODBCXX_STRING DatabaseMetaData::getDatabaseProductVersion(){  return this->_getStringInfo(SQL_DBMS_VER);}ODBCXX_STRING DatabaseMetaData::getDriverName(){  return this->_getStringInfo(SQL_DRIVER_NAME);}ODBCXX_STRING DatabaseMetaData::getDriverVersion(){  return this->_getStringInfo(SQL_DRIVER_VER);}int DatabaseMetaData::getDriverMajorVersion(){  ODBCXX_STRING s=this->_getStringInfo(SQL_DRIVER_ODBC_VER);  if(s.length()==5) {    return stringToInt(#if defined(ODBCXX_QT)		       s.left(2)#else		       s.substr(0,2)#endif		       );  }  throw SQLException    (ODBCXX_STRING_CONST("[libodbc++]: Invalid ODBC version string received from driver: ")+s);  ODBCXX_DUMMY_RETURN(0);}int DatabaseMetaData::getDriverMinorVersion(){  ODBCXX_STRING s=this->_getStringInfo(SQL_DRIVER_ODBC_VER);  if(s.length()==5) {    return stringToInt(#if defined(ODBCXX_QT)		       s.mid(3,2)#else		       s.substr(3,2)#endif		       );  }  throw SQLException    (ODBCXX_STRING_CONST("[libodbc++]: Invalid ODBC version string received from driver: ")+s);  ODBCXX_DUMMY_RETURN(0);}ODBCXX_STRING DatabaseMetaData::getIdentifierQuoteString(){  return this->_getStringInfo(SQL_IDENTIFIER_QUOTE_CHAR);}ODBCXX_STRING DatabaseMetaData::getCatalogTerm(){  return this->_getStringInfo(ODBC3_C(SQL_CATALOG_TERM,SQL_QUALIFIER_TERM));}ODBCXX_STRING DatabaseMetaData::getSchemaTerm(){  return this->_getStringInfo(ODBC3_C(SQL_SCHEMA_TERM,SQL_OWNER_TERM));}ODBCXX_STRING DatabaseMetaData::getTableTerm(){  return this->_getStringInfo(SQL_TABLE_TERM);}ODBCXX_STRING DatabaseMetaData::getProcedureTerm(){  return this->_getStringInfo(SQL_PROCEDURE_TERM);}ODBCXX_STRING DatabaseMetaData::getUserName(){  return this->_getStringInfo(SQL_USER_NAME);}ODBCXX_STRING DatabaseMetaData::getCatalogSeparator(){  return this->_getStringInfo(ODBC3_C(SQL_CATALOG_NAME_SEPARATOR,				      SQL_QUALIFIER_NAME_SEPARATOR));}bool DatabaseMetaData::isCatalogAtStart(){  return this->_getNumeric16(ODBC3_C(SQL_CATALOG_LOCATION,				     SQL_QUALIFIER_LOCATION))==SQL_QL_START;}ODBCXX_STRING DatabaseMetaData::getSQLKeywords(){  return this->_getStringInfo(SQL_KEYWORDS);}int DatabaseMetaData::getDefaultTransactionIsolation(){  SQLUINTEGER r=this->_getNumeric32(SQL_DEFAULT_TXN_ISOLATION);  switch(r) {  case SQL_TXN_READ_UNCOMMITTED:    return Connection::TRANSACTION_READ_UNCOMMITTED;  case SQL_TXN_READ_COMMITTED:    return Connection::TRANSACTION_READ_COMMITTED;  case SQL_TXN_REPEATABLE_READ:    return Connection::TRANSACTION_REPEATABLE_READ;  case SQL_TXN_SERIALIZABLE:#if defined(SQL_TXN_VERSIONING)  case SQL_TXN_VERSIONING:#endif    return Connection::TRANSACTION_SERIALIZABLE;  }  return Connection::TRANSACTION_NONE;}bool DatabaseMetaData::supportsTransactionIsolationLevel(int lev){  SQLUINTEGER r=this->_getNumeric32(SQL_TXN_ISOLATION_OPTION);  SQLUINTEGER ret=0;  switch(lev) {  case Connection::TRANSACTION_READ_UNCOMMITTED:    ret=r&SQL_TXN_READ_UNCOMMITTED;    break;  case Connection::TRANSACTION_READ_COMMITTED:    ret=r&SQL_TXN_READ_COMMITTED;    break;  case Connection::TRANSACTION_REPEATABLE_READ:    ret=r&SQL_TXN_REPEATABLE_READ;    break;  case Connection::TRANSACTION_SERIALIZABLE:    ret=(r&SQL_TXN_SERIALIZABLE)#if defined(SQL_TXN_VERSIONING)      || (r&SQL_TXN_VERSIONING)#endif      ;    break;  }  return ret!=0;}bool DatabaseMetaData::supportsOpenCursorsAcrossCommit(){  return this->_getNumeric16(SQL_CURSOR_COMMIT_BEHAVIOR)==SQL_CB_PRESERVE;}bool DatabaseMetaData::supportsOpenCursorsAcrossRollback(){  return this->_getNumeric16(SQL_CURSOR_ROLLBACK_BEHAVIOR)==SQL_CB_PRESERVE;}bool DatabaseMetaData::supportsOpenStatementsAcrossCommit(){  return this->_getNumeric16(SQL_CURSOR_COMMIT_BEHAVIOR)==SQL_CB_PRESERVE;}bool DatabaseMetaData::supportsOpenStatementsAcrossRollback(){  return this->_getNumeric16(SQL_CURSOR_ROLLBACK_BEHAVIOR)==SQL_CB_PRESERVE;}bool DatabaseMetaData::supportsResultSetType(int type){  const DriverInfo* di=this->_getDriverInfo();  switch(type) {  case ResultSet::TYPE_FORWARD_ONLY:    return di->supportsForwardOnly();    break;  case ResultSet::TYPE_SCROLL_INSENSITIVE:    return di->supportsStatic();    break;  case ResultSet::TYPE_SCROLL_SENSITIVE:    return di->supportsScrollSensitive();    break;  default:    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Invalid ResultSet type ")+       intToString(type));  }  ODBCXX_DUMMY_RETURN(false);}bool DatabaseMetaData::supportsResultSetConcurrency(int type,						    int concurrency){  const DriverInfo* di=this->_getDriverInfo();  if(!this->supportsResultSetType(type)) {    // no need to bother    return false;  }  int ct;  switch(type) {  case ResultSet::TYPE_SCROLL_SENSITIVE:    ct=di->getScrollSensitive();    break;  case ResultSet::TYPE_SCROLL_INSENSITIVE:    ct=SQL_CURSOR_STATIC;    break;  case ResultSet::TYPE_FORWARD_ONLY:    // forward only cursors are read-only by definition    return concurrency==ResultSet::CONCUR_READ_ONLY;    break;  default:    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Invalid ResultSet type ")+intToString(type));  }  switch(concurrency) {  case ResultSet::CONCUR_READ_ONLY:    return di->supportsReadOnly(ct);    break;  case ResultSet::CONCUR_UPDATABLE:    return di->supportsUpdatable(ct);    break;  default:    throw SQLException      (ODBCXX_STRING_CONST("[libodbc++]: Invalid ResultSet concurrency ")+intToString(type));  }  ODBCXX_DUMMY_RETURN(false);}bool DatabaseMetaData::nullPlusNonNullIsNull(){  return this->_getNumeric16    (SQL_CONCAT_NULL_BEHAVIOR)==SQL_CB_NULL;}bool DatabaseMetaData::supportsColumnAliasing(){  return this->_getStringInfo(SQL_COLUMN_ALIAS)==ODBCXX_STRING_CONST("Y");}

⌨️ 快捷键说明

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