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