1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 30*cdf0e10cSrcweir #include "calc/CConnection.hxx" 31*cdf0e10cSrcweir #include "calc/CDatabaseMetaData.hxx" 32*cdf0e10cSrcweir #include "calc/CCatalog.hxx" 33*cdf0e10cSrcweir #ifndef _CONNECTIVITY_CALC_ODRIVER_HXX_ 34*cdf0e10cSrcweir #include "calc/CDriver.hxx" 35*cdf0e10cSrcweir #endif 36*cdf0e10cSrcweir #ifndef CONNECTIVITY_RESOURCE_CALC_HRC 37*cdf0e10cSrcweir #include "resource/calc_res.hrc" 38*cdf0e10cSrcweir #endif 39*cdf0e10cSrcweir #include "resource/sharedresources.hxx" 40*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 43*cdf0e10cSrcweir #include <tools/urlobj.hxx> 44*cdf0e10cSrcweir #include "calc/CPreparedStatement.hxx" 45*cdf0e10cSrcweir #include "calc/CStatement.hxx" 46*cdf0e10cSrcweir #include <unotools/pathoptions.hxx> 47*cdf0e10cSrcweir #include <connectivity/dbexception.hxx> 48*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx> 49*cdf0e10cSrcweir #include <rtl/logfile.hxx> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir using namespace connectivity::calc; 52*cdf0e10cSrcweir using namespace connectivity::file; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir typedef connectivity::file::OConnection OConnection_BASE; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir //------------------------------------------------------------------------------ 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 59*cdf0e10cSrcweir using namespace ::com::sun::star::beans; 60*cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 61*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 62*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 63*cdf0e10cSrcweir using namespace ::com::sun::star::frame; 64*cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir OCalcConnection::OCalcConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0) 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::OCalcConnection" ); 71*cdf0e10cSrcweir // m_aFilenameExtension is not used 72*cdf0e10cSrcweir } 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir OCalcConnection::~OCalcConnection() 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir void OCalcConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) 79*cdf0e10cSrcweir throw(SQLException) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::construct" ); 82*cdf0e10cSrcweir // open file 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir sal_Int32 nLen = url.indexOf(':'); 85*cdf0e10cSrcweir nLen = url.indexOf(':',nLen+1); 86*cdf0e10cSrcweir ::rtl::OUString aDSN(url.copy(nLen+1)); 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir m_aFileName = aDSN; 89*cdf0e10cSrcweir INetURLObject aURL; 90*cdf0e10cSrcweir aURL.SetSmartProtocol(INET_PROT_FILE); 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir SvtPathOptions aPathOptions; 93*cdf0e10cSrcweir m_aFileName = aPathOptions.SubstituteVariable(m_aFileName); 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir aURL.SetSmartURL(m_aFileName); 96*cdf0e10cSrcweir if ( aURL.GetProtocol() == INET_PROT_NOT_VALID ) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir // don't pass invalid URL to loadComponentFromURL 99*cdf0e10cSrcweir throw SQLException(); 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir m_aFileName = aURL.GetMainURL(INetURLObject::NO_DECODE); 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir m_sPassword = ::rtl::OUString(); 104*cdf0e10cSrcweir const char* pPwd = "password"; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir const PropertyValue *pIter = info.getConstArray(); 107*cdf0e10cSrcweir const PropertyValue *pEnd = pIter + info.getLength(); 108*cdf0e10cSrcweir for(;pIter != pEnd;++pIter) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir if(!pIter->Name.compareToAscii(pPwd)) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir pIter->Value >>= m_sPassword; 113*cdf0e10cSrcweir break; 114*cdf0e10cSrcweir } 115*cdf0e10cSrcweir } // for(;pIter != pEnd;++pIter) 116*cdf0e10cSrcweir ODocHolder aDocHodler(this); // just to test that the doc can be loaded 117*cdf0e10cSrcweir acquireDoc(); 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 120*cdf0e10cSrcweir Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc() 121*cdf0e10cSrcweir { 122*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::acquireDoc" ); 123*cdf0e10cSrcweir if ( m_xDoc.is() ) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir osl_incrementInterlockedCount(&m_nDocCount); 126*cdf0e10cSrcweir return m_xDoc; 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir // open read-only as long as updating isn't implemented 129*cdf0e10cSrcweir Sequence<PropertyValue> aArgs(2); 130*cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden"); 131*cdf0e10cSrcweir aArgs[0].Value <<= (sal_Bool) sal_True; 132*cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly"); 133*cdf0e10cSrcweir aArgs[1].Value <<= (sal_Bool) sal_True; 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir if ( m_sPassword.getLength() ) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir const sal_Int32 nPos = aArgs.getLength(); 138*cdf0e10cSrcweir aArgs.realloc(nPos+1); 139*cdf0e10cSrcweir aArgs[nPos].Name = ::rtl::OUString::createFromAscii("Password"); 140*cdf0e10cSrcweir aArgs[nPos].Value <<= m_sPassword; 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir Reference< XComponentLoader > xDesktop( getDriver()->getFactory()->createInstance( 144*cdf0e10cSrcweir ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY ); 145*cdf0e10cSrcweir if (!xDesktop.is()) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir OSL_ASSERT("no desktop"); 148*cdf0e10cSrcweir throw SQLException(); 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir Reference< XComponent > xComponent; 151*cdf0e10cSrcweir Any aLoaderException; 152*cdf0e10cSrcweir try 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir xComponent = xDesktop->loadComponentFromURL( 155*cdf0e10cSrcweir m_aFileName, ::rtl::OUString::createFromAscii("_blank"), 0, aArgs ); 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir catch( const Exception& ) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir aLoaderException = ::cppu::getCaughtException(); 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir m_xDoc.set(xComponent, UNO_QUERY ); 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir // if the URL is not a spreadsheet document, throw the exception here 165*cdf0e10cSrcweir // instead of at the first access to it 166*cdf0e10cSrcweir if ( !m_xDoc.is() ) 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir Any aErrorDetails; 169*cdf0e10cSrcweir if ( aLoaderException.hasValue() ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir Exception aLoaderError; 172*cdf0e10cSrcweir OSL_VERIFY( aLoaderException >>= aLoaderError ); 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir SQLException aDetailException; 175*cdf0e10cSrcweir aDetailException.Message = m_aResources.getResourceStringWithSubstitution( 176*cdf0e10cSrcweir STR_LOAD_FILE_ERROR_MESSAGE, 177*cdf0e10cSrcweir "$exception_type$", aLoaderException.getValueTypeName(), 178*cdf0e10cSrcweir "$error_message$", aLoaderError.Message 179*cdf0e10cSrcweir ); 180*cdf0e10cSrcweir aErrorDetails <<= aDetailException; 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir const ::rtl::OUString sError( m_aResources.getResourceStringWithSubstitution( 184*cdf0e10cSrcweir STR_COULD_NOT_LOAD_FILE, 185*cdf0e10cSrcweir "$filename$", m_aFileName 186*cdf0e10cSrcweir ) ); 187*cdf0e10cSrcweir ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir osl_incrementInterlockedCount(&m_nDocCount); 190*cdf0e10cSrcweir return m_xDoc; 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 193*cdf0e10cSrcweir void OCalcConnection::releaseDoc() 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::releaseDoc" ); 196*cdf0e10cSrcweir if ( osl_decrementInterlockedCount(&m_nDocCount) == 0 ) 197*cdf0e10cSrcweir ::comphelper::disposeComponent( m_xDoc ); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 200*cdf0e10cSrcweir void OCalcConnection::disposing() 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::disposing" ); 203*cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir m_nDocCount = 0; 206*cdf0e10cSrcweir ::comphelper::disposeComponent( m_xDoc ); 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir OConnection::disposing(); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir // XServiceInfo 212*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(OCalcConnection, "com.sun.star.sdbc.drivers.calc.Connection", "com.sun.star.sdbc.Connection") 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir Reference< XDatabaseMetaData > SAL_CALL OCalcConnection::getMetaData( ) throw(SQLException, RuntimeException) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::getMetaData" ); 221*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 222*cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed); 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir Reference< XDatabaseMetaData > xMetaData = m_xMetaData; 226*cdf0e10cSrcweir if(!xMetaData.is()) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir xMetaData = new OCalcDatabaseMetaData(this); 229*cdf0e10cSrcweir m_xMetaData = xMetaData; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir return xMetaData; 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir //------------------------------------------------------------------------------ 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir ::com::sun::star::uno::Reference< XTablesSupplier > OCalcConnection::createCatalog() 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createCatalog" ); 240*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 241*cdf0e10cSrcweir Reference< XTablesSupplier > xTab = m_xCatalog; 242*cdf0e10cSrcweir if(!xTab.is()) 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir OCalcCatalog *pCat = new OCalcCatalog(this); 245*cdf0e10cSrcweir xTab = pCat; 246*cdf0e10cSrcweir m_xCatalog = xTab; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir return xTab; 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir Reference< XStatement > SAL_CALL OCalcConnection::createStatement( ) throw(SQLException, RuntimeException) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::createStatement" ); 256*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 257*cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir Reference< XStatement > xReturn = new OCalcStatement(this); 261*cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(xReturn)); 262*cdf0e10cSrcweir return xReturn; 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareStatement( const ::rtl::OUString& sql ) 268*cdf0e10cSrcweir throw(SQLException, RuntimeException) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareStatement" ); 271*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 272*cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed); 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir OCalcPreparedStatement* pStmt = new OCalcPreparedStatement(this); 276*cdf0e10cSrcweir Reference< XPreparedStatement > xHoldAlive = pStmt; 277*cdf0e10cSrcweir pStmt->construct(sql); 278*cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(*pStmt)); 279*cdf0e10cSrcweir return pStmt; 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir // -------------------------------------------------------------------------------- 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OCalcConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) 285*cdf0e10cSrcweir throw(SQLException, RuntimeException) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcConnection::prepareCall" ); 288*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 289*cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this ); 292*cdf0e10cSrcweir return NULL; 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 295*cdf0e10cSrcweir 296