diff options
author | Vladimir Glazunov <vg@openoffice.org> | 2010-10-14 12:52:12 +0200 |
---|---|---|
committer | Vladimir Glazunov <vg@openoffice.org> | 2010-10-14 12:52:12 +0200 |
commit | 686cf6927fdc031d07a8c2da04cbbc3de290d940 (patch) | |
tree | 664d130efd76e76f5f44f60e7ab06e665df6a8af /dbaccess/source | |
parent | 797f6c2c125f5bd93fc82066b9171d1a44440e73 (diff) | |
parent | c07e7342edf658a0722ad3b0c8b4fe8da8c0742b (diff) |
#i10000# changes from OOO330 m10
Diffstat (limited to 'dbaccess/source')
-rw-r--r-- | dbaccess/source/core/api/KeySet.cxx | 70 | ||||
-rw-r--r-- | dbaccess/source/core/api/KeySet.hxx | 7 | ||||
-rw-r--r-- | dbaccess/source/core/api/OptimisticSet.cxx | 2 | ||||
-rw-r--r-- | dbaccess/source/core/api/RowSetCache.cxx | 103 | ||||
-rw-r--r-- | dbaccess/source/core/inc/DatabaseDataProvider.hxx | 2 | ||||
-rw-r--r-- | dbaccess/source/core/misc/DatabaseDataProvider.cxx | 301 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppController.cxx | 19 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppControllerGen.cxx | 3 |
8 files changed, 286 insertions, 221 deletions
diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx index 6a7cd4087..1f20fd129 100644 --- a/dbaccess/source/core/api/KeySet.cxx +++ b/dbaccess/source/core/api/KeySet.cxx @@ -197,9 +197,10 @@ void OKeySet::initColumns() m_pParameterNames.reset( new SelectColumnsMetaData(bCase) ); m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) ); } -void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable - ,const Reference<XDatabaseMetaData>& i_xMeta - ,const Reference<XNameAccess>& i_xQueryColumns) +void OKeySet::findTableColumnsMatching_throw( const Any& i_aTable, + const ::rtl::OUString& i_rUpdateTableName, + const Reference<XDatabaseMetaData>& i_xMeta, + const Reference<XNameAccess>& i_xQueryColumns) { // first ask the database itself for the best columns which can be used Sequence< ::rtl::OUString> aBestColumnNames; @@ -220,37 +221,48 @@ void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i]; } - if ( m_sUpdateTableName.getLength() ) + ::rtl::OUString sUpdateTableName( i_rUpdateTableName ); + if ( sUpdateTableName.getLength() == 0 ) { - ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,m_sUpdateTableName,(*m_pKeyColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),m_sUpdateTableName,(*m_pColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,m_sUpdateTableName,(*m_pParameterNames),true); + OSL_ENSURE( false, "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." ); + // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement, + // then the below code will not produce correct results. + // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named + // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is + // already lost here. + // now getColumnPositions would travers the columns, and check which of them belong to the table denoted + // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table + // named "alias", there will be no matching - so getColumnPositions wouldn't find anything. + + ::rtl::OUString sCatalog, sSchema, sTable; + Reference<XPropertySet> xTableProp( i_aTable, UNO_QUERY_THROW ); + xTableProp->getPropertyValue( PROPERTY_CATALOGNAME )>>= sCatalog; + xTableProp->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema; + xTableProp->getPropertyValue( PROPERTY_NAME ) >>= sTable; + sUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation ); } - else + + ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*m_pKeyColumnNames),true); + ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true); + ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true); + + if ( m_pKeyColumnNames->empty() ) { - ::rtl::OUString sCatalog,sSchema,sTable; - Reference<XPropertySet> xTableProp(i_aTable,UNO_QUERY); - Any aCatalog = xTableProp->getPropertyValue(PROPERTY_CATALOGNAME); - aCatalog >>= sCatalog; - xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema; - xTableProp->getPropertyValue(PROPERTY_NAME) >>= sTable; - const ::rtl::OUString sComposedUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation ); - ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sComposedUpdateTableName,(*m_pKeyColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sComposedUpdateTableName,(*m_pColumnNames),true); - ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sComposedUpdateTableName,(*m_pParameterNames),true); + ::dbtools::throwGenericSQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not find any key column." ) ), *this ); } - SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin(); - SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end(); - for(;aPosIter != aPosEnd;++aPosIter) + for ( SelectColumnsMetaData::const_iterator keyColumn = m_pKeyColumnNames->begin(); + keyColumn != m_pKeyColumnNames->end(); + ++keyColumn + ) { - if ( xTblColumns->hasByName(aPosIter->second.sRealName) ) - { - Reference<XPropertySet> xProp(xTblColumns->getByName(aPosIter->second.sRealName),UNO_QUERY); - sal_Bool bAuto = sal_False; - if( (xProp->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bAuto) && bAuto) - m_aAutoColumns.push_back(aPosIter->first); - } + if ( !xTblColumns->hasByName( keyColumn->second.sRealName ) ) + continue; + + Reference<XPropertySet> xProp( xTblColumns->getByName( keyColumn->second.sRealName ), UNO_QUERY ); + sal_Bool bAuto = sal_False; + if ( ( xProp->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= bAuto ) && bAuto ) + m_aAutoColumns.push_back( keyColumn->first ); } } ::rtl::OUStringBuffer OKeySet::createKeyFilter() @@ -286,7 +298,7 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY); const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns(); - findTableColumnsMatching_throw(makeAny(m_xTable),xMeta,xQueryColumns); + findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns); // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first // without extra varaible to be set diff --git a/dbaccess/source/core/api/KeySet.hxx b/dbaccess/source/core/api/KeySet.hxx index 5403a56d6..631c22340 100644 --- a/dbaccess/source/core/api/KeySet.hxx +++ b/dbaccess/source/core/api/KeySet.hxx @@ -142,9 +142,10 @@ namespace dbaccess void impl_convertValue_throw(const ORowSetRow& _rInsertRow,const SelectColumnDescription& i_aMetaData); void initColumns(); - void findTableColumnsMatching_throw( const ::com::sun::star::uno::Any& i_aTable - ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>& i_xMeta - ,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& i_xQueryColumns); + void findTableColumnsMatching_throw( const ::com::sun::star::uno::Any& i_aTable, + const ::rtl::OUString& i_rUpdateTableName, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>& i_xMeta, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& i_xQueryColumns); ::rtl::OUStringBuffer createKeyFilter(); void tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch); void executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,const ::std::vector<sal_Int32>& _aIndexColumnPositions = ::std::vector<sal_Int32>()); diff --git a/dbaccess/source/core/api/OptimisticSet.cxx b/dbaccess/source/core/api/OptimisticSet.cxx index b68910d0f..832513330 100644 --- a/dbaccess/source/core/api/OptimisticSet.cxx +++ b/dbaccess/source/core/api/OptimisticSet.cxx @@ -133,7 +133,7 @@ void OptimisticSet::construct(const Reference< XResultSet>& _xDriverSet,const :: const ::rtl::OUString* pTableNameEnd = pTableNameIter + aTableNames.getLength(); for( ; pTableNameIter != pTableNameEnd ; ++pTableNameIter) { - findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),xMeta,xQueryColumns); + findTableColumnsMatching_throw(xTables->getByName(*pTableNameIter),*pTableNameIter,xMeta,xQueryColumns); } // the first row is empty because it's now easier for us to distinguish when we are beforefirst or first diff --git a/dbaccess/source/core/api/RowSetCache.cxx b/dbaccess/source/core/api/RowSetCache.cxx index d42c8d20f..73c671258 100644 --- a/dbaccess/source/core/api/RowSetCache.cxx +++ b/dbaccess/source/core/api/RowSetCache.cxx @@ -28,84 +28,44 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" -#ifndef _COMPHELPER_SEQSTREAM_HXX -#include <comphelper/seqstream.hxx> -#endif -#ifndef _COMPHELPER_UNO3_HXX_ -#include <comphelper/uno3.hxx> -#endif -#ifndef _COMPHELPER_EXTRACT_HXX_ -#include <comphelper/extract.hxx> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XKeysSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XTablesSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_ -#include <com/sun/star/sdbcx/KeyType.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_RESULTSETCONCURRENCY_HPP_ -#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_ -#include <com/sun/star/sdbc/ColumnValue.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ -#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> -#endif -#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_ -#include <com/sun/star/sdbcx/Privilege.hpp> -#endif -#ifndef _DBACORE_DATACOLUMN_HXX_ -#include "CRowSetDataColumn.hxx" -#endif -#ifndef DBACCESS_CORE_API_CROWSETCOLUMN_HXX + +#include "BookmarkSet.hxx" #include "CRowSetColumn.hxx" -#endif -#ifndef DBACCESS_CORE_API_ROWSETBASE_HXX +#include "CRowSetDataColumn.hxx" +#include "KeySet.hxx" +#include "OptimisticSet.hxx" #include "RowSetBase.hxx" -#endif +#include "RowSetCache.hxx" +#include "StaticSet.hxx" +#include "WrappedResultSet.hxx" +#include "core_resource.hrc" +#include "core_resource.hxx" +#include "dbastrings.hrc" + +/** === begin UNO includes === **/ +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbcx/CompareBookmark.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XKeysSupplier.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +/** === end UNO includes === **/ + +#include <comphelper/extract.hxx> +#include <comphelper/property.hxx> +#include <comphelper/seqstream.hxx> +#include <comphelper/uno3.hxx> #include <connectivity/dbexception.hxx> -#include <connectivity/sqlparse.hxx> -#include <connectivity/sqlnode.hxx> #include <connectivity/dbtools.hxx> #include <connectivity/sqliterator.hxx> -#ifndef _COMPHELPER_PROPERTY_HXX_ -#include <comphelper/property.hxx> -#endif -#ifndef _COM_SUN_STAR_SDBCX_COMPAREBOOKMARK_HPP_ -#include <com/sun/star/sdbcx/CompareBookmark.hpp> -#endif -#ifndef _TOOLS_DEBUG_HXX +#include <connectivity/sqlnode.hxx> +#include <connectivity/sqlparse.hxx> #include <tools/debug.hxx> -#endif +#include <tools/diagnose_ex.h> #include <algorithm> -#ifndef DBACCESS_CORE_API_ROWSETCACHE_HXX -#include "RowSetCache.hxx" -#endif -#ifndef _DBA_CORE_RESOURCE_HXX_ -#include "core_resource.hxx" -#endif -#ifndef _DBA_CORE_RESOURCE_HRC_ -#include "core_resource.hrc" -#endif -#ifndef DBACCESS_CORE_API_BOOKMARKSET_HXX -#include "BookmarkSet.hxx" -#endif -#ifndef DBACCESS_CORE_API_STATICSET_HXX -#include "StaticSet.hxx" -#endif -#ifndef DBACCESS_CORE_API_KEYSET_HXX -#include "KeySet.hxx" -#endif -#ifndef DBACCESS_SHARED_DBASTRINGS_HRC -#include "dbastrings.hrc" -#endif -#include "WrappedResultSet.hxx" -#include "OptimisticSet.hxx" using namespace dbaccess; using namespace dbtools; @@ -228,7 +188,10 @@ ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs, } catch(const Exception&) { + DBG_UNHANDLED_EXCEPTION(); } + m_pCacheSet = NULL; + m_xCacheSet.clear(); } else { diff --git a/dbaccess/source/core/inc/DatabaseDataProvider.hxx b/dbaccess/source/core/inc/DatabaseDataProvider.hxx index dae466e92..85f956a0b 100644 --- a/dbaccess/source/core/inc/DatabaseDataProvider.hxx +++ b/dbaccess/source/core/inc/DatabaseDataProvider.hxx @@ -223,7 +223,7 @@ private: void impl_fillRowSet_throw(); void impl_executeRowSet_throw(::osl::ResettableMutexGuard& _rClearForNotifies); bool impl_fillParameters_nothrow( ::osl::ResettableMutexGuard& _rClearForNotifies); - void impl_fillInternalDataProvider_throw(sal_Bool _bHasCategories,const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > >& i_aColumnNames); + void impl_fillInternalDataProvider_throw(sal_Bool _bHasCategories,const ::com::sun::star::uno::Sequence< ::rtl::OUString >& i_aColumnNames); void impl_invalidateParameter_nothrow(); ::com::sun::star::uno::Any impl_getNumberFormatKey_nothrow(const ::rtl::OUString & _sRangeRepresentation) const; diff --git a/dbaccess/source/core/misc/DatabaseDataProvider.cxx b/dbaccess/source/core/misc/DatabaseDataProvider.cxx index 0ede9ff23..d093170ca 100644 --- a/dbaccess/source/core/misc/DatabaseDataProvider.cxx +++ b/dbaccess/source/core/misc/DatabaseDataProvider.cxx @@ -31,10 +31,12 @@ #include "dbastrings.hrc" #include "cppuhelper/implbase1.hxx" #include <comphelper/types.hxx> +#include <comphelper/namedvaluecollection.hxx> #include <connectivity/FValue.hxx> #include <connectivity/dbtools.hxx> #include <rtl/ustrbuf.hxx> #include <rtl/math.hxx> +#include <tools/diagnose_ex.h> #include <com/sun/star/task/XInteractionHandler.hpp> #include <com/sun/star/sdb/XCompletedExecution.hpp> @@ -205,22 +207,24 @@ uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::creat osl::ResettableMutexGuard aClearForNotifies(m_aMutex); if ( createDataSourcePossible(_aArguments) ) { - sal_Bool bHasCategories = sal_True; - uno::Sequence< uno::Sequence< ::rtl::OUString > > aColumnNames; - const beans::PropertyValue* pArgIter = _aArguments.getConstArray(); - const beans::PropertyValue* pArgEnd = pArgIter + _aArguments.getLength(); - for(;pArgIter != pArgEnd;++pArgIter) + try { - if ( pArgIter->Name.equalsAscii("HasCategories") ) - { - pArgIter->Value >>= bHasCategories; - - } - else if ( pArgIter->Name.equalsAscii("ComplexColumnDescriptions") ) - { - pArgIter->Value >>= aColumnNames; - } + uno::Reference< chart::XChartDataArray> xChartData( m_xInternal, uno::UNO_QUERY_THROW ); + xChartData->setData( uno::Sequence< uno::Sequence< double > >() ); + xChartData->setColumnDescriptions( uno::Sequence< ::rtl::OUString >() ); + if ( m_xInternal->hasDataByRangeRepresentation( ::rtl::OUString::valueOf( sal_Int32(0) ) ) ) + m_xInternal->deleteSequence(0); } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + ::comphelper::NamedValueCollection aArgs( _aArguments ); + const sal_Bool bHasCategories = aArgs.getOrDefault( "HasCategories", sal_True ); + uno::Sequence< ::rtl::OUString > aColumnNames = + aArgs.getOrDefault( "ColumnDescriptions", uno::Sequence< ::rtl::OUString >() ); + bool bRet = false; if ( m_Command.getLength() != 0 && m_xActiveConnection.is() ) { @@ -240,10 +244,10 @@ uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::creat uno::Reference< lang::XInitialization> xIni(m_xInternal,uno::UNO_QUERY); if ( xIni.is() ) { - uno::Sequence< uno::Any > aArgs(1); + uno::Sequence< uno::Any > aInitArgs(1); beans::NamedValue aParam(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDefaultData")),uno::makeAny(sal_True)); - aArgs[0] <<= aParam; - xIni->initialize(aArgs); + aInitArgs[0] <<= aParam; + xIni->initialize(aInitArgs); } } @@ -254,41 +258,36 @@ uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::creat uno::Sequence< beans::PropertyValue > SAL_CALL DatabaseDataProvider::detectArguments(const uno::Reference< chart2::data::XDataSource > & _xDataSource) throw (uno::RuntimeException) { - uno::Sequence< beans::PropertyValue > aArguments( 4 ); - aArguments[0] = beans::PropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CellRangeRepresentation")), -1, uno::Any(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")) ), - beans::PropertyState_DIRECT_VALUE ); - aArguments[1] = beans::PropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataRowSource")), -1, uno::makeAny( chart::ChartDataRowSource_COLUMNS ), - beans::PropertyState_DIRECT_VALUE ); + ::comphelper::NamedValueCollection aArguments; + aArguments.put( "CellRangeRepresentation", uno::Any( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "all" ) ) ) ); + aArguments.put( "DataRowSource", uno::makeAny( chart::ChartDataRowSource_COLUMNS ) ); // internal data always contains labels and categories - aArguments[2] = beans::PropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FirstCellAsLabel")), -1, uno::makeAny( true ), beans::PropertyState_DIRECT_VALUE ); + aArguments.put( "FirstCellAsLabel", uno::makeAny( sal_True ) ); + sal_Bool bHasCategories = sal_False; if( _xDataSource.is()) { - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences(_xDataSource->getDataSequences()); - const sal_Int32 nCount( aSequences.getLength()); - for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) - { - if( aSequences[nIdx].is() ) - { - uno::Reference< beans::XPropertySet > xSeqProp( aSequences[nIdx]->getValues(), uno::UNO_QUERY ); - ::rtl::OUString aRole; - if( xSeqProp.is() && - (xSeqProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Role"))) >>= aRole) && - aRole.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) ) - { - bHasCategories = sal_True; - break; - } - } - } + uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences(_xDataSource->getDataSequences()); + const sal_Int32 nCount( aSequences.getLength()); + for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx ) + { + if( aSequences[nIdx].is() ) + { + uno::Reference< beans::XPropertySet > xSeqProp( aSequences[nIdx]->getValues(), uno::UNO_QUERY ); + ::rtl::OUString aRole; + if ( xSeqProp.is() + && ( xSeqProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ) ) ) >>= aRole ) + && aRole.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "categories" ) ) + ) + { + bHasCategories = sal_True; + break; + } + } + } } - - aArguments[3] = beans::PropertyValue( - ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasCategories")), -1, uno::makeAny( bHasCategories ), beans::PropertyState_DIRECT_VALUE ); - return aArguments; + aArguments.put( "HasCategories", uno::makeAny( bHasCategories ) ); + return aArguments.getPropertyValues(); } // ----------------------------------------------------------------------------- @@ -649,66 +648,136 @@ void DatabaseDataProvider::impl_executeRowSet_throw(::osl::ResettableMutexGuard& if ( impl_fillParameters_nothrow(_rClearForNotifies) ) m_xRowSet->execute(); } + // ----------------------------------------------------------------------------- -void DatabaseDataProvider::impl_fillInternalDataProvider_throw(sal_Bool _bHasCategories,const uno::Sequence< uno::Sequence< ::rtl::OUString > >& i_aColumnNames) +namespace { - // clear the data before fill the new one - uno::Reference< chart::XChartDataArray> xChartData(m_xInternal,uno::UNO_QUERY); - if ( xChartData.is() ) + struct ColumnDescription { - xChartData->setData(uno::Sequence< uno::Sequence<double> >()); - xChartData->setColumnDescriptions(uno::Sequence< ::rtl::OUString >()); - if ( m_xInternal->hasDataByRangeRepresentation(::rtl::OUString::valueOf(sal_Int32(0))) ) - m_xInternal->deleteSequence(0); - } + ::rtl::OUString sName; + sal_Int32 nResultSetPosition; + sal_Int32 nDataType; + + ColumnDescription() + :sName() + ,nResultSetPosition( 0 ) + ,nDataType( sdbc::DataType::VARCHAR ) + { + } + explicit ColumnDescription( const ::rtl::OUString& i_rName ) + :sName( i_rName ) + ,nResultSetPosition( 0 ) + ,nDataType( sdbc::DataType::VARCHAR ) + { + } + }; + + struct CreateColumnDescription : public ::std::unary_function< ::rtl::OUString, ColumnDescription > + { + ColumnDescription operator()( const ::rtl::OUString& i_rName ) + { + return ColumnDescription( i_rName ); + } + }; + + struct SelectColumnName : public ::std::unary_function< ColumnDescription, ::rtl::OUString > + { + const ::rtl::OUString& operator()( const ColumnDescription& i_rColumn ) + { + return i_rColumn.sName; + } + }; +} + +// ----------------------------------------------------------------------------- +void DatabaseDataProvider::impl_fillInternalDataProvider_throw(sal_Bool _bHasCategories,const uno::Sequence< ::rtl::OUString >& i_aColumnNames) +{ + // clear the data before fill the new one + uno::Reference< sdbcx::XColumnsSupplier > xColSup(m_xRowSet,uno::UNO_QUERY_THROW); + uno::Reference< container::XNameAccess > xColumns( xColSup->getColumns(), uno::UNO_SET_THROW ); + const uno::Sequence< ::rtl::OUString > aRowSetColumnNames( xColumns->getElementNames() ); - uno::Reference< sdbcx::XColumnsSupplier> xColSup(m_xRowSet,uno::UNO_QUERY_THROW); - uno::Reference< container::XNameAccess > xColumns = xColSup->getColumns(); - uno::Sequence< ::rtl::OUString > aColumns; + typedef ::std::vector< ColumnDescription > ColumnDescriptions; + ColumnDescriptions aColumns; + bool bFirstColumnIsCategory = _bHasCategories; if ( i_aColumnNames.getLength() ) { - aColumns.realloc(1); - aColumns[0] = xColumns->getElementNames()[0]; - for(sal_Int32 i = 0 ; i < i_aColumnNames.getLength();++i) + // some normalizations ... + uno::Sequence< ::rtl::OUString > aImposedColumnNames( i_aColumnNames ); + + // strangely, there exist documents where the ColumnDescriptions end with a number of empty strings. /me + // thinks they're generated when you have a chart based on a result set with n columns, but remove some + // of those columns from the chart - it looks like a bug in the report XML export to me. + // So, get rid of the "trailing" empty columns + sal_Int32 nLastNonEmptyColName = aImposedColumnNames.getLength() - 1; + for ( ; nLastNonEmptyColName >= 0; --nLastNonEmptyColName ) { - if ( i_aColumnNames[i].getLength() ) + if ( aImposedColumnNames[ nLastNonEmptyColName ].getLength() != 0 ) + break; + } + aImposedColumnNames.realloc( nLastNonEmptyColName + 1 ); + + // second, for X-Y-charts the ColumnDescriptions exported by chart miss the name of the first (non-category) + // column. This, this results in a ColumnDescriptions array like <"", "col2", "col3">, where you'd expect + // <"col1", "col2", "col3">. + // Fix this with some heuristics: + if ( ( aImposedColumnNames.getLength() > 0 ) && ( aImposedColumnNames[0].getLength() == 0 ) ) + { + const sal_Int32 nAssumedRowSetColumnIndex = _bHasCategories ? 1 : 0; + if ( nAssumedRowSetColumnIndex < aRowSetColumnNames.getLength() ) + aImposedColumnNames[0] = aRowSetColumnNames[ nAssumedRowSetColumnIndex ]; + } + + const sal_Int32 nCount = aImposedColumnNames.getLength(); + for ( sal_Int32 i = 0 ; i < nCount; ++i ) + { + const ::rtl::OUString sColumnName( aImposedColumnNames[i] ); + if ( !xColumns->hasByName( sColumnName ) ) + continue; + + if ( _bHasCategories && aColumns.empty() ) { - sal_Int32 nCount = aColumns.getLength(); - aColumns.realloc(nCount+1); - aColumns[nCount] = i_aColumnNames[i][0]; + if ( aRowSetColumnNames.getLength() ) + aColumns.push_back( ColumnDescription( aRowSetColumnNames[0] ) ); + else + aColumns.push_back( ColumnDescription( sColumnName ) ); + bFirstColumnIsCategory = true; } + aColumns.push_back( ColumnDescription( sColumnName ) ); } } - else + if ( aColumns.empty() ) { - aColumns = xColumns->getElementNames(); + aColumns.resize( aRowSetColumnNames.getLength() ); + ::std::transform( + aRowSetColumnNames.getConstArray(), + aRowSetColumnNames.getConstArray() + aRowSetColumnNames.getLength(), + aColumns.begin(), + CreateColumnDescription() + ); } + // fill the data - uno::Reference< sdbc::XResultSet> xRes(m_xRowSet,uno::UNO_QUERY_THROW); - uno::Reference< sdbc::XRow> xRow(m_xRowSet,uno::UNO_QUERY_THROW); - uno::Reference< sdbc::XResultSetMetaData> xResultSetMetaData = uno::Reference< sdbc::XResultSetMetaDataSupplier>(m_xRowSet,uno::UNO_QUERY)->getMetaData(); - uno::Reference< sdbc::XColumnLocate> xColumnLocate(m_xRowSet,uno::UNO_QUERY_THROW); - - ::std::vector<sal_Int32> aColumnTypes; - uno::Sequence< uno::Any > aLabelArgs(1); - const sal_Int32 nCount = aColumns.getLength(); - if ( nCount ) - aColumnTypes.push_back(xResultSetMetaData->getColumnType(1)); - - ::std::vector< sal_Int32 > aColumnPositions; - const ::rtl::OUString* pIter = aColumns.getConstArray(); - const ::rtl::OUString* pEnd = pIter + aColumns.getLength(); - for(sal_Int32 k = 0;pIter != pEnd;++pIter,++k) + uno::Reference< sdbc::XResultSet> xRes( m_xRowSet, uno::UNO_QUERY_THROW ); + uno::Reference< sdbc::XRow> xRow( m_xRowSet,uno::UNO_QUERY_THROW ); + uno::Reference< sdbc::XResultSetMetaDataSupplier > xSuppMeta( m_xRowSet,uno::UNO_QUERY_THROW ); + uno::Reference< sdbc::XResultSetMetaData > xResultSetMetaData( xSuppMeta->getMetaData(), uno::UNO_SET_THROW ); + uno::Reference< sdbc::XColumnLocate > xColumnLocate( m_xRowSet, uno::UNO_QUERY_THROW ); + + for ( ColumnDescriptions::iterator col = aColumns.begin(); + col != aColumns.end(); + ++col + ) { - aColumnPositions.push_back(xColumnLocate->findColumn(*pIter)); - uno::Reference< beans::XPropertySet> xColumn(xColumns->getByName(*pIter),uno::UNO_QUERY); - sal_Int32 nType = sdbc::DataType::VARCHAR; - if ( xColumn.is() ) - { - m_aNumberFormats.insert( ::std::map< ::rtl::OUString,uno::Any>::value_type(::rtl::OUString::valueOf(k),xColumn->getPropertyValue(PROPERTY_NUMBERFORMAT))); - xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType; - } - aColumnTypes.push_back(nType); + col->nResultSetPosition = xColumnLocate->findColumn( col->sName ); + + const uno::Reference< beans::XPropertySet > xColumn( xColumns->getByName( col->sName ), uno::UNO_QUERY_THROW ); + const uno::Any aNumberFormat( xColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) ); + OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= col->nDataType ); + + const sal_Int32 columnIndex = col - aColumns.begin(); + const ::rtl::OUString sRangeName = ::rtl::OUString::valueOf( columnIndex ); + m_aNumberFormats.insert( ::std::map< ::rtl::OUString, uno::Any >::value_type( sRangeName, aNumberFormat ) ); } ::std::vector< ::rtl::OUString > aRowLabels; @@ -719,31 +788,31 @@ void DatabaseDataProvider::impl_fillInternalDataProvider_throw(sal_Bool _bHasCat { ++nRowCount; - aValue.fill(1,aColumnTypes[0],xRow); - aRowLabels.push_back(aValue.getString()); + aValue.fill( aColumns[0].nResultSetPosition, aColumns[0].nDataType, xRow ); + aRowLabels.push_back( aValue.getString() ); + ::std::vector< double > aRow; - ::std::vector< sal_Int32 >::iterator aColumnPosIter = aColumnPositions.begin(); - ::std::vector< sal_Int32 >::iterator aColumnPosEnd = aColumnPositions.end(); - sal_Int32 i = 0; - if ( _bHasCategories ) + for ( ColumnDescriptions::const_iterator col = aColumns.begin(); + col != aColumns.end(); + ++col + ) { - ++aColumnPosIter; - ++i; - } - for (; aColumnPosIter != aColumnPosEnd; ++aColumnPosIter,++i) - { - aValue.fill(*aColumnPosIter,aColumnTypes[i],xRow); + if ( bFirstColumnIsCategory && ( col == aColumns.begin() ) ) + continue; + + aValue.fill( col->nResultSetPosition, col->nDataType, xRow ); if ( aValue.isNull() ) { double nValue; ::rtl::math::setNan( &nValue ); - aRow.push_back(nValue); + aRow.push_back( nValue ); } else - aRow.push_back(aValue.getDouble()); + aRow.push_back( aValue.getDouble() ); } - aDataValues.push_back(aRow); - } // while( xRes->next() && (!m_RowLimit || nRowCount < m_RowLimit) ) + + aDataValues.push_back( aRow ); + } // insert default data when no rows exist if ( !nRowCount ) @@ -759,19 +828,29 @@ void DatabaseDataProvider::impl_fillInternalDataProvider_throw(sal_Bool _bHasCat aRowLabels.push_back(::rtl::OUString::valueOf(h+1)); ::std::vector< double > aRow; const sal_Int32 nSize = sizeof(fDefaultData)/sizeof(fDefaultData[0]); - for (sal_Int32 j = 0; j < (nCount-1); ++j,++k) + for (size_t j = 0; j < (aColumns.size()-1); ++j,++k) { if ( k >= nSize ) k = 0; aRow.push_back(fDefaultData[k]); - } // for (sal_Int32 j = 0,k = 0; j < (nCount-1); ++j,++k) + } // for (sal_Int32 j = 0,k = 0; j < (aColumns.size()-1); ++j,++k) aDataValues.push_back(aRow); } } // if ( !nRowCount ) uno::Reference< chart::XChartDataArray> xData(m_xInternal,uno::UNO_QUERY); xData->setRowDescriptions(uno::Sequence< ::rtl::OUString >(&(*aRowLabels.begin()),aRowLabels.size())); - xData->setColumnDescriptions(uno::Sequence< ::rtl::OUString >(aColumns.getArray()+ (_bHasCategories ? 1 : 0),aColumns.getLength() - (_bHasCategories ? 1 : 0) )); + + const size_t nOffset = bFirstColumnIsCategory ? 1 : 0; + uno::Sequence< ::rtl::OUString > aColumnDescriptions( aColumns.size() - nOffset ); + ::std::transform( + aColumns.begin() + nOffset, + aColumns.end(), + aColumnDescriptions.getArray(), + SelectColumnName() + ); + xData->setColumnDescriptions( aColumnDescriptions ); + uno::Sequence< uno::Sequence< double > > aData(aDataValues.size()); uno::Sequence< double >* pDataIter = aData.getArray(); uno::Sequence< double >* pDataEnd = pDataIter + aData.getLength(); diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx index 001105bc1..b5e8aa501 100644 --- a/dbaccess/source/ui/app/AppController.cxx +++ b/dbaccess/source/ui/app/AppController.cxx @@ -1789,7 +1789,7 @@ bool OApplicationController::onEntryDoubleClick( SvTreeListBox& _rTree ) } catch(const Exception&) { - OSL_ENSURE(0,"Could not open element!"); + DBG_UNHANDLED_EXCEPTION(); } } return false; // not handled @@ -1842,12 +1842,20 @@ Reference< XComponent > OApplicationController::openElementWithArguments( const getContainer()->showPreview(NULL); } + bool isStandaloneDocument = false; switch ( _eType ) { case E_REPORT: + if ( _eOpenMode != E_OPEN_DESIGN ) + { + // reports which are opened in a mode other than design are no sub components of our application + // component, but standalone documents. + isStandaloneDocument = true; + } + // NO break! case E_FORM: { - if ( !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) ) + if ( isStandaloneDocument || !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) ) { ::std::auto_ptr< OLinkedDocumentsAccess > aHelper = getDocumentsAccess( _eType ); if ( !aHelper->isConnected() ) @@ -1856,7 +1864,8 @@ Reference< XComponent > OApplicationController::openElementWithArguments( const Reference< XComponent > xDefinition; xRet = aHelper->open( _sName, xDefinition, _eOpenMode, _rAdditionalArguments ); - onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition ); + if ( !isStandaloneDocument ) + onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition ); } } break; @@ -2781,9 +2790,9 @@ void OApplicationController::containerFound( const Reference< XContainer >& _xCo _xContainer->addContainerListener(this); } } - catch(Exception) + catch(const Exception&) { - OSL_ENSURE(0,"Could not listener on the container!"); + DBG_UNHANDLED_EXCEPTION(); } } // ----------------------------------------------------------------------------- diff --git a/dbaccess/source/ui/app/AppControllerGen.cxx b/dbaccess/source/ui/app/AppControllerGen.cxx index 7d2575220..70253590b 100644 --- a/dbaccess/source/ui/app/AppControllerGen.cxx +++ b/dbaccess/source/ui/app/AppControllerGen.cxx @@ -676,7 +676,8 @@ void OApplicationController::onDocumentOpened( const ::rtl::OUString& _rName, co try { - m_pSubComponentManager->onSubComponentOpened( _rName, _nType, _eMode, _rxDefinition.is() ? _rxDefinition : _xDocument ); + OSL_ENSURE( _xDocument.is(), "OApplicationController::onDocumentOpened: is there any *valid* scenario where this fails?" ); + m_pSubComponentManager->onSubComponentOpened( _rName, _nType, _eMode, _xDocument.is() ? _xDocument : _rxDefinition ); if ( _rxDefinition.is() ) { |