xref: /aoo41x/main/sc/source/core/data/dpsdbtab.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // INCLUDE --------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir #include <vcl/msgbox.hxx>
33cdf0e10cSrcweir #include <svl/zforlist.hxx>
34cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
35cdf0e10cSrcweir #include <comphelper/types.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <com/sun/star/sheet/DataImportMode.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
39cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp>
40cdf0e10cSrcweir #include <com/sun/star/sdb/XCompletedExecution.hpp>
41cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
42cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp>
44cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
45cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include "dpsdbtab.hxx"
49cdf0e10cSrcweir #include "collect.hxx"
50cdf0e10cSrcweir #include "global.hxx"
51cdf0e10cSrcweir #include "globstr.hrc"
52cdf0e10cSrcweir #include "dpcachetable.hxx"
53cdf0e10cSrcweir #include "dptabres.hxx"
54cdf0e10cSrcweir #include "document.hxx"
55cdf0e10cSrcweir #include "dpobject.hxx"
56cdf0e10cSrcweir 
57cdf0e10cSrcweir using namespace com::sun::star;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir using ::std::vector;
60cdf0e10cSrcweir using ::std::hash_map;
61cdf0e10cSrcweir using ::std::hash_set;
62cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
63cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
64cdf0e10cSrcweir using ::com::sun::star::uno::Any;
65cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #define SC_SERVICE_ROWSET			"com.sun.star.sdb.RowSet"
68cdf0e10cSrcweir #define SC_SERVICE_INTHANDLER		"com.sun.star.task.InteractionHandler"
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //!	move to a header file?
71cdf0e10cSrcweir #define SC_DBPROP_DATASOURCENAME	"DataSourceName"
72cdf0e10cSrcweir #define SC_DBPROP_COMMAND			"Command"
73cdf0e10cSrcweir #define SC_DBPROP_COMMANDTYPE		"CommandType"
74cdf0e10cSrcweir // -----------------------------------------------------------------------
75cdf0e10cSrcweir // Wang Xu Ming -- 2009-9-15
76cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
GetExistDPObjectCache(ScDocument * pDoc) const77cdf0e10cSrcweir  ScDPTableDataCache* ScImportSourceDesc::GetExistDPObjectCache( ScDocument* pDoc ) const
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     ScDPTableDataCache* pCache = NULL;
80cdf0e10cSrcweir     ScDPCollection* pDPCollection= pDoc->GetDPCollection();
81cdf0e10cSrcweir     sal_uInt16 nCount = pDPCollection->GetCount();
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     for ( short i=nCount-1; i>=0 ; i--)
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         if ( const ScImportSourceDesc* pUsedDesc = (*pDPCollection)[i]->GetImportSourceDesc() )
86cdf0e10cSrcweir             if ( *this == *pUsedDesc )
87cdf0e10cSrcweir             {
88cdf0e10cSrcweir                 long nID = (*pDPCollection)[i]->GetCacheId();
89cdf0e10cSrcweir                 if ( nID >= 0  )
90cdf0e10cSrcweir                     pCache= pDoc->GetDPObjectCache( nID );
91cdf0e10cSrcweir                 if ( pCache )
92cdf0e10cSrcweir                     return pCache;
93cdf0e10cSrcweir             }
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir     return NULL;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
CreateCache(ScDocument * pDoc,long nID) const98cdf0e10cSrcweir ScDPTableDataCache* ScImportSourceDesc::CreateCache( ScDocument* pDoc , long nID  ) const
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     if ( !pDoc )
101cdf0e10cSrcweir 		return NULL;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     sal_Int32 nSdbType = -1;
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     switch ( nType )
106cdf0e10cSrcweir     {
107cdf0e10cSrcweir     case sheet::DataImportMode_SQL:        nSdbType = sdb::CommandType::COMMAND;  break;
108cdf0e10cSrcweir     case sheet::DataImportMode_TABLE:   nSdbType = sdb::CommandType::TABLE;      break;
109cdf0e10cSrcweir     case sheet::DataImportMode_QUERY:  nSdbType = sdb::CommandType::QUERY;     break;
110cdf0e10cSrcweir     default:
111cdf0e10cSrcweir         return NULL;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 
115cdf0e10cSrcweir    ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc );
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     if ( pCache && ( nID < 0 || nID == pCache->GetId() ) )
118cdf0e10cSrcweir         return pCache;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     if ( pCache == NULL )
121cdf0e10cSrcweir 		pCache = new ScDPTableDataCache( pDoc );
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     uno::Reference<sdbc::XRowSet> xRowSet ;
124cdf0e10cSrcweir     try
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         xRowSet = uno::Reference<sdbc::XRowSet>(
127cdf0e10cSrcweir             comphelper::getProcessServiceFactory()->createInstance(
128cdf0e10cSrcweir             rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
129cdf0e10cSrcweir             uno::UNO_QUERY);
130cdf0e10cSrcweir         uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY );
131cdf0e10cSrcweir         DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
132cdf0e10cSrcweir         if ( xRowProp.is() )
133cdf0e10cSrcweir         {
134cdf0e10cSrcweir             //
135cdf0e10cSrcweir             //  set source parameters
136cdf0e10cSrcweir             //
137cdf0e10cSrcweir             uno::Any aAny;
138cdf0e10cSrcweir             aAny <<= rtl::OUString( aDBName );
139cdf0e10cSrcweir             xRowProp->setPropertyValue(
140cdf0e10cSrcweir                 rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
141cdf0e10cSrcweir 
142cdf0e10cSrcweir             aAny <<= rtl::OUString( aObject );
143cdf0e10cSrcweir             xRowProp->setPropertyValue(
144cdf0e10cSrcweir                 rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
145cdf0e10cSrcweir 
146cdf0e10cSrcweir             aAny <<= nSdbType;
147cdf0e10cSrcweir             xRowProp->setPropertyValue(
148cdf0e10cSrcweir                 rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
149cdf0e10cSrcweir 
150cdf0e10cSrcweir             uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY );
151cdf0e10cSrcweir             if ( xExecute.is() )
152cdf0e10cSrcweir             {
153cdf0e10cSrcweir                 uno::Reference<task::XInteractionHandler> xHandler(
154cdf0e10cSrcweir                     comphelper::getProcessServiceFactory()->createInstance(
155cdf0e10cSrcweir                     rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
156cdf0e10cSrcweir                     uno::UNO_QUERY);
157cdf0e10cSrcweir                 xExecute->executeWithCompletion( xHandler );
158cdf0e10cSrcweir             }
159cdf0e10cSrcweir             else
160cdf0e10cSrcweir                 xRowSet->execute();
161cdf0e10cSrcweir             SvNumberFormatter aFormat( pDoc->GetServiceManager(), ScGlobal::eLnge);
162cdf0e10cSrcweir             pCache->InitFromDataBase( xRowSet, *aFormat.GetNullDate() );
163cdf0e10cSrcweir             pCache->SetId( nID );
164cdf0e10cSrcweir             pDoc->AddDPObjectCache( pCache );
165cdf0e10cSrcweir             DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() );
166cdf0e10cSrcweir         }
167cdf0e10cSrcweir     }
168cdf0e10cSrcweir     catch ( sdbc::SQLException& rError )
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         //! store error message
171cdf0e10cSrcweir         delete pCache;
172cdf0e10cSrcweir         pCache = NULL;
173cdf0e10cSrcweir         InfoBox aInfoBox( 0, String(rError.Message) );
174cdf0e10cSrcweir         aInfoBox.Execute();
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     catch ( uno::Exception& )
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         delete pCache;
179cdf0e10cSrcweir         pCache = NULL;
180cdf0e10cSrcweir         DBG_ERROR("Unexpected exception in database");
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     ::comphelper::disposeComponent( xRowSet );
185cdf0e10cSrcweir      return pCache;
186cdf0e10cSrcweir }
187cdf0e10cSrcweir 
GetCache(ScDocument * pDoc,long nID) const188cdf0e10cSrcweir ScDPTableDataCache* ScImportSourceDesc::GetCache( ScDocument* pDoc, long nID ) const
189cdf0e10cSrcweir {
190cdf0e10cSrcweir     ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID );
191cdf0e10cSrcweir     if ( NULL == pCache && pDoc )
192cdf0e10cSrcweir         pCache = GetExistDPObjectCache( pDoc);
193cdf0e10cSrcweir     if ( NULL == pCache )
194cdf0e10cSrcweir         pCache = CreateCache( pDoc , nID );
195cdf0e10cSrcweir     return pCache;
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
GetCacheId(ScDocument * pDoc,long nID) const198cdf0e10cSrcweir long ScImportSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	ScDPTableDataCache* pCache = GetCache( pDoc,  nID);
201cdf0e10cSrcweir 	if ( NULL == pCache )
202cdf0e10cSrcweir 		return -1;
203cdf0e10cSrcweir 	else
204cdf0e10cSrcweir 		return pCache->GetId();
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir // -----------------------------------------------------------------------
208cdf0e10cSrcweir 
ScDatabaseDPData(ScDocument * pDoc,const ScImportSourceDesc & rImport,long nCacheId)209cdf0e10cSrcweir ScDatabaseDPData::ScDatabaseDPData(
210cdf0e10cSrcweir     ScDocument* pDoc,
211cdf0e10cSrcweir     const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) :
212cdf0e10cSrcweir     ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ),
213cdf0e10cSrcweir     aCacheTable( pDoc, GetCacheId() )     // base class ID is initialized with the GetCacheId call above
214cdf0e10cSrcweir {
215cdf0e10cSrcweir 
216cdf0e10cSrcweir }
217cdf0e10cSrcweir 
~ScDatabaseDPData()218cdf0e10cSrcweir ScDatabaseDPData::~ScDatabaseDPData()
219cdf0e10cSrcweir {
220cdf0e10cSrcweir }
221cdf0e10cSrcweir 
DisposeData()222cdf0e10cSrcweir void ScDatabaseDPData::DisposeData()
223cdf0e10cSrcweir {
224cdf0e10cSrcweir 	//!	use OpenDatabase here?
225cdf0e10cSrcweir      aCacheTable.clear();
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
GetColumnCount()228cdf0e10cSrcweir long ScDatabaseDPData::GetColumnCount()
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     CreateCacheTable();
231cdf0e10cSrcweir     return GetCacheTable().getColSize();
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir // End Comments
235cdf0e10cSrcweir 
getDimensionName(long nColumn)236cdf0e10cSrcweir String ScDatabaseDPData::getDimensionName(long nColumn)
237cdf0e10cSrcweir {
238cdf0e10cSrcweir 	if (getIsDataLayoutDimension(nColumn))
239cdf0e10cSrcweir 	{
240cdf0e10cSrcweir 		//!	different internal and display names?
241cdf0e10cSrcweir 		//return "Data";
242cdf0e10cSrcweir 		return ScGlobal::GetRscString(STR_PIVOT_DATA);
243cdf0e10cSrcweir 	}
244cdf0e10cSrcweir 
245cdf0e10cSrcweir     CreateCacheTable();
246cdf0e10cSrcweir 	return aCacheTable.getFieldName((SCCOL)nColumn);
247cdf0e10cSrcweir }
248cdf0e10cSrcweir 
getIsDataLayoutDimension(long nColumn)249cdf0e10cSrcweir sal_Bool ScDatabaseDPData::getIsDataLayoutDimension(long nColumn)
250cdf0e10cSrcweir {
251cdf0e10cSrcweir 	return ( nColumn == GetCacheTable().getColSize());
252cdf0e10cSrcweir }
253cdf0e10cSrcweir 
IsDateDimension(long)254cdf0e10cSrcweir sal_Bool ScDatabaseDPData::IsDateDimension(long /* nDim */)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir 	//!	later...
257cdf0e10cSrcweir 	return sal_False;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
SetEmptyFlags(sal_Bool,sal_Bool)260cdf0e10cSrcweir void ScDatabaseDPData::SetEmptyFlags( sal_Bool /* bIgnoreEmptyRows */, sal_Bool /* bRepeatIfEmpty */ )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir 	//	not used for database data
263cdf0e10cSrcweir 	//!	disable flags
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
CreateCacheTable()266cdf0e10cSrcweir void ScDatabaseDPData::CreateCacheTable()
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     if (!aCacheTable.empty())
269cdf0e10cSrcweir         return;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     aCacheTable.fillTable();
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
FilterCacheTable(const vector<ScDPCacheTable::Criterion> & rCriteria,const hash_set<sal_Int32> & rCatDims)274cdf0e10cSrcweir void ScDatabaseDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
275cdf0e10cSrcweir {
276cdf0e10cSrcweir     CreateCacheTable();
277cdf0e10cSrcweir     aCacheTable.filterByPageDimension(
278cdf0e10cSrcweir         rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
279cdf0e10cSrcweir }
280cdf0e10cSrcweir 
GetDrillDownData(const vector<ScDPCacheTable::Criterion> & rCriteria,const hash_set<sal_Int32> & rCatDims,Sequence<Sequence<Any>> & rData)281cdf0e10cSrcweir void ScDatabaseDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir     CreateCacheTable();
284cdf0e10cSrcweir     sal_Int32 nRowSize = aCacheTable.getRowSize();
285cdf0e10cSrcweir     if (!nRowSize)
286cdf0e10cSrcweir         return;
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     aCacheTable.filterTable(
289cdf0e10cSrcweir         rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
CalcResults(CalcInfo & rInfo,bool bAutoShow)292cdf0e10cSrcweir void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
293cdf0e10cSrcweir {
294cdf0e10cSrcweir     CreateCacheTable();
295cdf0e10cSrcweir     CalcResultsFromCacheTable( aCacheTable, rInfo, bAutoShow);
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
GetCacheTable() const298cdf0e10cSrcweir const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const
299cdf0e10cSrcweir {
300cdf0e10cSrcweir     return aCacheTable;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir // -----------------------------------------------------------------------
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 
309