diff options
-rw-r--r-- | sc/inc/dpobject.hxx | 8 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 70 | ||||
-rw-r--r-- | sc/source/core/data/dptablecache.cxx | 3 |
4 files changed, 83 insertions, 13 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5010e69c1b26..685f7d2947b7 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -253,6 +253,7 @@ public: class ScDPCollection { + friend class ScDPCache; public: /** @@ -277,6 +278,7 @@ public: private: void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs); void removeCache(const ScRange& rRange); + bool remove(const ScDPCache* p); }; /** @@ -295,6 +297,7 @@ public: private: void updateCache(const rtl::OUString& rName, const ScRange& rRange, std::set<ScDPObject*>& rRefs); void removeCache(const ::rtl::OUString& rName); + bool remove(const ScDPCache* p); }; /** @@ -333,6 +336,7 @@ public: 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); + bool remove(const ScDPCache* p); }; ScDPCollection(ScDocument* pDocument); @@ -375,6 +379,10 @@ public: DBCaches& GetDBCaches(); private: + /** Only to be called from ScDPCache::RemoveReference(). */ + void RemoveCache(const ScDPCache* pCache); + +private: typedef ::boost::ptr_vector<ScDPObject> TablesType; ScDocument* pDoc; diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index a10cee99598d..88abad3a7bf0 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1125,6 +1125,7 @@ ScRange insertDPSourceData(ScDocument* pDoc, DPFieldDef aFields[], size_t nField template<size_t _Size> bool checkDPTableOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* aOutputCheck[][_Size], const char* pCaption) { + bool bResult = true; const ScAddress& s = aOutRange.aStart; const ScAddress& e = aOutRange.aEnd; SheetPrinter printer(e.Row() - s.Row() + 1, e.Col() - s.Col() + 1); @@ -1145,18 +1146,18 @@ bool checkDPTableOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* if (!bEqual) { cerr << "Expected: " << aCheckVal << " Actual: " << aVal << endl; - return false; + bResult = false; } } else if (!aVal.isEmpty()) { cerr << "Empty cell expected" << endl; - return false; + bResult = false; } } } printer.print(pCaption); - return true; + return bResult; } ScDPObject* createDPFromSourceDesc( @@ -1334,10 +1335,9 @@ void Test::testDataPilot() printRange(m_pDoc, ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0), "Data sheet content (modified)"); // Now, create a copy of the datapilot object for the updated table, but - // don't clear the cache which should force the copy to use the old data + // don't reload the cache which should force the copy to use the old data // from the cache. ScDPObject* pDPObj2 = new ScDPObject(*pDPObj); - pDPs->FreeTable(pDPObj); pDPs->InsertNewTable(pDPObj2); aOutRange = pDPObj2->GetOutRange(); @@ -1361,6 +1361,10 @@ void Test::testDataPilot() CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess); } + // Free the first datapilot object after the 2nd one gets reloaded, to + // prevent the data cache from being deleted before the reload. + pDPs->FreeTable(pDPObj); + // 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()); std::set<ScDPObject*> aRefs; @@ -1396,7 +1400,6 @@ void Test::testDataPilot() aSrcRange.aEnd.SetTab(1); CPPUNIT_ASSERT_MESSAGE("Cache should be here.", pDPs->GetSheetCaches().hasCache(aSrcRange)); - pDPs->FreeTable(pDPObj2); CPPUNIT_ASSERT_MESSAGE("There shouldn't be any data pilot table stored with the document.", pDPs->GetCount() == 0); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 3332ec99f423..bc26c48d61f1 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -774,11 +774,8 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); if ( eRes != UR_NOTHING ) { - ScSheetSourceDesc aNewDesc(pDoc); - aNewDesc.SetSourceRange(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2)); - - SCsCOL nDiffX = nCol1 - (SCsCOL) pSheetDesc->GetSourceRange().aStart.Col(); - SCsROW nDiffY = nRow1 - (SCsROW) pSheetDesc->GetSourceRange().aStart.Row(); + SCsCOL nDiffX = nCol1 - pSheetDesc->GetSourceRange().aStart.Col(); + SCsROW nDiffY = nRow1 - pSheetDesc->GetSourceRange().aStart.Row(); ScQueryParam aParam = pSheetDesc->GetQueryParam(); aParam.nCol1 = sal::static_int_cast<SCCOL>( aParam.nCol1 + nDiffX ); @@ -790,8 +787,8 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, if (aParam.GetEntry(i).bDoQuery) aParam.GetEntry(i).nField += nDiffX; - aNewDesc.SetQueryParam(aParam); - SetSheetDesc( aNewDesc ); // allocates new pSheetDesc + pSheetDesc->SetQueryParam(aParam); + pSheetDesc->SetSourceRange(ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2)); } } } @@ -2610,6 +2607,22 @@ void ScDPCollection::SheetCaches::removeCache(const ScRange& rRange) maCaches.erase(itCache); } +bool ScDPCollection::SheetCaches::remove(const ScDPCache* p) +{ + CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end(); + for (; it != itEnd; ++it) + { + if (it->second == p) + { + size_t idx = it->first; + maCaches.erase(it); + maRanges[idx].SetInvalid(); + return true; + } + } + return false; +} + ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {} bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const @@ -2655,6 +2668,20 @@ void ScDPCollection::NameCaches::removeCache(const OUString& rName) maCaches.erase(itr); } +bool ScDPCollection::NameCaches::remove(const ScDPCache* p) +{ + CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end(); + for (; it != itEnd; ++it) + { + if (it->second == p) + { + maCaches.erase(it); + return true; + } + } + return false; +} + ScDPCollection::DBType::DBType(sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) : mnSdbType(nSdbType), maDBName(rDBName), maCommand(rCommand) {} @@ -2794,6 +2821,20 @@ void ScDPCollection::DBCaches::removeCache(sal_Int32 nSdbType, const OUString& r maCaches.erase(itr); } +bool ScDPCollection::DBCaches::remove(const ScDPCache* p) +{ + CachesType::iterator it = maCaches.begin(), itEnd = maCaches.end(); + for (; it != itEnd; ++it) + { + if (it->second == p) + { + maCaches.erase(it); + return true; + } + } + return false; +} + ScDPCollection::ScDPCollection(ScDocument* pDocument) : pDoc( pDocument ), maSheetCaches(pDocument), @@ -3080,6 +3121,21 @@ ScDPCollection::DBCaches& ScDPCollection::GetDBCaches() return maDBCaches; } +void ScDPCollection::RemoveCache(const ScDPCache* pCache) +{ + if (maSheetCaches.remove(pCache)) + // sheet cache removed. + return; + + if (maNameCaches.remove(pCache)) + // named range cache removed. + return; + + if (maDBCaches.remove(pCache)) + // database cache removed. + return; +} + bool operator<(const ScDPCollection::DBType& left, const ScDPCollection::DBType& right) { if (left.mnSdbType != right.mnSdbType) diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index 4ce51952d578..57f6ce18cda1 100644 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -37,6 +37,7 @@ #include "queryparam.hxx" #include "dpglobal.hxx" #include "dptabdat.hxx" +#include "dpobject.hxx" #include "docoptio.hxx" #include <unotools/textsearch.hxx> @@ -993,6 +994,8 @@ void ScDPCache::AddReference(ScDPObject* pObj) const void ScDPCache::RemoveReference(ScDPObject* pObj) const { maRefObjects.erase(pObj); + if (maRefObjects.empty()) + mpDoc->GetDPCollection()->RemoveCache(this); } const ScDPCache::ObjectSetType& ScDPCache::GetAllReferences() const |