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_dbaccess.hxx" 26 #ifndef _DBACORE_RESULTCOLUMN_HXX_ 27 #include "resultcolumn.hxx" 28 #endif 29 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ 30 #include <com/sun/star/lang/DisposedException.hpp> 31 #endif 32 #ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_ 33 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> 34 #endif 35 #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_ 36 #include <com/sun/star/sdbc/DataType.hpp> 37 #endif 38 #ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_ 39 #include <com/sun/star/sdbc/ColumnValue.hpp> 40 #endif 41 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ 42 #include <cppuhelper/typeprovider.hxx> 43 #endif 44 #ifndef _TOOLS_DEBUG_HXX 45 #include <tools/debug.hxx> 46 #endif 47 #ifndef TOOLS_DIAGNOSE_EX_H 48 #include <tools/diagnose_ex.h> 49 #endif 50 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC 51 #include "dbastrings.hrc" 52 #endif 53 #ifndef _DBASHARED_APITOOLS_HXX_ 54 #include "apitools.hxx" 55 #endif 56 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ 57 #include <com/sun/star/beans/PropertyAttribute.hpp> 58 #endif 59 #ifndef _CPPUHELPER_EXC_HLP_HXX_ 60 #include <cppuhelper/exc_hlp.hxx> 61 #endif 62 #ifndef _OSL_THREAD_H_ 63 #include <osl/thread.h> 64 #endif 65 66 using namespace ::com::sun::star::sdbc; 67 using namespace ::com::sun::star::beans; 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::lang; 70 using namespace ::com::sun::star::container; 71 using namespace ::osl; 72 using namespace ::comphelper; 73 using namespace ::cppu; 74 using namespace dbaccess; 75 76 DBG_NAME(OResultColumn) 77 //-------------------------------------------------------------------------- 78 OResultColumn::OResultColumn( const Reference < XResultSetMetaData >& _xMetaData, sal_Int32 _nPos, 79 const Reference< XDatabaseMetaData >& _rxDBMeta ) 80 :OColumn( true ) 81 ,m_xMetaData( _xMetaData ) 82 ,m_xDBMetaData( _rxDBMeta ) 83 ,m_nPos( _nPos ) 84 { 85 DBG_CTOR(OResultColumn,NULL); 86 } 87 // ----------------------------------------------------------------------------- 88 void OResultColumn::impl_determineIsRowVersion_nothrow() 89 { 90 if ( m_aIsRowVersion.hasValue() ) 91 return; 92 m_aIsRowVersion <<= (sal_Bool)(sal_False); 93 94 OSL_ENSURE( m_xDBMetaData.is(), "OResultColumn::impl_determineIsRowVersion_nothrow: no DBMetaData!" ); 95 if ( !m_xDBMetaData.is() ) 96 return; 97 98 try 99 { 100 ::rtl::OUString sCatalog, sSchema, sTable, sColumnName; 101 getPropertyValue( PROPERTY_CATALOGNAME ) >>= sCatalog; 102 getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema; 103 getPropertyValue( PROPERTY_TABLENAME ) >>= sTable; 104 getPropertyValue( PROPERTY_NAME ) >>= sColumnName; 105 106 try 107 { 108 Reference< XResultSet > xVersionColumns = m_xDBMetaData->getVersionColumns( 109 makeAny( sCatalog ), sSchema, sTable ); 110 if ( xVersionColumns.is() ) // allowed to be NULL 111 { 112 Reference< XRow > xResultRow( xVersionColumns, UNO_QUERY_THROW ); 113 while ( xVersionColumns->next() ) 114 { 115 if ( xResultRow->getString( 2 ) == sColumnName ) 116 { 117 m_aIsRowVersion <<= (sal_Bool)(sal_True); 118 break; 119 } 120 } 121 } 122 } 123 catch(const SQLException&) 124 { 125 } 126 } 127 catch( const Exception& ) 128 { 129 DBG_UNHANDLED_EXCEPTION(); 130 } 131 } 132 // ----------------------------------------------------------------------------- 133 OResultColumn::~OResultColumn() 134 { 135 DBG_DTOR(OResultColumn,NULL); 136 } 137 // com::sun::star::lang::XTypeProvider 138 //-------------------------------------------------------------------------- 139 Sequence< sal_Int8 > OResultColumn::getImplementationId() throw (RuntimeException) 140 { 141 static OImplementationId * pId = 0; 142 if (! pId) 143 { 144 MutexGuard aGuard( Mutex::getGlobalMutex() ); 145 if (! pId) 146 { 147 static OImplementationId aId; 148 pId = &aId; 149 } 150 } 151 return pId->getImplementationId(); 152 } 153 154 // XServiceInfo 155 //------------------------------------------------------------------------------ 156 rtl::OUString OResultColumn::getImplementationName( ) throw(RuntimeException) 157 { 158 return rtl::OUString::createFromAscii("com.sun.star.sdb.OResultColumn"); 159 } 160 161 //------------------------------------------------------------------------------ 162 Sequence< ::rtl::OUString > OResultColumn::getSupportedServiceNames( ) throw (RuntimeException) 163 { 164 Sequence< ::rtl::OUString > aSNS( 2 ); 165 aSNS[0] = SERVICE_SDBCX_COLUMN; 166 aSNS[1] = SERVICE_SDB_RESULTCOLUMN; 167 return aSNS; 168 } 169 170 // OComponentHelper 171 //------------------------------------------------------------------------------ 172 void OResultColumn::disposing() 173 { 174 OColumn::disposing(); 175 176 MutexGuard aGuard(m_aMutex); 177 m_xMetaData = NULL; 178 } 179 180 // comphelper::OPropertyArrayUsageHelper 181 //------------------------------------------------------------------------------ 182 ::cppu::IPropertyArrayHelper* OResultColumn::createArrayHelper( ) const 183 { 184 BEGIN_PROPERTY_HELPER(21) 185 DECL_PROP1(CATALOGNAME, ::rtl::OUString, READONLY); 186 DECL_PROP1(DISPLAYSIZE, sal_Int32, READONLY); 187 DECL_PROP1_BOOL(ISAUTOINCREMENT, READONLY); 188 DECL_PROP1_BOOL(ISCASESENSITIVE, READONLY); 189 DECL_PROP1_BOOL(ISCURRENCY, READONLY); 190 DECL_PROP1_BOOL(ISDEFINITELYWRITABLE, READONLY); 191 DECL_PROP1(ISNULLABLE, sal_Int32, READONLY); 192 DECL_PROP1_BOOL(ISREADONLY, READONLY); 193 DECL_PROP1_BOOL(ISROWVERSION, READONLY); 194 DECL_PROP1_BOOL(ISSEARCHABLE, READONLY); 195 DECL_PROP1_BOOL(ISSIGNED, READONLY); 196 DECL_PROP1_BOOL(ISWRITABLE, READONLY); 197 DECL_PROP1(LABEL, ::rtl::OUString, READONLY); 198 DECL_PROP1(NAME, ::rtl::OUString, READONLY); 199 DECL_PROP1(PRECISION, sal_Int32, READONLY); 200 DECL_PROP1(SCALE, sal_Int32, READONLY); 201 DECL_PROP1(SCHEMANAME, ::rtl::OUString, READONLY); 202 DECL_PROP1(SERVICENAME, ::rtl::OUString, READONLY); 203 DECL_PROP1(TABLENAME, ::rtl::OUString, READONLY); 204 DECL_PROP1(TYPE, sal_Int32, READONLY); 205 DECL_PROP1(TYPENAME, ::rtl::OUString, READONLY); 206 END_PROPERTY_HELPER(); 207 } 208 209 // cppu::OPropertySetHelper 210 //------------------------------------------------------------------------------ 211 ::cppu::IPropertyArrayHelper& OResultColumn::getInfoHelper() 212 { 213 return *static_cast< ::comphelper::OPropertyArrayUsageHelper< OResultColumn >* >(this)->getArrayHelper(); 214 } 215 216 //------------------------------------------------------------------------------ 217 namespace 218 { 219 template< typename TYPE > 220 void obtain( Any& _out_rValue, ::boost::optional< TYPE > _rCache, const sal_Int32 _nPos, const Reference < XResultSetMetaData >& _rxResultMeta, TYPE (SAL_CALL XResultSetMetaData::*Getter)( sal_Int32 ) ) 221 { 222 if ( !_rCache ) 223 _rCache.reset( (_rxResultMeta.get()->*Getter)( _nPos ) ); 224 _out_rValue <<= *_rCache; 225 } 226 } 227 228 //------------------------------------------------------------------------------ 229 void OResultColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const 230 { 231 try 232 { 233 if ( OColumn::isRegisteredProperty( nHandle ) ) 234 { 235 OColumn::getFastPropertyValue( rValue, nHandle ); 236 } 237 else 238 { 239 switch (nHandle) 240 { 241 case PROPERTY_ID_ISROWVERSION: 242 const_cast< OResultColumn* >( this )->impl_determineIsRowVersion_nothrow(); 243 rValue = m_aIsRowVersion; 244 break; 245 case PROPERTY_ID_TABLENAME: 246 rValue <<= m_xMetaData->getTableName(m_nPos); 247 break; 248 case PROPERTY_ID_SCHEMANAME: 249 rValue <<= m_xMetaData->getSchemaName(m_nPos); 250 break; 251 case PROPERTY_ID_CATALOGNAME: 252 rValue <<= m_xMetaData->getCatalogName(m_nPos); 253 break; 254 case PROPERTY_ID_ISSIGNED: 255 obtain( rValue, m_isSigned, m_nPos, m_xMetaData, &XResultSetMetaData::isSigned ); 256 break; 257 case PROPERTY_ID_ISCURRENCY: 258 obtain( rValue, m_isCurrency, m_nPos, m_xMetaData, &XResultSetMetaData::isCurrency ); 259 break; 260 case PROPERTY_ID_ISSEARCHABLE: 261 obtain( rValue, m_bSearchable, m_nPos, m_xMetaData, &XResultSetMetaData::isSearchable ); 262 break; 263 case PROPERTY_ID_ISCASESENSITIVE: 264 obtain( rValue, m_isCaseSensitive, m_nPos, m_xMetaData, &XResultSetMetaData::isCaseSensitive ); 265 break; 266 case PROPERTY_ID_ISREADONLY: 267 obtain( rValue, m_isReadOnly, m_nPos, m_xMetaData, &XResultSetMetaData::isReadOnly ); 268 break; 269 case PROPERTY_ID_ISWRITABLE: 270 obtain( rValue, m_isWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isWritable ); 271 break; 272 case PROPERTY_ID_ISDEFINITELYWRITABLE: 273 obtain( rValue, m_isDefinitelyWritable, m_nPos, m_xMetaData, &XResultSetMetaData::isDefinitelyWritable ); 274 break; 275 case PROPERTY_ID_ISAUTOINCREMENT: 276 obtain( rValue, m_isAutoIncrement, m_nPos, m_xMetaData, &XResultSetMetaData::isAutoIncrement ); 277 break; 278 case PROPERTY_ID_SERVICENAME: 279 rValue <<= m_xMetaData->getColumnServiceName(m_nPos); 280 break; 281 case PROPERTY_ID_LABEL: 282 obtain( rValue, m_sColumnLabel, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnLabel ); 283 break; 284 case PROPERTY_ID_DISPLAYSIZE: 285 obtain( rValue, m_nColumnDisplaySize, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnDisplaySize ); 286 break; 287 case PROPERTY_ID_TYPE: 288 obtain( rValue, m_nColumnType, m_nPos, m_xMetaData, &XResultSetMetaData::getColumnType ); 289 break; 290 case PROPERTY_ID_PRECISION: 291 obtain( rValue, m_nPrecision, m_nPos, m_xMetaData, &XResultSetMetaData::getPrecision ); 292 break; 293 case PROPERTY_ID_SCALE: 294 obtain( rValue, m_nScale, m_nPos, m_xMetaData, &XResultSetMetaData::getScale ); 295 break; 296 case PROPERTY_ID_ISNULLABLE: 297 obtain( rValue, m_isNullable, m_nPos, m_xMetaData, &XResultSetMetaData::isNullable ); 298 break; 299 case PROPERTY_ID_TYPENAME: 300 rValue <<= m_xMetaData->getColumnTypeName(m_nPos); 301 break; 302 default: 303 OSL_ENSURE( false, "OResultColumn::getFastPropertyValue: unknown property handle!" ); 304 break; 305 } 306 } 307 } 308 catch (SQLException& ) 309 { 310 // default handling if we caught an exception 311 switch (nHandle) 312 { 313 case PROPERTY_ID_LABEL: 314 case PROPERTY_ID_TYPENAME: 315 case PROPERTY_ID_SERVICENAME: 316 case PROPERTY_ID_TABLENAME: 317 case PROPERTY_ID_SCHEMANAME: 318 case PROPERTY_ID_CATALOGNAME: 319 // empty string'S 320 rValue <<= rtl::OUString(); 321 break; 322 case PROPERTY_ID_ISROWVERSION: 323 case PROPERTY_ID_ISAUTOINCREMENT: 324 case PROPERTY_ID_ISWRITABLE: 325 case PROPERTY_ID_ISDEFINITELYWRITABLE: 326 case PROPERTY_ID_ISCASESENSITIVE: 327 case PROPERTY_ID_ISSEARCHABLE: 328 case PROPERTY_ID_ISCURRENCY: 329 case PROPERTY_ID_ISSIGNED: 330 { 331 sal_Bool bVal = sal_False; 332 rValue.setValue(&bVal, getBooleanCppuType()); 333 } break; 334 case PROPERTY_ID_ISREADONLY: 335 { 336 sal_Bool bVal = sal_True; 337 rValue.setValue(&bVal, getBooleanCppuType()); 338 } break; 339 case PROPERTY_ID_SCALE: 340 case PROPERTY_ID_PRECISION: 341 case PROPERTY_ID_DISPLAYSIZE: 342 rValue <<= sal_Int32(0); 343 break; 344 case PROPERTY_ID_TYPE: 345 rValue <<= sal_Int32(DataType::SQLNULL); 346 break; 347 case PROPERTY_ID_ISNULLABLE: 348 rValue <<= ColumnValue::NULLABLE_UNKNOWN; 349 break; 350 } 351 } 352 } 353 354