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 77 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 98 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 188 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 198 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 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 218 ScDatabaseDPData::~ScDatabaseDPData() 219 { 220 } 221 222 void ScDatabaseDPData::DisposeData() 223 { 224 //! use OpenDatabase here? 225 aCacheTable.clear(); 226 } 227 228 long ScDatabaseDPData::GetColumnCount() 229 { 230 CreateCacheTable(); 231 return GetCacheTable().getColSize(); 232 } 233 234 // End Comments 235 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 249 sal_Bool ScDatabaseDPData::getIsDataLayoutDimension(long nColumn) 250 { 251 return ( nColumn == GetCacheTable().getColSize()); 252 } 253 254 sal_Bool ScDatabaseDPData::IsDateDimension(long /* nDim */) 255 { 256 //! later... 257 return sal_False; 258 } 259 260 void ScDatabaseDPData::SetEmptyFlags( sal_Bool /* bIgnoreEmptyRows */, sal_Bool /* bRepeatIfEmpty */ ) 261 { 262 // not used for database data 263 //! disable flags 264 } 265 266 void ScDatabaseDPData::CreateCacheTable() 267 { 268 if (!aCacheTable.empty()) 269 return; 270 271 aCacheTable.fillTable(); 272 } 273 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 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 292 void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow) 293 { 294 CreateCacheTable(); 295 CalcResultsFromCacheTable( aCacheTable, rInfo, bAutoShow); 296 } 297 298 const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const 299 { 300 return aCacheTable; 301 } 302 303 // ----------------------------------------------------------------------- 304 305 306 307 308 309