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_odbcbase.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) 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) 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) 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 ) 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 { 122 SQLSMALLINT nType = 0; 123 try 124 { 125 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column,SQL_DESC_CONCISE_TYPE); 126 if(nType == SQL_UNKNOWN_TYPE) 127 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column, SQL_DESC_TYPE); 128 } 129 catch(SQLException& ) // in this case we have an odbc 2.0 driver 130 { 131 nType = (SQLSMALLINT)getNumColAttrib(_pConnection,_aStatementHandle,_xInterface,column,SQL_DESC_CONCISE_TYPE ); 132 } 133 134 return nType; 135 } 136 // ----------------------------------------------------------------------------- 137 sal_Int32 SAL_CALL OResultSetMetaData::getColumnType( sal_Int32 column ) 138 { 139 ::std::map<sal_Int32,sal_Int32>::iterator aFind = m_aColumnTypes.find(column); 140 if ( aFind == m_aColumnTypes.end() ) 141 { 142 sal_Int32 nType = 0; 143 if(!m_bUseODBC2Types) 144 { 145 try 146 { 147 nType = getNumColAttrib(column,SQL_DESC_CONCISE_TYPE); 148 if(nType == SQL_UNKNOWN_TYPE) 149 nType = getNumColAttrib(column, SQL_DESC_TYPE); 150 nType = OTools::MapOdbcType2Jdbc(nType); 151 } 152 catch(SQLException& ) // in this case we have an odbc 2.0 driver 153 { 154 m_bUseODBC2Types = sal_True; 155 nType = OTools::MapOdbcType2Jdbc(getNumColAttrib(column,SQL_DESC_CONCISE_TYPE )); 156 } 157 } 158 else 159 nType = OTools::MapOdbcType2Jdbc(getNumColAttrib(column,SQL_DESC_CONCISE_TYPE )); 160 aFind = m_aColumnTypes.insert(::std::map<sal_Int32,sal_Int32>::value_type(column,nType)).first; 161 } 162 163 164 return aFind->second; 165 } 166 // ------------------------------------------------------------------------- 167 168 sal_Int32 SAL_CALL OResultSetMetaData::getColumnCount( ) 169 { 170 if(m_nColCount != -1) 171 return m_nColCount; 172 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnCount" ); 173 sal_Int16 nNumResultCols=0; 174 OTools::ThrowException(m_pConnection,N3SQLNumResultCols(m_aStatementHandle,&nNumResultCols),m_aStatementHandle,SQL_HANDLE_STMT,*this); 175 return m_nColCount = nNumResultCols; 176 } 177 // ------------------------------------------------------------------------- 178 179 sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive( sal_Int32 column ) 180 { 181 return getNumColAttrib(column,SQL_DESC_CASE_SENSITIVE) == SQL_TRUE; 182 } 183 // ------------------------------------------------------------------------- 184 185 ::rtl::OUString SAL_CALL OResultSetMetaData::getSchemaName( sal_Int32 column ) 186 { 187 return getCharColAttrib(column,SQL_DESC_SCHEMA_NAME); 188 } 189 // ------------------------------------------------------------------------- 190 191 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnName( sal_Int32 column ) 192 { 193 return getCharColAttrib(column,SQL_DESC_NAME); 194 } 195 // ------------------------------------------------------------------------- 196 ::rtl::OUString SAL_CALL OResultSetMetaData::getTableName( sal_Int32 column ) 197 { 198 return getCharColAttrib(column,SQL_DESC_TABLE_NAME); 199 } 200 // ------------------------------------------------------------------------- 201 ::rtl::OUString SAL_CALL OResultSetMetaData::getCatalogName( sal_Int32 column ) 202 { 203 return getCharColAttrib(column,SQL_DESC_CATALOG_NAME); 204 } 205 // ------------------------------------------------------------------------- 206 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnTypeName( sal_Int32 column ) 207 { 208 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnTypeName" ); 209 return getCharColAttrib(column,SQL_DESC_TYPE_NAME); 210 } 211 // ------------------------------------------------------------------------- 212 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnLabel( sal_Int32 column ) 213 { 214 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnLabel" ); 215 return getCharColAttrib(column,SQL_DESC_LABEL); 216 } 217 // ------------------------------------------------------------------------- 218 ::rtl::OUString SAL_CALL OResultSetMetaData::getColumnServiceName( sal_Int32 /*column*/ ) 219 { 220 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getColumnServiceName" ); 221 return ::rtl::OUString(); 222 } 223 // ------------------------------------------------------------------------- 224 225 sal_Bool SAL_CALL OResultSetMetaData::isCurrency( sal_Int32 column ) 226 { 227 return getNumColAttrib(column,SQL_DESC_FIXED_PREC_SCALE) == SQL_TRUE; 228 } 229 // ------------------------------------------------------------------------- 230 231 sal_Bool SAL_CALL OResultSetMetaData::isAutoIncrement( sal_Int32 column ) 232 { 233 return getNumColAttrib(column,SQL_DESC_AUTO_UNIQUE_VALUE) == SQL_TRUE; 234 } 235 // ------------------------------------------------------------------------- 236 237 238 sal_Bool SAL_CALL OResultSetMetaData::isSigned( sal_Int32 column ) 239 { 240 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isSigned" ); 241 return getNumColAttrib(column,SQL_DESC_UNSIGNED) == SQL_FALSE; 242 } 243 // ------------------------------------------------------------------------- 244 sal_Int32 SAL_CALL OResultSetMetaData::getPrecision( sal_Int32 column ) 245 { 246 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getPrecision" ); 247 sal_Int32 nType = 0; 248 try 249 { 250 nType = getNumColAttrib(column,SQL_DESC_PRECISION); 251 } 252 catch(const SQLException& ) // in this case we have an odbc 2.0 driver 253 { 254 m_bUseODBC2Types = sal_True; 255 nType = getNumColAttrib(column,SQL_COLUMN_PRECISION ); 256 } 257 return nType; 258 } 259 // ----------------------------------------------------------------------------- 260 sal_Int32 SAL_CALL OResultSetMetaData::getScale( sal_Int32 column ) 261 { 262 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::getScale" ); 263 sal_Int32 nType = 0; 264 try 265 { 266 nType = getNumColAttrib(column,SQL_DESC_SCALE); 267 } 268 catch(const SQLException& ) // in this case we have an odbc 2.0 driver 269 { 270 m_bUseODBC2Types = sal_True; 271 nType = getNumColAttrib(column,SQL_COLUMN_SCALE ); 272 } 273 return nType; 274 } 275 // ------------------------------------------------------------------------- 276 277 sal_Int32 SAL_CALL OResultSetMetaData::isNullable( sal_Int32 column ) 278 { 279 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isNullable" ); 280 return getNumColAttrib(column,SQL_DESC_NULLABLE); 281 } 282 // ------------------------------------------------------------------------- 283 284 sal_Bool SAL_CALL OResultSetMetaData::isSearchable( sal_Int32 column ) 285 { 286 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isSearchable" ); 287 return getNumColAttrib(column,SQL_DESC_SEARCHABLE) != SQL_PRED_NONE; 288 } 289 // ------------------------------------------------------------------------- 290 291 sal_Bool SAL_CALL OResultSetMetaData::isReadOnly( sal_Int32 column ) 292 { 293 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isReadOnly" ); 294 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_READONLY; 295 } 296 // ------------------------------------------------------------------------- 297 298 sal_Bool SAL_CALL OResultSetMetaData::isDefinitelyWritable( sal_Int32 column ) 299 { 300 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isDefinitelyWritable" ); 301 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_WRITE; 302 ; 303 } 304 // ------------------------------------------------------------------------- 305 sal_Bool SAL_CALL OResultSetMetaData::isWritable( sal_Int32 column ) 306 { 307 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSetMetaData::isWritable" ); 308 return getNumColAttrib(column,SQL_DESC_UPDATABLE) == SQL_ATTR_WRITE; 309 } 310 // ------------------------------------------------------------------------- 311