Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / core / misc / DatabaseDataProvider.cxx
blob1b256dc3e4cd28538162433928d5570587d42588
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "DatabaseDataProvider.hxx"
21 #include "dbastrings.hrc"
22 #include "cppuhelper/implbase1.hxx"
23 #include <cppuhelper/supportsservice.hxx>
24 #include <comphelper/types.hxx>
25 #include <comphelper/namedvaluecollection.hxx>
26 #include <connectivity/FValue.hxx>
27 #include <connectivity/dbtools.hxx>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/math.hxx>
30 #include <sal/macros.h>
31 #include <tools/diagnose_ex.h>
33 #include <com/sun/star/task/XInteractionHandler.hpp>
34 #include <com/sun/star/sdb/XCompletedExecution.hpp>
35 #include <com/sun/star/sdb/CommandType.hpp>
36 #include <com/sun/star/sdbc/DataType.hpp>
37 #include <com/sun/star/sdbc/XRow.hpp>
38 #include <com/sun/star/sdbc/XResultSet.hpp>
39 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
40 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
41 #include <com/sun/star/sdbc/XColumnLocate.hpp>
42 #include <com/sun/star/beans/NamedValue.hpp>
43 #include <com/sun/star/chart/ChartDataRowSource.hpp>
44 #include <com/sun/star/chart/XChartDataArray.hpp>
45 #include <com/sun/star/chart/XDateCategories.hpp>
47 #include <vector>
48 #include <list>
50 namespace dbaccess
52 using namespace ::com::sun::star;
53 using ::com::sun::star::sdbc::SQLException;
54 using ::com::sun::star::uno::Reference;
55 using ::com::sun::star::uno::RuntimeException;
57 DatabaseDataProvider::DatabaseDataProvider(uno::Reference< uno::XComponentContext > const & context) :
58 TDatabaseDataProvider(m_aMutex),
59 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >(
60 context, static_cast< Implements >(
61 IMPLEMENTS_PROPERTY_SET), uno::Sequence< OUString >()),
62 m_aParameterManager( m_aMutex, context ),
63 m_aFilterManager(),
64 m_xContext(context),
65 m_CommandType(sdb::CommandType::COMMAND), // #i94114
66 m_RowLimit(0),
67 m_EscapeProcessing(true),
68 m_ApplyFilter(true)
70 m_xInternal.set( m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.chart.InternalDataProvider",m_xContext ), uno::UNO_QUERY );
71 m_xRangeConversion.set(m_xInternal,uno::UNO_QUERY);
72 m_xComplexDescriptionAccess.set(m_xInternal,uno::UNO_QUERY);
74 osl_atomic_increment( &m_refCount );
76 m_xRowSet.set( m_xContext->getServiceManager()->createInstanceWithContext(SERVICE_SDB_ROWSET,m_xContext ), uno::UNO_QUERY );
77 m_xAggregate.set(m_xRowSet,uno::UNO_QUERY);
78 m_xAggregateSet.set(m_xRowSet,uno::UNO_QUERY);
79 uno::Reference<beans::XPropertySet> xProp(static_cast< ::cppu::OWeakObject* >( this ),uno::UNO_QUERY);
80 m_aFilterManager.initialize( m_xAggregateSet );
81 m_aParameterManager.initialize( xProp, m_xAggregate );
82 m_xAggregateSet->setPropertyValue(PROPERTY_COMMAND_TYPE,uno::makeAny(m_CommandType));
83 m_xAggregateSet->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,uno::makeAny(m_EscapeProcessing));
85 osl_atomic_decrement( &m_refCount );
88 void SAL_CALL DatabaseDataProvider::disposing()
90 lang::EventObject aEvt(static_cast<XWeak*>(this));
92 m_aParameterManager.dispose(); // (to free any references it may have to me)
93 m_aFilterManager.dispose(); // (dito)
95 m_xParent.clear();
96 m_xAggregateSet.clear();
97 m_xAggregate.clear();
98 m_xRangeConversion.clear();
99 ::comphelper::disposeComponent(m_xRowSet);
100 ::comphelper::disposeComponent(m_xInternal);
101 m_xActiveConnection.clear();
104 uno::Any DatabaseDataProvider::queryInterface(uno::Type const & type) throw (uno::RuntimeException, std::exception)
106 return TDatabaseDataProvider::queryInterface(type);
109 OUString DatabaseDataProvider::getImplementationName_Static( ) throw(uno::RuntimeException)
111 return OUString("com.sun.star.comp.dbaccess.DatabaseDataProvider");
114 // XServiceInfo
115 OUString SAL_CALL DatabaseDataProvider::getImplementationName( ) throw(uno::RuntimeException, std::exception)
117 return getImplementationName_Static();
120 sal_Bool SAL_CALL DatabaseDataProvider::supportsService( const OUString& _rServiceName ) throw(uno::RuntimeException, std::exception)
122 return cppu::supportsService(this, _rServiceName);
125 uno::Sequence< OUString > DatabaseDataProvider::getSupportedServiceNames_Static( ) throw (uno::RuntimeException)
127 uno::Sequence< OUString > aSNS( 1 );
128 aSNS[0] = "com.sun.star.chart2.data.DatabaseDataProvider";
129 return aSNS;
132 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getSupportedServiceNames( ) throw(uno::RuntimeException, std::exception)
134 return getSupportedServiceNames_Static();
137 uno::Reference< uno::XInterface > DatabaseDataProvider::Create(uno::Reference< uno::XComponentContext > const & context)
139 return *(new DatabaseDataProvider(context)) ;
142 // lang::XInitialization:
143 void SAL_CALL DatabaseDataProvider::initialize(const uno::Sequence< uno::Any > & aArguments) throw (uno::RuntimeException, uno::Exception, std::exception)
145 osl::MutexGuard g(m_aMutex);
146 const uno::Any* pIter = aArguments.getConstArray();
147 const uno::Any* pEnd = pIter + aArguments.getLength();
148 for(;pIter != pEnd;++pIter)
150 if ( !m_xActiveConnection.is() )
151 (*pIter) >>= m_xActiveConnection;
152 else if ( !m_xHandler.is() )
153 (*pIter) >>= m_xHandler;
155 m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, uno::makeAny( m_xActiveConnection ) );
158 // chart2::data::XDataProvider:
159 sal_Bool SAL_CALL DatabaseDataProvider::createDataSourcePossible(const uno::Sequence< beans::PropertyValue > & _aArguments) throw (uno::RuntimeException, std::exception)
161 const beans::PropertyValue* pArgIter = _aArguments.getConstArray();
162 const beans::PropertyValue* pArgEnd = pArgIter + _aArguments.getLength();
163 for(;pArgIter != pArgEnd;++pArgIter)
165 if ( pArgIter->Name == "DataRowSource" )
167 ::com::sun::star::chart::ChartDataRowSource eRowSource = ::com::sun::star::chart::ChartDataRowSource_COLUMNS;
168 pArgIter->Value >>= eRowSource;
169 if ( eRowSource != ::com::sun::star::chart::ChartDataRowSource_COLUMNS )
170 return sal_False;
172 else if ( pArgIter->Name == "CellRangeRepresentation" )
174 OUString sRange;
175 pArgIter->Value >>= sRange;
176 if ( sRange != "all" )
177 return sal_False;
179 else if ( pArgIter->Name == "FirstCellAsLabel" )
181 bool bFirstCellAsLabel = true;
182 pArgIter->Value >>= bFirstCellAsLabel;
183 if ( !bFirstCellAsLabel )
184 return sal_False;
187 return sal_True;
190 uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::createDataSource(const uno::Sequence< beans::PropertyValue > & _aArguments) throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
192 osl::ResettableMutexGuard aClearForNotifies(m_aMutex);
193 if ( createDataSourcePossible(_aArguments) )
197 uno::Reference< chart::XChartDataArray> xChartData( m_xInternal, uno::UNO_QUERY_THROW );
198 xChartData->setData( uno::Sequence< uno::Sequence< double > >() );
199 xChartData->setColumnDescriptions( uno::Sequence< OUString >() );
200 if ( m_xInternal->hasDataByRangeRepresentation( OUString::number( 0 ) ) )
201 m_xInternal->deleteSequence(0);
203 catch( const uno::Exception& )
205 DBG_UNHANDLED_EXCEPTION();
208 ::comphelper::NamedValueCollection aArgs( _aArguments );
209 const bool bHasCategories = aArgs.getOrDefault( "HasCategories", sal_True );
210 uno::Sequence< OUString > aColumnNames =
211 aArgs.getOrDefault( "ColumnDescriptions", uno::Sequence< OUString >() );
213 bool bRet = false;
214 if ( !m_Command.isEmpty() && m_xActiveConnection.is() )
218 impl_fillRowSet_throw();
219 impl_executeRowSet_throw(aClearForNotifies);
220 impl_fillInternalDataProvider_throw(bHasCategories,aColumnNames);
221 bRet = true;
223 catch(const uno::Exception& /*e*/)
227 if ( !bRet ) // no command set or an error occurred, use Internal data handler
229 uno::Reference< lang::XInitialization> xIni(m_xInternal,uno::UNO_QUERY);
230 if ( xIni.is() )
232 uno::Sequence< uno::Any > aInitArgs(1);
233 beans::NamedValue aParam("CreateDefaultData",uno::makeAny(sal_True));
234 aInitArgs[0] <<= aParam;
235 xIni->initialize(aInitArgs);
240 return m_xInternal->createDataSource(_aArguments);
243 uno::Sequence< beans::PropertyValue > SAL_CALL DatabaseDataProvider::detectArguments(const uno::Reference< chart2::data::XDataSource > & _xDataSource) throw (uno::RuntimeException, std::exception)
245 ::comphelper::NamedValueCollection aArguments;
246 aArguments.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) );
247 aArguments.put( "DataRowSource", uno::makeAny( chart::ChartDataRowSource_COLUMNS ) );
248 // internal data always contains labels
249 aArguments.put( "FirstCellAsLabel", uno::makeAny( sal_True ) );
251 bool bHasCategories = false;
252 if( _xDataSource.is())
254 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences(_xDataSource->getDataSequences());
255 const sal_Int32 nCount( aSequences.getLength());
256 for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
258 if( aSequences[nIdx].is() )
260 uno::Reference< beans::XPropertySet > xSeqProp( aSequences[nIdx]->getValues(), uno::UNO_QUERY );
261 OUString aRole;
262 if ( xSeqProp.is()
263 && ( xSeqProp->getPropertyValue( "Role" ) >>= aRole )
264 && aRole == "categories"
267 bHasCategories = true;
268 break;
273 aArguments.put( "HasCategories", uno::makeAny( bHasCategories ) );
274 return aArguments.getPropertyValues();
277 sal_Bool SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentationPossible(const OUString & /*aRangeRepresentation*/) throw (uno::RuntimeException, std::exception)
279 return sal_True;
282 uno::Any DatabaseDataProvider::impl_getNumberFormatKey_nothrow(const OUString & _sRangeRepresentation) const
284 ::std::map< OUString,com::sun::star::uno::Any>::const_iterator aFind = m_aNumberFormats.find(_sRangeRepresentation);
285 if ( aFind != m_aNumberFormats.end() )
286 return aFind->second;
287 return uno::makeAny(sal_Int32(0));
290 uno::Reference< chart2::data::XDataSequence > SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentation(const OUString & _sRangeRepresentation) throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
292 osl::MutexGuard g(m_aMutex);
293 uno::Reference< chart2::data::XDataSequence > xData = m_xInternal->createDataSequenceByRangeRepresentation(_sRangeRepresentation);
294 uno::Reference<beans::XPropertySet> xProp(xData,uno::UNO_QUERY);
295 static const char s_sNumberFormatKey[] = "NumberFormatKey";
296 if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(s_sNumberFormatKey) )
298 xProp->setPropertyValue(s_sNumberFormatKey,impl_getNumberFormatKey_nothrow(_sRangeRepresentation));
300 return xData;
303 uno::Reference<chart2::data::XDataSequence>
304 SAL_CALL DatabaseDataProvider::createDataSequenceByValueArray(
305 const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ )
306 throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
308 return uno::Reference<chart2::data::XDataSequence>();
311 uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexRowDescriptions() throw (uno::RuntimeException, std::exception)
313 return m_xComplexDescriptionAccess->getComplexRowDescriptions();
316 void SAL_CALL DatabaseDataProvider::setComplexRowDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aRowDescriptions ) throw (uno::RuntimeException, std::exception)
318 m_xComplexDescriptionAccess->setComplexRowDescriptions(aRowDescriptions);
321 uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexColumnDescriptions() throw (uno::RuntimeException, std::exception)
323 return m_xComplexDescriptionAccess->getComplexColumnDescriptions();
326 void SAL_CALL DatabaseDataProvider::setComplexColumnDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aColumnDescriptions ) throw (uno::RuntimeException, std::exception)
328 m_xComplexDescriptionAccess->setComplexColumnDescriptions(aColumnDescriptions);
331 // ____ XChartDataArray ____
332 uno::Sequence< uno::Sequence< double > > SAL_CALL DatabaseDataProvider::getData() throw (uno::RuntimeException, std::exception)
334 return m_xComplexDescriptionAccess->getData();
337 void SAL_CALL DatabaseDataProvider::setData( const uno::Sequence< uno::Sequence< double > >& rDataInRows ) throw (uno::RuntimeException, std::exception)
339 m_xComplexDescriptionAccess->setData(rDataInRows);
342 void SAL_CALL DatabaseDataProvider::setRowDescriptions( const uno::Sequence< OUString >& aRowDescriptions ) throw (uno::RuntimeException, std::exception)
344 m_xComplexDescriptionAccess->setRowDescriptions(aRowDescriptions);
347 void SAL_CALL DatabaseDataProvider::setColumnDescriptions( const uno::Sequence< OUString >& aColumnDescriptions ) throw (uno::RuntimeException, std::exception)
349 m_xComplexDescriptionAccess->setColumnDescriptions(aColumnDescriptions);
352 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getRowDescriptions() throw (uno::RuntimeException, std::exception)
354 return m_xComplexDescriptionAccess->getRowDescriptions();
357 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getColumnDescriptions() throw (uno::RuntimeException, std::exception)
359 return m_xComplexDescriptionAccess->getColumnDescriptions();
362 // ____ XChartData (base of XChartDataArray) ____
363 void SAL_CALL DatabaseDataProvider::addChartDataChangeEventListener(const uno::Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& x) throw (uno::RuntimeException, std::exception)
365 m_xComplexDescriptionAccess->addChartDataChangeEventListener(x);
368 void SAL_CALL DatabaseDataProvider::removeChartDataChangeEventListener(const uno::Reference< ::com::sun::star::chart::XChartDataChangeEventListener >& x) throw (uno::RuntimeException, std::exception)
370 m_xComplexDescriptionAccess->removeChartDataChangeEventListener(x);
373 double SAL_CALL DatabaseDataProvider::getNotANumber() throw (uno::RuntimeException, std::exception)
375 return m_xComplexDescriptionAccess->getNotANumber();
378 sal_Bool SAL_CALL DatabaseDataProvider::isNotANumber( double nNumber ) throw (uno::RuntimeException, std::exception)
380 return m_xComplexDescriptionAccess->isNotANumber(nNumber);
383 uno::Reference< sheet::XRangeSelection > SAL_CALL DatabaseDataProvider::getRangeSelection() throw (uno::RuntimeException, std::exception)
385 // TODO: Exchange the default return implementation for "getRangeSelection" !!!
386 // Exchange the default return implementation.
387 // NOTE: Default initialized polymorphic structs can cause problems because of
388 // missing default initialization of primitive types of some C++ compilers or
389 // different Any initialization in Java and C++ polymorphic structs.
390 return uno::Reference< sheet::XRangeSelection >();
393 // chart2::data::XRangeXMLConversion:
394 OUString SAL_CALL DatabaseDataProvider::convertRangeToXML(const OUString & _sRangeRepresentation) throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
396 osl::MutexGuard g(m_aMutex);
397 return m_xRangeConversion->convertRangeToXML(_sRangeRepresentation);
400 OUString SAL_CALL DatabaseDataProvider::convertRangeFromXML(const OUString & _sXMLRange) throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
402 osl::MutexGuard g(m_aMutex);
403 return m_xRangeConversion->convertRangeFromXML(_sXMLRange);
406 // com.sun.star.beans.XPropertySet:
407 uno::Reference< beans::XPropertySetInfo > SAL_CALL DatabaseDataProvider::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
409 return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertySetInfo();
412 void SAL_CALL DatabaseDataProvider::setPropertyValue(const OUString & aPropertyName, const uno::Any & aValue) throw (uno::RuntimeException, beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, std::exception)
414 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::setPropertyValue(aPropertyName, aValue);
417 uno::Any SAL_CALL DatabaseDataProvider::getPropertyValue(const OUString & aPropertyName) throw (uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException, std::exception)
419 return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertyValue(aPropertyName);
422 void SAL_CALL DatabaseDataProvider::addPropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener) throw (uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException, std::exception)
424 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addPropertyChangeListener(aPropertyName, xListener);
427 void SAL_CALL DatabaseDataProvider::removePropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener) throw (uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException, std::exception)
429 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removePropertyChangeListener(aPropertyName, xListener);
432 void SAL_CALL DatabaseDataProvider::addVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener) throw (uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException, std::exception)
434 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addVetoableChangeListener(aPropertyName, xListener);
437 void SAL_CALL DatabaseDataProvider::removeVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener) throw (uno::RuntimeException, beans::UnknownPropertyException, lang::WrappedTargetException, std::exception)
439 ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removeVetoableChangeListener(aPropertyName, xListener);
442 // chart2::data::XDatabaseDataProvider:
443 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getMasterFields() throw (uno::RuntimeException, std::exception)
445 osl::MutexGuard g(m_aMutex);
446 return m_MasterFields;
449 void SAL_CALL DatabaseDataProvider::setMasterFields(const uno::Sequence< OUString > & the_value) throw (uno::RuntimeException, std::exception)
451 impl_invalidateParameter_nothrow();
452 set(OUString("MasterFields"),the_value,m_MasterFields);
455 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getDetailFields() throw (uno::RuntimeException, std::exception)
457 osl::MutexGuard g(m_aMutex);
458 return m_DetailFields;
461 void SAL_CALL DatabaseDataProvider::setDetailFields(const uno::Sequence< OUString > & the_value) throw (uno::RuntimeException, std::exception)
463 set("DetailFields",the_value,m_DetailFields);
466 OUString SAL_CALL DatabaseDataProvider::getCommand() throw (uno::RuntimeException, std::exception)
468 osl::MutexGuard g(m_aMutex);
469 return m_Command;
472 void SAL_CALL DatabaseDataProvider::setCommand(const OUString & the_value) throw (uno::RuntimeException, std::exception)
475 osl::MutexGuard g(m_aMutex);
476 impl_invalidateParameter_nothrow();
477 m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND, uno::makeAny( the_value ) );
479 set(PROPERTY_COMMAND,the_value,m_Command);
482 ::sal_Int32 SAL_CALL DatabaseDataProvider::getCommandType() throw (uno::RuntimeException, std::exception)
484 osl::MutexGuard g(m_aMutex);
485 return m_CommandType;
488 void SAL_CALL DatabaseDataProvider::setCommandType(::sal_Int32 the_value) throw (uno::RuntimeException, std::exception)
491 osl::MutexGuard g(m_aMutex);
492 m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND_TYPE, uno::makeAny( the_value ) );
494 set(PROPERTY_COMMAND_TYPE,the_value,m_CommandType);
497 OUString SAL_CALL DatabaseDataProvider::getFilter() throw (uno::RuntimeException, std::exception)
499 osl::MutexGuard g(m_aMutex);
500 return m_aFilterManager.getFilterComponent( dbtools::FilterManager::fcPublicFilter );
503 void SAL_CALL DatabaseDataProvider::setFilter(const OUString & the_value) throw (uno::RuntimeException, std::exception)
506 osl::MutexGuard g(m_aMutex);
507 m_aFilterManager.setFilterComponent( dbtools::FilterManager::fcPublicFilter, the_value );
509 set(PROPERTY_FILTER,the_value,m_Filter);
512 sal_Bool SAL_CALL DatabaseDataProvider::getApplyFilter() throw (RuntimeException, std::exception)
514 osl::MutexGuard g(m_aMutex);
515 return m_ApplyFilter;
518 void SAL_CALL DatabaseDataProvider::setApplyFilter( sal_Bool the_value ) throw (RuntimeException, std::exception)
521 osl::MutexGuard g(m_aMutex);
522 m_xAggregateSet->setPropertyValue( PROPERTY_APPLYFILTER, uno::makeAny( the_value ) );
524 set(PROPERTY_APPLYFILTER,(bool)the_value,m_ApplyFilter);
527 OUString SAL_CALL DatabaseDataProvider::getHavingClause() throw (uno::RuntimeException, std::exception)
529 osl::MutexGuard g(m_aMutex);
530 return m_HavingClause;
533 void SAL_CALL DatabaseDataProvider::setHavingClause( const OUString& the_value ) throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
536 osl::MutexGuard g(m_aMutex);
537 m_xAggregateSet->setPropertyValue( PROPERTY_HAVING_CLAUSE, uno::makeAny( the_value ) );
539 set(PROPERTY_HAVING_CLAUSE,the_value,m_HavingClause);
542 OUString SAL_CALL DatabaseDataProvider::getGroupBy() throw (uno::RuntimeException, std::exception)
544 osl::MutexGuard g(m_aMutex);
545 return m_GroupBy;
548 void SAL_CALL DatabaseDataProvider::setGroupBy( const OUString& the_value ) throw (beans::UnknownPropertyException, uno::RuntimeException, std::exception)
551 osl::MutexGuard g(m_aMutex);
552 m_xAggregateSet->setPropertyValue( PROPERTY_GROUP_BY, uno::makeAny( the_value ) );
554 set(PROPERTY_GROUP_BY,the_value,m_GroupBy);
557 OUString SAL_CALL DatabaseDataProvider::getOrder() throw (uno::RuntimeException, std::exception)
559 osl::MutexGuard g(m_aMutex);
560 return m_Order;
563 void SAL_CALL DatabaseDataProvider::setOrder( const OUString& the_value ) throw (uno::RuntimeException, std::exception)
566 osl::MutexGuard g(m_aMutex);
567 m_xAggregateSet->setPropertyValue( PROPERTY_ORDER, uno::makeAny( the_value ) );
569 set(PROPERTY_ORDER,the_value,m_Order);
572 sal_Bool SAL_CALL DatabaseDataProvider::getEscapeProcessing() throw (uno::RuntimeException, std::exception)
574 osl::MutexGuard g(m_aMutex);
575 return m_EscapeProcessing;
578 void SAL_CALL DatabaseDataProvider::setEscapeProcessing(sal_Bool the_value) throw (uno::RuntimeException, std::exception)
580 set(PROPERTY_ESCAPE_PROCESSING,(bool)the_value,m_EscapeProcessing);
583 ::sal_Int32 SAL_CALL DatabaseDataProvider::getRowLimit() throw (uno::RuntimeException, std::exception)
585 osl::MutexGuard g(m_aMutex);
586 return m_RowLimit;
589 void SAL_CALL DatabaseDataProvider::setRowLimit(::sal_Int32 the_value) throw (uno::RuntimeException, std::exception)
591 set("RowLimit",the_value,m_RowLimit);
594 uno::Reference< sdbc::XConnection > SAL_CALL DatabaseDataProvider::getActiveConnection() throw (uno::RuntimeException, std::exception)
596 osl::MutexGuard g(m_aMutex);
597 return m_xActiveConnection;
600 void SAL_CALL DatabaseDataProvider::setActiveConnection(const uno::Reference< sdbc::XConnection > & the_value) throw (uno::RuntimeException, lang::IllegalArgumentException, std::exception)
602 if ( !the_value.is() )
603 throw lang::IllegalArgumentException();
604 set(PROPERTY_ACTIVE_CONNECTION,the_value,m_xActiveConnection);
607 OUString SAL_CALL DatabaseDataProvider::getDataSourceName() throw (uno::RuntimeException, std::exception)
609 osl::MutexGuard g(m_aMutex);
610 return m_DataSourceName;
613 void SAL_CALL DatabaseDataProvider::setDataSourceName(const OUString& the_value) throw (uno::RuntimeException, std::exception)
615 set(PROPERTY_DATASOURCENAME,the_value,m_DataSourceName);
618 void DatabaseDataProvider::impl_executeRowSet_throw(::osl::ResettableMutexGuard& _rClearForNotifies)
620 if ( impl_fillParameters_nothrow(_rClearForNotifies) )
621 m_xRowSet->execute();
624 namespace
626 struct ColumnDescription
628 OUString sName;
629 sal_Int32 nResultSetPosition;
630 sal_Int32 nDataType;
632 ColumnDescription()
633 :sName()
634 ,nResultSetPosition( 0 )
635 ,nDataType( sdbc::DataType::VARCHAR )
638 explicit ColumnDescription( const OUString& i_rName )
639 :sName( i_rName )
640 ,nResultSetPosition( 0 )
641 ,nDataType( sdbc::DataType::VARCHAR )
646 struct CreateColumnDescription : public ::std::unary_function< OUString, ColumnDescription >
648 ColumnDescription operator()( const OUString& i_rName )
650 return ColumnDescription( i_rName );
654 struct SelectColumnName : public ::std::unary_function< ColumnDescription, OUString >
656 const OUString& operator()( const ColumnDescription& i_rColumn )
658 return i_rColumn.sName;
663 void DatabaseDataProvider::impl_fillInternalDataProvider_throw(bool _bHasCategories,const uno::Sequence< OUString >& i_aColumnNames)
665 // clear the data before fill the new one
666 uno::Reference< sdbcx::XColumnsSupplier > xColSup(m_xRowSet,uno::UNO_QUERY_THROW);
667 uno::Reference< container::XNameAccess > xColumns( xColSup->getColumns(), uno::UNO_SET_THROW );
668 const uno::Sequence< OUString > aRowSetColumnNames( xColumns->getElementNames() );
670 typedef ::std::vector< ColumnDescription > ColumnDescriptions;
671 ColumnDescriptions aColumns;
672 bool bFirstColumnIsCategory = _bHasCategories;
673 if ( i_aColumnNames.getLength() )
675 // some normalizations ...
676 uno::Sequence< OUString > aImposedColumnNames( i_aColumnNames );
678 // strangely, there exist documents where the ColumnDescriptions end with a number of empty strings. /me
679 // thinks they're generated when you have a chart based on a result set with n columns, but remove some
680 // of those columns from the chart - it looks like a bug in the report XML export to me.
681 // So, get rid of the "trailing" empty columns
682 sal_Int32 nLastNonEmptyColName = aImposedColumnNames.getLength() - 1;
683 for ( ; nLastNonEmptyColName >= 0; --nLastNonEmptyColName )
685 if ( !aImposedColumnNames[ nLastNonEmptyColName ].isEmpty() )
686 break;
688 aImposedColumnNames.realloc( nLastNonEmptyColName + 1 );
690 // second, for X-Y-charts the ColumnDescriptions exported by chart miss the name of the first (non-category)
691 // column. This, this results in a ColumnDescriptions array like <"", "col2", "col3">, where you'd expect
692 // <"col1", "col2", "col3">.
693 // Fix this with some heuristics:
694 if ( ( aImposedColumnNames.getLength() > 0 ) && ( !aImposedColumnNames[0].isEmpty() ) )
696 const sal_Int32 nAssumedRowSetColumnIndex = _bHasCategories ? 1 : 0;
697 if ( nAssumedRowSetColumnIndex < aRowSetColumnNames.getLength() )
698 aImposedColumnNames[0] = aRowSetColumnNames[ nAssumedRowSetColumnIndex ];
701 const sal_Int32 nCount = aImposedColumnNames.getLength();
702 for ( sal_Int32 i = 0 ; i < nCount; ++i )
704 const OUString sColumnName( aImposedColumnNames[i] );
705 if ( !xColumns->hasByName( sColumnName ) )
706 continue;
708 if ( _bHasCategories && aColumns.empty() )
710 if ( aRowSetColumnNames.getLength() )
711 aColumns.push_back( ColumnDescription( aRowSetColumnNames[0] ) );
712 else
713 aColumns.push_back( ColumnDescription( sColumnName ) );
714 bFirstColumnIsCategory = true;
716 aColumns.push_back( ColumnDescription( sColumnName ) );
719 if ( aColumns.empty() )
721 aColumns.resize( aRowSetColumnNames.getLength() );
722 ::std::transform(
723 aRowSetColumnNames.getConstArray(),
724 aRowSetColumnNames.getConstArray() + aRowSetColumnNames.getLength(),
725 aColumns.begin(),
726 CreateColumnDescription()
730 // fill the data
731 uno::Reference< sdbc::XResultSet> xRes( m_xRowSet, uno::UNO_QUERY_THROW );
732 uno::Reference< sdbc::XRow> xRow( m_xRowSet,uno::UNO_QUERY_THROW );
733 uno::Reference< sdbc::XResultSetMetaDataSupplier > xSuppMeta( m_xRowSet,uno::UNO_QUERY_THROW );
734 uno::Reference< sdbc::XResultSetMetaData > xResultSetMetaData( xSuppMeta->getMetaData(), uno::UNO_SET_THROW );
735 uno::Reference< sdbc::XColumnLocate > xColumnLocate( m_xRowSet, uno::UNO_QUERY_THROW );
737 for ( ColumnDescriptions::iterator col = aColumns.begin();
738 col != aColumns.end();
739 ++col
742 col->nResultSetPosition = xColumnLocate->findColumn( col->sName );
744 const uno::Reference< beans::XPropertySet > xColumn( xColumns->getByName( col->sName ), uno::UNO_QUERY_THROW );
745 const uno::Any aNumberFormat( xColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) );
746 OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= col->nDataType );
748 const sal_Int32 columnIndex = col - aColumns.begin();
749 const OUString sRangeName = OUString::number( columnIndex );
750 m_aNumberFormats.insert( ::std::map< OUString, uno::Any >::value_type( sRangeName, aNumberFormat ) );
753 ::std::vector< OUString > aRowLabels;
754 ::std::vector< ::std::vector< double > > aDataValues;
755 sal_Int32 nRowCount = 0;
756 ::connectivity::ORowSetValue aValue;
757 while( xRes->next() && (!m_RowLimit || nRowCount < m_RowLimit) )
759 ++nRowCount;
761 aValue.fill( aColumns[0].nResultSetPosition, aColumns[0].nDataType, xRow );
762 aRowLabels.push_back( aValue.getString() );
764 ::std::vector< double > aRow;
765 for ( ColumnDescriptions::const_iterator col = aColumns.begin();
766 col != aColumns.end();
767 ++col
770 if ( bFirstColumnIsCategory && ( col == aColumns.begin() ) )
771 continue;
773 aValue.fill( col->nResultSetPosition, col->nDataType, xRow );
774 if ( aValue.isNull() )
776 double nValue;
777 ::rtl::math::setNan( &nValue );
778 aRow.push_back( nValue );
780 else
781 aRow.push_back( aValue.getDouble() );
784 aDataValues.push_back( aRow );
787 // insert default data when no rows exist
788 if ( !nRowCount )
790 nRowCount = 3;
791 const double fDefaultData[ ] =
792 { 9.10, 3.20, 4.54,
793 2.40, 8.80, 9.65,
794 3.10, 1.50, 3.70,
795 4.30, 9.02, 6.20 };
796 for(sal_Int32 h = 0,k = 0; h < nRowCount; ++h,++k )
798 aRowLabels.push_back(OUString::number(h+1));
799 ::std::vector< double > aRow;
800 const sal_Int32 nSize = sizeof(fDefaultData)/sizeof(fDefaultData[0]);
801 for (size_t j = 0; j < (aColumns.size()-1); ++j,++k)
803 if ( k >= nSize )
804 k = 0;
805 aRow.push_back(fDefaultData[k]);
807 aDataValues.push_back(aRow);
811 uno::Reference< chart::XChartDataArray> xData(m_xInternal,uno::UNO_QUERY);
812 xData->setRowDescriptions(uno::Sequence< OUString >(&(*aRowLabels.begin()),aRowLabels.size()));
814 const size_t nOffset = bFirstColumnIsCategory ? 1 : 0;
815 uno::Sequence< OUString > aColumnDescriptions( aColumns.size() - nOffset );
816 ::std::transform(
817 aColumns.begin() + nOffset,
818 aColumns.end(),
819 aColumnDescriptions.getArray(),
820 SelectColumnName()
822 xData->setColumnDescriptions( aColumnDescriptions );
824 uno::Sequence< uno::Sequence< double > > aData(aDataValues.size());
825 uno::Sequence< double >* pDataIter = aData.getArray();
826 uno::Sequence< double >* pDataEnd = pDataIter + aData.getLength();
827 for(sal_Int32 i= 0;pDataIter != pDataEnd; ++pDataIter,++i )
829 if ( !aDataValues[i].empty() )
830 *pDataIter = uno::Sequence< double >(&(*(aDataValues[i]).begin()),(aDataValues[i]).size());
832 xData->setData(aData);
835 void DatabaseDataProvider::impl_fillRowSet_throw()
837 m_xAggregateSet->setPropertyValue( PROPERTY_FILTER, uno::makeAny( getFilter() ) );
838 uno::Reference< sdbc::XParameters> xParam(m_xRowSet,uno::UNO_QUERY_THROW);
839 xParam->clearParameters( );
842 bool DatabaseDataProvider::impl_fillParameters_nothrow( ::osl::ResettableMutexGuard& _rClearForNotifies)
844 // do we have to fill the parameters again?
845 if ( !m_aParameterManager.isUpToDate() )
846 m_aParameterManager.updateParameterInfo( m_aFilterManager );
848 if ( m_aParameterManager.isUpToDate() )
849 return m_aParameterManager.fillParameterValues( m_xHandler, _rClearForNotifies );
851 return true;
854 // com::sun::star::sdbc::XParameters
855 void SAL_CALL DatabaseDataProvider::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) throw( SQLException, RuntimeException, std::exception )
857 m_aParameterManager.setNull(parameterIndex, sqlType);
860 void SAL_CALL DatabaseDataProvider::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& typeName) throw( SQLException, RuntimeException, std::exception )
862 m_aParameterManager.setObjectNull(parameterIndex, sqlType, typeName);
865 void SAL_CALL DatabaseDataProvider::setBoolean(sal_Int32 parameterIndex, sal_Bool x) throw( SQLException, RuntimeException, std::exception )
867 m_aParameterManager.setBoolean(parameterIndex, x);
870 void SAL_CALL DatabaseDataProvider::setByte(sal_Int32 parameterIndex, sal_Int8 x) throw( SQLException, RuntimeException, std::exception )
872 m_aParameterManager.setByte(parameterIndex, x);
875 void SAL_CALL DatabaseDataProvider::setShort(sal_Int32 parameterIndex, sal_Int16 x) throw( SQLException, RuntimeException, std::exception )
877 m_aParameterManager.setShort(parameterIndex, x);
880 void SAL_CALL DatabaseDataProvider::setInt(sal_Int32 parameterIndex, sal_Int32 x) throw( SQLException, RuntimeException, std::exception )
882 m_aParameterManager.setInt(parameterIndex, x);
885 void SAL_CALL DatabaseDataProvider::setLong(sal_Int32 parameterIndex, sal_Int64 x) throw( SQLException, RuntimeException, std::exception )
887 m_aParameterManager.setLong(parameterIndex, x);
890 void SAL_CALL DatabaseDataProvider::setFloat(sal_Int32 parameterIndex, float x) throw( SQLException, RuntimeException, std::exception )
892 m_aParameterManager.setFloat(parameterIndex, x);
895 void SAL_CALL DatabaseDataProvider::setDouble(sal_Int32 parameterIndex, double x) throw( SQLException, RuntimeException, std::exception )
897 m_aParameterManager.setDouble(parameterIndex, x);
900 void SAL_CALL DatabaseDataProvider::setString(sal_Int32 parameterIndex, const OUString& x) throw( SQLException, RuntimeException, std::exception )
902 m_aParameterManager.setString(parameterIndex, x);
905 void SAL_CALL DatabaseDataProvider::setBytes(sal_Int32 parameterIndex, const uno::Sequence< sal_Int8 >& x) throw( SQLException, RuntimeException, std::exception )
907 m_aParameterManager.setBytes(parameterIndex, x);
910 void SAL_CALL DatabaseDataProvider::setDate(sal_Int32 parameterIndex, const util::Date& x) throw( SQLException, RuntimeException, std::exception )
912 m_aParameterManager.setDate(parameterIndex, x);
915 void SAL_CALL DatabaseDataProvider::setTime(sal_Int32 parameterIndex, const util::Time& x) throw( SQLException, RuntimeException, std::exception )
917 m_aParameterManager.setTime(parameterIndex, x);
920 void SAL_CALL DatabaseDataProvider::setTimestamp(sal_Int32 parameterIndex, const util::DateTime& x) throw( SQLException, RuntimeException, std::exception )
922 m_aParameterManager.setTimestamp(parameterIndex, x);
925 void SAL_CALL DatabaseDataProvider::setBinaryStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException, std::exception )
927 m_aParameterManager.setBinaryStream(parameterIndex, x, length);
930 void SAL_CALL DatabaseDataProvider::setCharacterStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length) throw( SQLException, RuntimeException, std::exception )
932 m_aParameterManager.setCharacterStream(parameterIndex, x, length);
935 void SAL_CALL DatabaseDataProvider::setObjectWithInfo(sal_Int32 parameterIndex, const uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale) throw( SQLException, RuntimeException, std::exception )
937 m_aParameterManager.setObjectWithInfo(parameterIndex, x, targetSqlType, scale);
940 void SAL_CALL DatabaseDataProvider::setObject(sal_Int32 parameterIndex, const uno::Any& x) throw( SQLException, RuntimeException, std::exception )
942 m_aParameterManager.setObject(parameterIndex, x);
945 void SAL_CALL DatabaseDataProvider::setRef(sal_Int32 parameterIndex, const uno::Reference<sdbc::XRef>& x) throw( SQLException, RuntimeException, std::exception )
947 m_aParameterManager.setRef(parameterIndex, x);
950 void SAL_CALL DatabaseDataProvider::setBlob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XBlob>& x) throw( SQLException, RuntimeException, std::exception )
952 m_aParameterManager.setBlob(parameterIndex, x);
955 void SAL_CALL DatabaseDataProvider::setClob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XClob>& x) throw( SQLException, RuntimeException, std::exception )
957 m_aParameterManager.setClob(parameterIndex, x);
960 void SAL_CALL DatabaseDataProvider::setArray(sal_Int32 parameterIndex, const Reference<sdbc::XArray>& x) throw( SQLException, RuntimeException, std::exception )
962 m_aParameterManager.setArray(parameterIndex, x);
965 void SAL_CALL DatabaseDataProvider::clearParameters() throw( SQLException, RuntimeException, std::exception )
967 m_aParameterManager.clearParameters();
970 // com::sun::star::sdbc::XRowSet
971 void SAL_CALL DatabaseDataProvider::execute() throw( SQLException, RuntimeException, std::exception )
973 uno::Sequence< beans::PropertyValue > aEmpty;
974 createDataSource(aEmpty);
977 void SAL_CALL DatabaseDataProvider::addRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener) throw( RuntimeException, std::exception )
979 if (m_xRowSet.is())
980 m_xRowSet->addRowSetListener(_rListener);
983 void SAL_CALL DatabaseDataProvider::removeRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener) throw( RuntimeException, std::exception )
985 if (m_xRowSet.is())
986 m_xRowSet->removeRowSetListener(_rListener);
989 // com::sun::star::sdbc::XResultSet
990 sal_Bool SAL_CALL DatabaseDataProvider::next() throw( SQLException, RuntimeException, std::exception )
992 return m_xRowSet->next();
995 sal_Bool SAL_CALL DatabaseDataProvider::isBeforeFirst() throw( SQLException, RuntimeException, std::exception )
997 return m_xRowSet->isBeforeFirst();
1000 sal_Bool SAL_CALL DatabaseDataProvider::isAfterLast() throw( SQLException, RuntimeException, std::exception )
1002 return m_xRowSet->isAfterLast();
1005 sal_Bool SAL_CALL DatabaseDataProvider::isFirst() throw( SQLException, RuntimeException, std::exception )
1007 return m_xRowSet->isFirst();
1010 sal_Bool SAL_CALL DatabaseDataProvider::isLast() throw( SQLException, RuntimeException, std::exception )
1012 return m_xRowSet->isLast();
1015 void SAL_CALL DatabaseDataProvider::beforeFirst() throw( SQLException, RuntimeException, std::exception )
1017 m_xRowSet->beforeFirst();
1020 void SAL_CALL DatabaseDataProvider::afterLast() throw( SQLException, RuntimeException, std::exception )
1022 m_xRowSet->afterLast();
1025 sal_Bool SAL_CALL DatabaseDataProvider::first() throw( SQLException, RuntimeException, std::exception )
1027 return m_xRowSet->first();
1030 sal_Bool SAL_CALL DatabaseDataProvider::last() throw( SQLException, RuntimeException, std::exception )
1032 return m_xRowSet->last();
1035 sal_Int32 SAL_CALL DatabaseDataProvider::getRow() throw( SQLException, RuntimeException, std::exception )
1037 return m_xRowSet->getRow();
1040 sal_Bool SAL_CALL DatabaseDataProvider::absolute(sal_Int32 row) throw( SQLException, RuntimeException, std::exception )
1042 return m_xRowSet->absolute(row);
1045 sal_Bool SAL_CALL DatabaseDataProvider::relative(sal_Int32 rows) throw( SQLException, RuntimeException, std::exception )
1047 return m_xRowSet->relative(rows);
1050 sal_Bool SAL_CALL DatabaseDataProvider::previous() throw( SQLException, RuntimeException, std::exception )
1052 return m_xRowSet->previous();
1055 void SAL_CALL DatabaseDataProvider::refreshRow() throw( SQLException, RuntimeException, std::exception )
1057 m_xRowSet->refreshRow();
1060 sal_Bool SAL_CALL DatabaseDataProvider::rowUpdated() throw( SQLException, RuntimeException, std::exception )
1062 return m_xRowSet->rowUpdated();
1065 sal_Bool SAL_CALL DatabaseDataProvider::rowInserted() throw( SQLException, RuntimeException, std::exception )
1067 return m_xRowSet->rowInserted();
1070 sal_Bool SAL_CALL DatabaseDataProvider::rowDeleted() throw( SQLException, RuntimeException, std::exception )
1072 return m_xRowSet->rowDeleted();
1075 uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getStatement() throw( SQLException, RuntimeException, std::exception )
1077 return m_xRowSet->getStatement();
1080 uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getParent( ) throw (uno::RuntimeException, std::exception)
1082 return m_xParent;
1085 void SAL_CALL DatabaseDataProvider::setParent( const uno::Reference< uno::XInterface >& _xParent ) throw (lang::NoSupportException, uno::RuntimeException, std::exception)
1087 osl::MutexGuard g(m_aMutex);
1088 m_xParent = _xParent;
1091 void DatabaseDataProvider::impl_invalidateParameter_nothrow()
1093 osl::MutexGuard g(m_aMutex);
1094 m_aParameterManager.clearAllParameterInformation();
1097 } // namespace dbaccess
1099 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */