summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/dpobject.hxx8
-rw-r--r--sc/qa/unit/ucalc.cxx15
-rw-r--r--sc/source/core/data/dpobject.cxx70
-rw-r--r--sc/source/core/data/dptablecache.cxx3
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