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