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]

Reply via email to