1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <DatabaseDataProvider.hxx>
21 #include <strings.hxx>
22 #include <cppuhelper/supportsservice.hxx>
23 #include <comphelper/types.hxx>
24 #include <comphelper/namedvaluecollection.hxx>
25 #include <connectivity/FValue.hxx>
26 #include <rtl/math.hxx>
27 #include <sal/macros.h>
28 #include <tools/diagnose_ex.h>
29 
30 #include <com/sun/star/task/XInteractionHandler.hpp>
31 #include <com/sun/star/sdb/CommandType.hpp>
32 #include <com/sun/star/sdbc/DataType.hpp>
33 #include <com/sun/star/sdbc/XRow.hpp>
34 #include <com/sun/star/sdbc/XResultSet.hpp>
35 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
36 #include <com/sun/star/sdbc/XColumnLocate.hpp>
37 #include <com/sun/star/beans/NamedValue.hpp>
38 #include <com/sun/star/chart/ChartDataRowSource.hpp>
39 #include <com/sun/star/chart/XChartDataArray.hpp>
40 
41 #include <vector>
42 
43 // TODO: update for new HavingClause-aware FilterManager
44 
45 namespace dbaccess
46 {
47 using namespace ::com::sun::star;
48 using ::com::sun::star::uno::Reference;
49 
DatabaseDataProvider(uno::Reference<uno::XComponentContext> const & context)50 DatabaseDataProvider::DatabaseDataProvider(uno::Reference< uno::XComponentContext > const & context) :
51     TDatabaseDataProvider(m_aMutex),
52     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >(
53         context, IMPLEMENTS_PROPERTY_SET, uno::Sequence< OUString >()),
54     m_aParameterManager( m_aMutex, context ),
55     m_aFilterManager(),
56     m_xContext(context),
57     m_CommandType(sdb::CommandType::COMMAND), // #i94114
58     m_RowLimit(0),
59     m_EscapeProcessing(true),
60     m_ApplyFilter(true)
61 {
62     m_xInternal.set( m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.chart.InternalDataProvider",m_xContext ), uno::UNO_QUERY );
63     m_xRangeConversion.set(m_xInternal,uno::UNO_QUERY);
64     m_xComplexDescriptionAccess.set(m_xInternal,uno::UNO_QUERY);
65 
66     osl_atomic_increment( &m_refCount );
67     {
68         m_xRowSet.set( m_xContext->getServiceManager()->createInstanceWithContext(SERVICE_SDB_ROWSET,m_xContext ), uno::UNO_QUERY );
69         m_xAggregate.set(m_xRowSet,uno::UNO_QUERY);
70         m_xAggregateSet.set(m_xRowSet,uno::UNO_QUERY);
71         uno::Reference<beans::XPropertySet> xProp(static_cast< ::cppu::OWeakObject* >( this ),uno::UNO_QUERY);
72         m_aFilterManager.initialize( m_xAggregateSet );
73         m_aParameterManager.initialize( xProp, m_xAggregate );
74         m_xAggregateSet->setPropertyValue(PROPERTY_COMMAND_TYPE,uno::makeAny(m_CommandType));
75         m_xAggregateSet->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,uno::makeAny(m_EscapeProcessing));
76     }
77     osl_atomic_decrement( &m_refCount );
78 }
79 
disposing()80 void SAL_CALL DatabaseDataProvider::disposing()
81 {
82     m_aParameterManager.dispose();   // (to free any references it may have to me)
83     m_aFilterManager.dispose();      // (ditto)
84 
85     m_xParent.clear();
86     m_xAggregateSet.clear();
87     m_xAggregate.clear();
88     m_xRangeConversion.clear();
89     ::comphelper::disposeComponent(m_xRowSet);
90     ::comphelper::disposeComponent(m_xInternal);
91     m_xActiveConnection.clear();
92 }
93 
queryInterface(uno::Type const & type)94 uno::Any DatabaseDataProvider::queryInterface(uno::Type const & type)
95 {
96     return TDatabaseDataProvider::queryInterface(type);
97 }
98 
99 // XServiceInfo
getImplementationName()100 OUString SAL_CALL DatabaseDataProvider::getImplementationName(  )
101 {
102     return "com.sun.star.comp.dbaccess.DatabaseDataProvider";
103 }
104 
supportsService(const OUString & _rServiceName)105 sal_Bool SAL_CALL DatabaseDataProvider::supportsService( const OUString& _rServiceName )
106 {
107     return cppu::supportsService(this, _rServiceName);
108 }
109 
getSupportedServiceNames()110 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getSupportedServiceNames(  )
111 {
112     return { "com.sun.star.chart2.data.DatabaseDataProvider" };
113 }
114 
115 // lang::XInitialization:
initialize(const uno::Sequence<uno::Any> & aArguments)116 void SAL_CALL DatabaseDataProvider::initialize(const uno::Sequence< uno::Any > & aArguments)
117 {
118     osl::MutexGuard g(m_aMutex);
119     const uno::Any* pIter   = aArguments.getConstArray();
120     const uno::Any* pEnd    = pIter + aArguments.getLength();
121     for(;pIter != pEnd;++pIter)
122     {
123         if ( !m_xActiveConnection.is() )
124             (*pIter) >>= m_xActiveConnection;
125         else if ( !m_xHandler.is() )
126             (*pIter) >>= m_xHandler;
127     }
128     m_xAggregateSet->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, uno::makeAny( m_xActiveConnection ) );
129 }
130 
131 // chart2::data::XDataProvider:
createDataSourcePossible(const uno::Sequence<beans::PropertyValue> & _aArguments)132 sal_Bool SAL_CALL DatabaseDataProvider::createDataSourcePossible(const uno::Sequence< beans::PropertyValue > & _aArguments)
133 {
134     const beans::PropertyValue* pArgIter = _aArguments.getConstArray();
135     const beans::PropertyValue* pArgEnd  = pArgIter + _aArguments.getLength();
136     for(;pArgIter != pArgEnd;++pArgIter)
137     {
138         if ( pArgIter->Name == "DataRowSource" )
139         {
140             css::chart::ChartDataRowSource eRowSource = css::chart::ChartDataRowSource_COLUMNS;
141             pArgIter->Value >>= eRowSource;
142             if ( eRowSource != css::chart::ChartDataRowSource_COLUMNS )
143                 return false;
144         }
145         else if ( pArgIter->Name == "CellRangeRepresentation" )
146         {
147             OUString sRange;
148             pArgIter->Value >>= sRange;
149             if ( sRange != "all" )
150                 return false;
151         }
152         else if ( pArgIter->Name == "FirstCellAsLabel" )
153         {
154             bool bFirstCellAsLabel = true;
155             pArgIter->Value >>= bFirstCellAsLabel;
156             if ( !bFirstCellAsLabel )
157                 return false;
158         }
159     }
160     return true;
161 }
162 
createDataSource(const uno::Sequence<beans::PropertyValue> & _aArguments)163 uno::Reference< chart2::data::XDataSource > SAL_CALL DatabaseDataProvider::createDataSource(const uno::Sequence< beans::PropertyValue > & _aArguments)
164 {
165     osl::ResettableMutexGuard aClearForNotifies(m_aMutex);
166     if ( createDataSourcePossible(_aArguments) )
167     {
168         try
169         {
170             uno::Reference< chart::XChartDataArray> xChartData( m_xInternal, uno::UNO_QUERY_THROW );
171             xChartData->setData( uno::Sequence< uno::Sequence< double > >() );
172             xChartData->setColumnDescriptions( uno::Sequence< OUString >() );
173             if ( m_xInternal->hasDataByRangeRepresentation( OUString::number( 0 ) ) )
174                 m_xInternal->deleteSequence(0);
175         }
176         catch( const uno::Exception& )
177         {
178             DBG_UNHANDLED_EXCEPTION("dbaccess");
179         }
180 
181         ::comphelper::NamedValueCollection aArgs( _aArguments );
182         const bool bHasCategories = aArgs.getOrDefault( "HasCategories", true );
183         uno::Sequence< OUString > aColumnNames =
184             aArgs.getOrDefault( "ColumnDescriptions", uno::Sequence< OUString >() );
185 
186         bool bRet = false;
187         if ( !m_Command.isEmpty() && m_xActiveConnection.is() )
188         {
189             try
190             {
191                 impl_fillRowSet_throw();
192                 if ( impl_fillParameters_nothrow(aClearForNotifies) )
193                     m_xRowSet->execute();
194                 impl_fillInternalDataProvider_throw(bHasCategories,aColumnNames);
195                 bRet = true;
196             }
197             catch(const uno::Exception& /*e*/)
198             {
199             }
200         }
201         if ( !bRet ) // no command set or an error occurred, use Internal data handler
202         {
203             uno::Reference< lang::XInitialization> xIni(m_xInternal,uno::UNO_QUERY);
204             if ( xIni.is() )
205             {
206                 uno::Sequence< uno::Any > aInitArgs(1);
207                 beans::NamedValue aParam("CreateDefaultData",uno::makeAny(true));
208                 aInitArgs[0] <<= aParam;
209                 xIni->initialize(aInitArgs);
210             }
211         }
212 
213     }
214     return m_xInternal->createDataSource(_aArguments);
215 }
216 
detectArguments(const uno::Reference<chart2::data::XDataSource> & _xDataSource)217 uno::Sequence< beans::PropertyValue > SAL_CALL DatabaseDataProvider::detectArguments(const uno::Reference< chart2::data::XDataSource > & _xDataSource)
218 {
219     ::comphelper::NamedValueCollection aArguments;
220     aArguments.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) );
221     aArguments.put( "DataRowSource", uno::makeAny( chart::ChartDataRowSource_COLUMNS ) );
222     // internal data always contains labels
223     aArguments.put( "FirstCellAsLabel", uno::makeAny( true ) );
224 
225     bool bHasCategories = false;
226     if( _xDataSource.is())
227     {
228         uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences(_xDataSource->getDataSequences());
229         const sal_Int32 nCount( aSequences.getLength());
230         for( sal_Int32 nIdx=0; nIdx<nCount; ++nIdx )
231         {
232             if( aSequences[nIdx].is() )
233             {
234                 uno::Reference< beans::XPropertySet > xSeqProp( aSequences[nIdx]->getValues(), uno::UNO_QUERY );
235                 OUString aRole;
236                 if  (   xSeqProp.is()
237                     &&  ( xSeqProp->getPropertyValue( "Role" ) >>= aRole )
238                     &&  aRole == "categories"
239                     )
240                 {
241                     bHasCategories = true;
242                     break;
243                 }
244             }
245         }
246     }
247     aArguments.put( "HasCategories", uno::makeAny( bHasCategories ) );
248     return aArguments.getPropertyValues();
249 }
250 
createDataSequenceByRangeRepresentationPossible(const OUString &)251 sal_Bool SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentationPossible(const OUString & /*aRangeRepresentation*/)
252 {
253     return true;
254 }
255 
impl_getNumberFormatKey_nothrow(const OUString & _sRangeRepresentation) const256 uno::Any DatabaseDataProvider::impl_getNumberFormatKey_nothrow(const OUString & _sRangeRepresentation) const
257 {
258     std::map< OUString,css::uno::Any>::const_iterator aFind = m_aNumberFormats.find(_sRangeRepresentation);
259     if ( aFind != m_aNumberFormats.end() )
260         return aFind->second;
261     return uno::makeAny(sal_Int32(0));
262 }
263 
createDataSequenceByRangeRepresentation(const OUString & _sRangeRepresentation)264 uno::Reference< chart2::data::XDataSequence > SAL_CALL DatabaseDataProvider::createDataSequenceByRangeRepresentation(const OUString & _sRangeRepresentation)
265 {
266     osl::MutexGuard g(m_aMutex);
267     uno::Reference< chart2::data::XDataSequence > xData = m_xInternal->createDataSequenceByRangeRepresentation(_sRangeRepresentation);
268     uno::Reference<beans::XPropertySet> xProp(xData,uno::UNO_QUERY);
269     static constexpr OUStringLiteral s_sNumberFormatKey = u"NumberFormatKey";
270     if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(s_sNumberFormatKey) )
271     {
272         xProp->setPropertyValue(s_sNumberFormatKey,impl_getNumberFormatKey_nothrow(_sRangeRepresentation));
273     }
274     return xData;
275 }
276 
277 uno::Reference<chart2::data::XDataSequence>
createDataSequenceByValueArray(const OUString &,const OUString &)278 SAL_CALL DatabaseDataProvider::createDataSequenceByValueArray(
279     const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ )
280 {
281     return uno::Reference<chart2::data::XDataSequence>();
282 }
283 
getComplexRowDescriptions()284 uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexRowDescriptions()
285 {
286     return m_xComplexDescriptionAccess->getComplexRowDescriptions();
287 }
288 
setComplexRowDescriptions(const uno::Sequence<uno::Sequence<OUString>> & aRowDescriptions)289 void SAL_CALL DatabaseDataProvider::setComplexRowDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aRowDescriptions )
290 {
291     m_xComplexDescriptionAccess->setComplexRowDescriptions(aRowDescriptions);
292 }
293 
getComplexColumnDescriptions()294 uno::Sequence< uno::Sequence< OUString > > SAL_CALL DatabaseDataProvider::getComplexColumnDescriptions()
295 {
296     return m_xComplexDescriptionAccess->getComplexColumnDescriptions();
297 }
298 
setComplexColumnDescriptions(const uno::Sequence<uno::Sequence<OUString>> & aColumnDescriptions)299 void SAL_CALL DatabaseDataProvider::setComplexColumnDescriptions( const uno::Sequence< uno::Sequence< OUString > >& aColumnDescriptions )
300 {
301     m_xComplexDescriptionAccess->setComplexColumnDescriptions(aColumnDescriptions);
302 }
303 
304 // ____ XChartDataArray ____
getData()305 uno::Sequence< uno::Sequence< double > > SAL_CALL DatabaseDataProvider::getData()
306 {
307     return m_xComplexDescriptionAccess->getData();
308 }
309 
setData(const uno::Sequence<uno::Sequence<double>> & rDataInRows)310 void SAL_CALL DatabaseDataProvider::setData( const uno::Sequence< uno::Sequence< double > >& rDataInRows )
311 {
312     m_xComplexDescriptionAccess->setData(rDataInRows);
313 }
314 
setRowDescriptions(const uno::Sequence<OUString> & aRowDescriptions)315 void SAL_CALL DatabaseDataProvider::setRowDescriptions( const uno::Sequence< OUString >& aRowDescriptions )
316 {
317     m_xComplexDescriptionAccess->setRowDescriptions(aRowDescriptions);
318 }
319 
setColumnDescriptions(const uno::Sequence<OUString> & aColumnDescriptions)320 void SAL_CALL DatabaseDataProvider::setColumnDescriptions( const uno::Sequence< OUString >& aColumnDescriptions )
321 {
322     m_xComplexDescriptionAccess->setColumnDescriptions(aColumnDescriptions);
323 }
324 
getRowDescriptions()325 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getRowDescriptions()
326 {
327     return m_xComplexDescriptionAccess->getRowDescriptions();
328 }
329 
getColumnDescriptions()330 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getColumnDescriptions()
331 {
332     return m_xComplexDescriptionAccess->getColumnDescriptions();
333 }
334 
335 // ____ XChartData (base of XChartDataArray) ____
addChartDataChangeEventListener(const uno::Reference<css::chart::XChartDataChangeEventListener> & x)336 void SAL_CALL DatabaseDataProvider::addChartDataChangeEventListener(const uno::Reference< css::chart::XChartDataChangeEventListener >& x)
337 {
338     m_xComplexDescriptionAccess->addChartDataChangeEventListener(x);
339 }
340 
removeChartDataChangeEventListener(const uno::Reference<css::chart::XChartDataChangeEventListener> & x)341 void SAL_CALL DatabaseDataProvider::removeChartDataChangeEventListener(const uno::Reference< css::chart::XChartDataChangeEventListener >& x)
342 {
343     m_xComplexDescriptionAccess->removeChartDataChangeEventListener(x);
344 }
345 
getNotANumber()346 double SAL_CALL DatabaseDataProvider::getNotANumber()
347 {
348     return m_xComplexDescriptionAccess->getNotANumber();
349 }
350 
isNotANumber(double nNumber)351 sal_Bool SAL_CALL DatabaseDataProvider::isNotANumber( double nNumber )
352 {
353     return m_xComplexDescriptionAccess->isNotANumber(nNumber);
354 }
355 
getRangeSelection()356 uno::Reference< sheet::XRangeSelection > SAL_CALL DatabaseDataProvider::getRangeSelection()
357 {
358     // TODO: Exchange the default return implementation for "getRangeSelection" !!!
359     // Exchange the default return implementation.
360     // NOTE: Default initialized polymorphic structs can cause problems because of
361     // missing default initialization of primitive types of some C++ compilers or
362     // different Any initialization in Java and C++ polymorphic structs.
363     return uno::Reference< sheet::XRangeSelection >();
364 }
365 
366 // chart2::data::XRangeXMLConversion:
convertRangeToXML(const OUString & _sRangeRepresentation)367 OUString SAL_CALL DatabaseDataProvider::convertRangeToXML(const OUString & _sRangeRepresentation)
368 {
369     osl::MutexGuard g(m_aMutex);
370     return m_xRangeConversion->convertRangeToXML(_sRangeRepresentation);
371 }
372 
convertRangeFromXML(const OUString & _sXMLRange)373 OUString SAL_CALL DatabaseDataProvider::convertRangeFromXML(const OUString & _sXMLRange)
374 {
375     osl::MutexGuard g(m_aMutex);
376     return m_xRangeConversion->convertRangeFromXML(_sXMLRange);
377 }
378 
379 // com.sun.star.beans.XPropertySet:
getPropertySetInfo()380 uno::Reference< beans::XPropertySetInfo > SAL_CALL DatabaseDataProvider::getPropertySetInfo()
381 {
382     return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertySetInfo();
383 }
384 
setPropertyValue(const OUString & aPropertyName,const uno::Any & aValue)385 void SAL_CALL DatabaseDataProvider::setPropertyValue(const OUString & aPropertyName, const uno::Any & aValue)
386 {
387     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::setPropertyValue(aPropertyName, aValue);
388 }
389 
getPropertyValue(const OUString & aPropertyName)390 uno::Any SAL_CALL DatabaseDataProvider::getPropertyValue(const OUString & aPropertyName)
391 {
392     return ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::getPropertyValue(aPropertyName);
393 }
394 
addPropertyChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & xListener)395 void SAL_CALL DatabaseDataProvider::addPropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener)
396 {
397     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addPropertyChangeListener(aPropertyName, xListener);
398 }
399 
removePropertyChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XPropertyChangeListener> & xListener)400 void SAL_CALL DatabaseDataProvider::removePropertyChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XPropertyChangeListener > & xListener)
401 {
402     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removePropertyChangeListener(aPropertyName, xListener);
403 }
404 
addVetoableChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XVetoableChangeListener> & xListener)405 void SAL_CALL DatabaseDataProvider::addVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener)
406 {
407     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::addVetoableChangeListener(aPropertyName, xListener);
408 }
409 
removeVetoableChangeListener(const OUString & aPropertyName,const uno::Reference<beans::XVetoableChangeListener> & xListener)410 void SAL_CALL DatabaseDataProvider::removeVetoableChangeListener(const OUString & aPropertyName, const uno::Reference< beans::XVetoableChangeListener > & xListener)
411 {
412     ::cppu::PropertySetMixin< chart2::data::XDatabaseDataProvider >::removeVetoableChangeListener(aPropertyName, xListener);
413 }
414 
415 // chart2::data::XDatabaseDataProvider:
getMasterFields()416 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getMasterFields()
417 {
418     osl::MutexGuard g(m_aMutex);
419     return m_MasterFields;
420 }
421 
setMasterFields(const uno::Sequence<OUString> & the_value)422 void SAL_CALL DatabaseDataProvider::setMasterFields(const uno::Sequence< OUString > & the_value)
423 {
424     impl_invalidateParameter_nothrow();
425     set("MasterFields",the_value,m_MasterFields);
426 }
427 
getDetailFields()428 uno::Sequence< OUString > SAL_CALL DatabaseDataProvider::getDetailFields()
429 {
430     osl::MutexGuard g(m_aMutex);
431     return m_DetailFields;
432 }
433 
setDetailFields(const uno::Sequence<OUString> & the_value)434 void SAL_CALL DatabaseDataProvider::setDetailFields(const uno::Sequence< OUString > & the_value)
435 {
436     set("DetailFields",the_value,m_DetailFields);
437 }
438 
getCommand()439 OUString SAL_CALL DatabaseDataProvider::getCommand()
440 {
441     osl::MutexGuard g(m_aMutex);
442     return m_Command;
443 }
444 
setCommand(const OUString & the_value)445 void SAL_CALL DatabaseDataProvider::setCommand(const OUString & the_value)
446 {
447     {
448         osl::MutexGuard g(m_aMutex);
449         impl_invalidateParameter_nothrow();
450         m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND,   uno::makeAny( the_value ) );
451     }
452     set(PROPERTY_COMMAND,the_value,m_Command);
453 }
454 
getCommandType()455 ::sal_Int32 SAL_CALL DatabaseDataProvider::getCommandType()
456 {
457     osl::MutexGuard g(m_aMutex);
458     return m_CommandType;
459 }
460 
setCommandType(::sal_Int32 the_value)461 void SAL_CALL DatabaseDataProvider::setCommandType(::sal_Int32 the_value)
462 {
463     {
464         osl::MutexGuard g(m_aMutex);
465         m_xAggregateSet->setPropertyValue( PROPERTY_COMMAND_TYPE,   uno::makeAny( the_value ) );
466     }
467     set(PROPERTY_COMMAND_TYPE,the_value,m_CommandType);
468 }
469 
getFilter()470 OUString SAL_CALL DatabaseDataProvider::getFilter()
471 {
472     osl::MutexGuard g(m_aMutex);
473     return m_aFilterManager.getFilterComponent( dbtools::FilterManager::FilterComponent::PublicFilter );
474 }
475 
setFilter(const OUString & the_value)476 void SAL_CALL DatabaseDataProvider::setFilter(const OUString & the_value)
477 {
478     {
479         osl::MutexGuard g(m_aMutex);
480         m_aFilterManager.setFilterComponent( dbtools::FilterManager::FilterComponent::PublicFilter, the_value );
481     }
482     set(PROPERTY_FILTER,the_value,m_Filter);
483 }
484 
getApplyFilter()485 sal_Bool SAL_CALL DatabaseDataProvider::getApplyFilter()
486 {
487     osl::MutexGuard g(m_aMutex);
488     return m_ApplyFilter;
489 }
490 
setApplyFilter(sal_Bool the_value)491 void SAL_CALL DatabaseDataProvider::setApplyFilter( sal_Bool the_value )
492 {
493     {
494         osl::MutexGuard g(m_aMutex);
495         m_xAggregateSet->setPropertyValue( PROPERTY_APPLYFILTER,   uno::makeAny( the_value ) );
496     }
497     set(PROPERTY_APPLYFILTER,static_cast<bool>(the_value),m_ApplyFilter);
498 }
499 
getHavingClause()500 OUString SAL_CALL DatabaseDataProvider::getHavingClause()
501 {
502     osl::MutexGuard g(m_aMutex);
503     return m_HavingClause;
504 }
505 
setHavingClause(const OUString & the_value)506 void SAL_CALL DatabaseDataProvider::setHavingClause( const OUString& the_value )
507 {
508     {
509         osl::MutexGuard g(m_aMutex);
510         m_xAggregateSet->setPropertyValue( PROPERTY_HAVING_CLAUSE,   uno::makeAny( the_value ) );
511     }
512     set(PROPERTY_HAVING_CLAUSE,the_value,m_HavingClause);
513 }
514 
getGroupBy()515 OUString SAL_CALL DatabaseDataProvider::getGroupBy()
516 {
517     osl::MutexGuard g(m_aMutex);
518     return m_GroupBy;
519 }
520 
setGroupBy(const OUString & the_value)521 void SAL_CALL DatabaseDataProvider::setGroupBy( const OUString& the_value )
522 {
523     {
524         osl::MutexGuard g(m_aMutex);
525         m_xAggregateSet->setPropertyValue( PROPERTY_GROUP_BY,   uno::makeAny( the_value ) );
526     }
527     set(PROPERTY_GROUP_BY,the_value,m_GroupBy);
528 }
529 
getOrder()530 OUString SAL_CALL DatabaseDataProvider::getOrder()
531 {
532     osl::MutexGuard g(m_aMutex);
533     return m_Order;
534 }
535 
setOrder(const OUString & the_value)536 void SAL_CALL DatabaseDataProvider::setOrder( const OUString& the_value )
537 {
538     {
539         osl::MutexGuard g(m_aMutex);
540         m_xAggregateSet->setPropertyValue( PROPERTY_ORDER,   uno::makeAny( the_value ) );
541     }
542     set(PROPERTY_ORDER,the_value,m_Order);
543 }
544 
getEscapeProcessing()545 sal_Bool SAL_CALL DatabaseDataProvider::getEscapeProcessing()
546 {
547     osl::MutexGuard g(m_aMutex);
548     return m_EscapeProcessing;
549 }
550 
setEscapeProcessing(sal_Bool the_value)551 void SAL_CALL DatabaseDataProvider::setEscapeProcessing(sal_Bool the_value)
552 {
553     set(PROPERTY_ESCAPE_PROCESSING,static_cast<bool>(the_value),m_EscapeProcessing);
554 }
555 
getRowLimit()556 ::sal_Int32 SAL_CALL DatabaseDataProvider::getRowLimit()
557 {
558     osl::MutexGuard g(m_aMutex);
559     return m_RowLimit;
560 }
561 
setRowLimit(::sal_Int32 the_value)562 void SAL_CALL DatabaseDataProvider::setRowLimit(::sal_Int32 the_value)
563 {
564     set("RowLimit",the_value,m_RowLimit);
565 }
566 
getActiveConnection()567 uno::Reference< sdbc::XConnection > SAL_CALL DatabaseDataProvider::getActiveConnection()
568 {
569     osl::MutexGuard g(m_aMutex);
570     return m_xActiveConnection;
571 }
572 
setActiveConnection(const uno::Reference<sdbc::XConnection> & the_value)573 void SAL_CALL DatabaseDataProvider::setActiveConnection(const uno::Reference< sdbc::XConnection > & the_value)
574 {
575     if ( !the_value.is() )
576         throw lang::IllegalArgumentException();
577     set(PROPERTY_ACTIVE_CONNECTION,the_value,m_xActiveConnection);
578 }
579 
getDataSourceName()580 OUString SAL_CALL DatabaseDataProvider::getDataSourceName()
581 {
582     osl::MutexGuard g(m_aMutex);
583     return m_DataSourceName;
584 }
585 
setDataSourceName(const OUString & the_value)586 void SAL_CALL DatabaseDataProvider::setDataSourceName(const OUString& the_value)
587 {
588     set(PROPERTY_DATASOURCENAME,the_value,m_DataSourceName);
589 }
590 
591 namespace
592 {
593     struct ColumnDescription
594     {
595         OUString sName;
596         sal_Int32       nResultSetPosition;
597         sal_Int32       nDataType;
598 
ColumnDescriptiondbaccess::__anon903106e20111::ColumnDescription599         ColumnDescription()
600             :sName()
601             ,nResultSetPosition( 0 )
602             ,nDataType( sdbc::DataType::VARCHAR )
603         {
604         }
ColumnDescriptiondbaccess::__anon903106e20111::ColumnDescription605         explicit ColumnDescription( const OUString& i_rName )
606             :sName( i_rName )
607             ,nResultSetPosition( 0 )
608             ,nDataType( sdbc::DataType::VARCHAR )
609         {
610         }
611     };
612 
613     struct CreateColumnDescription
614     {
operator ()dbaccess::__anon903106e20111::CreateColumnDescription615         ColumnDescription operator()( const OUString& i_rName )
616         {
617             return ColumnDescription( i_rName );
618         }
619     };
620 
621     struct SelectColumnName
622     {
operator ()dbaccess::__anon903106e20111::SelectColumnName623         const OUString& operator()( const ColumnDescription& i_rColumn )
624         {
625             return i_rColumn.sName;
626         }
627     };
628 }
629 
impl_fillInternalDataProvider_throw(bool _bHasCategories,const uno::Sequence<OUString> & i_aColumnNames)630 void DatabaseDataProvider::impl_fillInternalDataProvider_throw(bool _bHasCategories,const uno::Sequence< OUString >& i_aColumnNames)
631 {
632     // clear the data before fill the new one
633     uno::Reference< sdbcx::XColumnsSupplier > xColSup(m_xRowSet,uno::UNO_QUERY_THROW);
634     uno::Reference< container::XNameAccess > xColumns( xColSup->getColumns(), uno::UNO_SET_THROW );
635     const uno::Sequence< OUString > aRowSetColumnNames( xColumns->getElementNames() );
636 
637     typedef std::vector< ColumnDescription > ColumnDescriptions;
638     ColumnDescriptions aColumns;
639     bool bFirstColumnIsCategory = _bHasCategories;
640     if ( i_aColumnNames.hasElements() )
641     {
642         // some normalizations ...
643         uno::Sequence< OUString > aImposedColumnNames( i_aColumnNames );
644 
645         // strangely, there exist documents where the ColumnDescriptions end with a number of empty strings. /me
646         // thinks they're generated when you have a chart based on a result set with n columns, but remove some
647         // of those columns from the chart - it looks like a bug in the report XML export to me.
648         // So, get rid of the "trailing" empty columns
649         sal_Int32 nLastNonEmptyColName = aImposedColumnNames.getLength() - 1;
650         for ( ; nLastNonEmptyColName >= 0; --nLastNonEmptyColName )
651         {
652             if ( !aImposedColumnNames[ nLastNonEmptyColName ].isEmpty() )
653                 break;
654         }
655         aImposedColumnNames.realloc( nLastNonEmptyColName + 1 );
656 
657         // second, for X-Y-charts the ColumnDescriptions exported by chart miss the name of the first (non-category)
658         // column. This, this results in a ColumnDescriptions array like <"", "col2", "col3">, where you'd expect
659         // <"col1", "col2", "col3">.
660         // Fix this with some heuristics:
661         if ( aImposedColumnNames.hasElements() && ( !aImposedColumnNames[0].isEmpty() ) )
662         {
663             const sal_Int32 nAssumedRowSetColumnIndex = _bHasCategories ? 1 : 0;
664             if ( nAssumedRowSetColumnIndex < aRowSetColumnNames.getLength() )
665                 aImposedColumnNames[0] = aRowSetColumnNames[ nAssumedRowSetColumnIndex ];
666         }
667 
668         const sal_Int32 nCount = aImposedColumnNames.getLength();
669         for ( sal_Int32 i = 0 ; i < nCount; ++i )
670         {
671             const OUString sColumnName( aImposedColumnNames[i] );
672             if ( !xColumns->hasByName( sColumnName ) )
673                 continue;
674 
675             if ( _bHasCategories && aColumns.empty() )
676             {
677                 if ( aRowSetColumnNames.hasElements() )
678                     aColumns.emplace_back( aRowSetColumnNames[0] );
679                 else
680                     aColumns.emplace_back( sColumnName );
681                 bFirstColumnIsCategory = true;
682             }
683             aColumns.emplace_back( sColumnName );
684         }
685     }
686     if ( aColumns.empty() )
687     {
688         aColumns.resize( aRowSetColumnNames.getLength() );
689         std::transform(
690             aRowSetColumnNames.begin(),
691             aRowSetColumnNames.end(),
692             aColumns.begin(),
693             CreateColumnDescription()
694        );
695     }
696 
697     // fill the data
698     uno::Reference< sdbc::XResultSet> xRes( m_xRowSet, uno::UNO_QUERY_THROW );
699     uno::Reference< sdbc::XRow> xRow( m_xRowSet,uno::UNO_QUERY_THROW );
700     uno::Reference< sdbc::XResultSetMetaDataSupplier > xSuppMeta( m_xRowSet,uno::UNO_QUERY_THROW );
701     uno::Reference< sdbc::XColumnLocate > xColumnLocate( m_xRowSet, uno::UNO_QUERY_THROW );
702 
703     sal_Int32 columnIndex = 0;
704     for (auto & column : aColumns)
705     {
706         column.nResultSetPosition = xColumnLocate->findColumn( column.sName );
707 
708         const uno::Reference< beans::XPropertySet > xColumn( xColumns->getByName( column.sName ), uno::UNO_QUERY_THROW );
709         const uno::Any aNumberFormat( xColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) );
710         OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= column.nDataType );
711 
712         const OUString sRangeName = OUString::number( columnIndex );
713         m_aNumberFormats.emplace( sRangeName, aNumberFormat );
714         ++columnIndex;
715     }
716 
717     std::vector< OUString > aRowLabels;
718     std::vector< std::vector< double > > aDataValues;
719     sal_Int32 nRowCount = 0;
720     ::connectivity::ORowSetValue aValue;
721     while( xRes->next() && (!m_RowLimit || nRowCount < m_RowLimit) )
722     {
723         ++nRowCount;
724 
725         aValue.fill( aColumns[0].nResultSetPosition, aColumns[0].nDataType, xRow );
726         aRowLabels.push_back( aValue.getString() );
727 
728         std::vector< double > aRow;
729         bool bFirstLoop = true;
730         for (auto const& column : aColumns)
731         {
732             if (bFirstLoop)
733             {
734                 bFirstLoop = false;
735                 if (bFirstColumnIsCategory)
736                     continue;
737             }
738 
739             aValue.fill( column.nResultSetPosition, column.nDataType, xRow );
740             if ( aValue.isNull() )
741             {
742                 double nValue;
743                 ::rtl::math::setNan( &nValue );
744                 aRow.push_back( nValue );
745             }
746             else
747                 aRow.push_back( aValue.getDouble() );
748         }
749 
750         aDataValues.push_back( aRow );
751     }
752 
753     // insert default data when no rows exist
754     if ( !nRowCount )
755     {
756         nRowCount = 3;
757         static const double fDefaultData[ ] =
758             { 9.10, 3.20, 4.54,
759               2.40, 8.80, 9.65,
760               3.10, 1.50, 3.70,
761               4.30, 9.02, 6.20 };
762         for(sal_Int32 h = 0,k = 0; h < nRowCount; ++h,++k )
763         {
764             aRowLabels.push_back(OUString::number(h+1));
765             std::vector< double > aRow;
766             const sal_Int32 nSize = SAL_N_ELEMENTS(fDefaultData);
767             for (size_t j = 0; j < (aColumns.size()-1); ++j,++k)
768             {
769                 if ( k >= nSize )
770                     k = 0;
771                 aRow.push_back(fDefaultData[k]);
772             }
773             aDataValues.push_back(aRow);
774         }
775     }
776 
777     uno::Reference< chart::XChartDataArray> xData(m_xInternal,uno::UNO_QUERY);
778     xData->setRowDescriptions(comphelper::containerToSequence(aRowLabels));
779 
780     const size_t nOffset = bFirstColumnIsCategory ? 1 : 0;
781     uno::Sequence< OUString > aColumnDescriptions( aColumns.size() - nOffset );
782     std::transform(
783         aColumns.begin() + nOffset,
784         aColumns.end(),
785         aColumnDescriptions.getArray(),
786         SelectColumnName()
787     );
788     xData->setColumnDescriptions( aColumnDescriptions );
789 
790     uno::Sequence< uno::Sequence< double > > aData(aDataValues.size());
791     uno::Sequence< double >* pDataIter  = aData.getArray();
792     uno::Sequence< double >* pDataEnd   = pDataIter + aData.getLength();
793     for(sal_Int32 i= 0;pDataIter != pDataEnd; ++pDataIter,++i )
794     {
795         if ( !aDataValues[i].empty() )
796             *pDataIter = comphelper::containerToSequence(aDataValues[i]);
797     }
798     xData->setData(aData);
799 }
800 
impl_fillRowSet_throw()801 void DatabaseDataProvider::impl_fillRowSet_throw()
802 {
803     m_xAggregateSet->setPropertyValue( PROPERTY_FILTER,   uno::makeAny( getFilter() ) );
804     uno::Reference< sdbc::XParameters> xParam(m_xRowSet,uno::UNO_QUERY_THROW);
805     xParam->clearParameters( );
806 }
807 
impl_fillParameters_nothrow(::osl::ResettableMutexGuard & _rClearForNotifies)808 bool DatabaseDataProvider::impl_fillParameters_nothrow( ::osl::ResettableMutexGuard& _rClearForNotifies)
809 {
810     // do we have to fill the parameters again?
811     if ( !m_aParameterManager.isUpToDate() )
812         m_aParameterManager.updateParameterInfo( m_aFilterManager );
813 
814     if ( m_aParameterManager.isUpToDate() )
815         return m_aParameterManager.fillParameterValues( m_xHandler, _rClearForNotifies );
816 
817     return true;
818 }
819 
820 // css::sdbc::XParameters
setNull(sal_Int32 parameterIndex,sal_Int32 sqlType)821 void SAL_CALL DatabaseDataProvider::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType)
822 {
823     m_aParameterManager.setNull(parameterIndex, sqlType);
824 }
825 
setObjectNull(sal_Int32 parameterIndex,sal_Int32 sqlType,const OUString & typeName)826 void SAL_CALL DatabaseDataProvider::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const OUString& typeName)
827 {
828     m_aParameterManager.setObjectNull(parameterIndex, sqlType, typeName);
829 }
830 
setBoolean(sal_Int32 parameterIndex,sal_Bool x)831 void SAL_CALL DatabaseDataProvider::setBoolean(sal_Int32 parameterIndex, sal_Bool x)
832 {
833     m_aParameterManager.setBoolean(parameterIndex, x);
834 }
835 
setByte(sal_Int32 parameterIndex,sal_Int8 x)836 void SAL_CALL DatabaseDataProvider::setByte(sal_Int32 parameterIndex, sal_Int8 x)
837 {
838     m_aParameterManager.setByte(parameterIndex, x);
839 }
840 
setShort(sal_Int32 parameterIndex,sal_Int16 x)841 void SAL_CALL DatabaseDataProvider::setShort(sal_Int32 parameterIndex, sal_Int16 x)
842 {
843     m_aParameterManager.setShort(parameterIndex, x);
844 }
845 
setInt(sal_Int32 parameterIndex,sal_Int32 x)846 void SAL_CALL DatabaseDataProvider::setInt(sal_Int32 parameterIndex, sal_Int32 x)
847 {
848     m_aParameterManager.setInt(parameterIndex, x);
849 }
850 
setLong(sal_Int32 parameterIndex,sal_Int64 x)851 void SAL_CALL DatabaseDataProvider::setLong(sal_Int32 parameterIndex, sal_Int64 x)
852 {
853     m_aParameterManager.setLong(parameterIndex, x);
854 }
855 
setFloat(sal_Int32 parameterIndex,float x)856 void SAL_CALL DatabaseDataProvider::setFloat(sal_Int32 parameterIndex, float x)
857 {
858     m_aParameterManager.setFloat(parameterIndex, x);
859 }
860 
setDouble(sal_Int32 parameterIndex,double x)861 void SAL_CALL DatabaseDataProvider::setDouble(sal_Int32 parameterIndex, double x)
862 {
863     m_aParameterManager.setDouble(parameterIndex, x);
864 }
865 
setString(sal_Int32 parameterIndex,const OUString & x)866 void SAL_CALL DatabaseDataProvider::setString(sal_Int32 parameterIndex, const OUString& x)
867 {
868     m_aParameterManager.setString(parameterIndex, x);
869 }
870 
setBytes(sal_Int32 parameterIndex,const uno::Sequence<sal_Int8> & x)871 void SAL_CALL DatabaseDataProvider::setBytes(sal_Int32 parameterIndex, const uno::Sequence< sal_Int8 >& x)
872 {
873     m_aParameterManager.setBytes(parameterIndex, x);
874 }
875 
setDate(sal_Int32 parameterIndex,const util::Date & x)876 void SAL_CALL DatabaseDataProvider::setDate(sal_Int32 parameterIndex, const util::Date& x)
877 {
878     m_aParameterManager.setDate(parameterIndex, x);
879 }
880 
setTime(sal_Int32 parameterIndex,const util::Time & x)881 void SAL_CALL DatabaseDataProvider::setTime(sal_Int32 parameterIndex, const util::Time& x)
882 {
883     m_aParameterManager.setTime(parameterIndex, x);
884 }
885 
setTimestamp(sal_Int32 parameterIndex,const util::DateTime & x)886 void SAL_CALL DatabaseDataProvider::setTimestamp(sal_Int32 parameterIndex, const util::DateTime& x)
887 {
888     m_aParameterManager.setTimestamp(parameterIndex, x);
889 }
890 
setBinaryStream(sal_Int32 parameterIndex,const uno::Reference<io::XInputStream> & x,sal_Int32 length)891 void SAL_CALL DatabaseDataProvider::setBinaryStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length)
892 {
893     m_aParameterManager.setBinaryStream(parameterIndex, x, length);
894 }
895 
setCharacterStream(sal_Int32 parameterIndex,const uno::Reference<io::XInputStream> & x,sal_Int32 length)896 void SAL_CALL DatabaseDataProvider::setCharacterStream(sal_Int32 parameterIndex, const uno::Reference<io::XInputStream>& x, sal_Int32 length)
897 {
898     m_aParameterManager.setCharacterStream(parameterIndex, x, length);
899 }
900 
setObjectWithInfo(sal_Int32 parameterIndex,const uno::Any & x,sal_Int32 targetSqlType,sal_Int32 scale)901 void SAL_CALL DatabaseDataProvider::setObjectWithInfo(sal_Int32 parameterIndex, const uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale)
902 {
903     m_aParameterManager.setObjectWithInfo(parameterIndex, x, targetSqlType, scale);
904 }
905 
setObject(sal_Int32 parameterIndex,const uno::Any & x)906 void SAL_CALL DatabaseDataProvider::setObject(sal_Int32 parameterIndex, const uno::Any& x)
907 {
908     m_aParameterManager.setObject(parameterIndex, x);
909 }
910 
setRef(sal_Int32 parameterIndex,const uno::Reference<sdbc::XRef> & x)911 void SAL_CALL DatabaseDataProvider::setRef(sal_Int32 parameterIndex, const uno::Reference<sdbc::XRef>& x)
912 {
913     m_aParameterManager.setRef(parameterIndex, x);
914 }
915 
setBlob(sal_Int32 parameterIndex,const uno::Reference<sdbc::XBlob> & x)916 void SAL_CALL DatabaseDataProvider::setBlob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XBlob>& x)
917 {
918     m_aParameterManager.setBlob(parameterIndex, x);
919 }
920 
setClob(sal_Int32 parameterIndex,const uno::Reference<sdbc::XClob> & x)921 void SAL_CALL DatabaseDataProvider::setClob(sal_Int32 parameterIndex, const uno::Reference<sdbc::XClob>& x)
922 {
923     m_aParameterManager.setClob(parameterIndex, x);
924 }
925 
setArray(sal_Int32 parameterIndex,const Reference<sdbc::XArray> & x)926 void SAL_CALL DatabaseDataProvider::setArray(sal_Int32 parameterIndex, const Reference<sdbc::XArray>& x)
927 {
928     m_aParameterManager.setArray(parameterIndex, x);
929 }
930 
clearParameters()931 void SAL_CALL DatabaseDataProvider::clearParameters()
932 {
933     m_aParameterManager.clearParameters();
934 }
935 
936 // css::sdbc::XRowSet
execute()937 void SAL_CALL DatabaseDataProvider::execute()
938 {
939     uno::Sequence< beans::PropertyValue > aEmpty;
940     createDataSource(aEmpty);
941 }
942 
addRowSetListener(const uno::Reference<sdbc::XRowSetListener> & _rListener)943 void SAL_CALL DatabaseDataProvider::addRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener)
944 {
945     if (m_xRowSet.is())
946         m_xRowSet->addRowSetListener(_rListener);
947 }
948 
removeRowSetListener(const uno::Reference<sdbc::XRowSetListener> & _rListener)949 void SAL_CALL DatabaseDataProvider::removeRowSetListener(const uno::Reference<sdbc::XRowSetListener>& _rListener)
950 {
951     if (m_xRowSet.is())
952         m_xRowSet->removeRowSetListener(_rListener);
953 }
954 
955 // css::sdbc::XResultSet
next()956 sal_Bool SAL_CALL DatabaseDataProvider::next()
957 {
958     return m_xRowSet->next();
959 }
960 
isBeforeFirst()961 sal_Bool SAL_CALL DatabaseDataProvider::isBeforeFirst()
962 {
963     return m_xRowSet->isBeforeFirst();
964 }
965 
isAfterLast()966 sal_Bool SAL_CALL DatabaseDataProvider::isAfterLast()
967 {
968     return m_xRowSet->isAfterLast();
969 }
970 
isFirst()971 sal_Bool SAL_CALL DatabaseDataProvider::isFirst()
972 {
973     return m_xRowSet->isFirst();
974 }
975 
isLast()976 sal_Bool SAL_CALL DatabaseDataProvider::isLast()
977 {
978     return m_xRowSet->isLast();
979 }
980 
beforeFirst()981 void SAL_CALL DatabaseDataProvider::beforeFirst()
982 {
983     m_xRowSet->beforeFirst();
984 }
985 
afterLast()986 void SAL_CALL DatabaseDataProvider::afterLast()
987 {
988     m_xRowSet->afterLast();
989 }
990 
first()991 sal_Bool SAL_CALL DatabaseDataProvider::first()
992 {
993     return m_xRowSet->first();
994 }
995 
last()996 sal_Bool SAL_CALL DatabaseDataProvider::last()
997 {
998     return m_xRowSet->last();
999 }
1000 
getRow()1001 sal_Int32 SAL_CALL DatabaseDataProvider::getRow()
1002 {
1003     return m_xRowSet->getRow();
1004 }
1005 
absolute(sal_Int32 row)1006 sal_Bool SAL_CALL DatabaseDataProvider::absolute(sal_Int32 row)
1007 {
1008     return m_xRowSet->absolute(row);
1009 }
1010 
relative(sal_Int32 rows)1011 sal_Bool SAL_CALL DatabaseDataProvider::relative(sal_Int32 rows)
1012 {
1013     return m_xRowSet->relative(rows);
1014 }
1015 
previous()1016 sal_Bool SAL_CALL DatabaseDataProvider::previous()
1017 {
1018     return m_xRowSet->previous();
1019 }
1020 
refreshRow()1021 void SAL_CALL DatabaseDataProvider::refreshRow()
1022 {
1023     m_xRowSet->refreshRow();
1024 }
1025 
rowUpdated()1026 sal_Bool SAL_CALL DatabaseDataProvider::rowUpdated()
1027 {
1028     return m_xRowSet->rowUpdated();
1029 }
1030 
rowInserted()1031 sal_Bool SAL_CALL DatabaseDataProvider::rowInserted()
1032 {
1033     return m_xRowSet->rowInserted();
1034 }
1035 
rowDeleted()1036 sal_Bool SAL_CALL DatabaseDataProvider::rowDeleted()
1037 {
1038     return m_xRowSet->rowDeleted();
1039 }
1040 
getStatement()1041 uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getStatement()
1042 {
1043     return m_xRowSet->getStatement();
1044 }
1045 
getParent()1046 uno::Reference< uno::XInterface > SAL_CALL DatabaseDataProvider::getParent(  )
1047 {
1048     return m_xParent;
1049 }
1050 
setParent(const uno::Reference<uno::XInterface> & _xParent)1051 void SAL_CALL DatabaseDataProvider::setParent( const uno::Reference< uno::XInterface >& _xParent )
1052 {
1053     osl::MutexGuard g(m_aMutex);
1054     m_xParent = _xParent;
1055 }
1056 
impl_invalidateParameter_nothrow()1057 void DatabaseDataProvider::impl_invalidateParameter_nothrow()
1058 {
1059     osl::MutexGuard g(m_aMutex);
1060     m_aParameterManager.clearAllParameterInformation();
1061 }
1062 
1063 } // namespace dbaccess
1064 
1065 
1066 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 &)1067 com_sun_star_comp_dbaccess_DatabaseDataProvider_get_implementation(
1068     css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
1069 {
1070     return cppu::acquire(new dbaccess::DatabaseDataProvider(context));
1071 }
1072 
1073 
1074 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1075