diff options
Diffstat (limited to 'connectivity/source/drivers/calc')
-rw-r--r-- | connectivity/source/drivers/calc/CCatalog.cxx | 80 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CColumns.cxx | 55 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CConnection.cxx | 295 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CDatabaseMetaData.cxx | 490 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CDriver.cxx | 105 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CPreparedStatement.cxx | 43 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CResultSet.cxx | 191 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CStatement.cxx | 43 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CTable.cxx | 871 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CTables.cxx | 62 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/CalcDriver.xml | 32 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/Cservices.cxx | 175 | ||||
-rwxr-xr-x | connectivity/source/drivers/calc/calc.xcu | 63 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/exports.dxp | 3 | ||||
-rw-r--r-- | connectivity/source/drivers/calc/makefile.mk | 96 |
15 files changed, 2604 insertions, 0 deletions
diff --git a/connectivity/source/drivers/calc/CCatalog.cxx b/connectivity/source/drivers/calc/CCatalog.cxx new file mode 100644 index 000000000000..449e720f18c4 --- /dev/null +++ b/connectivity/source/drivers/calc/CCatalog.cxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" + + +#include "calc/CCatalog.hxx" +#include "calc/CConnection.hxx" +#include "calc/CTables.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <rtl/logfile.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; + +// ------------------------------------------------------------------------- +using namespace connectivity::calc; +// ------------------------------------------------------------------------- +OCalcCatalog::OCalcCatalog(OCalcConnection* _pCon) : file::OFileCatalog(_pCon) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcCatalog::OCalcCatalog" ); +} +// ------------------------------------------------------------------------- +void OCalcCatalog::refreshTables() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcCatalog::refreshTables" ); + TStringVector aVector; + Sequence< ::rtl::OUString > aTypes; + OCalcConnection::ODocHolder aDocHodler(((OCalcConnection*)m_pConnection)); + Reference< XResultSet > xResult = m_xMetaData->getTables(Any(), + ::rtl::OUString::createFromAscii("%"),::rtl::OUString::createFromAscii("%"),aTypes); + + if(xResult.is()) + { + Reference< XRow > xRow(xResult,UNO_QUERY); + while(xResult->next()) + aVector.push_back(xRow->getString(3)); + } + if(m_pTables) + m_pTables->reFill(aVector); + else + m_pTables = new OCalcTables(m_xMetaData,*this,m_aMutex,aVector); + + // this avoids that the document will be loaded a 2nd time when one table will be accessed. + //if ( m_pTables && m_pTables->hasElements() ) + // m_pTables->getByIndex(0); +} +// ----------------------------------------------------------------------------- + + + diff --git a/connectivity/source/drivers/calc/CColumns.cxx b/connectivity/source/drivers/calc/CColumns.cxx new file mode 100644 index 000000000000..394302c2aeb8 --- /dev/null +++ b/connectivity/source/drivers/calc/CColumns.cxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CColumns.hxx" +#include "calc/CTable.hxx" +#include "connectivity/sdbcx/VColumn.hxx" + +using namespace connectivity::calc; +using namespace connectivity; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; + + +sdbcx::ObjectType OCalcColumns::createObject(const ::rtl::OUString& _rName) +{ + OCalcTable* pTable = (OCalcTable*)m_pTable; + ::vos::ORef<OSQLColumns> aCols = pTable->getTableColumns(); + + OSQLColumns::Vector::const_iterator aIter = find(aCols->get().begin(),aCols->get().end(),_rName,::comphelper::UStringMixEqual(isCaseSensitive())); + sdbcx::ObjectType xRet; + if(aIter != aCols->get().end()) + xRet = sdbcx::ObjectType(*aIter,UNO_QUERY); + return xRet; +} +// ------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/calc/CConnection.cxx b/connectivity/source/drivers/calc/CConnection.cxx new file mode 100644 index 000000000000..2d5e1a93d3ee --- /dev/null +++ b/connectivity/source/drivers/calc/CConnection.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CConnection.hxx" +#include "calc/CDatabaseMetaData.hxx" +#include "calc/CCatalog.hxx" +#ifndef _CONNECTIVITY_CALC_ODRIVER_HXX_ +#include "calc/CDriver.hxx" +#endif +#ifndef CONNECTIVITY_RESOURCE_CALC_HRC +#include "resource/calc_res.hrc" +#endif +#include "resource/sharedresources.hxx" +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <tools/urlobj.hxx> +#include "calc/CPreparedStatement.hxx" +#include "calc/CStatement.hxx" +#include <unotools/pathoptions.hxx> +#include <connectivity/dbexception.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <rtl/logfile.hxx> + +using namespace connectivity::calc; +using namespace connectivity::file; + +typedef connectivity::file::OConnection OConnection_BASE; + +//------------------------------------------------------------------------------ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::sheet; + +// -------------------------------------------------------------------------------- + +OCalcConnection::OCalcConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::OCalcConnection" ); + // m_aFilenameExtension is not used +} + +OCalcConnection::~OCalcConnection() +{ +} + +void OCalcConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) + throw(SQLException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::construct" ); + // open file + + sal_Int32 nLen = url.indexOf(':'); + nLen = url.indexOf(':',nLen+1); + ::rtl::OUString aDSN(url.copy(nLen+1)); + + m_aFileName = aDSN; + INetURLObject aURL; + aURL.SetSmartProtocol(INET_PROT_FILE); + { + SvtPathOptions aPathOptions; + m_aFileName = aPathOptions.SubstituteVariable(m_aFileName); + } + aURL.SetSmartURL(m_aFileName); + if ( aURL.GetProtocol() == INET_PROT_NOT_VALID ) + { + // don't pass invalid URL to loadComponentFromURL + throw SQLException(); + } + m_aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE); + + m_sPassword = ::rtl::OUString(); + const char* pPwd = "password"; + + const PropertyValue *pIter = info.getConstArray(); + const PropertyValue *pEnd = pIter + info.getLength(); + for(;pIter != pEnd;++pIter) + { + if(!pIter->Name.compareToAscii(pPwd)) + { + pIter->Value >>= m_sPassword; + break; + } + } // for(;pIter != pEnd;++pIter) + ODocHolder aDocHodler(this); // just to test that the doc can be loaded + acquireDoc(); +} +// ----------------------------------------------------------------------------- +Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::acquireDoc" ); + if ( m_xDoc.is() ) + { + osl_incrementInterlockedCount(&m_nDocCount); + return m_xDoc; + } + // open read-only as long as updating isn't implemented + Sequence<PropertyValue> aArgs(2); + aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden"); + aArgs[0].Value <<= (sal_Bool) sal_True; + aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly"); + aArgs[1].Value <<= (sal_Bool) sal_True; + + if ( m_sPassword.getLength() ) + { + const sal_Int32 nPos = aArgs.getLength(); + aArgs.realloc(nPos+1); + aArgs[nPos].Name = ::rtl::OUString::createFromAscii("Password"); + aArgs[nPos].Value <<= m_sPassword; + } + + Reference< XComponentLoader > xDesktop( getDriver()->getFactory()->createInstance( + ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); + if (!xDesktop.is()) + { + OSL_ASSERT("no desktop"); + throw SQLException(); + } + Reference< XComponent > xComponent; + Any aLoaderException; + try + { + xComponent = xDesktop->loadComponentFromURL( + m_aFileName, ::rtl::OUString::createFromAscii("_blank"), 0, aArgs ); + } + catch( const Exception& ) + { + aLoaderException = ::cppu::getCaughtException(); + } + + m_xDoc.set(xComponent, UNO_QUERY ); + + // if the URL is not a spreadsheet document, throw the exception here + // instead of at the first access to it + if ( !m_xDoc.is() ) + { + Any aErrorDetails; + if ( aLoaderException.hasValue() ) + { + Exception aLoaderError; + OSL_VERIFY( aLoaderException >>= aLoaderError ); + + SQLException aDetailException; + aDetailException.Message = m_aResources.getResourceStringWithSubstitution( + STR_LOAD_FILE_ERROR_MESSAGE, + "$exception_type$", aLoaderException.getValueTypeName(), + "$error_message$", aLoaderError.Message + ); + aErrorDetails <<= aDetailException; + } + + const ::rtl::OUString sError( m_aResources.getResourceStringWithSubstitution( + STR_COULD_NOT_LOAD_FILE, + "$filename$", m_aFileName + ) ); + ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); + } + osl_incrementInterlockedCount(&m_nDocCount); + return m_xDoc; +} +// ----------------------------------------------------------------------------- +void OCalcConnection::releaseDoc() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::releaseDoc" ); + if ( osl_decrementInterlockedCount(&m_nDocCount) == 0 ) + ::comphelper::disposeComponent( m_xDoc ); +} +// ----------------------------------------------------------------------------- +void OCalcConnection::disposing() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::disposing" ); + ::osl::MutexGuard aGuard(m_aMutex); + + m_nDocCount = 0; + ::comphelper::disposeComponent( m_xDoc ); + + OConnection::disposing(); +} + +// XServiceInfo +// -------------------------------------------------------------------------------- + +IMPLEMENT_SERVICE_INFO(OCalcConnection, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection") + +// -------------------------------------------------------------------------------- + +Reference< XDatabaseMetaData > SAL_CALL OCalcConnection::getMetaData( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::getMetaData" ); + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + Reference< XDatabaseMetaData > xMetaData = m_xMetaData; + if(!xMetaData.is()) + { + xMetaData = new OCalcDatabaseMetaData(this); + m_xMetaData = xMetaData; + } + + return xMetaData; +} + +//------------------------------------------------------------------------------ + +::com::sun::star::uno::Reference< XTablesSupplier > OCalcConnection::createCatalog() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createCatalog" ); + ::osl::MutexGuard aGuard( m_aMutex ); + Reference< XTablesSupplier > xTab = m_xCatalog; + if(!xTab.is()) + { + OCalcCatalog *pCat = new OCalcCatalog(this); + xTab = pCat; + m_xCatalog = xTab; + } + return xTab; +} + +// -------------------------------------------------------------------------------- + +Reference< XStatement > SAL_CALL OCalcConnection::createStatement( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createStatement" ); + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + Reference< XStatement > xReturn = new OCalcStatement(this); + m_aStatements.push_back(WeakReferenceHelper(xReturn)); + return xReturn; +} + +// -------------------------------------------------------------------------------- + +Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareStatement( const ::rtl::OUString& sql ) + throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareStatement" ); + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + + OCalcPreparedStatement* pStmt = new OCalcPreparedStatement(this); + Reference< XPreparedStatement > xHoldAlive = pStmt; + pStmt->construct(sql); + m_aStatements.push_back(WeakReferenceHelper(*pStmt)); + return pStmt; +} + +// -------------------------------------------------------------------------------- + +Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) + throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareCall" ); + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OConnection_BASE::rBHelper.bDisposed); + + ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this ); + return NULL; +} +// ----------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/calc/CDatabaseMetaData.cxx b/connectivity/source/drivers/calc/CDatabaseMetaData.cxx new file mode 100644 index 000000000000..274597ebb72c --- /dev/null +++ b/connectivity/source/drivers/calc/CDatabaseMetaData.cxx @@ -0,0 +1,490 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" + + +#include "calc/CDatabaseMetaData.hxx" +#include "calc/CConnection.hxx" +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XIndexesSupplier.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XDatabaseRanges.hpp> +#include <com/sun/star/sheet/XDatabaseRange.hpp> +#include <tools/urlobj.hxx> +#include "FDatabaseMetaDataResultSet.hxx" +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <comphelper/types.hxx> +#include <rtl/logfile.hxx> + +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::sheet; + +// ------------------------------------------------------------------------- + +OCalcDatabaseMetaData::OCalcDatabaseMetaData(OConnection* _pCon) :ODatabaseMetaData(_pCon) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::OCalcDatabaseMetaData" ); +} + +// ------------------------------------------------------------------------- + +OCalcDatabaseMetaData::~OCalcDatabaseMetaData() +{ +} + +// ------------------------------------------------------------------------- +Reference< XResultSet > OCalcDatabaseMetaData::impl_getTypeInfo_throw( ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::impl_getTypeInfo_throw" ); + ::osl::MutexGuard aGuard( m_aMutex ); + + ODatabaseMetaDataResultSet* pResult = new ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTypeInfo); + Reference< XResultSet > xRef = pResult; + + static ODatabaseMetaDataResultSet::ORows aRows; + if(aRows.empty()) + { + ODatabaseMetaDataResultSet::ORow aRow; + + aRows.reserve(6); + aRow.reserve(18); + + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(new ORowSetValueDecorator(::rtl::OUString::createFromAscii("VARCHAR"))); + aRow.push_back(new ORowSetValueDecorator(DataType::VARCHAR)); + aRow.push_back(new ORowSetValueDecorator((sal_Int32)65535)); + aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue()); + aRow.push_back(ODatabaseMetaDataResultSet::getQuoteValue()); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(ODatabaseMetaDataResultSet::get1Value()); // ORowSetValue((sal_Int32)ColumnValue::NULLABLE) + aRow.push_back(ODatabaseMetaDataResultSet::get1Value()); + aRow.push_back(new ORowSetValueDecorator((sal_Int32)ColumnSearch::CHAR)); + aRow.push_back(ODatabaseMetaDataResultSet::get1Value()); + aRow.push_back(ODatabaseMetaDataResultSet::get0Value()); + aRow.push_back(ODatabaseMetaDataResultSet::get0Value()); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(ODatabaseMetaDataResultSet::get0Value()); + aRow.push_back(ODatabaseMetaDataResultSet::get0Value()); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRow.push_back(new ORowSetValueDecorator((sal_Int32)10)); + + + aRows.push_back(aRow); + + aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DECIMAL")); + aRow[2] = new ORowSetValueDecorator(DataType::DECIMAL); + aRow[3] = ODatabaseMetaDataResultSet::get0Value(); + aRow[9] = ODatabaseMetaDataResultSet::getBasicValue(); + aRow[15] = ODatabaseMetaDataResultSet::get0Value(); + aRows.push_back(aRow); + + aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("BOOL")); + aRow[2] = new ORowSetValueDecorator(DataType::BIT); + aRow[3] = new ORowSetValueDecorator((sal_Int32)20); + aRow[9] = ODatabaseMetaDataResultSet::getBasicValue(); + aRow[15] = new ORowSetValueDecorator((sal_Int32)15); + aRows.push_back(aRow); + + aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("DATE")); + aRow[2] = new ORowSetValueDecorator(DataType::DATE); + aRow[3] = ODatabaseMetaDataResultSet::get0Value(); + aRow[9] = ODatabaseMetaDataResultSet::getBasicValue(); + aRow[15] = ODatabaseMetaDataResultSet::get0Value(); + aRows.push_back(aRow); + + aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("TIME")); + aRow[2] = new ORowSetValueDecorator(DataType::TIME); + aRow[3] = ODatabaseMetaDataResultSet::get0Value(); + aRow[9] = ODatabaseMetaDataResultSet::getBasicValue(); + aRow[15] = ODatabaseMetaDataResultSet::get0Value(); + aRows.push_back(aRow); + + aRow[1] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("TIMESTAMP")); + aRow[2] = new ORowSetValueDecorator(DataType::TIMESTAMP); + aRow[3] = ODatabaseMetaDataResultSet::get0Value(); + aRow[9] = ODatabaseMetaDataResultSet::getBasicValue(); + aRow[15] = ODatabaseMetaDataResultSet::get0Value(); + aRows.push_back(aRow); + } + + pResult->setRows(aRows); + return xRef; +} + +// ------------------------------------------------------------------------- + +Reference< XResultSet > SAL_CALL OCalcDatabaseMetaData::getColumns( + const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/, const ::rtl::OUString& tableNamePattern, + const ::rtl::OUString& columnNamePattern ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getColumns" ); + ::osl::MutexGuard aGuard( m_aMutex ); + + + Reference< XTablesSupplier > xTables = m_pConnection->createCatalog(); + if(!xTables.is()) + throw SQLException(); + + Reference< XNameAccess> xNames = xTables->getTables(); + if(!xNames.is()) + throw SQLException(); + + ODatabaseMetaDataResultSet::ORows aRows; + ODatabaseMetaDataResultSet::ORow aRow(19); + + aRow[10] = new ORowSetValueDecorator((sal_Int32)10); + + Sequence< ::rtl::OUString> aTabNames(xNames->getElementNames()); + const ::rtl::OUString* pTabIter = aTabNames.getConstArray(); + const ::rtl::OUString* pTabEnd = pTabIter + aTabNames.getLength(); + for(;pTabIter != pTabEnd;++pTabIter) + { + if(match(tableNamePattern,*pTabIter,'\0')) + { + const Reference< XColumnsSupplier> xTable(xNames->getByName(*pTabIter),UNO_QUERY_THROW); + OSL_ENSURE(xTable.is(),"Table not found! Normallya exception had to be thrown here!"); + aRow[3] = new ORowSetValueDecorator(*pTabIter); + + const Reference< XNameAccess> xColumns = xTable->getColumns(); + if(!xColumns.is()) + throw SQLException(); + + const Sequence< ::rtl::OUString> aColNames(xColumns->getElementNames()); + + const ::rtl::OUString* pColumnIter = aColNames.getConstArray(); + const ::rtl::OUString* pEnd = pColumnIter + aColNames.getLength(); + Reference< XPropertySet> xColumn; + for(sal_Int32 i=1;pColumnIter != pEnd;++pColumnIter,++i) + { + if(match(columnNamePattern,*pColumnIter,'\0')) + { + aRow[4] = new ORowSetValueDecorator( *pColumnIter); + + xColumns->getByName(*pColumnIter) >>= xColumn; + OSL_ENSURE(xColumn.is(),"Columns contains a column who isn't a fastpropertyset!"); + aRow[5] = new ORowSetValueDecorator(::comphelper::getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)))); + aRow[6] = new ORowSetValueDecorator(::comphelper::getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)))); + aRow[7] = new ORowSetValueDecorator(::comphelper::getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)))); + // aRow[8] = xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)); + aRow[9] = new ORowSetValueDecorator(::comphelper::getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)))); + aRow[11] = new ORowSetValueDecorator(::comphelper::getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE)))); + // aRow[12] = xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)); + aRow[13] = new ORowSetValueDecorator(::comphelper::getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE)))); + // aRow[14] = xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)); + // aRow[15] = xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)); + switch(sal_Int32(aRow[5]->getValue())) + { + case DataType::CHAR: + case DataType::VARCHAR: + aRow[16] = new ORowSetValueDecorator((sal_Int32)254); + break; + case DataType::LONGVARCHAR: + aRow[16] = new ORowSetValueDecorator((sal_Int32)65535); + break; + default: + aRow[16] = new ORowSetValueDecorator((sal_Int32)0); + } + aRow[17] = new ORowSetValueDecorator(i); + switch(sal_Int32(aRow[11]->getValue())) + { + case ColumnValue::NO_NULLS: + aRow[18] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("NO")); + break; + case ColumnValue::NULLABLE: + aRow[18] = new ORowSetValueDecorator(::rtl::OUString::createFromAscii("YES")); + break; + default: + aRow[18] = new ORowSetValueDecorator(::rtl::OUString()); + } + aRows.push_back(aRow); + } + } + } + } + + ODatabaseMetaDataResultSet* pResult = new ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eColumns); + Reference< XResultSet > xRef = pResult; + pResult->setRows(aRows); + + return xRef; +} + +// ------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL OCalcDatabaseMetaData::getURL( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getURL" ); + ::osl::MutexGuard aGuard( m_aMutex ); + + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdbc:calc:")) + m_pConnection->getURL(); +} + +// ------------------------------------------------------------------------- + +sal_Int32 SAL_CALL OCalcDatabaseMetaData::getMaxBinaryLiteralLength( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getMaxBinaryLiteralLength" ); + return STRING_MAXLEN; +} + +// ------------------------------------------------------------------------- + +sal_Int32 SAL_CALL OCalcDatabaseMetaData::getMaxCharLiteralLength( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getMaxCharLiteralLength" ); + return STRING_MAXLEN; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OCalcDatabaseMetaData::getMaxColumnNameLength( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getMaxColumnNameLength" ); + return STRING_MAXLEN; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OCalcDatabaseMetaData::getMaxColumnsInIndex( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getMaxColumnsInIndex" ); + return 1; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OCalcDatabaseMetaData::getMaxColumnsInTable( ) throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getMaxColumnsInTable" ); + return 256; +} + +// ------------------------------------------------------------------------- + +sal_Bool lcl_IsEmptyOrHidden( const Reference<XSpreadsheets>& xSheets, const ::rtl::OUString& rName ) +{ + Any aAny = xSheets->getByName( rName ); + Reference<XSpreadsheet> xSheet; + if ( aAny >>= xSheet ) + { + // test if sheet is hidden + + Reference<XPropertySet> xProp( xSheet, UNO_QUERY ); + if (xProp.is()) + { + sal_Bool bVisible = sal_Bool(); + Any aVisAny = xProp->getPropertyValue( ::rtl::OUString::createFromAscii("IsVisible") ); + if ( aVisAny >>= bVisible ) + if (!bVisible) + return sal_True; // hidden + } + +#if 0 + // test if whole sheet is empty + + Reference<XCellRangeAddressable> xAddr( xSheet, UNO_QUERY ); + Reference<XCellRangesQuery> xQuery( xSheet, UNO_QUERY ); + if ( xAddr.is() && xQuery.is() ) + { + CellRangeAddress aTotalRange = xAddr->getRangeAddress(); + // queryIntersection to get a ranges object + Reference<XSheetCellRanges> xRanges = xQuery->queryIntersection( aTotalRange ); + if (xRanges.is()) + { + Reference<XEnumerationAccess> xCells = xRanges->getCells(); + if (xCells.is()) + { + if ( !xCells->hasElements() ) + return sal_True; // empty + } + } + } +#endif + + // use the same data area as in OCalcTable to test for empty table + + Reference<XSheetCellCursor> xCursor = xSheet->createCursor(); + Reference<XCellRangeAddressable> xRange( xCursor, UNO_QUERY ); + if ( xRange.is() ) + { + xCursor->collapseToSize( 1, 1 ); // single (first) cell + xCursor->collapseToCurrentRegion(); // contiguous data area + + CellRangeAddress aRangeAddr = xRange->getRangeAddress(); + if ( aRangeAddr.StartColumn == aRangeAddr.EndColumn && + aRangeAddr.StartRow == aRangeAddr.EndRow ) + { + // single cell -> check content + Reference<XCell> xCell = xCursor->getCellByPosition( 0, 0 ); + if ( xCell.is() && xCell->getType() == CellContentType_EMPTY ) + return sal_True; + } + } + } + + return sal_False; +} + +sal_Bool lcl_IsUnnamed( const Reference<XDatabaseRanges>& xRanges, const ::rtl::OUString& rName ) +{ + sal_Bool bUnnamed = sal_False; + + Any aAny = xRanges->getByName( rName ); + Reference<XDatabaseRange> xRange; + if ( aAny >>= xRange ) + { + Reference<XPropertySet> xRangeProp( xRange, UNO_QUERY ); + if ( xRangeProp.is() ) + { + try + { + Any aUserAny = xRangeProp->getPropertyValue( ::rtl::OUString::createFromAscii("IsUserDefined") ); + sal_Bool bUserDefined = sal_Bool(); + if ( aUserAny >>= bUserDefined ) + bUnnamed = !bUserDefined; + } + catch ( UnknownPropertyException& ) + { + // optional property + } + } + } + + return bUnnamed; +} + +// ------------------------------------------------------------------------- + +Reference< XResultSet > SAL_CALL OCalcDatabaseMetaData::getTables( + const Any& /*catalog*/, const ::rtl::OUString& /*schemaPattern*/, + const ::rtl::OUString& tableNamePattern, const Sequence< ::rtl::OUString >& types ) + throw(SQLException, RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcDatabaseMetaData::getTables" ); + ::osl::MutexGuard aGuard( m_aMutex ); + + ODatabaseMetaDataResultSet* pResult = new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables); + Reference< XResultSet > xRef = pResult; + + // check if ORowSetValue type is given + // when no types are given then we have to return all tables e.g. TABLE + + ::rtl::OUString aTable(::rtl::OUString::createFromAscii("TABLE")); + + sal_Bool bTableFound = sal_True; + sal_Int32 nLength = types.getLength(); + if(nLength) + { + bTableFound = sal_False; + + const ::rtl::OUString* pIter = types.getConstArray(); + const ::rtl::OUString* pEnd = pIter + nLength; + for(;pIter != pEnd;++pIter) + { + if(*pIter == aTable) + { + bTableFound = sal_True; + break; + } + } + } + if(!bTableFound) + return xRef; + + // get the sheet names from the document + + OCalcConnection::ODocHolder aDocHodler(((OCalcConnection*)m_pConnection)); + Reference<XSpreadsheetDocument> xDoc = aDocHodler.getDoc(); + if ( !xDoc.is() ) + throw SQLException(); + Reference<XSpreadsheets> xSheets = xDoc->getSheets(); + if ( !xSheets.is() ) + throw SQLException(); + Sequence< ::rtl::OUString > aSheetNames = xSheets->getElementNames(); + + ODatabaseMetaDataResultSet::ORows aRows; + sal_Int32 nSheetCount = aSheetNames.getLength(); + for (sal_Int32 nSheet=0; nSheet<nSheetCount; nSheet++) + { + ::rtl::OUString aName = aSheetNames[nSheet]; + if ( !lcl_IsEmptyOrHidden( xSheets, aName ) && match(tableNamePattern,aName,'\0') ) + { + ODatabaseMetaDataResultSet::ORow aRow(3); + aRow.reserve(6); + aRow.push_back(new ORowSetValueDecorator(aName)); + aRow.push_back(new ORowSetValueDecorator(aTable)); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRows.push_back(aRow); + } + } + + // also use database ranges + + Reference<XPropertySet> xDocProp( xDoc, UNO_QUERY ); + if ( xDocProp.is() ) + { + Any aRangesAny = xDocProp->getPropertyValue( ::rtl::OUString::createFromAscii("DatabaseRanges") ); + Reference<XDatabaseRanges> xRanges; + if ( aRangesAny >>= xRanges ) + { + Sequence< ::rtl::OUString > aDBNames = xRanges->getElementNames(); + sal_Int32 nDBCount = aDBNames.getLength(); + for (sal_Int32 nRange=0; nRange<nDBCount; nRange++) + { + ::rtl::OUString aName = aDBNames[nRange]; + if ( !lcl_IsUnnamed( xRanges, aName ) && match(tableNamePattern,aName,'\0') ) + { + ODatabaseMetaDataResultSet::ORow aRow(3); + aRow.reserve(6); + aRow.push_back(new ORowSetValueDecorator(aName)); + aRow.push_back(new ORowSetValueDecorator(aTable)); + aRow.push_back(ODatabaseMetaDataResultSet::getEmptyValue()); + aRows.push_back(aRow); + } + } + } + } + + pResult->setRows(aRows); + + return xRef; +} +// ----------------------------------------------------------------------------- + + diff --git a/connectivity/source/drivers/calc/CDriver.cxx b/connectivity/source/drivers/calc/CDriver.cxx new file mode 100644 index 000000000000..f3ae81ad6670 --- /dev/null +++ b/connectivity/source/drivers/calc/CDriver.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CDriver.hxx" +#include "calc/CConnection.hxx" +#include <com/sun/star/lang/DisposedException.hpp> +#include "connectivity/dbexception.hxx" +#include "resource/sharedresources.hxx" +#include "resource/calc_res.hrc" + +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::lang; + + +//------------------------------------------------------------------------------ +// static ServiceInfo + +rtl::OUString ODriver::getImplementationName_Static( ) throw(RuntimeException) +{ + return rtl::OUString::createFromAscii("com.sun.star.comp.sdbc.calc.ODriver"); +} + +::rtl::OUString SAL_CALL ODriver::getImplementationName( ) throw(RuntimeException) +{ + return getImplementationName_Static(); +} + +// service names from file::OFileDriver + +//------------------------------------------------------------------ + +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + connectivity::calc::ODriver_CreateInstance(const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception ) +{ + return *(new ODriver(_rxFactory)); +} + +Reference< XConnection > SAL_CALL ODriver::connect( const ::rtl::OUString& url, + const Sequence< PropertyValue >& info ) throw(SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if (ODriver_BASE::rBHelper.bDisposed) + throw DisposedException(); + + if ( ! acceptsURL(url) ) + return NULL; + + OCalcConnection* pCon = new OCalcConnection(this); + pCon->construct(url,info); + Reference< XConnection > xCon = pCon; + m_xConnections.push_back(WeakReferenceHelper(*pCon)); + + return xCon; +} + +sal_Bool SAL_CALL ODriver::acceptsURL( const ::rtl::OUString& url ) + throw(SQLException, RuntimeException) +{ + return url.compareTo(::rtl::OUString::createFromAscii("sdbc:calc:"),10) == 0; +} + +Sequence< DriverPropertyInfo > SAL_CALL ODriver::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw(SQLException, RuntimeException) +{ + if ( !acceptsURL(url) ) + { + SharedResources aResources; + const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + return Sequence< DriverPropertyInfo >(); +} +// ----------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/calc/CPreparedStatement.cxx b/connectivity/source/drivers/calc/CPreparedStatement.cxx new file mode 100644 index 000000000000..46f5b8342a71 --- /dev/null +++ b/connectivity/source/drivers/calc/CPreparedStatement.cxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CPreparedStatement.hxx" +#include "calc/CResultSet.hxx" + +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace com::sun::star::uno; +// ------------------------------------------------------------------------- +OResultSet* OCalcPreparedStatement::createResultSet() +{ + return new OCalcResultSet(this,m_aSQLIterator); +} +// ------------------------------------------------------------------------- +IMPLEMENT_SERVICE_INFO(OCalcPreparedStatement,"com.sun.star.sdbc.driver.calc.PreparedStatement","com.sun.star.sdbc.PreparedStatement"); + diff --git a/connectivity/source/drivers/calc/CResultSet.cxx b/connectivity/source/drivers/calc/CResultSet.cxx new file mode 100644 index 000000000000..6f2566c5ff94 --- /dev/null +++ b/connectivity/source/drivers/calc/CResultSet.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include <com/sun/star/sdbcx/CompareBookmark.hpp> +#include "calc/CResultSet.hxx" +#include <com/sun/star/lang/DisposedException.hpp> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> + +using namespace ::comphelper; +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace ::cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; +// using namespace com::sun::star::container; +// using namespace com::sun::star::util; +//------------------------------------------------------------------------------ +OCalcResultSet::OCalcResultSet( OStatement_Base* pStmt,connectivity::OSQLParseTreeIterator& _aSQLIterator) + : file::OResultSet(pStmt,_aSQLIterator) + ,m_bBookmarkable(sal_True) +{ + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISBOOKMARKABLE), PROPERTY_ID_ISBOOKMARKABLE, PropertyAttribute::READONLY,&m_bBookmarkable, ::getBooleanCppuType()); +} +// ------------------------------------------------------------------------- +::rtl::OUString SAL_CALL OCalcResultSet::getImplementationName( ) throw ( RuntimeException) +{ + return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.calc.ResultSet"); +} +// ------------------------------------------------------------------------- +Sequence< ::rtl::OUString > SAL_CALL OCalcResultSet::getSupportedServiceNames( ) throw( RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(2); + aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ResultSet"); + aSupported[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.ResultSet"); + return aSupported; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OCalcResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw( RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); + const ::rtl::OUString* pSupported = aSupported.getConstArray(); + const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); + for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported) + ; + + return pSupported != pEnd; +} +// ------------------------------------------------------------------------- +Any SAL_CALL OCalcResultSet::queryInterface( const Type & rType ) throw(RuntimeException) +{ + Any aRet = OResultSet::queryInterface(rType); + return aRet.hasValue() ? aRet : OCalcResultSet_BASE::queryInterface(rType); +} +// ------------------------------------------------------------------------- + Sequence< Type > SAL_CALL OCalcResultSet::getTypes( ) throw( RuntimeException) +{ + return ::comphelper::concatSequences(OResultSet::getTypes(),OCalcResultSet_BASE::getTypes()); +} + +// ------------------------------------------------------------------------- +// XRowLocate +Any SAL_CALL OCalcResultSet::getBookmark( ) throw( SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + return makeAny((sal_Int32)(m_aRow->get())[0]->getValue()); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OCalcResultSet::moveToBookmark( const Any& bookmark ) throw( SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_bRowDeleted = m_bRowInserted = m_bRowUpdated = sal_False; + + return Move(IResultSetHelper::BOOKMARK,comphelper::getINT32(bookmark),sal_True); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OCalcResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw( SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + m_bRowDeleted = m_bRowInserted = m_bRowUpdated = sal_False; + + Move(IResultSetHelper::BOOKMARK,comphelper::getINT32(bookmark),sal_False); + + return relative(rows); +} + +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OCalcResultSet::compareBookmarks( const Any& lhs, const Any& rhs ) throw( SQLException, RuntimeException) +{ + return (lhs == rhs) ? 0 : 2; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL OCalcResultSet::hasOrderedBookmarks( ) throw( SQLException, RuntimeException) +{ + return sal_True; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OCalcResultSet::hashBookmark( const Any& bookmark ) throw( SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + + return comphelper::getINT32(bookmark); +} +// ------------------------------------------------------------------------- +// XDeleteRows +Sequence< sal_Int32 > SAL_CALL OCalcResultSet::deleteRows( const Sequence< Any >& /*rows*/ ) throw( SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + ::dbtools::throwFeatureNotImplementedException( "XDeleteRows::deleteRows", *this ); + return Sequence< sal_Int32 >(); +} +// ------------------------------------------------------------------------- +sal_Bool OCalcResultSet::fillIndexValues(const Reference< XColumnsSupplier> &/*_xIndex*/) +{ + // Calc table has no index + return sal_False; +} +// ------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper & OCalcResultSet::getInfoHelper() +{ + return *OCalcResultSet_BASE3::getArrayHelper(); +} +// ----------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper* OCalcResultSet::createArrayHelper() const +{ + Sequence< Property > aProps; + describeProperties(aProps); + return new ::cppu::OPropertyArrayHelper(aProps); +} +// ------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +void SAL_CALL OCalcResultSet::acquire() throw() +{ + OCalcResultSet_BASE2::acquire(); +} +// ----------------------------------------------------------------------------- +void SAL_CALL OCalcResultSet::release() throw() +{ + OCalcResultSet_BASE2::release(); +} +// ----------------------------------------------------------------------------- +::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OCalcResultSet::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException) +{ + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); +} +// ----------------------------------------------------------------------------- + + diff --git a/connectivity/source/drivers/calc/CStatement.cxx b/connectivity/source/drivers/calc/CStatement.cxx new file mode 100644 index 000000000000..95eece44ddca --- /dev/null +++ b/connectivity/source/drivers/calc/CStatement.cxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CStatement.hxx" +#include "calc/CResultSet.hxx" + +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace com::sun::star::uno; +// ------------------------------------------------------------------------- +OResultSet* OCalcStatement::createResultSet() +{ + return new OCalcResultSet(this,m_aSQLIterator); +} +// ------------------------------------------------------------------------- +IMPLEMENT_SERVICE_INFO(OCalcStatement,"com.sun.star.sdbc.driver.calc.Statement","com.sun.star.sdbc.Statement"); + diff --git a/connectivity/source/drivers/calc/CTable.cxx b/connectivity/source/drivers/calc/CTable.cxx new file mode 100644 index 000000000000..a4e5f35825f5 --- /dev/null +++ b/connectivity/source/drivers/calc/CTable.cxx @@ -0,0 +1,871 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CTable.hxx" +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +//#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_ +//#include <com/sun/star/ucb/XContentAccess.hpp> +//#endif +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/XDatabaseRanges.hpp> +#include <com/sun/star/sheet/XDatabaseRange.hpp> +#include <com/sun/star/sheet/XCellRangeReferrer.hpp> +#include <com/sun/star/sheet/XUsedAreaCursor.hpp> +#include <com/sun/star/sheet/CellFlags.hpp> +#include <com/sun/star/sheet/FormulaResult.hpp> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/text/XText.hpp> +#include <svl/converter.hxx> +#include "calc/CConnection.hxx" +#include "calc/CColumns.hxx" +#include "connectivity/sdbcx/VColumn.hxx" +#include <rtl/ustrbuf.hxx> +#include <osl/thread.h> +#include <tools/config.hxx> +#include <comphelper/sequence.hxx> +#include <svl/zforlist.hxx> +#include <rtl/math.hxx> +#include <comphelper/extract.hxx> +#include <connectivity/dbexception.hxx> +#include <connectivity/dbconversion.hxx> +#include <comphelper/types.hxx> +#include <rtl/logfile.hxx> + +using namespace connectivity; +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace ::cppu; +using namespace ::dbtools; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::util; + +// ------------------------------------------------------------------------- + +void lcl_UpdateArea( const Reference<XCellRange>& xUsedRange, sal_Int32& rEndCol, sal_Int32& rEndRow ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_UpdateArea" ); + // update rEndCol, rEndRow if any non-empty cell in xUsedRange is right/below + + const Reference<XCellRangesQuery> xUsedQuery( xUsedRange, UNO_QUERY ); + if ( xUsedQuery.is() ) + { + const sal_Int16 nContentFlags = + CellFlags::STRING | CellFlags::VALUE | CellFlags::DATETIME | CellFlags::FORMULA | CellFlags::ANNOTATION; + + const Reference<XSheetCellRanges> xUsedRanges = xUsedQuery->queryContentCells( nContentFlags ); + const Sequence<CellRangeAddress> aAddresses = xUsedRanges->getRangeAddresses(); + + const sal_Int32 nCount = aAddresses.getLength(); + const CellRangeAddress* pData = aAddresses.getConstArray(); + for ( sal_Int32 i=0; i<nCount; i++ ) + { + rEndCol = pData[i].EndColumn > rEndCol ? pData[i].EndColumn : rEndCol; + rEndRow = pData[i].EndRow > rEndRow ? pData[i].EndRow : rEndRow; + } + } +} + +void lcl_GetDataArea( const Reference<XSpreadsheet>& xSheet, sal_Int32& rColumnCount, sal_Int32& rRowCount ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetDataArea" ); + Reference<XSheetCellCursor> xCursor = xSheet->createCursor(); + Reference<XCellRangeAddressable> xRange( xCursor, UNO_QUERY ); + if ( !xRange.is() ) + { + rColumnCount = rRowCount = 0; + return; + } + + // first find the contiguous cell area starting at A1 + + xCursor->collapseToSize( 1, 1 ); // single (first) cell + xCursor->collapseToCurrentRegion(); // contiguous data area + + CellRangeAddress aRegionAddr = xRange->getRangeAddress(); + sal_Int32 nEndCol = aRegionAddr.EndColumn; + sal_Int32 nEndRow = aRegionAddr.EndRow; + + Reference<XUsedAreaCursor> xUsed( xCursor, UNO_QUERY ); + if ( xUsed.is() ) + { + // The used area from XUsedAreaCursor includes visible attributes. + // If the used area is larger than the contiguous cell area, find non-empty + // cells in that area. + + xUsed->gotoEndOfUsedArea( sal_False ); + CellRangeAddress aUsedAddr = xRange->getRangeAddress(); + + if ( aUsedAddr.EndColumn > aRegionAddr.EndColumn ) + { + Reference<XCellRange> xUsedRange = xSheet->getCellRangeByPosition( + aRegionAddr.EndColumn + 1, 0, aUsedAddr.EndColumn, aUsedAddr.EndRow ); + lcl_UpdateArea( xUsedRange, nEndCol, nEndRow ); + } + + if ( aUsedAddr.EndRow > aRegionAddr.EndRow ) + { + // only up to the last column of aRegionAddr, the other columns are handled above + Reference<XCellRange> xUsedRange = xSheet->getCellRangeByPosition( + 0, aRegionAddr.EndRow + 1, aRegionAddr.EndColumn, aUsedAddr.EndRow ); + lcl_UpdateArea( xUsedRange, nEndCol, nEndRow ); + } + } + + rColumnCount = nEndCol + 1; // number of columns + rRowCount = nEndRow; // first row (headers) is not counted +} + +CellContentType lcl_GetContentOrResultType( const Reference<XCell>& xCell ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetContentOrResultType" ); + CellContentType eCellType = xCell->getType(); + if ( eCellType == CellContentType_FORMULA ) + { + static const ::rtl::OUString s_sFormulaResultType(RTL_CONSTASCII_USTRINGPARAM("FormulaResultType")); + Reference<XPropertySet> xProp( xCell, UNO_QUERY ); + try + { + xProp->getPropertyValue( s_sFormulaResultType ) >>= eCellType; // type of formula result + } + catch (UnknownPropertyException&) + { + eCellType = CellContentType_VALUE; // if FormulaResultType property not available + } + } + return eCellType; +} + +Reference<XCell> lcl_GetUsedCell( const Reference<XSpreadsheet>& xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetUsedCell" ); + Reference<XCell> xCell = xSheet->getCellByPosition( nDocColumn, nDocRow ); + if ( xCell.is() && xCell->getType() == CellContentType_EMPTY ) + { + // get first non-empty cell + + Reference<XCellRangeAddressable> xAddr( xSheet, UNO_QUERY ); + if (xAddr.is()) + { + CellRangeAddress aTotalRange = xAddr->getRangeAddress(); + sal_Int32 nLastRow = aTotalRange.EndRow; + Reference<XCellRangesQuery> xQuery( xSheet->getCellRangeByPosition( nDocColumn, nDocRow, nDocColumn, nLastRow ), UNO_QUERY ); + if (xQuery.is()) + { + // queryIntersection to get a ranges object + Reference<XSheetCellRanges> xRanges = xQuery->queryIntersection( aTotalRange ); + if (xRanges.is()) + { + Reference<XEnumerationAccess> xCells = xRanges->getCells(); + if (xCells.is()) + { + Reference<XEnumeration> xEnum = xCells->createEnumeration(); + if ( xEnum.is() && xEnum->hasMoreElements() ) + { + // get first non-empty cell from enumeration + xCell.set(xEnum->nextElement(),UNO_QUERY); + } + // otherwise, keep empty cell + } + } + } + } + } + return xCell; +} + +bool lcl_HasTextInColumn( const Reference<XSpreadsheet>& xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_HasTextInColumn" ); + // look for any text cell or text result in the column + + Reference<XCellRangeAddressable> xAddr( xSheet, UNO_QUERY ); + if (xAddr.is()) + { + CellRangeAddress aTotalRange = xAddr->getRangeAddress(); + sal_Int32 nLastRow = aTotalRange.EndRow; + Reference<XCellRangesQuery> xQuery( xSheet->getCellRangeByPosition( nDocColumn, nDocRow, nDocColumn, nLastRow ), UNO_QUERY ); + if (xQuery.is()) + { + // are there text cells in the column? + Reference<XSheetCellRanges> xTextContent = xQuery->queryContentCells( CellFlags::STRING ); + if ( xTextContent.is() && xTextContent->hasElements() ) + return true; + + // are there formulas with text results in the column? + Reference<XSheetCellRanges> xTextFormula = xQuery->queryFormulaCells( FormulaResult::STRING ); + if ( xTextFormula.is() && xTextFormula->hasElements() ) + return true; + } + } + + return false; +} + +void lcl_GetColumnInfo( const Reference<XSpreadsheet>& xSheet, const Reference<XNumberFormats>& xFormats, + sal_Int32 nDocColumn, sal_Int32 nStartRow, sal_Bool bHasHeaders, + ::rtl::OUString& rName, sal_Int32& rDataType, sal_Bool& rCurrency ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetColumnInfo" ); + //! avoid duplicate field names + + // get column name from first row, if range contains headers + + if ( bHasHeaders ) + { + Reference<XText> xHeaderText( xSheet->getCellByPosition( nDocColumn, nStartRow ), UNO_QUERY ); + if ( xHeaderText.is() ) + rName = xHeaderText->getString(); + } + + // get column type from first data row + + sal_Int32 nDataRow = nStartRow; + if ( bHasHeaders ) + ++nDataRow; + Reference<XCell> xDataCell = lcl_GetUsedCell( xSheet, nDocColumn, nDataRow ); + + Reference<XPropertySet> xProp( xDataCell, UNO_QUERY ); + if ( xProp.is() ) + { + rCurrency = sal_False; // set to true for currency below + + const CellContentType eCellType = lcl_GetContentOrResultType( xDataCell ); + // #i35178# use "text" type if there is any text cell in the column + if ( eCellType == CellContentType_TEXT || lcl_HasTextInColumn( xSheet, nDocColumn, nDataRow ) ) + rDataType = DataType::VARCHAR; + else if ( eCellType == CellContentType_VALUE ) + { + // get number format to distinguish between different types + + sal_Int16 nNumType = NumberFormat::NUMBER; + try + { + static ::rtl::OUString s_NumberFormat(RTL_CONSTASCII_USTRINGPARAM("NumberFormat")); + sal_Int32 nKey = 0; + + if ( xProp->getPropertyValue( s_NumberFormat ) >>= nKey ) + { + const Reference<XPropertySet> xFormat = xFormats->getByKey( nKey ); + if ( xFormat.is() ) + { + xFormat->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nNumType; + } + } + } + catch ( Exception& ) + { + } + + if ( nNumType & NumberFormat::TEXT ) + rDataType = DataType::VARCHAR; + else if ( nNumType & NumberFormat::NUMBER ) + rDataType = DataType::DECIMAL; + else if ( nNumType & NumberFormat::CURRENCY ) + { + rCurrency = sal_True; + rDataType = DataType::DECIMAL; + } + else if ( ( nNumType & NumberFormat::DATETIME ) == NumberFormat::DATETIME ) + { + // NumberFormat::DATETIME is DATE | TIME + rDataType = DataType::TIMESTAMP; + } + else if ( nNumType & NumberFormat::DATE ) + rDataType = DataType::DATE; + else if ( nNumType & NumberFormat::TIME ) + rDataType = DataType::TIME; + else if ( nNumType & NumberFormat::LOGICAL ) + rDataType = DataType::BIT; + else + rDataType = DataType::DECIMAL; + } + else + { + // whole column empty + rDataType = DataType::VARCHAR; + } + } +} + +// ------------------------------------------------------------------------- + +void lcl_SetValue( ORowSetValue& rValue, const Reference<XSpreadsheet>& xSheet, + sal_Int32 nStartCol, sal_Int32 nStartRow, sal_Bool bHasHeaders, + const ::Date& rNullDate, + sal_Int32 nDBRow, sal_Int32 nDBColumn, sal_Int32 nType ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_SetValue" ); + sal_Int32 nDocColumn = nStartCol + nDBColumn - 1; // database counts from 1 + sal_Int32 nDocRow = nStartRow + nDBRow - 1; + if (bHasHeaders) + ++nDocRow; + + const Reference<XCell> xCell = xSheet->getCellByPosition( nDocColumn, nDocRow ); + if ( xCell.is() ) + { + CellContentType eCellType = lcl_GetContentOrResultType( xCell ); + switch (nType) + { + case DataType::VARCHAR: + if ( eCellType == CellContentType_EMPTY ) + rValue.setNull(); + else + { + // #i25840# still let Calc convert numbers to text + const Reference<XText> xText( xCell, UNO_QUERY ); + if ( xText.is() ) + rValue = xText->getString(); + } + break; + case DataType::DECIMAL: + if ( eCellType == CellContentType_VALUE ) + rValue = xCell->getValue(); // double + else + rValue.setNull(); + break; + case DataType::BIT: + if ( eCellType == CellContentType_VALUE ) + rValue = (sal_Bool)( xCell->getValue() != 0.0 ); + else + rValue.setNull(); + break; + case DataType::DATE: + if ( eCellType == CellContentType_VALUE ) + { + ::Date aDate( rNullDate ); + aDate += (long)::rtl::math::approxFloor( xCell->getValue() ); + ::com::sun::star::util::Date aDateStruct( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() ); + rValue = aDateStruct; + } + else + rValue.setNull(); + break; + case DataType::TIME: + if ( eCellType == CellContentType_VALUE ) + { + double fCellVal = xCell->getValue(); + double fTime = fCellVal - rtl::math::approxFloor( fCellVal ); + long nIntTime = (long)rtl::math::round( fTime * 8640000.0 ); + if ( nIntTime == 8640000 ) + nIntTime = 0; // 23:59:59.995 and above is 00:00:00.00 + ::com::sun::star::util::Time aTime; + aTime.HundredthSeconds = (sal_uInt16)( nIntTime % 100 ); + nIntTime /= 100; + aTime.Seconds = (sal_uInt16)( nIntTime % 60 ); + nIntTime /= 60; + aTime.Minutes = (sal_uInt16)( nIntTime % 60 ); + nIntTime /= 60; + OSL_ENSURE( nIntTime < 24, "error in time calculation" ); + aTime.Hours = (sal_uInt16) nIntTime; + rValue = aTime; + } + else + rValue.setNull(); + break; + case DataType::TIMESTAMP: + if ( eCellType == CellContentType_VALUE ) + { + double fCellVal = xCell->getValue(); + double fDays = ::rtl::math::approxFloor( fCellVal ); + double fTime = fCellVal - fDays; + long nIntDays = (long)fDays; + long nIntTime = (long)::rtl::math::round( fTime * 8640000.0 ); + if ( nIntTime == 8640000 ) + { + nIntTime = 0; // 23:59:59.995 and above is 00:00:00.00 + ++nIntDays; // (next day) + } + + ::com::sun::star::util::DateTime aDateTime; + + aDateTime.HundredthSeconds = (sal_uInt16)( nIntTime % 100 ); + nIntTime /= 100; + aDateTime.Seconds = (sal_uInt16)( nIntTime % 60 ); + nIntTime /= 60; + aDateTime.Minutes = (sal_uInt16)( nIntTime % 60 ); + nIntTime /= 60; + OSL_ENSURE( nIntTime < 24, "error in time calculation" ); + aDateTime.Hours = (sal_uInt16) nIntTime; + + ::Date aDate( rNullDate ); + aDate += nIntDays; + aDateTime.Day = aDate.GetDay(); + aDateTime.Month = aDate.GetMonth(); + aDateTime.Year = aDate.GetYear(); + + rValue = aDateTime; + } + else + rValue.setNull(); + break; + } // switch (nType) + } + +// rValue.setTypeKind(nType); +} + +// ------------------------------------------------------------------------- + +::rtl::OUString lcl_GetColumnStr( sal_Int32 nColumn ) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetColumnStr" ); + if ( nColumn < 26 ) + return ::rtl::OUString::valueOf( (sal_Unicode) ( 'A' + nColumn ) ); + else + { + ::rtl::OUStringBuffer aBuffer(2); + aBuffer.setLength( 2 ); + aBuffer.setCharAt( 0, (sal_Unicode) ( 'A' + ( nColumn / 26 ) - 1 ) ); + aBuffer.setCharAt( 1, (sal_Unicode) ( 'A' + ( nColumn % 26 ) ) ); + return aBuffer.makeStringAndClear(); + } +} + +void OCalcTable::fillColumns() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::fillColumns" ); + if ( !m_xSheet.is() ) + throw SQLException(); + + String aStrFieldName; + aStrFieldName.AssignAscii("Column"); + ::rtl::OUString aTypeName; + ::comphelper::UStringMixEqual aCase(m_pConnection->getMetaData()->storesMixedCaseQuotedIdentifiers()); + const sal_Bool bStoresMixedCaseQuotedIdentifiers = getConnection()->getMetaData()->storesMixedCaseQuotedIdentifiers(); + + for (sal_Int32 i = 0; i < m_nDataCols; i++) + { + ::rtl::OUString aColumnName; + sal_Int32 eType = DataType::OTHER; + sal_Bool bCurrency = sal_False; + + lcl_GetColumnInfo( m_xSheet, m_xFormats, m_nStartCol + i, m_nStartRow, m_bHasHeaders, + aColumnName, eType, bCurrency ); + + if ( !aColumnName.getLength() ) + aColumnName = lcl_GetColumnStr( i ); + + sal_Int32 nPrecision = 0; //! ... + sal_Int32 nDecimals = 0; //! ... + + switch ( eType ) + { + case DataType::VARCHAR: + { + static const ::rtl::OUString s_sType(RTL_CONSTASCII_USTRINGPARAM("VARCHAR")); + aTypeName = s_sType; + } + break; + case DataType::DECIMAL: + aTypeName = ::rtl::OUString::createFromAscii("DECIMAL"); + break; + case DataType::BIT: + aTypeName = ::rtl::OUString::createFromAscii("BOOL"); + break; + case DataType::DATE: + aTypeName = ::rtl::OUString::createFromAscii("DATE"); + break; + case DataType::TIME: + aTypeName = ::rtl::OUString::createFromAscii("TIME"); + break; + case DataType::TIMESTAMP: + aTypeName = ::rtl::OUString::createFromAscii("TIMESTAMP"); + break; + default: + OSL_ASSERT("missing type name"); + aTypeName = ::rtl::OUString(); + } + + // check if the column name already exists + ::rtl::OUString aAlias = aColumnName; + OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); + sal_Int32 nExprCnt = 0; + while(aFind != m_aColumns->get().end()) + { + (aAlias = aColumnName) += ::rtl::OUString::valueOf((sal_Int32)++nExprCnt); + aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); + } + + sdbcx::OColumn* pColumn = new sdbcx::OColumn( aAlias, aTypeName, ::rtl::OUString(),::rtl::OUString(), + ColumnValue::NULLABLE, nPrecision, nDecimals, + eType, sal_False, sal_False, bCurrency, + bStoresMixedCaseQuotedIdentifiers); + Reference< XPropertySet> xCol = pColumn; + m_aColumns->get().push_back(xCol); + m_aTypes.push_back(eType); + m_aPrecisions.push_back(nPrecision); + m_aScales.push_back(nDecimals); + } +} + +// ------------------------------------------------------------------------- +OCalcTable::OCalcTable(sdbcx::OCollection* _pTables,OCalcConnection* _pConnection, + const ::rtl::OUString& _Name, + const ::rtl::OUString& _Type, + const ::rtl::OUString& _Description , + const ::rtl::OUString& _SchemaName, + const ::rtl::OUString& _CatalogName + ) : OCalcTable_BASE(_pTables,_pConnection,_Name, + _Type, + _Description, + _SchemaName, + _CatalogName) + ,m_pConnection(_pConnection) + ,m_nStartCol(0) + ,m_nStartRow(0) + ,m_nDataCols(0) + ,m_nDataRows(0) + ,m_bHasHeaders(sal_False) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::OCalcTable" ); +} +// ----------------------------------------------------------------------------- +void OCalcTable::construct() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::construct" ); + // get sheet object + Reference< XSpreadsheetDocument> xDoc = m_pConnection->acquireDoc(); + if (xDoc.is()) + { + Reference<XSpreadsheets> xSheets = xDoc->getSheets(); + if ( xSheets.is() && xSheets->hasByName( m_Name ) ) + { + m_xSheet.set(xSheets->getByName( m_Name ),UNO_QUERY); + if ( m_xSheet.is() ) + { + lcl_GetDataArea( m_xSheet, m_nDataCols, m_nDataRows ); + m_bHasHeaders = sal_True; + // whole sheet is always assumed to include a header row + } + } + else // no sheet -> try database range + { + Reference<XPropertySet> xDocProp( xDoc, UNO_QUERY ); + if ( xDocProp.is() ) + { + Reference<XDatabaseRanges> xRanges(xDocProp->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DatabaseRanges")) ),UNO_QUERY); + + if ( xRanges.is() && xRanges->hasByName( m_Name ) ) + { + Reference<XDatabaseRange> xDBRange(xRanges->getByName( m_Name ),UNO_QUERY); + Reference<XCellRangeReferrer> xRefer( xDBRange, UNO_QUERY ); + if ( xRefer.is() ) + { + // Header flag is always stored with database range + // Get flag from FilterDescriptor + + sal_Bool bRangeHeader = sal_True; + Reference<XPropertySet> xFiltProp( xDBRange->getFilterDescriptor(), UNO_QUERY ); + if ( xFiltProp.is() ) + xFiltProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContainsHeader"))) >>= bRangeHeader; + + Reference<XSheetCellRange> xSheetRange( xRefer->getReferredCells(), UNO_QUERY ); + Reference<XCellRangeAddressable> xAddr( xSheetRange, UNO_QUERY ); + if ( xSheetRange.is() && xAddr.is() ) + { + m_xSheet = xSheetRange->getSpreadsheet(); + CellRangeAddress aRangeAddr = xAddr->getRangeAddress(); + m_nStartCol = aRangeAddr.StartColumn; + m_nStartRow = aRangeAddr.StartRow; + m_nDataCols = aRangeAddr.EndColumn - m_nStartCol + 1; + // m_nDataRows is excluding header row + m_nDataRows = aRangeAddr.EndRow - m_nStartRow; + if ( !bRangeHeader ) + { + // m_nDataRows counts the whole range + m_nDataRows += 1; + } + + m_bHasHeaders = bRangeHeader; + } + } + } + } + } + + Reference<XNumberFormatsSupplier> xSupp( xDoc, UNO_QUERY ); + if (xSupp.is()) + m_xFormats = xSupp->getNumberFormats(); + + Reference<XPropertySet> xProp( xDoc, UNO_QUERY ); + if (xProp.is()) + { + ::com::sun::star::util::Date aDateStruct; + if ( xProp->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NullDate")) ) >>= aDateStruct ) + m_aNullDate = ::Date( aDateStruct.Day, aDateStruct.Month, aDateStruct.Year ); + } + } + + //! default if no null date available? + + fillColumns(); + + refreshColumns(); +} +// ------------------------------------------------------------------------- +void OCalcTable::refreshColumns() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::refreshColumns" ); + ::osl::MutexGuard aGuard( m_aMutex ); + + TStringVector aVector; + + OSQLColumns::Vector::const_iterator aEnd = m_aColumns->get().end(); + for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != aEnd;++aIter) + aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName()); + + if(m_pColumns) + m_pColumns->reFill(aVector); + else + m_pColumns = new OCalcColumns(this,m_aMutex,aVector); +} +// ------------------------------------------------------------------------- +void OCalcTable::refreshIndexes() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::refreshIndexes" ); + // Calc table has no index +} + +// ------------------------------------------------------------------------- +void SAL_CALL OCalcTable::disposing(void) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::disposing" ); + OFileTable::disposing(); + ::osl::MutexGuard aGuard(m_aMutex); + m_aColumns = NULL; + if ( m_pConnection ) + m_pConnection->releaseDoc(); + m_pConnection = NULL; + +} +// ------------------------------------------------------------------------- +Sequence< Type > SAL_CALL OCalcTable::getTypes( ) throw(RuntimeException) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getTypes" ); + Sequence< Type > aTypes = OTable_TYPEDEF::getTypes(); + ::std::vector<Type> aOwnTypes; + aOwnTypes.reserve(aTypes.getLength()); + + const Type* pBegin = aTypes.getConstArray(); + const Type* pEnd = pBegin + aTypes.getLength(); + for(;pBegin != pEnd;++pBegin) + { + if(!( *pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) || + *pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) || + *pBegin == ::getCppuType((const Reference<XRename>*)0) || + *pBegin == ::getCppuType((const Reference<XAlterTable>*)0) || + *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))) + aOwnTypes.push_back(*pBegin); + } + aOwnTypes.push_back(::getCppuType( (const Reference< ::com::sun::star::lang::XUnoTunnel > *)0 )); + + const Type* pAttrs = aOwnTypes.empty() ? 0 : &aOwnTypes[0]; + return Sequence< Type >(pAttrs, aOwnTypes.size()); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL OCalcTable::queryInterface( const Type & rType ) throw(RuntimeException) +{ + if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) || + rType == ::getCppuType((const Reference<XIndexesSupplier>*)0) || + rType == ::getCppuType((const Reference<XRename>*)0) || + rType == ::getCppuType((const Reference<XAlterTable>*)0) || + rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)) + return Any(); + + const Any aRet = ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this)); + return aRet.hasValue() ? aRet : OTable_TYPEDEF::queryInterface(rType); +} + +//-------------------------------------------------------------------------- +Sequence< sal_Int8 > OCalcTable::getUnoTunnelImplementationId() +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getUnoTunnelImplementationId" ); + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +// com::sun::star::lang::XUnoTunnel +//------------------------------------------------------------------ +sal_Int64 OCalcTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException) +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getSomething" ); + return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) + ? reinterpret_cast< sal_Int64 >( this ) + : OCalcTable_BASE::getSomething(rId); +} +//------------------------------------------------------------------ +sal_Int32 OCalcTable::getCurrentLastPos() const +{ + //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getCurrentLastPos" ); + return m_nDataRows; +} +//------------------------------------------------------------------ +sal_Bool OCalcTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::seekRow" ); + // ---------------------------------------------------------- + // Positionierung vorbereiten: + + sal_uInt32 nNumberOfRecords = m_nDataRows; + sal_uInt32 nTempPos = m_nFilePos; + m_nFilePos = nCurPos; + + switch(eCursorPosition) + { + case IResultSetHelper::NEXT: + m_nFilePos++; + break; + case IResultSetHelper::PRIOR: + if (m_nFilePos > 0) + m_nFilePos--; + break; + case IResultSetHelper::FIRST: + m_nFilePos = 1; + break; + case IResultSetHelper::LAST: + m_nFilePos = nNumberOfRecords; + break; + case IResultSetHelper::RELATIVE: + m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L + : (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset); + break; + case IResultSetHelper::ABSOLUTE: + case IResultSetHelper::BOOKMARK: + m_nFilePos = (sal_uInt32)nOffset; + break; + } + + if (m_nFilePos > (sal_Int32)nNumberOfRecords) + m_nFilePos = (sal_Int32)nNumberOfRecords + 1; + + if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1) + goto Error; + else + { + //! read buffer / setup row object etc? + } + goto End; + +Error: + switch(eCursorPosition) + { + case IResultSetHelper::PRIOR: + case IResultSetHelper::FIRST: + m_nFilePos = 0; + break; + case IResultSetHelper::LAST: + case IResultSetHelper::NEXT: + case IResultSetHelper::ABSOLUTE: + case IResultSetHelper::RELATIVE: + if (nOffset > 0) + m_nFilePos = nNumberOfRecords + 1; + else if (nOffset < 0) + m_nFilePos = 0; + break; + case IResultSetHelper::BOOKMARK: + m_nFilePos = nTempPos; // vorherige Position + } + // aStatus.Set(SDB_STAT_NO_DATA_FOUND); + return sal_False; + +End: + nCurPos = m_nFilePos; + return sal_True; +} +//------------------------------------------------------------------ +sal_Bool OCalcTable::fetchRow( OValueRefRow& _rRow, const OSQLColumns & _rCols, + sal_Bool _bUseTableDefs, sal_Bool bRetrieveData ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::fetchRow" ); + // read the bookmark + + BOOL bIsCurRecordDeleted = sal_False; + _rRow->setDeleted(bIsCurRecordDeleted); + *(_rRow->get())[0] = m_nFilePos; + + if (!bRetrieveData) + return TRUE; + + // fields + + OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin(); + OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end(); + const OValueRefVector::Vector::size_type nCount = _rRow->get().size(); + for (OValueRefVector::Vector::size_type i = 1; aIter != aEnd && i < nCount; + ++aIter, i++) + { + if ( (_rRow->get())[i]->isBound() ) + { + sal_Int32 nType = 0; + if ( _bUseTableDefs ) + nType = m_aTypes[i-1]; + else + (*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; + + + lcl_SetValue( (_rRow->get())[i]->get(), m_xSheet, m_nStartCol, m_nStartRow, m_bHasHeaders, + m_aNullDate, m_nFilePos, i, nType ); + } + } + return sal_True; +} +// ------------------------------------------------------------------------- +void OCalcTable::FileClose() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::FileClose" ); + ::osl::MutexGuard aGuard(m_aMutex); + + OCalcTable_BASE::FileClose(); +} +// ------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/calc/CTables.cxx b/connectivity/source/drivers/calc/CTables.cxx new file mode 100644 index 000000000000..64066b681728 --- /dev/null +++ b/connectivity/source/drivers/calc/CTables.cxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CTables.hxx" +#include "calc/CTable.hxx" +#include "file/FCatalog.hxx" +#ifndef _CONNECTIVITY_FILE_BCONNECTION_HXX_ +#include "file/FConnection.hxx" +#endif +#include "calc/CCatalog.hxx" +#include <comphelper/types.hxx> +#include <rtl/logfile.hxx> + +using namespace ::comphelper; +using namespace connectivity; +using namespace connectivity::calc; +using namespace connectivity::file; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +namespace starutil = ::com::sun::star::util; + +sdbcx::ObjectType OCalcTables::createObject(const ::rtl::OUString& _rName) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTables::createObject" ); + OCalcTable* pTable = new OCalcTable(this,(OCalcConnection*)static_cast<OFileCatalog&>(m_rParent).getConnection(), + _rName,::rtl::OUString::createFromAscii("TABLE")); + sdbcx::ObjectType xRet = pTable; + pTable->construct(); + return xRet; +} +// ------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/calc/CalcDriver.xml b/connectivity/source/drivers/calc/CalcDriver.xml new file mode 100644 index 000000000000..a8d5715f8e44 --- /dev/null +++ b/connectivity/source/drivers/calc/CalcDriver.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//W3C//DTD HTML 3.2//EN" "module-description.dtd"> +<module-description> + <module-name>file</module-name> + <component-description> + <author>Niklas Nebel</author> + <name>com.sun.star.sdbc.driver.calc.ODriver</name> + <description>This library implements the database driver for spreadsheet (Calc) file formats. +</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="final"/> + <supported-service>com.sun.star.sdbc.Driver</supported-service> + <supported-service>com.sun.star.sdbcx.Driver</supported-service> + <service-dependency> ... </service-dependency> + </component-description> + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + <project-build-dependency>vos</project-build-dependency> + <runtime-module-dependency>cppuhelper</runtime-module-dependency> + <runtime-module-dependency>cppu</runtime-module-dependency> + <runtime-module-dependency>sal</runtime-module-dependency> + <runtime-module-dependency>vos</runtime-module-dependency> + <runtime-module-dependency>osl</runtime-module-dependency> + <runtime-module-dependency>svtools-light1</runtime-module-dependency> + <runtime-module-dependency>svtools</runtime-module-dependency> + <runtime-module-dependency>ucbhelper</runtime-module-dependency> + <runtime-module-dependency>dbtools</runtime-module-dependency> + <runtime-module-dependency>unotools</runtime-module-dependency> + <runtime-module-dependency>comphelper</runtime-module-dependency> +</module-description> diff --git a/connectivity/source/drivers/calc/Cservices.cxx b/connectivity/source/drivers/calc/Cservices.cxx new file mode 100644 index 000000000000..b172d9d4cf88 --- /dev/null +++ b/connectivity/source/drivers/calc/Cservices.cxx @@ -0,0 +1,175 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_connectivity.hxx" +#include "calc/CDriver.hxx" +#include <cppuhelper/factory.hxx> +#include <osl/diagnose.h> + +using namespace connectivity::calc; +using ::rtl::OUString; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::registry::XRegistryKey; +using ::com::sun::star::lang::XSingleServiceFactory; +using ::com::sun::star::lang::XMultiServiceFactory; + +typedef Reference< XSingleServiceFactory > (SAL_CALL *createFactoryFunc) + ( + const Reference< XMultiServiceFactory > & rServiceManager, + const OUString & rComponentName, + ::cppu::ComponentInstantiation pCreateFunction, + const Sequence< OUString > & rServiceNames, + rtl_ModuleCount* _pT + ); + +//*************************************************************************************** +// +// Die vorgeschriebene C-Api muss erfuellt werden! +// Sie besteht aus drei Funktionen, die von dem Modul exportiert werden muessen. +// + +//--------------------------------------------------------------------------------------- +void REGISTER_PROVIDER( + const OUString& aServiceImplName, + const Sequence< OUString>& Services, + const Reference< ::com::sun::star::registry::XRegistryKey > & xKey) +{ + OUString aMainKeyName; + aMainKeyName = OUString::createFromAscii("/"); + aMainKeyName += aServiceImplName; + aMainKeyName += OUString::createFromAscii("/UNO/SERVICES"); + + Reference< ::com::sun::star::registry::XRegistryKey > xNewKey( xKey->createKey(aMainKeyName) ); + OSL_ENSURE(xNewKey.is(), "FILE::component_writeInfo : could not create a registry key !"); + + for (sal_Int32 i=0; i<Services.getLength(); ++i) + xNewKey->createKey(Services[i]); +} + + +//--------------------------------------------------------------------------------------- +struct ProviderRequest +{ + Reference< XSingleServiceFactory > xRet; + Reference< XMultiServiceFactory > const xServiceManager; + OUString const sImplementationName; + + ProviderRequest( + void* pServiceManager, + sal_Char const* pImplementationName + ) + : xServiceManager(reinterpret_cast<XMultiServiceFactory*>(pServiceManager)) + , sImplementationName(OUString::createFromAscii(pImplementationName)) + { + } + + inline + sal_Bool CREATE_PROVIDER( + const OUString& Implname, + const Sequence< OUString > & Services, + ::cppu::ComponentInstantiation Factory, + createFactoryFunc creator + ) + { + if (!xRet.is() && (Implname == sImplementationName)) + try + { + xRet = creator( xServiceManager, sImplementationName,Factory, Services,0); + } + catch(...) + { + } + return xRet.is(); + } + + void* getProvider() const { return xRet.get(); } +}; + +//--------------------------------------------------------------------------------------- + +extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL +component_getImplementationEnvironment( + const sal_Char **ppEnvTypeName, + uno_Environment ** /*ppEnv*/ + ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//--------------------------------------------------------------------------------------- +extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( + void* /*pServiceManager*/, + void* pRegistryKey + ) +{ + if (pRegistryKey) + try + { + Reference< ::com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast< ::com::sun::star::registry::XRegistryKey*>(pRegistryKey)); + + REGISTER_PROVIDER( + ODriver::getImplementationName_Static(), + ODriver::getSupportedServiceNames_Static(), xKey); + + return sal_True; + } + catch (::com::sun::star::registry::InvalidRegistryException& ) + { + OSL_ENSURE(sal_False, "FILE::component_writeInfo : could not create a registry key ! ## InvalidRegistryException !"); + } + + return sal_False; +} + +//--------------------------------------------------------------------------------------- +extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( + const sal_Char* pImplementationName, + void* pServiceManager, + void* /*pRegistryKey*/) +{ + void* pRet = 0; + if (pServiceManager) + { + ProviderRequest aReq(pServiceManager,pImplementationName); + + aReq.CREATE_PROVIDER( + ODriver::getImplementationName_Static(), + ODriver::getSupportedServiceNames_Static(), + ODriver_CreateInstance, ::cppu::createSingleFactory) + ; + + if(aReq.xRet.is()) + aReq.xRet->acquire(); + + pRet = aReq.getProvider(); + } + + return pRet; +}; + diff --git a/connectivity/source/drivers/calc/calc.xcu b/connectivity/source/drivers/calc/calc.xcu new file mode 100755 index 000000000000..b7b494fdfa56 --- /dev/null +++ b/connectivity/source/drivers/calc/calc.xcu @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--*********************************************************************** + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************ --> +<oor:component-data oor:name="Drivers" oor:package="org.openoffice.Office.DataAccess" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <node oor:name="Installed"> + <node oor:name="sdbc:calc:*" oor:op="replace"> + <prop oor:name="Driver"> + <value>com.sun.star.comp.sdbc.calc.ODriver</value> + </prop> + <prop oor:name="DriverTypeDisplayName" oor:type="xs:string"> + <value xml:lang="en-US">Spreadsheet</value> + </prop> + <node oor:name="Features"> + <node oor:name="EscapeDateTime" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + </node> + <node oor:name="MetaData"> + <node oor:name="SupportsBrowsing" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="FileSystemBased" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="MediaType" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:string"> + <value>application/vnd.oasis.opendocument.spreadsheet</value> + </prop> + </node> + </node> + </node> + </node> +</oor:component-data> diff --git a/connectivity/source/drivers/calc/exports.dxp b/connectivity/source/drivers/calc/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/connectivity/source/drivers/calc/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/connectivity/source/drivers/calc/makefile.mk b/connectivity/source/drivers/calc/makefile.mk new file mode 100644 index 000000000000..8e193524aa45 --- /dev/null +++ b/connectivity/source/drivers/calc/makefile.mk @@ -0,0 +1,96 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=..$/.. +PRJNAME=connectivity +TARGET=calc + +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE + +# --- Settings ---------------------------------- +.IF "$(DBGUTIL_OJ)"!="" +ENVCFLAGS+=/FR$(SLO)$/ +.ENDIF + +.INCLUDE : $(PRJ)$/makefile.pmk +.INCLUDE : $(PRJ)$/version.mk + + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/CResultSet.obj \ + $(SLO)$/CStatement.obj \ + $(SLO)$/CPreparedStatement.obj \ + $(SLO)$/CDatabaseMetaData.obj \ + $(SLO)$/CCatalog.obj \ + $(SLO)$/CColumns.obj \ + $(SLO)$/CTable.obj \ + $(SLO)$/CTables.obj \ + $(SLO)$/CConnection.obj \ + $(SLO)$/Cservices.obj \ + $(SLO)$/CDriver.obj + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map + +# --- Library ----------------------------------- + +SHL1TARGET=$(TARGET)$(DLLPOSTFIX) +SHL1OBJS=$(SLOFILES) +SHL1STDLIBS=\ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SVLLIB) \ + $(TOOLSLIB) \ + $(UNOTOOLSLIB) \ + $(SALLIB) \ + $(DBTOOLSLIB) \ + $(DBFILELIB) \ + $(COMPHELPERLIB) + + +#.IF "$(DBFILELIB)" == "" +#SHL1STDLIBS+= ifile.lib +#.ENDIF + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + + +# --- Targets ---------------------------------- + +.INCLUDE : $(PRJ)$/target.pmk + + |