Tag: cws_src680_dba205b User: fs Date: 2006/08/09 13:00:58 Modified: dba/connectivity/source/commontools/TTableHelper.cxx
Log: during #b6248060#: respect the OrdinalPosition as returned by XDatabaseMetaData::getColumns - don't assume the columns are returned in the same order as they appear in the table File Changes: Directory: /dba/connectivity/source/commontools/ ================================================ File [changed]: TTableHelper.cxx Url: http://dba.openoffice.org/source/browse/dba/connectivity/source/commontools/TTableHelper.cxx?r1=1.5&r2=1.5.18.1 Delta lines: +106 -13 ---------------------- --- TTableHelper.cxx 10 Jul 2006 14:19:45 -0000 1.5 +++ TTableHelper.cxx 9 Aug 2006 20:00:56 -0000 1.5.18.1 @@ -4,9 +4,9 @@ * * $RCSfile: TTableHelper.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.5.18.1 $ * - * last change: $Author: obo $ $Date: 2006/07/10 14:19:45 $ + * last change: $Author: fs $ $Date: 2006/08/09 20:00:56 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -72,6 +72,9 @@ #ifndef _CONNECTIVITY_SDBCX_COLLECTION_HXX_ #include "connectivity/sdbcx/VCollection.hxx" #endif +#ifndef UNOTOOLS_INC_SHAREDUNOCOMPONENT_HXX +#include <unotools/sharedunocomponent.hxx> +#endif #ifndef CONNECTIVITY_CONNECTION_HXX #include "TConnection.hxx" #endif @@ -133,6 +136,80 @@ m_xConnection = NULL; m_xMetaData = NULL; } + +// ------------------------------------------------------------------------- +namespace +{ + typedef sal_Int32 OrdinalPosition; + struct ColumnDesc + { + ::rtl::OUString sName; + OrdinalPosition nOrdinalPosition; + + ColumnDesc() {} + ColumnDesc( const ::rtl::OUString& _rName, OrdinalPosition _nPosition ) + :sName( _rName ) + ,nOrdinalPosition( _nPosition ) + { + } + }; + + /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns + */ + void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, ::std::vector< ColumnDesc >& _out_rColumns ) + { + Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW ); + ::rtl::OUString sName; + OrdinalPosition nOrdinalPosition( 0 ); + while ( _rxResult->next() ) + { + sName = xRow->getString( 4 ); // COLUMN_NAME + nOrdinalPosition = xRow->getInt( 17 ); // ORDINAL_POSITION + _out_rColumns.push_back( ColumnDesc( sName, nOrdinalPosition ) ); + } + } + + /** checks a given array of ColumnDesc's whether it has reasonable ordinal positions. If not, + they will be normalized to be the array index. + */ + void lcl_sanitizeColumnDescs( ::std::vector< ColumnDesc >& _rColumns ) + { + ::std::set< OrdinalPosition > aUsedOrdinals; + bool bDuplicates = false; + bool bTooSmall = false; + bool bTooLarge = false; + size_t nColumnCount( _rColumns.size() ); + for ( ::std::vector< ColumnDesc >::const_iterator check = _rColumns.begin(); + ( check != _rColumns.end() ) && !bDuplicates && !bTooSmall && !bTooLarge; + ++check + ) + { + if ( aUsedOrdinals.find( check->nOrdinalPosition ) != aUsedOrdinals.end() ) + bDuplicates = true; + else if ( check->nOrdinalPosition < 1 ) + bTooSmall = true; + else if ( check->nOrdinalPosition > (OrdinalPosition)nColumnCount ) + bTooLarge = true; + else + aUsedOrdinals.insert( check->nOrdinalPosition ); + } + + if ( bDuplicates || bTooSmall || bTooLarge ) + { + OSL_ENSURE( false, "lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" ); + + OrdinalPosition nNormalizedPosition = 1; + for ( ::std::vector< ColumnDesc >::iterator reset = _rColumns.begin(); + reset != _rColumns.end(); + ++reset, ++nNormalizedPosition + ) + { + reset->nOrdinalPosition = nNormalizedPosition; + } + } + } +} + // ------------------------------------------------------------------------- void OTableHelper::refreshColumns() { @@ -142,20 +219,36 @@ Any aCatalog; if ( m_CatalogName.getLength() ) aCatalog <<= m_CatalogName; -OSL_TRACE( "meta data: %p", getMetaData().get() ); - Reference< XResultSet > xResult = getMetaData()->getColumns( + + ::utl::SharedUNOComponent< XResultSet > xResult( getMetaData()->getColumns( aCatalog, m_SchemaName, m_Name, - ::rtl::OUString::createFromAscii("%")); + ::rtl::OUString::createFromAscii("%") + ) ); - if ( xResult.is() ) - { - Reference< XRow > xRow(xResult,UNO_QUERY); - while( xResult->next() ) - aVector.push_back(xRow->getString(4)); - ::comphelper::disposeComponent(xResult); - } + // collect the column names, together with their ordinal position + ::std::vector< ColumnDesc > aColumns; + lcl_collectColumnDescs_throw( xResult, aColumns ); + + // ensure that the ordinal positions as obtained from the meta data do make sense + lcl_sanitizeColumnDescs( aColumns ); + + // sort by ordinal position + ::std::map< OrdinalPosition, ::rtl::OUString > aSortedColumns; + for ( ::std::vector< ColumnDesc >::const_iterator copy = aColumns.begin(); + copy != aColumns.end(); + ++copy + ) + aSortedColumns[ copy->nOrdinalPosition ] = copy->sName; + + // copy them to aVector, now that we have the proper ordering + ::std::transform( + aSortedColumns.begin(), + aSortedColumns.end(), + ::std::insert_iterator< TStringVector >( aVector, aVector.begin() ), + ::std::select2nd< ::std::map< OrdinalPosition, ::rtl::OUString >::value_type >() + ); } if(m_pColumns) --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
