summaryrefslogtreecommitdiff
path: root/sc/source/core/data/dpsdbtab.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/dpsdbtab.cxx')
-rw-r--r--sc/source/core/data/dpsdbtab.cxx321
1 files changed, 321 insertions, 0 deletions
diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx
new file mode 100644
index 000000000000..01f63f0cbaa9
--- /dev/null
+++ b/sc/source/core/data/dpsdbtab.cxx
@@ -0,0 +1,321 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: dpsdbtab.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE --------------------------------------------------------------
+
+#include <tools/debug.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/zforlist.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/types.hxx>
+
+#include <com/sun/star/sheet/DataImportMode.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/XCompletedExecution.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbc/XRowSet.hpp>
+#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include "dpsdbtab.hxx"
+#include "collect.hxx"
+#include "global.hxx"
+#include "globstr.hrc"
+#include "dpcachetable.hxx"
+#include "dptabres.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+
+using namespace com::sun::star;
+
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::UNO_QUERY;
+
+#define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet"
+#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler"
+
+//! move to a header file?
+#define SC_DBPROP_DATASOURCENAME "DataSourceName"
+#define SC_DBPROP_COMMAND "Command"
+#define SC_DBPROP_COMMANDTYPE "CommandType"
+
+// -----------------------------------------------------------------------
+
+class ScDatabaseDPData_Impl
+{
+public:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager;
+ ScImportSourceDesc aDesc;
+ long nColCount;
+ uno::Reference<sdbc::XRowSet> xRowSet;
+ sal_Int32* pTypes;
+ SvNumberFormatter* pFormatter;
+
+ ScDPCacheTable aCacheTable;
+
+ ScDatabaseDPData_Impl(ScDPCollection* p) :
+ aCacheTable(p)
+ {
+ }
+};
+
+// -----------------------------------------------------------------------
+
+ScDatabaseDPData::ScDatabaseDPData(
+ ScDocument* pDoc,
+ const ScImportSourceDesc& rImport ) :
+ ScDPTableData(pDoc)
+{
+ pImpl = new ScDatabaseDPData_Impl(pDoc->GetDPCollection());
+ pImpl->xServiceManager = pDoc->GetServiceManager();
+ pImpl->aDesc = rImport;
+ pImpl->nColCount = 0;
+ pImpl->pTypes = NULL;
+ pImpl->pFormatter = NULL; // created on demand
+
+ OpenDatabase();
+ CreateCacheTable();
+}
+
+ScDatabaseDPData::~ScDatabaseDPData()
+{
+ ::comphelper::disposeComponent( pImpl->xRowSet );
+
+ delete[] pImpl->pTypes;
+ delete pImpl->pFormatter; // NumberFormatter is local for this object
+ delete pImpl;
+}
+
+void ScDatabaseDPData::DisposeData()
+{
+ //! use OpenDatabase here?
+ pImpl->aCacheTable.clear();
+}
+
+BOOL ScDatabaseDPData::OpenDatabase()
+{
+ sal_Int32 nSdbType = -1;
+ switch ( pImpl->aDesc.nType )
+ {
+ case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break;
+ case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break;
+ case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break;
+ default:
+ return FALSE;
+ }
+
+ BOOL bSuccess = FALSE;
+ try
+ {
+ pImpl->xRowSet = uno::Reference<sdbc::XRowSet>(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xRowProp( pImpl->xRowSet, uno::UNO_QUERY );
+ DBG_ASSERT( xRowProp.is(), "can't get RowSet" );
+ if ( xRowProp.is() )
+ {
+ //
+ // set source parameters
+ //
+
+ uno::Any aAny;
+
+ aAny <<= rtl::OUString( pImpl->aDesc.aDBName );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny );
+
+ aAny <<= rtl::OUString( pImpl->aDesc.aObject );
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny );
+
+ aAny <<= nSdbType;
+ xRowProp->setPropertyValue(
+ rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny );
+
+ uno::Reference<sdb::XCompletedExecution> xExecute( pImpl->xRowSet, uno::UNO_QUERY );
+ if ( xExecute.is() )
+ {
+ uno::Reference<task::XInteractionHandler> xHandler(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ),
+ uno::UNO_QUERY);
+ xExecute->executeWithCompletion( xHandler );
+ }
+ else
+ pImpl->xRowSet->execute();
+
+ //
+ // get column descriptions
+ //
+
+ pImpl->nColCount = 0;
+ uno::Reference<sdbc::XResultSetMetaData> xMeta;
+ uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( pImpl->xRowSet, uno::UNO_QUERY );
+ if ( xMetaSupp.is() )
+ xMeta = xMetaSupp->getMetaData();
+ if ( xMeta.is() )
+ pImpl->nColCount = xMeta->getColumnCount(); // this is the number of real columns
+
+ uno::Reference<sdbc::XResultSet> xResSet( pImpl->xRowSet, uno::UNO_QUERY );
+ if ( pImpl->nColCount > 0 && xResSet.is() )
+ {
+ pImpl->pTypes = new sal_Int32[pImpl->nColCount];
+ for (long nCol=0; nCol<pImpl->nColCount; nCol++)
+ pImpl->pTypes[nCol] = xMeta->getColumnType( nCol+1 );
+
+ bSuccess = TRUE;
+ }
+ }
+ }
+ catch ( sdbc::SQLException& rError )
+ {
+ //! store error message
+ InfoBox aInfoBox( 0, String(rError.Message) );
+ aInfoBox.Execute();
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR("Unexpected exception in database");
+ }
+
+
+ if (!bSuccess)
+ ::comphelper::disposeComponent( pImpl->xRowSet );
+
+ return bSuccess;
+}
+
+long ScDatabaseDPData::GetColumnCount()
+{
+ return pImpl->nColCount;
+}
+
+const TypedScStrCollection& ScDatabaseDPData::GetColumnEntries(long nColumn)
+{
+ CreateCacheTable();
+ return pImpl->aCacheTable.getFieldEntries(nColumn);
+}
+
+String ScDatabaseDPData::getDimensionName(long nColumn)
+{
+ if (getIsDataLayoutDimension(nColumn))
+ {
+ //! different internal and display names?
+ //return "Data";
+ return ScGlobal::GetRscString(STR_PIVOT_DATA);
+ }
+
+ CreateCacheTable();
+ const String* pStr = pImpl->aCacheTable.getFieldName(nColumn);
+ if (pStr)
+ return *pStr;
+
+ DBG_ERROR("getDimensionName: invalid dimension");
+ return String();
+}
+
+BOOL ScDatabaseDPData::getIsDataLayoutDimension(long nColumn)
+{
+ return ( nColumn == pImpl->nColCount );
+}
+
+BOOL ScDatabaseDPData::IsDateDimension(long /* nDim */)
+{
+ //! later...
+ return FALSE;
+}
+
+void ScDatabaseDPData::SetEmptyFlags( BOOL /* bIgnoreEmptyRows */, BOOL /* bRepeatIfEmpty */ )
+{
+ // not used for database data
+ //! disable flags
+}
+
+void ScDatabaseDPData::CreateCacheTable()
+{
+ if (!pImpl->aCacheTable.empty())
+ return;
+
+ // Get null date.
+ if (!pImpl->pFormatter)
+ pImpl->pFormatter = new SvNumberFormatter(pImpl->xServiceManager, ScGlobal::eLnge);
+
+ pImpl->aCacheTable.fillTable(pImpl->xRowSet, *pImpl->pFormatter->GetNullDate());
+}
+
+void ScDatabaseDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims)
+{
+ CreateCacheTable();
+ pImpl->aCacheTable.filterByPageDimension(
+ rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()));
+}
+
+void ScDatabaseDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData)
+{
+ CreateCacheTable();
+ sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize();
+ if (!nRowSize)
+ return;
+
+ pImpl->aCacheTable.filterTable(
+ rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>());
+}
+
+void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
+{
+ CreateCacheTable();
+ CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow);
+}
+
+const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const
+{
+ return pImpl->aCacheTable;
+}
+
+// -----------------------------------------------------------------------
+
+
+
+
+