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