1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include "odbc/OResultSetMetaData.hxx" 31 #include "odbc/OTools.hxx" 32 #include <rtl/logfile.hxx> 33 34 using namespace connectivity::odbc; 35 using namespace com::sun::star::uno; 36 using namespace com::sun::star::lang; 37 using namespace com::sun::star::sdbc; 38 39 // ------------------------------------------------------------------------- 40 OResultSetMetaData::~OResultSetMetaData() 41 { 42 } 43 // ------------------------------------------------------------------------- 44 ::rtl::OUString OResultSetMetaData::getCharColAttrib(sal_Int32 _column,sal_Int32 ident) throw(SQLException, RuntimeException) 45 { 46 sal_Int32 column = _column; 47 if(_column <(sal_Int32) m_vMapping.size()) // use mapping 48 column = m_vMapping[_column]; 49 50 SQLSMALLINT BUFFER_LEN = 128; 51 char *pName = new char[BUFFER_LEN+1]; 52 SQLSMALLINT nRealLen=0; 53 SQLRETURN nRet = N3SQLColAttribute(m_aStatementHandle, 54 (SQLUSMALLINT)column, 55 (SQLUSMALLINT)ident, 56 (SQLPOINTER)pName, 57 BUFFER_LEN, 58 &nRealLen, 59 NULL 60 ); 61 ::rtl::OUString sValue; 62 if ( nRet == SQL_SUCCESS ) 63 { 64 if ( nRealLen < 0 ) 65 nRealLen = BUFFER_LEN; 66 sValue = ::rtl::OUString(pName,nRealLen,m_pConnection->getTextEncoding()); 67 } 68 delete [] pName; 69 OTools::ThrowException(m_pConnection,nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 70 if(nRealLen > BUFFER_LEN) 71 { 72 pName = new char[nRealLen+1]; 73 nRet = N3SQLColAttribute(m_aStatementHandle, 74 (SQLUSMALLINT)column, 75 (SQLUSMALLINT)ident, 76 (SQLPOINTER)pName, 77 nRealLen, 78 &nRealLen, 79 NULL 80 ); 81 if ( nRet == SQL_SUCCESS && nRealLen > 0) 82 sValue = ::rtl::OUString(pName,nRealLen,m_pConnection->getTextEncoding()); 83 delete [] pName; 84 OTools::ThrowException(m_pConnection,nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this); 85 } 86 87 return sValue; 88 } 89 // ------------------------------------------------------------------------- 90 SQLLEN OResultSetMetaData::getNumColAttrib(OConnection* _pConnection 91 ,SQLHANDLE _aStatementHandle 92 ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface 93 ,sal_Int32 _column 94 ,sal_Int32 _ident) throw(SQLException, RuntimeException) 95 { 96 SQLLEN nValue=0; 97 OTools::ThrowException(_pConnection,(*(T3SQLColAttribute)_pConnection->getOdbcFunction(ODBC3SQLColAttribute))(_aStatementHandle, 98 (SQLUSMALLINT)_column, 99 (SQLUSMALLINT)_ident, 100 NULL, 101 0, 102 NULL, 103 &nValue),_aStatementHandle,SQL_HANDLE_STMT,_xInterface); 104 return nValue; 105 } 106 // ------------------------------------------------------------------------- 107 sal_Int32 OResultSetMetaData::getNumColAttrib(sal_Int32 _column,sal_Int32 ident) throw(SQLException, RuntimeException) 108 { 109 sal_Int32 column = _column; 110 if(_column < (sal_Int32)m_vMapping.size()) // use mapping 111 column = m_vMapping[_column]; 112 113 return getNumColAttrib(m_pConnection,m_aStatementHandle,*this,column,ident); 114 } 115 // ------------------------------------------------------------------------- 116 sal_Int32 SAL_CALL OResultSetMetaData::getColumnDisplaySize( sal_Int32 column ) throw(SQLException, RuntimeException) 117 { 118 return getNumColAttrib(column,SQL_DESC_DISPLAY_SIZE); 119 } 120 // ------------------------------------------------------------------------- 121 SQLSMALLINT OResultSetMetaData::getColumnODBCType(OConnection* _pConnection 122 ,SQLHANDLE _aStatementHandle 123 ,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xInterface 124 ,sal_Int32 column) 125 throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) 126 { 127 SQLSMALLINT nType = 0; 128 try 129 { 130 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column,SQL_DESC_CONCISE_TYPE); 131 if(nType == SQL_UNKNOWN_TYPE) 132 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column, SQL_DESC_TYPE); 133 } 134 catch(SQLException& ) // in this case we have an odbc 2.0 driver 135 { 136 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column,SQL_DESC_CONCISE_TYPE ); 137 } 138 139 return nType; 140 } 141 // ----------------------------------------------------------------------------- 142 sal_Int32 SAL_CALL OResultSetMetaData::getColumnType( sal_Int32 column ) throw(SQLException, RuntimeException) 143 { 144 ::std::map<sal_Int32,sal_Int32>::iterator aFind = m_aColumnTypes.find(column); 145 if ( aFind == m_aColumnTypes.end() ) 146 { 147 sal_Int32 nType = 0; 148 if(!m_bUseODBC2Types) 149 { 150 try 151 { 152 nType = getNumColAttrib(column,SQL_DESC_CONCISE_TYPE); 153 if(nType == SQL_UNKNOWN_TYPE) 154 nType = getNumColAttrib(column, SQL_DESC_TYPE); 155 nType = OTools::MapOdbcType2Jdbc(nType); 156 } 157 catch(SQLException& ) // in this case we have an odbc 2.0 driver 158 { 159 m_bUseODBC2Types = sal_True; 160 nType = OTools::MapOdbcType2Jdbc(getNumColAttrib(column,SQL_DESC_CONCISE_TYPE )); 161 } 162 } 163 else 164 nType = OTools::MapOdbcType2Jdbc(getNumColAttrib(column,SQL_DESC_CONCISE_TYPE )); 165 aFind = m_aColumnTypes.insert(::std::map<sal_Int32,sal_Int32>::value_type(column,nType)).first; 166 } 167 168 169 return aFind->second; 170 } 171 // ------------------------------------------------------------------------- 172 173 sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount( ) throw(SQLException, RuntimeException) 174 { 175 if(m_nColCount != -1) 176 return m_nColCount; 177 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnCount" ); 178 sal_Int16 nNumResultCols=0; 179 OTools::ThrowException(m_pConnection,N3SQLNumResultCols(m_aStatementHandle,&nNumResultCols),m_aStatementHandle,SQL_HANDLE_STMT,*this); 180 return m_nColCount = nNumResultCols; 181 } 182 // ------------------------------------------------------------------------- 183 184 sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive( sal_Int32 column ) throw(SQLException, RuntimeException) 185 { 186 return getNumColAttrib(column,SQL_DESC_CASE_SENSITIVE) == SQL_TRUE; 187 } 188 // ------------------------------------------------------------------------- 189 190 ::rtl::OUString SAL_CALL OResultSetMetaData::getSchemaName( sal_Int32 column ) throw(SQLException, RuntimeException) 191 { 192 return getCharColAttrib(column,SQL_DESC_SCHEMA_NAME); 193 } 194 // ------------------------------------------------------------------------- 195 196 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnName( sal_Int32 column ) throw(SQLException, RuntimeException) 197 { 198 return getCharColAttrib(column,SQL_DESC_NAME); 199 } 200 // ------------------------------------------------------------------------- 201 ::rtl::OUString SAL_CALL OResultSetMetaData::getTableName( sal_Int32 column ) throw(SQLException, RuntimeException) 202 { 203 return getCharColAttrib(column,SQL_DESC_TABLE_NAME); 204 } 205 // ------------------------------------------------------------------------- 206 ::rtl::OUString SAL_CALL OResultSetMetaData::getCatalogName( sal_Int32 column ) throw(SQLException, RuntimeException) 207 { 208 return getCharColAttrib(column,SQL_DESC_CATALOG_NAME); 209 } 210 // ------------------------------------------------------------------------- 211 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnTypeName( sal_Int32 column ) throw(SQLException, RuntimeException) 212 { 213 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnTypeName" ); 214 return getCharColAttrib(column,SQL_DESC_TYPE_NAME); 215 } 216 // ------------------------------------------------------------------------- 217 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnLabel( sal_Int32 column ) throw(SQLException, RuntimeException) 218 { 219 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnLabel" ); 220 return getCharColAttrib(column,SQL_DESC_LABEL); 221 } 222 // ------------------------------------------------------------------------- 223 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ ) throw(SQLException, RuntimeException) 224 { 225 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnServiceName" ); 226 return ::rtl::OUString(); 227 } 228 // ------------------------------------------------------------------------- 229 230 sal_Bool SAL_CALL OResultSetMetaData::isCurrency( sal_Int32 column ) throw(SQLException, RuntimeException) 231 { 232 return getNumColAttrib(column,SQL_DESC_FIXED_PREC_SCALE) == SQL_TRUE; 233 } 234 // ------------------------------------------------------------------------- 235 236 sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement( sal_Int32 column ) throw(SQLException, RuntimeException) 237 { 238 return getNumColAttrib(column,SQL_DESC_AUTO_UNIQUE_VALUE) == SQL_TRUE; 239 } 240 // ------------------------------------------------------------------------- 241 242 243 sal_Bool SAL_CALL OResultSetMetaData::isSigned( sal_Int32 column ) throw(SQLException, RuntimeException) 244 { 245 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isSigned" ); 246 return getNumColAttrib(column,SQL_DESC_UNSIGNED) == SQL_FALSE; 247 } 248 // ------------------------------------------------------------------------- 249 sal_Int32 SAL_CALL OResultSetMetaData::getPrecision( sal_Int32 column ) throw(SQLException, RuntimeException) 250 { 251 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getPrecision" ); 252 sal_Int32 nType = 0; 253 try 254 { 255 nType = getNumColAttrib(column,SQL_DESC_PRECISION); 256 } 257 catch(const SQLException& ) // in this case we have an odbc 2.0 driver 258 { 259 m_bUseODBC2Types = sal_True; 260 nType = getNumColAttrib(column,SQL_COLUMN_PRECISION ); 261 } 262 return nType; 263 } 264 // ----------------------------------------------------------------------------- 265 sal_Int32 SAL_CALL OResultSetMetaData::getScale( sal_Int32 column ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) 266 { 267 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getScale" ); 268 sal_Int32 nType = 0; 269 try 270 { 271 nType = getNumColAttrib(column,SQL_DESC_SCALE); 272 } 273 catch(const SQLException& ) // in this case we have an odbc 2.0 driver 274 { 275 m_bUseODBC2Types = sal_True; 276 nType = getNumColAttrib(column,SQL_COLUMN_SCALE ); 277 } 278 return nType; 279 } 280 // ------------------------------------------------------------------------- 281 282 sal_Int32 SAL_CALL OResultSetMetaData::isNullable( sal_Int32 column ) throw(SQLException, RuntimeException) 283 { 284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isNullable" ); 285 return getNumColAttrib(column,SQL_DESC_NULLABLE); 286 } 287 // ------------------------------------------------------------------------- 288 289 sal_Bool SAL_CALL OResultSetMetaData::isSearchable( sal_Int32 column ) throw(SQLException, RuntimeException) 290 { 291 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isSearchable" ); 292 return getNumColAttrib(column,SQL_DESC_SEARCHABLE) != SQL_PRED_NONE; 293 } 294 // ------------------------------------------------------------------------- 295 296 sal_Bool SAL_CALL OResultSetMetaData::isReadOnly( sal_Int32 column ) throw(SQLException, RuntimeException) 297 { 298 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isReadOnly" ); 299 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_READONLY; 300 } 301 // ------------------------------------------------------------------------- 302 303 sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) throw(SQLException, RuntimeException) 304 { 305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isDefinitelyWritable" ); 306 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_WRITE; 307 ; 308 } 309 // ------------------------------------------------------------------------- 310 sal_Bool SAL_CALL OResultSetMetaData::isWritable( sal_Int32 column ) throw(SQLException, RuntimeException) 311 { 312 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isWritable" ); 313 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_WRITE; 314 } 315 // ------------------------------------------------------------------------- 316 317