diff options
-rw-r--r-- | sc/inc/dpobject.hxx | 11 | ||||
-rw-r--r-- | sc/inc/dptablecache.hxx | 3 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 182 | ||||
-rw-r--r-- | sc/source/core/data/dptablecache.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/unoobj/dapiuno.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/dbfunc3.cxx | 11 |
7 files changed, 172 insertions, 53 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 769e0ac234e4..5010e69c1b26 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -37,6 +37,8 @@ #include "pivot.hxx" #include <com/sun/star/sheet/XDimensionsSupplier.hpp> +#include <set> + #include <boost/ptr_container/ptr_list.hpp> #include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_map.hpp> @@ -273,6 +275,7 @@ public: UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz); private: + void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs); void removeCache(const ScRange& rRange); }; @@ -290,6 +293,7 @@ public: bool hasCache(const rtl::OUString& rName) const; const ScDPCache* getCache(const ::rtl::OUString& rName, const ScRange& rRange); private: + void updateCache(const rtl::OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs); void removeCache(const ::rtl::OUString& rName); }; @@ -323,6 +327,11 @@ public: DBCaches(ScDocument* pDoc); const ScDPCache* getCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand); private: + com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet( + sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand); + + void updateCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand, + std::set<ScDPObject*>& rRefs); void removeCache(sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand); }; @@ -330,7 +339,7 @@ public: ScDPCollection(const ScDPCollection& r); ~ScDPCollection(); - sal_uLong ClearCache(ScDPObject* pDPObj); + sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); SC_DLLPUBLIC size_t GetCount() const; SC_DLLPUBLIC ScDPObject* operator[](size_t nIndex); diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx index a67103d0f788..882f42293064 100644 --- a/sc/inc/dptablecache.hxx +++ b/sc/inc/dptablecache.hxx @@ -50,10 +50,10 @@ class SC_DLLPUBLIC ScDPCache { public: typedef ::boost::ptr_vector<ScDPItemData> DataListType; + typedef std::set<ScDPObject*> ObjectSetType; private: typedef ::boost::ptr_vector<DataListType> DataGridType; typedef ::boost::ptr_vector< ::std::vector<SCROW> > RowGridType; - typedef std::set<ScDPObject*> ObjectSetType; ScDocument* mpDoc; long mnColumnCount; @@ -96,6 +96,7 @@ private: public: void AddReference(ScDPObject* pObj) const; void RemoveReference(ScDPObject* pObj) const; + const ObjectSetType& GetAllReferences() const; SCROW GetIdByItemData( long nDim, const String& sItemData ) const; SCROW GetIdByItemData( long nDim, const ScDPItemData& rData ) const; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 419ce6307ed7..0a08c8f6f914 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1363,7 +1363,8 @@ void Test::testDataPilot() // This time clear the cache to refresh the data from the source range. CPPUNIT_ASSERT_MESSAGE("This datapilot should be based on sheet data.", pDPObj2->IsSheetData()); - sal_uLong nErrId = pDPs->ClearCache(pDPObj2); + std::set<ScDPObject*> aRefs; + sal_uLong nErrId = pDPs->ReloadCache(pDPObj2, aRefs); CPPUNIT_ASSERT_MESSAGE("Cache removal failed.", nErrId == 0); pDPObj2->ClearSource(); pDPObj2->Output(aOutRange.aStart); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 3999d55c6d91..3332ec99f423 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -2568,6 +2568,31 @@ void ScDPCollection::SheetCaches::updateReference( } } +void ScDPCollection::SheetCaches::updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs) +{ + RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange); + if (it == maRanges.end()) + { + // Not cached. Nothing to do. + rRefs.clear(); + return; + } + + size_t nIndex = std::distance(maRanges.begin(), it); + CachesType::iterator itCache = maCaches.find(nIndex); + if (itCache == maCaches.end()) + { + // Cache pool and index pool out-of-sync !!! + rRefs.clear(); + return; + } + + ScDPCache& rCache = *itCache->second; + rCache.InitFromDoc(mpDoc, rRange); + std::set<ScDPObject*> aRefs(rCache.GetAllReferences()); + rRefs.swap(aRefs); +} + void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange) { RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange); @@ -2608,6 +2633,21 @@ const ScDPCache* ScDPCollection::NameCaches::getCache(const OUString& rName, con return p; } +void ScDPCollection::NameCaches::updateCache(const OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs) +{ + CachesType::iterator itr = maCaches.find(rName); + if (itr == maCaches.end()) + { + rRefs.clear(); + return; + } + + ScDPCache& rCache = *itr->second; + rCache.InitFromDoc(mpDoc, rRange); + std::set<ScDPObject*> aRefs(rCache.GetAllReferences()); + rRefs.swap(aRefs); +} + void ScDPCollection::NameCaches::removeCache(const OUString& rName) { CachesType::iterator itr = maCaches.find(rName); @@ -2633,68 +2673,117 @@ const ScDPCache* ScDPCollection::DBCaches::getCache(sal_Int32 nSdbType, const OU // already cached. return itr->second; - uno::Reference<sdbc::XRowSet> xRowSet ; + uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand); + if (!xRowSet.is()) + return NULL; + + SAL_WNODEPRECATED_DECLARATIONS_PUSH + ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc)); + SAL_WNODEPRECATED_DECLARATIONS_POP + SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge); + pCache->InitFromDataBase(xRowSet, *aFormat.GetNullDate()); + ::comphelper::disposeComponent(xRowSet); + const ScDPCache* p = pCache.get(); + maCaches.insert(aType, pCache); + return p; +} + +uno::Reference<sdbc::XRowSet> ScDPCollection::DBCaches::createRowSet( + sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand) +{ + uno::Reference<sdbc::XRowSet> xRowSet; try { xRowSet = uno::Reference<sdbc::XRowSet>( comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_ROWSET )) ), - uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SERVICE_ROWSET))), + UNO_QUERY); + + uno::Reference<beans::XPropertySet> xRowProp(xRowSet, UNO_QUERY); OSL_ENSURE( xRowProp.is(), "can't get RowSet" ); - if ( xRowProp.is() ) + if (!xRowProp.is()) { - // - // set source parameters - // - uno::Any aAny; - aAny <<= rDBName; - xRowProp->setPropertyValue( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_DATASOURCENAME)), aAny ); - - aAny <<= rCommand; - xRowProp->setPropertyValue( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMAND)), aAny ); - - aAny <<= nSdbType; - xRowProp->setPropertyValue( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMANDTYPE)), aAny ); - - uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY ); - if ( xExecute.is() ) - { - uno::Reference<task::XInteractionHandler> xHandler( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_INTHANDLER )) ), - uno::UNO_QUERY); - xExecute->executeWithCompletion( xHandler ); - } - else - xRowSet->execute(); + xRowSet.set(NULL); + return xRowSet; + } + + // + // set source parameters + // + uno::Any aAny; + aAny <<= rDBName; + xRowProp->setPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_DATASOURCENAME)), aAny ); + + aAny <<= rCommand; + xRowProp->setPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMAND)), aAny ); + + aAny <<= nSdbType; + xRowProp->setPropertyValue( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_DBPROP_COMMANDTYPE)), aAny ); + + uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY ); + if ( xExecute.is() ) + { + uno::Reference<task::XInteractionHandler> xHandler( + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_SERVICE_INTHANDLER )) ), + uno::UNO_QUERY); + xExecute->executeWithCompletion( xHandler ); } + else + xRowSet->execute(); + + return xRowSet; } catch ( const sdbc::SQLException& rError ) { //! store error message InfoBox aInfoBox( 0, String(rError.Message) ); aInfoBox.Execute(); - return NULL; } catch ( uno::Exception& ) { OSL_FAIL("Unexpected exception in database"); - return NULL; } - SAL_WNODEPRECATED_DECLARATIONS_PUSH - ::std::auto_ptr<ScDPCache> pCache(new ScDPCache(mpDoc)); - SAL_WNODEPRECATED_DECLARATIONS_POP + xRowSet.set(NULL); + return xRowSet; +} + +void ScDPCollection::DBCaches::updateCache( + sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand, std::set<ScDPObject*>& rRefs) +{ + DBType aType(nSdbType, rDBName, rCommand); + CachesType::iterator it = maCaches.find(aType); + if (it == maCaches.end()) + { + // not cached. + rRefs.clear(); + return; + } + + ScDPCache& rCache = *it->second; + + uno::Reference<sdbc::XRowSet> xRowSet = createRowSet(nSdbType, rDBName, rCommand); + if (!xRowSet.is()) + { + rRefs.clear(); + return; + } + SvNumberFormatter aFormat(mpDoc->GetServiceManager(), ScGlobal::eLnge); - pCache->InitFromDataBase(xRowSet, *aFormat.GetNullDate()); - ::comphelper::disposeComponent(xRowSet); - const ScDPCache* p = pCache.get(); - maCaches.insert(aType, pCache); - return p; + if (!rCache.InitFromDataBase(xRowSet, *aFormat.GetNullDate())) + { + // initialization failed. + rRefs.clear(); + return; + } + + comphelper::disposeComponent(xRowSet); + std::set<ScDPObject*> aRefs(rCache.GetAllReferences()); + aRefs.swap(rRefs); } void ScDPCollection::DBCaches::removeCache(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) @@ -2745,7 +2834,7 @@ public: } -sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj) +sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs) { if (pDPObj->IsSheetData()) { @@ -2762,13 +2851,13 @@ sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj) { // cache by named range ScDPCollection::NameCaches& rCaches = GetNameCaches(); - rCaches.removeCache(pDesc->GetRangeName()); + rCaches.updateCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), rRefs); } else { // cache by cell range ScDPCollection::SheetCaches& rCaches = GetSheetCaches(); - rCaches.removeCache(pDesc->GetSourceRange()); + rCaches.updateCache(pDesc->GetSourceRange(), rRefs); } } else if (pDPObj->IsImportData()) @@ -2779,7 +2868,8 @@ sal_uLong ScDPCollection::ClearCache(ScDPObject* pDPObj) return STR_ERR_DATAPILOTSOURCE; ScDPCollection::DBCaches& rCaches = GetDBCaches(); - rCaches.removeCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject); + rCaches.updateCache( + pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs); } return 0; } diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index 683a8750387a..4ce51952d578 100644 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -995,6 +995,11 @@ void ScDPCache::RemoveReference(ScDPObject* pObj) const maRefObjects.erase(pObj); } +const ScDPCache::ObjectSetType& ScDPCache::GetAllReferences() const +{ + return maRefObjects; +} + SCROW ScDPCache::GetIdByItemData(long nDim, const String& sItemData ) const { if ( nDim < mnColumnCount && nDim >=0 ) diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index 5a5bed38bed8..e67f1abceecb 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1276,8 +1276,14 @@ void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) if (pDPObj) { ScDBDocFunc aFunc(*GetDocShell()); - GetDocShell()->GetDocument()->GetDPCollection()->ClearCache(pDPObj); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, true ); + std::set<ScDPObject*> aRefs; + GetDocShell()->GetDocument()->GetDPCollection()->ReloadCache(pDPObj, aRefs); + std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); + for (; it != itEnd; ++it) + { + ScDPObject* pObj = *it; + aFunc.DataPilotUpdate(pObj, pObj, true, true); + } } } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 0d4de9452e61..b71774299816 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -707,7 +707,8 @@ void ScDBFunc::RecalcPivotTable() { // Remove existing data cache for the data that this datapilot uses, // to force re-build data cache. - sal_uLong nErrId = pDPs->ClearCache(pDPObj); + std::set<ScDPObject*> aRefs; + sal_uLong nErrId = pDPs->ReloadCache(pDPObj, aRefs); if (nErrId) { ErrorMessage(nErrId); @@ -715,7 +716,13 @@ void ScDBFunc::RecalcPivotTable() } ScDBDocFunc aFunc( *pDocSh ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false ); + std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); + for (; it != itEnd; ++it) + { + ScDPObject* pObj = *it; + aFunc.DataPilotUpdate(pObj, pObj, true, false); + } + CursorPosChanged(); // shells may be switched } else |