summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/dpobject.hxx11
-rw-r--r--sc/inc/dptablecache.hxx3
-rw-r--r--sc/qa/unit/ucalc.cxx3
-rw-r--r--sc/source/core/data/dpobject.cxx182
-rw-r--r--sc/source/core/data/dptablecache.cxx5
-rw-r--r--sc/source/ui/unoobj/dapiuno.cxx10
-rw-r--r--sc/source/ui/view/dbfunc3.cxx11
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