1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dpsdbtab.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE --------------------------------------------------------------
38 #include <tools/debug.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <svtools/zforlist.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/types.hxx>
44 #include <com/sun/star/sheet/DataImportMode.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/sdb/CommandType.hpp>
47 #include <com/sun/star/sdb/XCompletedExecution.hpp>
48 #include <com/sun/star/sdbc/DataType.hpp>
49 #include <com/sun/star/sdbc/XRow.hpp>
50 #include <com/sun/star/sdbc/XRowSet.hpp>
51 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
52 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
55 #include "dpsdbtab.hxx"
56 #include "collect.hxx"
58 #include "globstr.hrc"
59 #include "dpcachetable.hxx"
60 #include "dptabres.hxx"
61 #include "document.hxx"
62 #include "dpobject.hxx"
64 using namespace com::sun::star
;
67 using ::std::hash_map
;
68 using ::std::hash_set
;
69 using ::com::sun::star::uno::Sequence
;
70 using ::com::sun::star::uno::Reference
;
71 using ::com::sun::star::uno::Any
;
72 using ::com::sun::star::uno::UNO_QUERY
;
74 #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
75 #define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler"
77 //! move to a header file?
78 #define SC_DBPROP_DATASOURCENAME "DataSourceName"
79 #define SC_DBPROP_COMMAND "Command"
80 #define SC_DBPROP_COMMANDTYPE "CommandType"
82 // -----------------------------------------------------------------------
84 class ScDatabaseDPData_Impl
87 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
> xServiceManager
;
88 ScImportSourceDesc aDesc
;
90 uno::Reference
<sdbc::XRowSet
> xRowSet
;
92 SvNumberFormatter
* pFormatter
;
94 ScDPCacheTable aCacheTable
;
96 ScDatabaseDPData_Impl(ScDPCollection
* p
) :
102 // -----------------------------------------------------------------------
104 ScDatabaseDPData::ScDatabaseDPData(
106 const ScImportSourceDesc
& rImport
) :
109 pImpl
= new ScDatabaseDPData_Impl(pDoc
->GetDPCollection());
110 pImpl
->xServiceManager
= pDoc
->GetServiceManager();
111 pImpl
->aDesc
= rImport
;
112 pImpl
->nColCount
= 0;
113 pImpl
->pTypes
= NULL
;
114 pImpl
->pFormatter
= NULL
; // created on demand
120 ScDatabaseDPData::~ScDatabaseDPData()
122 ::comphelper::disposeComponent( pImpl
->xRowSet
);
124 delete[] pImpl
->pTypes
;
125 delete pImpl
->pFormatter
; // NumberFormatter is local for this object
129 void ScDatabaseDPData::DisposeData()
131 //! use OpenDatabase here?
132 pImpl
->aCacheTable
.clear();
135 BOOL
ScDatabaseDPData::OpenDatabase()
137 sal_Int32 nSdbType
= -1;
138 switch ( pImpl
->aDesc
.nType
)
140 case sheet::DataImportMode_SQL
: nSdbType
= sdb::CommandType::COMMAND
; break;
141 case sheet::DataImportMode_TABLE
: nSdbType
= sdb::CommandType::TABLE
; break;
142 case sheet::DataImportMode_QUERY
: nSdbType
= sdb::CommandType::QUERY
; break;
147 BOOL bSuccess
= FALSE
;
150 pImpl
->xRowSet
= uno::Reference
<sdbc::XRowSet
>(
151 comphelper::getProcessServiceFactory()->createInstance(
152 rtl::OUString::createFromAscii( SC_SERVICE_ROWSET
) ),
154 uno::Reference
<beans::XPropertySet
> xRowProp( pImpl
->xRowSet
, uno::UNO_QUERY
);
155 DBG_ASSERT( xRowProp
.is(), "can't get RowSet" );
159 // set source parameters
164 aAny
<<= rtl::OUString( pImpl
->aDesc
.aDBName
);
165 xRowProp
->setPropertyValue(
166 rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME
), aAny
);
168 aAny
<<= rtl::OUString( pImpl
->aDesc
.aObject
);
169 xRowProp
->setPropertyValue(
170 rtl::OUString::createFromAscii(SC_DBPROP_COMMAND
), aAny
);
173 xRowProp
->setPropertyValue(
174 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE
), aAny
);
176 uno::Reference
<sdb::XCompletedExecution
> xExecute( pImpl
->xRowSet
, uno::UNO_QUERY
);
179 uno::Reference
<task::XInteractionHandler
> xHandler(
180 comphelper::getProcessServiceFactory()->createInstance(
181 rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER
) ),
183 xExecute
->executeWithCompletion( xHandler
);
186 pImpl
->xRowSet
->execute();
189 // get column descriptions
192 pImpl
->nColCount
= 0;
193 uno::Reference
<sdbc::XResultSetMetaData
> xMeta
;
194 uno::Reference
<sdbc::XResultSetMetaDataSupplier
> xMetaSupp( pImpl
->xRowSet
, uno::UNO_QUERY
);
195 if ( xMetaSupp
.is() )
196 xMeta
= xMetaSupp
->getMetaData();
198 pImpl
->nColCount
= xMeta
->getColumnCount(); // this is the number of real columns
200 uno::Reference
<sdbc::XResultSet
> xResSet( pImpl
->xRowSet
, uno::UNO_QUERY
);
201 if ( pImpl
->nColCount
> 0 && xResSet
.is() )
203 pImpl
->pTypes
= new sal_Int32
[pImpl
->nColCount
];
204 for (long nCol
=0; nCol
<pImpl
->nColCount
; nCol
++)
205 pImpl
->pTypes
[nCol
] = xMeta
->getColumnType( nCol
+1 );
211 catch ( sdbc::SQLException
& rError
)
213 //! store error message
214 InfoBox
aInfoBox( 0, String(rError
.Message
) );
217 catch ( uno::Exception
& )
219 DBG_ERROR("Unexpected exception in database");
224 ::comphelper::disposeComponent( pImpl
->xRowSet
);
229 long ScDatabaseDPData::GetColumnCount()
231 return pImpl
->nColCount
;
234 const TypedScStrCollection
& ScDatabaseDPData::GetColumnEntries(long nColumn
)
237 return pImpl
->aCacheTable
.getFieldEntries(nColumn
);
240 String
ScDatabaseDPData::getDimensionName(long nColumn
)
242 if (getIsDataLayoutDimension(nColumn
))
244 //! different internal and display names?
246 return ScGlobal::GetRscString(STR_PIVOT_DATA
);
250 const String
* pStr
= pImpl
->aCacheTable
.getFieldName(nColumn
);
254 DBG_ERROR("getDimensionName: invalid dimension");
258 BOOL
ScDatabaseDPData::getIsDataLayoutDimension(long nColumn
)
260 return ( nColumn
== pImpl
->nColCount
);
263 BOOL
ScDatabaseDPData::IsDateDimension(long /* nDim */)
269 void ScDatabaseDPData::SetEmptyFlags( BOOL
/* bIgnoreEmptyRows */, BOOL
/* bRepeatIfEmpty */ )
271 // not used for database data
275 void ScDatabaseDPData::CreateCacheTable()
277 if (!pImpl
->aCacheTable
.empty())
281 if (!pImpl
->pFormatter
)
282 pImpl
->pFormatter
= new SvNumberFormatter(pImpl
->xServiceManager
, ScGlobal::eLnge
);
284 pImpl
->aCacheTable
.fillTable(pImpl
->xRowSet
, *pImpl
->pFormatter
->GetNullDate());
287 void ScDatabaseDPData::FilterCacheTable(const vector
<ScDPCacheTable::Criterion
>& rCriteria
, const hash_set
<sal_Int32
>& rCatDims
)
290 pImpl
->aCacheTable
.filterByPageDimension(
291 rCriteria
, (IsRepeatIfEmpty() ? rCatDims
: hash_set
<sal_Int32
>()));
294 void ScDatabaseDPData::GetDrillDownData(const vector
<ScDPCacheTable::Criterion
>& rCriteria
, const hash_set
<sal_Int32
>& rCatDims
, Sequence
< Sequence
<Any
> >& rData
)
297 sal_Int32 nRowSize
= pImpl
->aCacheTable
.getRowSize();
301 pImpl
->aCacheTable
.filterTable(
302 rCriteria
, rData
, IsRepeatIfEmpty() ? rCatDims
: hash_set
<sal_Int32
>());
305 void ScDatabaseDPData::CalcResults(CalcInfo
& rInfo
, bool bAutoShow
)
308 CalcResultsFromCacheTable(pImpl
->aCacheTable
, rInfo
, bAutoShow
);
311 const ScDPCacheTable
& ScDatabaseDPData::GetCacheTable() const
313 return pImpl
->aCacheTable
;
316 // -----------------------------------------------------------------------