Update ooo320-m1
[ooovba.git] / sc / source / core / data / dpsdbtab.cxx
blob80dd69eb2be3fd7ef7615e67ea9a9f1a1e4e1a45
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dpsdbtab.cxx,v $
10 * $Revision: 1.15 $
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"
57 #include "global.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;
66 using ::std::vector;
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
86 public:
87 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager;
88 ScImportSourceDesc aDesc;
89 long nColCount;
90 uno::Reference<sdbc::XRowSet> xRowSet;
91 sal_Int32* pTypes;
92 SvNumberFormatter* pFormatter;
94 ScDPCacheTable aCacheTable;
96 ScDatabaseDPData_Impl(ScDPCollection* p) :
97 aCacheTable(p)
102 // -----------------------------------------------------------------------
104 ScDatabaseDPData::ScDatabaseDPData(
105 ScDocument* pDoc,
106 const ScImportSourceDesc& rImport ) :
107 ScDPTableData(pDoc)
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
116 OpenDatabase();
117 CreateCacheTable();
120 ScDatabaseDPData::~ScDatabaseDPData()
122 ::comphelper::disposeComponent( pImpl->xRowSet );
124 delete[] pImpl->pTypes;
125 delete pImpl->pFormatter; // NumberFormatter is local for this object
126 delete pImpl;
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;
143 default:
144 return FALSE;
147 BOOL bSuccess = FALSE;
150 pImpl->xRowSet = uno::Reference<sdbc::XRowSet>(
151 comphelper::getProcessServiceFactory()->createInstance(
152 rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
153 uno::UNO_QUERY);
154 uno::Reference<beans::XPropertySet> xRowProp( pImpl->xRowSet, uno::UNO_QUERY );
155 DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
156 if ( xRowProp.is() )
159 // set source parameters
162 uno::Any aAny;
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 );
172 aAny <<= nSdbType;
173 xRowProp->setPropertyValue(
174 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
176 uno::Reference<sdb::XCompletedExecution> xExecute( pImpl->xRowSet, uno::UNO_QUERY );
177 if ( xExecute.is() )
179 uno::Reference<task::XInteractionHandler> xHandler(
180 comphelper::getProcessServiceFactory()->createInstance(
181 rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
182 uno::UNO_QUERY);
183 xExecute->executeWithCompletion( xHandler );
185 else
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();
197 if ( xMeta.is() )
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 );
207 bSuccess = TRUE;
211 catch ( sdbc::SQLException& rError )
213 //! store error message
214 InfoBox aInfoBox( 0, String(rError.Message) );
215 aInfoBox.Execute();
217 catch ( uno::Exception& )
219 DBG_ERROR("Unexpected exception in database");
223 if (!bSuccess)
224 ::comphelper::disposeComponent( pImpl->xRowSet );
226 return bSuccess;
229 long ScDatabaseDPData::GetColumnCount()
231 return pImpl->nColCount;
234 const TypedScStrCollection& ScDatabaseDPData::GetColumnEntries(long nColumn)
236 CreateCacheTable();
237 return pImpl->aCacheTable.getFieldEntries(nColumn);
240 String ScDatabaseDPData::getDimensionName(long nColumn)
242 if (getIsDataLayoutDimension(nColumn))
244 //! different internal and display names?
245 //return "Data";
246 return ScGlobal::GetRscString(STR_PIVOT_DATA);
249 CreateCacheTable();
250 const String* pStr = pImpl->aCacheTable.getFieldName(nColumn);
251 if (pStr)
252 return *pStr;
254 DBG_ERROR("getDimensionName: invalid dimension");
255 return String();
258 BOOL ScDatabaseDPData::getIsDataLayoutDimension(long nColumn)
260 return ( nColumn == pImpl->nColCount );
263 BOOL ScDatabaseDPData::IsDateDimension(long /* nDim */)
265 //! later...
266 return FALSE;
269 void ScDatabaseDPData::SetEmptyFlags( BOOL /* bIgnoreEmptyRows */, BOOL /* bRepeatIfEmpty */ )
271 // not used for database data
272 //! disable flags
275 void ScDatabaseDPData::CreateCacheTable()
277 if (!pImpl->aCacheTable.empty())
278 return;
280 // Get null date.
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)
289 CreateCacheTable();
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)
296 CreateCacheTable();
297 sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize();
298 if (!nRowSize)
299 return;
301 pImpl->aCacheTable.filterTable(
302 rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
305 void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
307 CreateCacheTable();
308 CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow);
311 const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const
313 return pImpl->aCacheTable;
316 // -----------------------------------------------------------------------