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