diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /dbaccess/source/core/misc | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dbaccess/source/core/misc')
-rw-r--r-- | dbaccess/source/core/misc/ContainerMediator.cxx | 231 | ||||
-rw-r--r-- | dbaccess/source/core/misc/DatabaseDataProvider.cxx | 1066 | ||||
-rw-r--r-- | dbaccess/source/core/misc/PropertyForward.cxx | 146 | ||||
-rw-r--r-- | dbaccess/source/core/misc/apitools.cxx | 114 | ||||
-rw-r--r-- | dbaccess/source/core/misc/dsntypes.cxx | 565 | ||||
-rw-r--r-- | dbaccess/source/core/misc/migrwarndlg.cxx | 22 | ||||
-rw-r--r-- | dbaccess/source/core/misc/objectnameapproval.cxx | 74 | ||||
-rw-r--r-- | dbaccess/source/core/misc/sdbcoretools.cxx | 142 | ||||
-rw-r--r-- | dbaccess/source/core/misc/veto.cxx | 49 |
9 files changed, 2409 insertions, 0 deletions
diff --git a/dbaccess/source/core/misc/ContainerMediator.cxx b/dbaccess/source/core/misc/ContainerMediator.cxx new file mode 100644 index 000000000..338858c87 --- /dev/null +++ b/dbaccess/source/core/misc/ContainerMediator.cxx @@ -0,0 +1,231 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ContainerMediator.hxx> +#include <PropertyForward.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XRename.hpp> +#include <comphelper/property.hxx> +#include <tools/diagnose_ex.h> + +namespace dbaccess +{ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::sdbcx; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::container; + +OContainerMediator::OContainerMediator( const Reference< XContainer >& _xContainer, const Reference< XNameAccess >& _xSettings ) + : m_xSettings( _xSettings ) + , m_xContainer( _xContainer ) +{ + + if ( _xSettings.is() && _xContainer.is() ) + { + osl_atomic_increment(&m_refCount); + try + { + m_xContainer->addContainerListener(this); + Reference< XContainer > xContainer(_xSettings, UNO_QUERY); + if ( xContainer.is() ) + xContainer->addContainerListener(this); + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION("dbaccess", "OContainerMediator::OContainerMediator"); + } + osl_atomic_decrement( &m_refCount ); + } + else + { + m_xSettings.clear(); + m_xContainer.clear(); + } +} + +OContainerMediator::~OContainerMediator() +{ + acquire(); + impl_cleanup_nothrow(); +} + +void OContainerMediator::impl_cleanup_nothrow() +{ + try + { + Reference< XContainer > xContainer( m_xSettings, UNO_QUERY ); + if ( xContainer.is() ) + xContainer->removeContainerListener( this ); + m_xSettings.clear(); + + xContainer = m_xContainer; + if ( xContainer.is() ) + xContainer->removeContainerListener( this ); + m_xContainer.clear(); + + m_aForwardList.clear(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } +} + +void SAL_CALL OContainerMediator::elementInserted( const ContainerEvent& _rEvent ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( _rEvent.Source == m_xSettings && m_xSettings.is() ) + { + OUString sElementName; + _rEvent.Accessor >>= sElementName; + PropertyForwardList::const_iterator aFind = m_aForwardList.find(sElementName); + if ( aFind != m_aForwardList.end() ) + { + Reference< XPropertySet> xDest(_rEvent.Element,UNO_QUERY); + aFind->second->setDefinition( xDest ); + } + } +} + +void SAL_CALL OContainerMediator::elementRemoved( const ContainerEvent& _rEvent ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + Reference< XContainer > xContainer = m_xContainer; + if ( !(_rEvent.Source == xContainer && xContainer.is()) ) + return; + + OUString sElementName; + _rEvent.Accessor >>= sElementName; + m_aForwardList.erase(sElementName); + try + { + Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY ); + if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) ) + xNameContainer->removeByName( sElementName ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } +} + +void SAL_CALL OContainerMediator::elementReplaced( const ContainerEvent& _rEvent ) +{ + Reference< XContainer > xContainer = m_xContainer; + if ( !(_rEvent.Source == xContainer && xContainer.is()) ) + return; + + OUString sElementName; + _rEvent.ReplacedElement >>= sElementName; + + PropertyForwardList::const_iterator aFind = m_aForwardList.find(sElementName); + if ( aFind == m_aForwardList.end() ) + return; + + OUString sNewName; + _rEvent.Accessor >>= sNewName; + try + { + Reference<XNameContainer> xNameContainer( m_xSettings, UNO_QUERY_THROW ); + if ( xNameContainer.is() && m_xSettings->hasByName( sElementName ) ) + { + Reference<XRename> xSource(m_xSettings->getByName(sElementName),UNO_QUERY_THROW); + xSource->rename(sNewName); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + + aFind->second->setName(sNewName); +} + +void SAL_CALL OContainerMediator::disposing( const EventObject& /*Source*/ ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + + impl_cleanup_nothrow(); +} + +void OContainerMediator::impl_initSettings_nothrow( const OUString& _rName, const Reference< XPropertySet >& _rxDestination ) +{ + try + { + if ( m_xSettings.is() && m_xSettings->hasByName( _rName ) ) + { + Reference< XPropertySet > xSettings( m_xSettings->getByName( _rName ), UNO_QUERY_THROW ); + ::comphelper::copyProperties( xSettings, _rxDestination ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } +} + +void OContainerMediator::notifyElementCreated( const OUString& _sName, const Reference< XPropertySet >& _xDest ) +{ + if ( !m_xSettings.is() ) + return; + + PropertyForwardList::const_iterator aFind = m_aForwardList.find( _sName ); + if ( aFind != m_aForwardList.end() + && aFind->second->getDefinition().is() + ) + { + OSL_FAIL( "OContainerMediator::notifyElementCreated: is this really a valid case?" ); + return; + } + + std::vector< OUString > aPropertyList; + try + { + // initially copy from the settings object (if existent) to the newly created object + impl_initSettings_nothrow( _sName, _xDest ); + + // collect the to-be-monitored properties + Reference< XPropertySetInfo > xPSI( _xDest->getPropertySetInfo(), UNO_SET_THROW ); + const Sequence< Property > aProperties( xPSI->getProperties() ); + for ( auto const & property : aProperties ) + { + if ( ( property.Attributes & PropertyAttribute::READONLY ) != 0 ) + continue; + if ( ( property.Attributes & PropertyAttribute::BOUND ) == 0 ) + continue; + + aPropertyList.push_back( property.Name ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + + ::rtl::Reference pForward( new OPropertyForward( _xDest, m_xSettings, _sName, aPropertyList ) ); + m_aForwardList[ _sName ] = pForward; +} + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/DatabaseDataProvider.cxx b/dbaccess/source/core/misc/DatabaseDataProvider.cxx new file mode 100644 index 000000000..8695d518c --- /dev/null +++ b/dbaccess/source/core/misc/DatabaseDataProvider.cxx @@ -0,0 +1,1066 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <DatabaseDataProvider.hxx> +#include <strings.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/types.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <connectivity/FValue.hxx> +#include <sal/macros.h> +#include <tools/diagnose_ex.h> + +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbc/XColumnLocate.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/chart/ChartDataRowSource.hpp> +#include <com/sun/star/chart/XChartDataArray.hpp> + +#include <vector> + +// TODO: update for new HavingClause-aware FilterManager + +namespace dbaccess +{ +using namespace ::com::sun::star; +using ::com::sun::star::uno::Reference; + +DatabaseDataProvider::DatabaseDataProvider(uno::Reference< uno::XComponentContext > const & context) : + TDatabaseDataProvider(m_aMutex), + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >( + context, IMPLEMENTS_PROPERTY_SET, uno::Sequence< OUString >()), + m_aParameterManager( m_aMutex, context ), + m_xContext(context), + m_CommandType(sdb::CommandType::COMMAND), // #i94114 + m_RowLimit(0), + m_EscapeProcessing(true), + m_ApplyFilter(true) +{ + m_xInternal.set( m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.chart.InternalDataProvider",m_xContext ), uno::UNO_QUERY ); + m_xRangeConversion.set(m_xInternal,uno::UNO_QUERY); + m_xComplexDescriptionAccess.set(m_xInternal,uno::UNO_QUERY); + + osl_atomic_increment( &m_refCount ); + { + m_xRowSet.set( m_xContext->getServiceManager()->createInstanceWithContext(SERVICE_SDB_ROWSET,m_xContext ), uno::UNO_QUERY ); + m_xAggregate.set(m_xRowSet,uno::UNO_QUERY); + m_xAggregateSet.set(m_xRowSet,uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xProp(static_cast< ::cppu::OWeakObject* >( this ),uno::UNO_QUERY); + m_aFilterManager.initialize( m_xAggregateSet ); + m_aParameterManager.initialize( xProp, m_xAggregate ); + m_xAggregateSet->setPropertyValue(PROPERTY_COMMAND_TYPE,uno::Any(m_CommandType)); + m_xAggregateSet->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,uno::Any(m_EscapeProcessing)); + } + osl_atomic_decrement( &m_refCount ); +} + +void SAL_CALL DatabaseDataProvider::disposing() +{ + m_aParameterManager.dispose(); // (to free any references it may have to me) + m_aFilterManager.dispose(); // (ditto) + + m_xParent.clear(); + m_xAggregateSet.clear(); + m_xAggregate.clear(); + m_xRangeConversion.clear(); + ::comphelper::disposeComponent(m_xRowSet); + ::comphelper::disposeComponent(m_xInternal); + m_xActiveConnection.clear(); +} + +uno::Any DatabaseDataProvider::queryInterface(uno::Type const & type) +{ + return TDatabaseDataProvider::queryInterface(type); +} + +// XServiceInfo +OUString SAL_CALL DatabaseDataProvider::getImplementationName( ) +{ + return "com.sun.star.comp.dbaccess.DatabaseDataProvider"; +} + +sal_Bool SAL_CALL DatabaseDataProvider::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getSupportedServiceNames( ) +{ + return { "com.sun.star.chart2.data.DatabaseDataProvider" }; +} + +// lang::XInitialization: +void SAL_CALL DatabaseDataProvider::initialize(const uno::Sequence< uno::Any > & aArguments) +{ + osl::MutexGuard g(m_aMutex); + const uno::Any* pIter = aArguments.getConstArray(); + const uno::Any* pEnd = pIter + aArguments.getLength(); + for(;pIter != pEnd;++pIter) + { + if ( !m_xActiveConnection.is() ) + (*pIter) >>= m_xActiveConnection; + else if ( !m_xHandler.is() ) + (*pIter) >>= m_xHandler; + } + m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, uno::Any( m_xActiveConnection ) ); +} + +// chart2::data::XDataProvider: +sal_Bool SAL_CALL DatabaseDataProvider::createDataSourcePossible(const uno::Sequence< beans::PropertyValue > & _aArguments) +{ + const beans::PropertyValue* pArgIter = _aArguments.getConstArray(); + const beans::PropertyValue* pArgEnd = pArgIter + _aArguments.getLength(); + for(;pArgIter != pArgEnd;++pArgIter) + { + if ( pArgIter->Name == "DataRowSource" ) + { + css::chart::ChartDataRowSource eRowSource = css::chart::ChartDataRowSource_COLUMNS; + pArgIter->Value >>= eRowSource; + if ( eRowSource != css::chart::ChartDataRowSource_COLUMNS ) + return false; + } + else if ( pArgIter->Name == "CellRangeRepresentation" ) + { + OUString sRange; + pArgIter->Value >>= sRange; + if ( sRange != "all" ) + return false; + } + else if ( pArgIter->Name == "FirstCellAsLabel" ) + { + bool bFirstCellAsLabel = true; + pArgIter->Value >>= bFirstCellAsLabel; + if ( !bFirstCellAsLabel ) + return false; + } + } + return true; +} + +uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::createDataSource(const uno::Sequence< beans::PropertyValue > & _aArguments) +{ + osl::ResettableMutexGuard aClearForNotifies(m_aMutex); + if ( createDataSourcePossible(_aArguments) ) + { + try + { + uno::Reference< chart::XChartDataArray> xChartData( m_xInternal, uno::UNO_QUERY_THROW ); + xChartData->setData( uno::Sequence< uno::Sequence< double > >() ); + xChartData->setColumnDescriptions( uno::Sequence< OUString >() ); + if ( m_xInternal->hasDataByRangeRepresentation( OUString::number( 0 ) ) ) + m_xInternal->deleteSequence(0); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + + ::comphelper::NamedValueCollection aArgs( _aArguments ); + const bool bHasCategories = aArgs.getOrDefault( "HasCategories", true ); + uno::Sequence< OUString > aColumnNames = + aArgs.getOrDefault( "ColumnDescriptions", uno::Sequence< OUString >() ); + + bool bRet = false; + if ( !m_Command.isEmpty() && m_xActiveConnection.is() ) + { + try + { + impl_fillRowSet_throw(); + if ( impl_fillParameters_nothrow(aClearForNotifies) ) + m_xRowSet->execute(); + impl_fillInternalDataProvider_throw(bHasCategories,aColumnNames); + bRet = true; + } + catch(const uno::Exception& /*e*/) + { + } + } + if ( !bRet ) // no command set or an error occurred, use Internal data handler + { + uno::Reference< lang::XInitialization> xIni(m_xInternal,uno::UNO_QUERY); + if ( xIni.is() ) + { + beans::NamedValue aParam("CreateDefaultData",uno::Any(true)); + uno::Sequence< uno::Any > aInitArgs{ uno::Any(aParam) }; + xIni->initialize(aInitArgs); + } + } + + } + return m_xInternal->createDataSource(_aArguments); +} + +uno::Sequence< beans::PropertyValue > SAL_CALL DatabaseDataProvider::detectArguments(const uno::Reference< chart2::data::XDataSource > & _xDataSource) +{ + ::comphelper::NamedValueCollection aArguments; + aArguments.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) ); + aArguments.put( "DataRowSource", uno::Any( chart::ChartDataRowSource_COLUMNS ) ); + // internal data always contains labels + aArguments.put( "FirstCellAsLabel", uno::Any( true ) ); + + bool bHasCategories = 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 ); + OUString aRole; + if ( xSeqProp.is() + && ( xSeqProp->getPropertyValue( "Role" ) >>= aRole ) + && aRole == "categories" + ) + { + bHasCategories = true; + break; + } + } + } + } + aArguments.put( "HasCategories", uno::Any( bHasCategories ) ); + return aArguments.getPropertyValues(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentationPossible(const OUString & /*aRangeRepresentation*/) +{ + return true; +} + +uno::Any DatabaseDataProvider::impl_getNumberFormatKey_nothrow(const OUString & _sRangeRepresentation) const +{ + std::map< OUString,css::uno::Any>::const_iterator aFind = m_aNumberFormats.find(_sRangeRepresentation); + if ( aFind != m_aNumberFormats.end() ) + return aFind->second; + return uno::Any(sal_Int32(0)); +} + +uno::Reference< chart2::data::XDataSequence > SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentation(const OUString & _sRangeRepresentation) +{ + osl::MutexGuard g(m_aMutex); + uno::Reference< chart2::data::XDataSequence > xData = m_xInternal->createDataSequenceByRangeRepresentation(_sRangeRepresentation); + uno::Reference<beans::XPropertySet> xProp(xData,uno::UNO_QUERY); + static constexpr OUStringLiteral s_sNumberFormatKey = u"NumberFormatKey"; + if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(s_sNumberFormatKey) ) + { + xProp->setPropertyValue(s_sNumberFormatKey,impl_getNumberFormatKey_nothrow(_sRangeRepresentation)); + } + return xData; +} + +uno::Reference<chart2::data::XDataSequence> +SAL_CALL DatabaseDataProvider::createDataSequenceByValueArray( + const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/, const OUString& /*aRoleQualifier*/ ) +{ + return uno::Reference<chart2::data::XDataSequence>(); +} + +uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexRowDescriptions() +{ + return m_xComplexDescriptionAccess->getComplexRowDescriptions(); +} + +void SAL_CALL DatabaseDataProvider::setComplexRowDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aRowDescriptions ) +{ + m_xComplexDescriptionAccess->setComplexRowDescriptions(aRowDescriptions); +} + +uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexColumnDescriptions() +{ + return m_xComplexDescriptionAccess->getComplexColumnDescriptions(); +} + +void SAL_CALL DatabaseDataProvider::setComplexColumnDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aColumnDescriptions ) +{ + m_xComplexDescriptionAccess->setComplexColumnDescriptions(aColumnDescriptions); +} + +// ____ XChartDataArray ____ +uno::Sequence< uno::Sequence< double > > SAL_CALL DatabaseDataProvider::getData() +{ + return m_xComplexDescriptionAccess->getData(); +} + +void SAL_CALL DatabaseDataProvider::setData( const uno::Sequence< uno::Sequence< double > >& rDataInRows ) +{ + m_xComplexDescriptionAccess->setData(rDataInRows); +} + +void SAL_CALL DatabaseDataProvider::setRowDescriptions( const uno::Sequence< OUString >& aRowDescriptions ) +{ + m_xComplexDescriptionAccess->setRowDescriptions(aRowDescriptions); +} + +void SAL_CALL DatabaseDataProvider::setColumnDescriptions( const uno::Sequence< OUString >& aColumnDescriptions ) +{ + m_xComplexDescriptionAccess->setColumnDescriptions(aColumnDescriptions); +} + +uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getRowDescriptions() +{ + return m_xComplexDescriptionAccess->getRowDescriptions(); +} + +uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getColumnDescriptions() +{ + return m_xComplexDescriptionAccess->getColumnDescriptions(); +} + +// ____ XChartData (base of XChartDataArray) ____ +void SAL_CALL DatabaseDataProvider::addChartDataChangeEventListener(const uno::Reference< css::chart::XChartDataChangeEventListener >& x) +{ + m_xComplexDescriptionAccess->addChartDataChangeEventListener(x); +} + +void SAL_CALL DatabaseDataProvider::removeChartDataChangeEventListener(const uno::Reference< css::chart::XChartDataChangeEventListener >& x) +{ + m_xComplexDescriptionAccess->removeChartDataChangeEventListener(x); +} + +double SAL_CALL DatabaseDataProvider::getNotANumber() +{ + return m_xComplexDescriptionAccess->getNotANumber(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::isNotANumber( double nNumber ) +{ + return m_xComplexDescriptionAccess->isNotANumber(nNumber); +} + +uno::Reference< sheet::XRangeSelection > SAL_CALL DatabaseDataProvider::getRangeSelection() +{ + // TODO: Exchange the default return implementation for "getRangeSelection" !!! + // Exchange the default return implementation. + // NOTE: Default initialized polymorphic structs can cause problems because of + // missing default initialization of primitive types of some C++ compilers or + // different Any initialization in Java and C++ polymorphic structs. + return uno::Reference< sheet::XRangeSelection >(); +} + +// chart2::data::XRangeXMLConversion: +OUString SAL_CALL DatabaseDataProvider::convertRangeToXML(const OUString & _sRangeRepresentation) +{ + osl::MutexGuard g(m_aMutex); + return m_xRangeConversion->convertRangeToXML(_sRangeRepresentation); +} + +OUString SAL_CALL DatabaseDataProvider::convertRangeFromXML(const OUString & _sXMLRange) +{ + osl::MutexGuard g(m_aMutex); + return m_xRangeConversion->convertRangeFromXML(_sXMLRange); +} + +// com.sun.star.beans.XPropertySet: +uno::Reference< beans::XPropertySetInfo > SAL_CALL DatabaseDataProvider::getPropertySetInfo() +{ + return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertySetInfo(); +} + +void SAL_CALL DatabaseDataProvider::setPropertyValue(const OUString & aPropertyName, const uno::Any & aValue) +{ + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::setPropertyValue(aPropertyName, aValue); +} + +uno::Any SAL_CALL DatabaseDataProvider::getPropertyValue(const OUString & aPropertyName) +{ + return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertyValue(aPropertyName); +} + +void SAL_CALL DatabaseDataProvider::addPropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener) +{ + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addPropertyChangeListener(aPropertyName, xListener); +} + +void SAL_CALL DatabaseDataProvider::removePropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener) +{ + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removePropertyChangeListener(aPropertyName, xListener); +} + +void SAL_CALL DatabaseDataProvider::addVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener) +{ + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addVetoableChangeListener(aPropertyName, xListener); +} + +void SAL_CALL DatabaseDataProvider::removeVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener) +{ + ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removeVetoableChangeListener(aPropertyName, xListener); +} + +// chart2::data::XDatabaseDataProvider: +uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getMasterFields() +{ + osl::MutexGuard g(m_aMutex); + return m_MasterFields; +} + +void SAL_CALL DatabaseDataProvider::setMasterFields(const uno::Sequence< OUString > & the_value) +{ + impl_invalidateParameter_nothrow(); + set("MasterFields",the_value,m_MasterFields); +} + +uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getDetailFields() +{ + osl::MutexGuard g(m_aMutex); + return m_DetailFields; +} + +void SAL_CALL DatabaseDataProvider::setDetailFields(const uno::Sequence< OUString > & the_value) +{ + set("DetailFields",the_value,m_DetailFields); +} + +OUString SAL_CALL DatabaseDataProvider::getCommand() +{ + osl::MutexGuard g(m_aMutex); + return m_Command; +} + +void SAL_CALL DatabaseDataProvider::setCommand(const OUString & the_value) +{ + { + osl::MutexGuard g(m_aMutex); + impl_invalidateParameter_nothrow(); + m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND, uno::Any( the_value ) ); + } + set(PROPERTY_COMMAND,the_value,m_Command); +} + +::sal_Int32 SAL_CALL DatabaseDataProvider::getCommandType() +{ + osl::MutexGuard g(m_aMutex); + return m_CommandType; +} + +void SAL_CALL DatabaseDataProvider::setCommandType(::sal_Int32 the_value) +{ + { + osl::MutexGuard g(m_aMutex); + m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND_TYPE, uno::Any( the_value ) ); + } + set(PROPERTY_COMMAND_TYPE,the_value,m_CommandType); +} + +OUString SAL_CALL DatabaseDataProvider::getFilter() +{ + osl::MutexGuard g(m_aMutex); + return m_aFilterManager.getFilterComponent( dbtools::FilterManager::FilterComponent::PublicFilter ); +} + +void SAL_CALL DatabaseDataProvider::setFilter(const OUString & the_value) +{ + { + osl::MutexGuard g(m_aMutex); + m_aFilterManager.setFilterComponent( dbtools::FilterManager::FilterComponent::PublicFilter, the_value ); + } + set(PROPERTY_FILTER,the_value,m_Filter); +} + +sal_Bool SAL_CALL DatabaseDataProvider::getApplyFilter() +{ + osl::MutexGuard g(m_aMutex); + return m_ApplyFilter; +} + +void SAL_CALL DatabaseDataProvider::setApplyFilter( sal_Bool the_value ) +{ + { + osl::MutexGuard g(m_aMutex); + m_xAggregateSet->setPropertyValue( PROPERTY_APPLYFILTER, uno::Any( the_value ) ); + } + set(PROPERTY_APPLYFILTER,static_cast<bool>(the_value),m_ApplyFilter); +} + +OUString SAL_CALL DatabaseDataProvider::getHavingClause() +{ + osl::MutexGuard g(m_aMutex); + return m_HavingClause; +} + +void SAL_CALL DatabaseDataProvider::setHavingClause( const OUString& the_value ) +{ + { + osl::MutexGuard g(m_aMutex); + m_xAggregateSet->setPropertyValue( PROPERTY_HAVING_CLAUSE, uno::Any( the_value ) ); + } + set(PROPERTY_HAVING_CLAUSE,the_value,m_HavingClause); +} + +OUString SAL_CALL DatabaseDataProvider::getGroupBy() +{ + osl::MutexGuard g(m_aMutex); + return m_GroupBy; +} + +void SAL_CALL DatabaseDataProvider::setGroupBy( const OUString& the_value ) +{ + { + osl::MutexGuard g(m_aMutex); + m_xAggregateSet->setPropertyValue( PROPERTY_GROUP_BY, uno::Any( the_value ) ); + } + set(PROPERTY_GROUP_BY,the_value,m_GroupBy); +} + +OUString SAL_CALL DatabaseDataProvider::getOrder() +{ + osl::MutexGuard g(m_aMutex); + return m_Order; +} + +void SAL_CALL DatabaseDataProvider::setOrder( const OUString& the_value ) +{ + { + osl::MutexGuard g(m_aMutex); + m_xAggregateSet->setPropertyValue( PROPERTY_ORDER, uno::Any( the_value ) ); + } + set(PROPERTY_ORDER,the_value,m_Order); +} + +sal_Bool SAL_CALL DatabaseDataProvider::getEscapeProcessing() +{ + osl::MutexGuard g(m_aMutex); + return m_EscapeProcessing; +} + +void SAL_CALL DatabaseDataProvider::setEscapeProcessing(sal_Bool the_value) +{ + set(PROPERTY_ESCAPE_PROCESSING,static_cast<bool>(the_value),m_EscapeProcessing); +} + +::sal_Int32 SAL_CALL DatabaseDataProvider::getRowLimit() +{ + osl::MutexGuard g(m_aMutex); + return m_RowLimit; +} + +void SAL_CALL DatabaseDataProvider::setRowLimit(::sal_Int32 the_value) +{ + set("RowLimit",the_value,m_RowLimit); +} + +uno::Reference< sdbc::XConnection > SAL_CALL DatabaseDataProvider::getActiveConnection() +{ + osl::MutexGuard g(m_aMutex); + return m_xActiveConnection; +} + +void SAL_CALL DatabaseDataProvider::setActiveConnection(const uno::Reference< sdbc::XConnection > & the_value) +{ + if ( !the_value.is() ) + throw lang::IllegalArgumentException(); + set(PROPERTY_ACTIVE_CONNECTION,the_value,m_xActiveConnection); +} + +OUString SAL_CALL DatabaseDataProvider::getDataSourceName() +{ + osl::MutexGuard g(m_aMutex); + return m_DataSourceName; +} + +void SAL_CALL DatabaseDataProvider::setDataSourceName(const OUString& the_value) +{ + set(PROPERTY_DATASOURCENAME,the_value,m_DataSourceName); +} + +namespace +{ + struct ColumnDescription + { + OUString sName; + sal_Int32 nResultSetPosition; + sal_Int32 nDataType; + + ColumnDescription() + :nResultSetPosition( 0 ) + ,nDataType( sdbc::DataType::VARCHAR ) + { + } + explicit ColumnDescription( const OUString& i_rName ) + :sName( i_rName ) + ,nResultSetPosition( 0 ) + ,nDataType( sdbc::DataType::VARCHAR ) + { + } + }; + + struct CreateColumnDescription + { + ColumnDescription operator()( const OUString& i_rName ) + { + return ColumnDescription( i_rName ); + } + }; + + struct SelectColumnName + { + const OUString& operator()( const ColumnDescription& i_rColumn ) + { + return i_rColumn.sName; + } + }; +} + +void DatabaseDataProvider::impl_fillInternalDataProvider_throw(bool _bHasCategories,const uno::Sequence< 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< OUString > aRowSetColumnNames( xColumns->getElementNames() ); + + typedef std::vector< ColumnDescription > ColumnDescriptions; + ColumnDescriptions aColumns; + bool bFirstColumnIsCategory = _bHasCategories; + if ( i_aColumnNames.hasElements() ) + { + // some normalizations ... + uno::Sequence< 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 ( !aImposedColumnNames[ nLastNonEmptyColName ].isEmpty() ) + 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.hasElements() && ( !aImposedColumnNames[0].isEmpty() ) ) + { + const sal_Int32 nAssumedRowSetColumnIndex = _bHasCategories ? 1 : 0; + if ( nAssumedRowSetColumnIndex < aRowSetColumnNames.getLength() ) + aImposedColumnNames.getArray()[0] = aRowSetColumnNames[ nAssumedRowSetColumnIndex ]; + } + + const sal_Int32 nCount = aImposedColumnNames.getLength(); + for ( sal_Int32 i = 0 ; i < nCount; ++i ) + { + const OUString sColumnName( aImposedColumnNames[i] ); + if ( !xColumns->hasByName( sColumnName ) ) + continue; + + if ( _bHasCategories && aColumns.empty() ) + { + if ( aRowSetColumnNames.hasElements() ) + aColumns.emplace_back( aRowSetColumnNames[0] ); + else + aColumns.emplace_back( sColumnName ); + bFirstColumnIsCategory = true; + } + aColumns.emplace_back( sColumnName ); + } + } + if ( aColumns.empty() ) + { + aColumns.resize( aRowSetColumnNames.getLength() ); + std::transform( + aRowSetColumnNames.begin(), + aRowSetColumnNames.end(), + 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::XResultSetMetaDataSupplier > xSuppMeta( m_xRowSet,uno::UNO_QUERY_THROW ); + uno::Reference< sdbc::XColumnLocate > xColumnLocate( m_xRowSet, uno::UNO_QUERY_THROW ); + + sal_Int32 columnIndex = 0; + for (auto & column : aColumns) + { + column.nResultSetPosition = xColumnLocate->findColumn( column.sName ); + + const uno::Reference< beans::XPropertySet > xColumn( xColumns->getByName( column.sName ), uno::UNO_QUERY_THROW ); + const uno::Any aNumberFormat( xColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) ); + OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= column.nDataType ); + + const OUString sRangeName = OUString::number( columnIndex ); + m_aNumberFormats.emplace( sRangeName, aNumberFormat ); + ++columnIndex; + } + + std::vector< OUString > aRowLabels; + std::vector< std::vector< double > > aDataValues; + sal_Int32 nRowCount = 0; + ::connectivity::ORowSetValue aValue; + while( xRes->next() && (!m_RowLimit || nRowCount < m_RowLimit) ) + { + ++nRowCount; + + aValue.fill( aColumns[0].nResultSetPosition, aColumns[0].nDataType, xRow ); + aRowLabels.push_back( aValue.getString() ); + + std::vector< double > aRow; + bool bFirstLoop = true; + for (auto const& column : aColumns) + { + if (bFirstLoop) + { + bFirstLoop = false; + if (bFirstColumnIsCategory) + continue; + } + + aValue.fill( column.nResultSetPosition, column.nDataType, xRow ); + if ( aValue.isNull() ) + aRow.push_back( std::numeric_limits<double>::quiet_NaN() ); + else + aRow.push_back( aValue.getDouble() ); + } + + aDataValues.push_back( aRow ); + } + + // insert default data when no rows exist + if ( !nRowCount ) + { + nRowCount = 3; + static const double fDefaultData[ ] = + { 9.10, 3.20, 4.54, + 2.40, 8.80, 9.65, + 3.10, 1.50, 3.70, + 4.30, 9.02, 6.20 }; + for(sal_Int32 h = 0,k = 0; h < nRowCount; ++h,++k ) + { + aRowLabels.push_back(OUString::number(h+1)); + std::vector< double > aRow; + const sal_Int32 nSize = SAL_N_ELEMENTS(fDefaultData); + for (size_t j = 0; j < (aColumns.size()-1); ++j,++k) + { + if ( k >= nSize ) + k = 0; + aRow.push_back(fDefaultData[k]); + } + aDataValues.push_back(aRow); + } + } + + uno::Reference< chart::XChartDataArray> xData(m_xInternal,uno::UNO_QUERY); + xData->setRowDescriptions(comphelper::containerToSequence(aRowLabels)); + + const size_t nOffset = bFirstColumnIsCategory ? 1 : 0; + uno::Sequence< 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(); + for(sal_Int32 i= 0;pDataIter != pDataEnd; ++pDataIter,++i ) + { + if ( !aDataValues[i].empty() ) + *pDataIter = comphelper::containerToSequence(aDataValues[i]); + } + xData->setData(aData); +} + +void DatabaseDataProvider::impl_fillRowSet_throw() +{ + m_xAggregateSet->setPropertyValue( PROPERTY_FILTER, uno::Any( getFilter() ) ); + uno::Reference< sdbc::XParameters> xParam(m_xRowSet,uno::UNO_QUERY_THROW); + xParam->clearParameters( ); +} + +bool DatabaseDataProvider::impl_fillParameters_nothrow( ::osl::ResettableMutexGuard& _rClearForNotifies) +{ + // do we have to fill the parameters again? + if ( !m_aParameterManager.isUpToDate() ) + m_aParameterManager.updateParameterInfo( m_aFilterManager ); + + if ( m_aParameterManager.isUpToDate() ) + return m_aParameterManager.fillParameterValues( m_xHandler, _rClearForNotifies ); + + return true; +} + +// css::sdbc::XParameters +void SAL_CALL DatabaseDataProvider::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) +{ + m_aParameterManager.setNull(parameterIndex, sqlType); +} + +void SAL_CALL DatabaseDataProvider::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& typeName) +{ + m_aParameterManager.setObjectNull(parameterIndex, sqlType, typeName); +} + +void SAL_CALL DatabaseDataProvider::setBoolean(sal_Int32 parameterIndex, sal_Bool x) +{ + m_aParameterManager.setBoolean(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setByte(sal_Int32 parameterIndex, sal_Int8 x) +{ + m_aParameterManager.setByte(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setShort(sal_Int32 parameterIndex, sal_Int16 x) +{ + m_aParameterManager.setShort(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setInt(sal_Int32 parameterIndex, sal_Int32 x) +{ + m_aParameterManager.setInt(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setLong(sal_Int32 parameterIndex, sal_Int64 x) +{ + m_aParameterManager.setLong(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setFloat(sal_Int32 parameterIndex, float x) +{ + m_aParameterManager.setFloat(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setDouble(sal_Int32 parameterIndex, double x) +{ + m_aParameterManager.setDouble(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setString(sal_Int32 parameterIndex, const OUString& x) +{ + m_aParameterManager.setString(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setBytes(sal_Int32 parameterIndex, const uno::Sequence< sal_Int8 >& x) +{ + m_aParameterManager.setBytes(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setDate(sal_Int32 parameterIndex, const util::Date& x) +{ + m_aParameterManager.setDate(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setTime(sal_Int32 parameterIndex, const util::Time& x) +{ + m_aParameterManager.setTime(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setTimestamp(sal_Int32 parameterIndex, const util::DateTime& x) +{ + m_aParameterManager.setTimestamp(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setBinaryStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length) +{ + m_aParameterManager.setBinaryStream(parameterIndex, x, length); +} + +void SAL_CALL DatabaseDataProvider::setCharacterStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length) +{ + m_aParameterManager.setCharacterStream(parameterIndex, x, length); +} + +void SAL_CALL DatabaseDataProvider::setObjectWithInfo(sal_Int32 parameterIndex, const uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale) +{ + m_aParameterManager.setObjectWithInfo(parameterIndex, x, targetSqlType, scale); +} + +void SAL_CALL DatabaseDataProvider::setObject(sal_Int32 parameterIndex, const uno::Any& x) +{ + m_aParameterManager.setObject(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setRef(sal_Int32 parameterIndex, const uno::Reference<sdbc::XRef>& x) +{ + m_aParameterManager.setRef(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setBlob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XBlob>& x) +{ + m_aParameterManager.setBlob(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setClob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XClob>& x) +{ + m_aParameterManager.setClob(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::setArray(sal_Int32 parameterIndex, const Reference<sdbc::XArray>& x) +{ + m_aParameterManager.setArray(parameterIndex, x); +} + +void SAL_CALL DatabaseDataProvider::clearParameters() +{ + m_aParameterManager.clearParameters(); +} + +// css::sdbc::XRowSet +void SAL_CALL DatabaseDataProvider::execute() +{ + uno::Sequence< beans::PropertyValue > aEmpty; + createDataSource(aEmpty); +} + +void SAL_CALL DatabaseDataProvider::addRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener) +{ + if (m_xRowSet.is()) + m_xRowSet->addRowSetListener(_rListener); +} + +void SAL_CALL DatabaseDataProvider::removeRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener) +{ + if (m_xRowSet.is()) + m_xRowSet->removeRowSetListener(_rListener); +} + +// css::sdbc::XResultSet +sal_Bool SAL_CALL DatabaseDataProvider::next() +{ + return m_xRowSet->next(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::isBeforeFirst() +{ + return m_xRowSet->isBeforeFirst(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::isAfterLast() +{ + return m_xRowSet->isAfterLast(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::isFirst() +{ + return m_xRowSet->isFirst(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::isLast() +{ + return m_xRowSet->isLast(); +} + +void SAL_CALL DatabaseDataProvider::beforeFirst() +{ + m_xRowSet->beforeFirst(); +} + +void SAL_CALL DatabaseDataProvider::afterLast() +{ + m_xRowSet->afterLast(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::first() +{ + return m_xRowSet->first(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::last() +{ + return m_xRowSet->last(); +} + +sal_Int32 SAL_CALL DatabaseDataProvider::getRow() +{ + return m_xRowSet->getRow(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::absolute(sal_Int32 row) +{ + return m_xRowSet->absolute(row); +} + +sal_Bool SAL_CALL DatabaseDataProvider::relative(sal_Int32 rows) +{ + return m_xRowSet->relative(rows); +} + +sal_Bool SAL_CALL DatabaseDataProvider::previous() +{ + return m_xRowSet->previous(); +} + +void SAL_CALL DatabaseDataProvider::refreshRow() +{ + m_xRowSet->refreshRow(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::rowUpdated() +{ + return m_xRowSet->rowUpdated(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::rowInserted() +{ + return m_xRowSet->rowInserted(); +} + +sal_Bool SAL_CALL DatabaseDataProvider::rowDeleted() +{ + return m_xRowSet->rowDeleted(); +} + +uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getStatement() +{ + return m_xRowSet->getStatement(); +} + +uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getParent( ) +{ + return m_xParent; +} + +void SAL_CALL DatabaseDataProvider::setParent( const uno::Reference< uno::XInterface >& _xParent ) +{ + osl::MutexGuard g(m_aMutex); + m_xParent = _xParent; +} + +void DatabaseDataProvider::impl_invalidateParameter_nothrow() +{ + osl::MutexGuard g(m_aMutex); + m_aParameterManager.clearAllParameterInformation(); +} + +} // namespace dbaccess + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_dbaccess_DatabaseDataProvider_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& ) +{ + return cppu::acquire(new dbaccess::DatabaseDataProvider(context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/PropertyForward.cxx b/dbaccess/source/core/misc/PropertyForward.cxx new file mode 100644 index 000000000..239bd422f --- /dev/null +++ b/dbaccess/source/core/misc/PropertyForward.cxx @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <PropertyForward.hxx> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp> +#include <com/sun/star/sdbcx/XAppend.hpp> + +#include <comphelper/property.hxx> +#include <tools/diagnose_ex.h> + +namespace dbaccess +{ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::container; + using namespace ::com::sun::star::sdbcx; + using namespace ::com::sun::star::lang; + + + OPropertyForward::OPropertyForward( const Reference< XPropertySet>& _xSource, const Reference< XNameAccess>& _xDestContainer, + const OUString& _sName, const std::vector< OUString>& _aPropertyList ) + :m_xSource( _xSource, UNO_SET_THROW ) + ,m_xDestContainer( _xDestContainer, UNO_SET_THROW ) + ,m_sName( _sName ) + ,m_bInInsert( false ) + { + + osl_atomic_increment(&m_refCount); + try + { + if ( _aPropertyList.empty() ) + _xSource->addPropertyChangeListener( OUString(), this ); + else + { + for (auto const& property : _aPropertyList) + _xSource->addPropertyChangeListener(property, this); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + osl_atomic_decrement( &m_refCount ); + } + + OPropertyForward::~OPropertyForward() + { + } + + void SAL_CALL OPropertyForward::propertyChange( const PropertyChangeEvent& evt ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_xDestContainer.is() ) + throw DisposedException( OUString(), *this ); + + try + { + if ( !m_xDest.is() ) + { + if ( m_xDestContainer->hasByName( m_sName ) ) + { + m_xDest.set( m_xDestContainer->getByName( m_sName ), UNO_QUERY_THROW ); + } + else + { + Reference< XDataDescriptorFactory > xFactory( m_xDestContainer, UNO_QUERY_THROW ); + m_xDest.set( xFactory->createDataDescriptor(), UNO_SET_THROW ); + + ::comphelper::copyProperties( m_xSource, m_xDest ); + + m_bInInsert = true; + Reference< XAppend > xAppend( m_xDestContainer, UNO_QUERY_THROW ); + xAppend->appendByDescriptor( m_xDest ); + m_bInInsert = false; + } + + m_xDestInfo.set( m_xDest->getPropertySetInfo(), UNO_SET_THROW ); + } + + if ( m_xDestInfo->hasPropertyByName( evt.PropertyName ) ) + { + m_xDest->setPropertyValue( evt.PropertyName, evt.NewValue ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + } + + void SAL_CALL OPropertyForward::disposing( const css::lang::EventObject& /*_rSource*/ ) + { + ::osl::MutexGuard aGuard(m_aMutex); + + if ( !m_xSource.is() ) + throw DisposedException( OUString(), *this ); + + m_xSource->removePropertyChangeListener( OUString(), this ); + m_xSource = nullptr; + m_xDestContainer = nullptr; + m_xDestInfo = nullptr; + m_xDest = nullptr; + } + + void OPropertyForward::setDefinition( const css::uno::Reference< css::beans::XPropertySet>& _xDest ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInInsert ) + return; + + OSL_ENSURE( !m_xDest.is(), "OPropertyForward::setDefinition: definition object is already set!" ); + try + { + m_xDest.set( _xDest, UNO_SET_THROW ); + m_xDestInfo.set( m_xDest->getPropertySetInfo(), UNO_SET_THROW ); + ::comphelper::copyProperties( m_xDest, m_xSource ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + } + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/apitools.cxx b/dbaccess/source/core/misc/apitools.cxx new file mode 100644 index 000000000..efec92cf5 --- /dev/null +++ b/dbaccess/source/core/misc/apitools.cxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <apitools.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <sal/log.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace cppu; +using namespace osl; + +// various helper functions +// OSubComponent +OSubComponent::OSubComponent(Mutex& _rMutex, const Reference< XInterface > & xParent) + :OComponentHelper(_rMutex) + ,m_xParent(xParent) +{ + +} + +OSubComponent::~OSubComponent() +{ + m_xParent = nullptr; + +} + +// css::lang::XTypeProvider +Sequence< Type > OSubComponent::getTypes() +{ + OTypeCollection aTypes(cppu::UnoType<XComponent>::get(), + cppu::UnoType<XTypeProvider>::get(), + cppu::UnoType<XWeak>::get()); + + return aTypes.getTypes(); +} + +// XInterface + +void OSubComponent::release() noexcept +{ + Reference< XInterface > x( xDelegator ); + if (! x.is()) + { + if (osl_atomic_decrement( &m_refCount ) == 0 ) + { + if (! rBHelper.bDisposed) + { + // *before* again incrementing our ref count, ensure that our weak connection point + // will not create references to us anymore (via XAdapter::queryAdapted) + disposeWeakConnectionPoint(); + + Reference< XInterface > xHoldAlive( *this ); + // remember the parent + Reference< XInterface > xParent; + { + MutexGuard aGuard( rBHelper.rMutex ); + xParent = m_xParent; + m_xParent = nullptr; + } + + SAL_WARN_IF( m_refCount != 1, "dbaccess.core", "OSubComponent::release: invalid ref count (before dispose)!" ); + + // First dispose + dispose(); + + // only the alive ref holds the object + SAL_WARN_IF( m_refCount != 1, "dbaccess.core", "OSubComponent::release: invalid ref count (after dispose)!" ); + + // release the parent in the ~ + if (xParent.is()) + { + MutexGuard aGuard( rBHelper.rMutex ); + m_xParent = xParent; + } + + // destroy the object if xHoldAlive decrement the refcount to 0 + return; + } + } + // restore the reference count + osl_atomic_increment( &m_refCount ); + } + + // as we cover the job of the componenthelper we use the ... + OWeakAggObject::release(); +} + +Any OSubComponent::queryInterface( const Type & rType ) +{ + Any aReturn; + if (!rType.equals(cppu::UnoType<XAggregation>::get())) + aReturn = OComponentHelper::queryInterface(rType); + + return aReturn; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/dsntypes.cxx b/dbaccess/source/core/misc/dsntypes.cxx new file mode 100644 index 000000000..d8ceed402 --- /dev/null +++ b/dbaccess/source/core/misc/dsntypes.cxx @@ -0,0 +1,565 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <config_java.h> +#include <dsntypes.hxx> +#include <unotools/confignode.hxx> +#include <o3tl/safeint.hxx> +#include <o3tl/string_view.hxx> +#include <osl/diagnose.h> +#include <tools/wldcrd.hxx> +#include <osl/file.hxx> +#include <officecfg/Office/Common.hxx> +#include <comphelper/string.hxx> + +namespace dbaccess +{ + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::lang; + + namespace + { + void lcl_extractHostAndPort(std::u16string_view _sUrl, OUString& _sHostname, sal_Int32& _nPortNumber) + { + if ( comphelper::string::getTokenCount(_sUrl, ':') >= 2 ) + { + sal_Int32 nPos {0}; + _sHostname = o3tl::getToken(_sUrl, 0, ':', nPos); + _nPortNumber = o3tl::toInt32(o3tl::getToken(_sUrl, 0, ':', nPos)); + } + } + } +// ODsnTypeCollection +ODsnTypeCollection::ODsnTypeCollection(const css::uno::Reference< css::uno::XComponentContext >& _xContext) +:m_aDriverConfig(_xContext) +#if OSL_DEBUG_LEVEL > 0 +,m_nLivingIterators(0) +#endif +{ + const uno::Sequence< OUString > aURLs = m_aDriverConfig.getURLs(); + const OUString* pIter = aURLs.getConstArray(); + const OUString* pEnd = pIter + aURLs.getLength(); + for(;pIter != pEnd;++pIter ) + { + m_aDsnPrefixes.push_back(*pIter); + m_aDsnTypesDisplayNames.push_back(m_aDriverConfig.getDriverTypeDisplayName(*pIter)); + } + + OSL_ENSURE(m_aDsnTypesDisplayNames.size() == m_aDsnPrefixes.size(), + "ODsnTypeCollection::ODsnTypeCollection : invalid resources !"); +} + +ODsnTypeCollection::~ODsnTypeCollection() +{ +#if OSL_DEBUG_LEVEL > 0 + OSL_ENSURE(0 == m_nLivingIterators, "ODsnTypeCollection::~ODsnTypeCollection : there are still living iterator objects!"); +#endif +} + +OUString ODsnTypeCollection::getTypeDisplayName(std::u16string_view _sURL) const +{ + return m_aDriverConfig.getDriverTypeDisplayName(_sURL); +} + +OUString ODsnTypeCollection::cutPrefix(std::u16string_view _sURL) const +{ + OUString sRet; + OUString sOldPattern; + + // on Windows or with gen rendering, the urls may begin with an ~ + std::u16string_view sCleanURL = comphelper::string::stripStart(_sURL, '~'); + + for (auto const& dsnPrefix : m_aDsnPrefixes) + { + WildCard aWildCard(dsnPrefix); + if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(sCleanURL) ) + { + // This relies on the fact that all patterns are of the form + // foo* + // that is, the very concept of "prefix" applies. + OUString prefix(comphelper::string::stripEnd(dsnPrefix, '*')); + OSL_ENSURE(o3tl::make_unsigned(prefix.getLength()) <= sCleanURL.size(), "How can A match B when A shorter than B?"); + sRet = sCleanURL.substr(prefix.getLength()); + sOldPattern = dsnPrefix; + } + } + + return sRet; +} + +OUString ODsnTypeCollection::getPrefix(const OUString& _sURL) const +{ + OUString sRet; + OUString sOldPattern; + for (auto const& dsnPrefix : m_aDsnPrefixes) + { + WildCard aWildCard(dsnPrefix); + if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) ) + { + // This relies on the fact that all patterns are of the form + // foo* + // that is, the very concept of "prefix" applies. + sRet = comphelper::string::stripEnd(dsnPrefix, '*'); + OSL_ENSURE(sRet.getLength() <= _sURL.getLength(), "How can A match B when A shorter than B?"); + sOldPattern = dsnPrefix; + } + } + + return sRet; +} + +bool ODsnTypeCollection::hasDriver( const char* _pAsciiPattern ) const +{ + OUString sPrefix( getPrefix( OUString::createFromAscii( _pAsciiPattern ) ) ); + return !sPrefix.isEmpty(); +} + +bool ODsnTypeCollection::isConnectionUrlRequired(std::u16string_view _sURL) const +{ + OUString sRet; + OUString sOldPattern; + for (auto const& dsnPrefix : m_aDsnPrefixes) + { + WildCard aWildCard(dsnPrefix); + if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) ) + { + sRet = dsnPrefix; + sOldPattern = dsnPrefix; + } + } + return !sRet.isEmpty() && sRet[sRet.getLength()-1] == '*'; +} + +OUString ODsnTypeCollection::getMediaType(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("MediaType",OUString()); +} + +OUString ODsnTypeCollection::getDatasourcePrefixFromMediaType(std::u16string_view _sMediaType,std::u16string_view _sExtension) +{ + OUString sURL, sFallbackURL; + const uno::Sequence< OUString > aURLs = m_aDriverConfig.getURLs(); + const OUString* pIter = aURLs.getConstArray(); + const OUString* pEnd = pIter + aURLs.getLength(); + for(;pIter != pEnd;++pIter ) + { + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(*pIter); + if ( aFeatures.getOrDefault("MediaType",OUString()) == _sMediaType ) + { + const OUString sFileExtension = aFeatures.getOrDefault("Extension",OUString()); + if ( _sExtension == sFileExtension ) + { + sURL = *pIter; + break; + } + if ( sFileExtension.isEmpty() && !_sExtension.empty() ) + sFallbackURL = *pIter; + } + } + + if ( sURL.isEmpty() && !sFallbackURL.isEmpty() ) + sURL = sFallbackURL; + + sURL = comphelper::string::stripEnd(sURL, '*'); + return sURL; +} + +bool ODsnTypeCollection::isShowPropertiesEnabled( const OUString& _sURL ) +{ + return !( _sURL.startsWithIgnoreAsciiCase("sdbc:embedded:hsqldb") + || _sURL.startsWithIgnoreAsciiCase("sdbc:embedded:firebird") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:outlook") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:outlookexp") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:mozilla:") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:kab") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:local") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:groupwise") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:ldap") + || _sURL.startsWithIgnoreAsciiCase("sdbc:address:macab") ); +} + +void ODsnTypeCollection::extractHostNamePort(const OUString& _rDsn,OUString& _sDatabaseName,OUString& _rsHostname,sal_Int32& _nPortNumber) const +{ + OUString sUrl = cutPrefix(_rDsn); + if ( _rDsn.startsWithIgnoreAsciiCase("jdbc:oracle:thin:") ) + { + lcl_extractHostAndPort(sUrl,_rsHostname,_nPortNumber); + const sal_Int32 nUrlTokens {comphelper::string::getTokenCount(sUrl, ':')}; + if ( _rsHostname.isEmpty() && nUrlTokens == 2 ) + { + _nPortNumber = -1; + _rsHostname = sUrl.getToken(0,':'); + } + if ( !_rsHostname.isEmpty() ) + _rsHostname = _rsHostname.copy(_rsHostname.lastIndexOf('@')+1); + _sDatabaseName = sUrl.copy(sUrl.lastIndexOf(':')+1); + } + else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:address:ldap:") ) + { + lcl_extractHostAndPort(sUrl,_sDatabaseName,_nPortNumber); + } + else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:mysql:mysqlc:") + || _rDsn.startsWithIgnoreAsciiCase("sdbc:mysql:jdbc:") ) + { + lcl_extractHostAndPort(sUrl,_rsHostname,_nPortNumber); + + const sal_Int32 nUrlTokens {comphelper::string::getTokenCount(sUrl, '/')}; + if ( _nPortNumber == -1 && _rsHostname.isEmpty() && nUrlTokens == 2 ) + _rsHostname = sUrl.getToken(0,'/'); + _sDatabaseName = sUrl.copy(sUrl.lastIndexOf('/')+1); + } + else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:Provider=Microsoft.ACE.OLEDB.12.0;DATA SOURCE=") + || _rDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=") ) + { + OUString sNewFileName; + if ( ::osl::FileBase::getFileURLFromSystemPath( sUrl, sNewFileName ) == ::osl::FileBase::E_None ) + { + _sDatabaseName = sNewFileName; + } + } +} + +OUString ODsnTypeCollection::getJavaDriverClass(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getProperties(_sURL); + return aFeatures.getOrDefault("JavaDriverClass",OUString()); +} + +bool ODsnTypeCollection::isFileSystemBased(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("FileSystemBased",false); +} + +bool ODsnTypeCollection::supportsTableCreation(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("SupportsTableCreation",false); +} + +bool ODsnTypeCollection::supportsColumnDescription(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("SupportsColumnDescription",false); +} + +bool ODsnTypeCollection::supportsBrowsing(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("SupportsBrowsing",false); +} + +bool ODsnTypeCollection::supportsDBCreation(std::u16string_view _sURL) const +{ + const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL); + return aFeatures.getOrDefault("SupportsDBCreation",false); +} + +Sequence<PropertyValue> ODsnTypeCollection::getDefaultDBSettings( std::u16string_view _sURL ) const +{ + const ::comphelper::NamedValueCollection& aProperties = m_aDriverConfig.getProperties(_sURL); + return aProperties.getPropertyValues(); +} + +bool ODsnTypeCollection::isEmbeddedDatabase( std::u16string_view _sURL ) +{ + return o3tl::starts_with( _sURL, u"sdbc:embedded:" ); +} + +OUString ODsnTypeCollection::getEmbeddedDatabase() +{ + if (!HAVE_FEATURE_JAVA || officecfg::Office::Common::Misc::ExperimentalMode::get()) + return "sdbc:embedded:firebird"; + else + return "sdbc:embedded:hsqldb"; +} + + +DATASOURCE_TYPE ODsnTypeCollection::determineType(std::u16string_view _rDsn) const +{ + OUString sDsn(comphelper::string::stripEnd(_rDsn, '*')); + sal_Int32 nSeparator = sDsn.indexOf(u':'); + if (-1 == nSeparator) + { + if (!sDsn.isEmpty()) + { + // there should be at least one such separator + OSL_FAIL("ODsnTypeCollection::implDetermineType : missing the colon !"); + } + + return DST_UNKNOWN; + } + + // find first : + if (sDsn.startsWithIgnoreAsciiCase("jdbc:oracle:thin:")) + return DST_ORACLE_JDBC; + + if (sDsn.startsWithIgnoreAsciiCase("jdbc:")) + return DST_JDBC; + + if (sDsn.equalsIgnoreAsciiCase("sdbc:embedded:hsqldb")) + return DST_EMBEDDED_HSQLDB; + + if (sDsn.equalsIgnoreAsciiCase("sdbc:embedded:firebird")) + return DST_EMBEDDED_FIREBIRD; + + // find second : + nSeparator = sDsn.indexOf(u':', nSeparator + 1); + if (-1 == nSeparator) + { + // at the moment only jdbc is allowed to have just one separator + OSL_FAIL("ODsnTypeCollection::implDetermineType : missing the second colon !"); + return DST_UNKNOWN; + } + + if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:")) + { + if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:")) + { + if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:Provider=Microsoft.ACE.OLEDB.12.0;")) + return DST_MSACCESS_2007; + else + return DST_MSACCESS; + } + return DST_ADO; + } + + struct KnownPrefix + { + const OUString sPrefix; + const DATASOURCE_TYPE eType; + const bool bMatchComplete; + + KnownPrefix( const OUString &_s, const DATASOURCE_TYPE _t, const bool _m ) + :sPrefix( _s ) + ,eType ( _t ) + ,bMatchComplete( _m ) + { + } + + bool match( const OUString &url) const + { + if(bMatchComplete) + { + return url.equalsIgnoreAsciiCase(sPrefix); + } + else + { + return url.startsWithIgnoreAsciiCase(sPrefix); + } + } + }; + const KnownPrefix aKnowPrefixes[] = + { + KnownPrefix( "sdbc:calc:", DST_CALC, false ), + KnownPrefix( "sdbc:writer:", DST_WRITER, false ), + KnownPrefix( "sdbc:flat:", DST_FLAT, false ), + KnownPrefix( "sdbc:odbc:", DST_ODBC, false ), + KnownPrefix( "sdbc:dbase:", DST_DBASE, false ), + KnownPrefix( "sdbc:firebird:", DST_FIREBIRD, false ), + KnownPrefix( "sdbc:mysql:odbc:", DST_MYSQL_ODBC, false ), + KnownPrefix( "sdbc:mysql:jdbc:", DST_MYSQL_JDBC, false ), + KnownPrefix( "sdbc:mysql:mysqlc:", DST_MYSQL_NATIVE, false ), + KnownPrefix( "sdbc:mysqlc:", DST_MYSQL_NATIVE_DIRECT,false ), + KnownPrefix( "sdbc:postgresql:", DST_POSTGRES ,false ), + + KnownPrefix( "sdbc:address:mozilla:", DST_MOZILLA, true ), + KnownPrefix( "sdbc:address:thunderbird:", DST_THUNDERBIRD, true ), + KnownPrefix( "sdbc:address:ldap:", DST_LDAP, true ), + KnownPrefix( "sdbc:address:outlook", DST_OUTLOOK, true ), + KnownPrefix( "sdbc:address:outlookexp", DST_OUTLOOKEXP, true ), + KnownPrefix( "sdbc:address:evolution:ldap", DST_EVOLUTION_LDAP, true ), + KnownPrefix( "sdbc:address:evolution:groupwise",DST_EVOLUTION_GROUPWISE,true ), + KnownPrefix( "sdbc:address:evolution:local", DST_EVOLUTION, true ), + KnownPrefix( "sdbc:address:kab", DST_KAB, true ), + KnownPrefix( "sdbc:address:macab", DST_MACAB, true ) + }; + + for (const auto & aKnowPrefixe : aKnowPrefixes) + { + if( aKnowPrefixe.match(sDsn) ) + { + return aKnowPrefixe.eType; + } + } + + return DST_UNKNOWN; +} + +void ODsnTypeCollection::fillPageIds(std::u16string_view _sURL,std::vector<sal_Int16>& _rOutPathIds) const +{ + DATASOURCE_TYPE eType = determineType(_sURL); + switch(eType) + { + case DST_ADO: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ADO); + break; + case DST_DBASE: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_DBASE); + break; + case DST_FLAT: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_TEXT); + break; + case DST_CALC: + case DST_WRITER: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET); + break; + case DST_ODBC: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ODBC); + break; + case DST_JDBC: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_JDBC); + break; + case DST_MYSQL_ODBC: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO); + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_ODBC); + break; + case DST_MYSQL_JDBC: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO); + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_JDBC); + break; + case DST_MYSQL_NATIVE: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO); + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_NATIVE); + break; + case DST_ORACLE_JDBC: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ORACLE); + break; + case DST_LDAP: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_LDAP); + break; + case DST_MSACCESS: + case DST_MSACCESS_2007: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MSACCESS); + break; + case DST_OUTLOOKEXP: + case DST_OUTLOOK: + case DST_MOZILLA: + case DST_THUNDERBIRD: + case DST_EVOLUTION: + case DST_EVOLUTION_GROUPWISE: + case DST_EVOLUTION_LDAP: + case DST_KAB: + case DST_MACAB: + case DST_EMBEDDED_HSQLDB: + case DST_EMBEDDED_FIREBIRD: + break; + default: + _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_USERDEFINED); + break; + } +} + +OUString ODsnTypeCollection::getType(std::u16string_view _sURL) const +{ + OUString sOldPattern; + for (auto const& dsnPrefix : m_aDsnPrefixes) + { + WildCard aWildCard(dsnPrefix); + if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) ) + { + sOldPattern = dsnPrefix; + } + } + return sOldPattern; +} + +sal_Int32 ODsnTypeCollection::getIndexOf(std::u16string_view _sURL) const +{ + sal_Int32 nRet = -1; + OUString sOldPattern; + sal_Int32 i = 0; + for (auto const& dsnPrefix : m_aDsnPrefixes) + { + WildCard aWildCard(dsnPrefix); + if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) ) + { + nRet = i; + sOldPattern = dsnPrefix; + } + ++i; + } + + return nRet; +} + +sal_Int32 ODsnTypeCollection::size() const +{ + return m_aDsnPrefixes.size(); +} + +// ODsnTypeCollection::TypeIterator +ODsnTypeCollection::TypeIterator::TypeIterator(const ODsnTypeCollection* _pContainer, sal_Int32 _nInitialPos) + :m_pContainer(_pContainer) + ,m_nPosition(_nInitialPos) +{ + OSL_ENSURE(m_pContainer, "ODsnTypeCollection::TypeIterator::TypeIterator : invalid container!"); +#if OSL_DEBUG_LEVEL > 0 + ++const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators; +#endif +} + +ODsnTypeCollection::TypeIterator::TypeIterator(const TypeIterator& _rSource) + :m_pContainer(_rSource.m_pContainer) + ,m_nPosition(_rSource.m_nPosition) +{ +#if OSL_DEBUG_LEVEL > 0 + ++const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators; +#endif +} + +ODsnTypeCollection::TypeIterator::~TypeIterator() +{ +#if OSL_DEBUG_LEVEL > 0 + --const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators; +#endif +} + +OUString const & ODsnTypeCollection::TypeIterator::getDisplayName() const +{ + OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size()), "ODsnTypeCollection::TypeIterator::getDisplayName : invalid position!"); + return m_pContainer->m_aDsnTypesDisplayNames[m_nPosition]; +} + +OUString const & ODsnTypeCollection::TypeIterator::getURLPrefix() const +{ + OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnPrefixes.size()), "ODsnTypeCollection::TypeIterator::getDisplayName : invalid position!"); + return m_pContainer->m_aDsnPrefixes[m_nPosition]; +} + +const ODsnTypeCollection::TypeIterator& ODsnTypeCollection::TypeIterator::operator++() +{ + OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size()), "ODsnTypeCollection::TypeIterator::operator++ : invalid position!"); + if (m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size())) + ++m_nPosition; + return *this; +} + +bool operator==(const ODsnTypeCollection::TypeIterator& lhs, const ODsnTypeCollection::TypeIterator& rhs) +{ + return (lhs.m_pContainer == rhs.m_pContainer) && (lhs.m_nPosition == rhs.m_nPosition); +} + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/migrwarndlg.cxx b/dbaccess/source/core/misc/migrwarndlg.cxx new file mode 100644 index 000000000..d1712fba3 --- /dev/null +++ b/dbaccess/source/core/misc/migrwarndlg.cxx @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <migrwarndlg.hxx> + +namespace dbaccess +{ +MigrationWarnDialog::MigrationWarnDialog(weld::Window* pParent) + : MessageDialogController(pParent, "dbaccess/ui/migrwarndlg.ui", "MigrationWarnDialog") + , m_xLater(m_xBuilder->weld_button("no")) +{ + m_xLater->grab_focus(); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/objectnameapproval.cxx b/dbaccess/source/core/misc/objectnameapproval.cxx new file mode 100644 index 000000000..3ec15caaa --- /dev/null +++ b/dbaccess/source/core/misc/objectnameapproval.cxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <objectnameapproval.hxx> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdb/tools/XConnectionTools.hpp> +#include <com/sun/star/sdb/CommandType.hpp> + +#include <cppuhelper/weakref.hxx> + +namespace dbaccess +{ + + using ::com::sun::star::sdbc::XConnection; + using ::com::sun::star::uno::WeakReference; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::sdb::tools::XConnectionTools; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::sdb::tools::XObjectNames; + using ::com::sun::star::uno::XInterface; + + namespace CommandType = com::sun::star::sdb::CommandType; + + // ObjectNameApproval_Impl + struct ObjectNameApproval_Impl + { + WeakReference< XConnection > aConnection; + sal_Int32 nCommandType; + }; + + // ObjectNameApproval + ObjectNameApproval::ObjectNameApproval( const Reference< XConnection >& _rxConnection, ObjectType _eType ) + :m_pImpl( new ObjectNameApproval_Impl ) + { + m_pImpl->aConnection = _rxConnection; + m_pImpl->nCommandType = _eType == TypeQuery ? CommandType::QUERY : CommandType::TABLE; + } + + ObjectNameApproval::~ObjectNameApproval() + { + } + + void ObjectNameApproval::approveElement( const OUString& _rName ) + { + Reference< XConnection > xConnection( m_pImpl->aConnection ); + if ( !xConnection.is() ) + throw DisposedException(); + + Reference< XConnectionTools > xConnectionTools( xConnection, UNO_QUERY_THROW ); + Reference< XObjectNames > xObjectNames( xConnectionTools->getObjectNames(), css::uno::UNO_SET_THROW ); + xObjectNames->checkNameForCreate( m_pImpl->nCommandType, _rName ); + } + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/sdbcoretools.cxx b/dbaccess/source/core/misc/sdbcoretools.cxx new file mode 100644 index 000000000..1789aea84 --- /dev/null +++ b/dbaccess/source/core/misc/sdbcoretools.cxx @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sdbcoretools.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/sdb/XDocumentDataSource.hpp> +#include <com/sun/star/task/InteractionRequestStringResolver.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/ElementModes.hpp> + +#include <tools/diagnose_ex.h> +#include <comphelper/interaction.hxx> +#include <rtl/ref.hxx> + +namespace dbaccess +{ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::io; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::sdb; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::task; + using namespace ::com::sun::star::embed; + using namespace ::com::sun::star::container; + + void notifyDataSourceModified(const css::uno::Reference< css::uno::XInterface >& _rxObject) + { + Reference< XInterface > xDs = getDataSource( _rxObject ); + Reference<XDocumentDataSource> xDocumentDataSource(xDs,UNO_QUERY); + if ( xDocumentDataSource.is() ) + xDs = xDocumentDataSource->getDatabaseDocument(); + Reference< XModifiable > xModi( xDs, UNO_QUERY ); + if ( xModi.is() ) + xModi->setModified(true); + } + + Reference< XInterface > getDataSource( const Reference< XInterface >& _rxDependentObject ) + { + Reference< XInterface > xParent = _rxDependentObject; + Reference< XInterface > xReturn; + while( xParent.is() ) + { + xReturn = xParent; + Reference<XChild> xChild(xParent,UNO_QUERY); + xParent.set(xChild.is() ? xChild->getParent() : Reference< XInterface >(),UNO_QUERY); + } + return xReturn; + } + + OUString extractExceptionMessage( const Reference<XComponentContext> & _rContext, const Any& _rError ) + { + OUString sDisplayMessage; + + try + { + Reference< XInteractionRequestStringResolver > xStringResolver = InteractionRequestStringResolver::create(_rContext); + + ::rtl::Reference pRequest( new ::comphelper::OInteractionRequest( _rError ) ); + ::rtl::Reference pApprove( new ::comphelper::OInteractionApprove ); + pRequest->addContinuation( pApprove ); + Optional< OUString > aMessage = xStringResolver->getStringFromInformationalRequest( pRequest ); + if ( aMessage.IsPresent ) + sDisplayMessage = aMessage.Value; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + + if ( sDisplayMessage.isEmpty() ) + { + Exception aExcept; + _rError >>= aExcept; + + sDisplayMessage = _rError.getValueTypeName() + + ":\n" + + aExcept.Message; + } + + return sDisplayMessage; + } + + namespace tools::stor { + + bool storageIsWritable_nothrow( const Reference< XStorage >& _rxStorage ) + { + if ( !_rxStorage.is() ) + return false; + + sal_Int32 nMode = ElementModes::READ; + try + { + Reference< XPropertySet > xStorageProps( _rxStorage, UNO_QUERY_THROW ); + xStorageProps->getPropertyValue( "OpenMode" ) >>= nMode; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("dbaccess"); + } + return ( nMode & ElementModes::WRITE ) != 0; + } + + bool commitStorageIfWriteable( const Reference< XStorage >& _rxStorage ) + { + bool bSuccess = false; + Reference< XTransactedObject > xTrans( _rxStorage, UNO_QUERY ); + if ( xTrans.is() ) + { + if ( storageIsWritable_nothrow( _rxStorage ) ) + xTrans->commit(); + bSuccess = true; + } + return bSuccess; + } + +} + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dbaccess/source/core/misc/veto.cxx b/dbaccess/source/core/misc/veto.cxx new file mode 100644 index 000000000..d2596d4e1 --- /dev/null +++ b/dbaccess/source/core/misc/veto.cxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <veto.hxx> + +namespace dbaccess +{ + + using ::com::sun::star::uno::Any; + + // Veto + Veto::Veto( const Any& _rDetails ) + :m_aDetails( _rDetails ) + { + } + + Veto::~Veto() + { + } + + OUString SAL_CALL Veto::getReason() + { + return OUString(); + } + + Any SAL_CALL Veto::getDetails() + { + return m_aDetails; + } + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |