/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #include #include "file/FConnection.hxx" #include "file/FDatabaseMetaData.hxx" #include "file/FDriver.hxx" #include "file/FStatement.hxx" #include "file/FPreparedStatement.hxx" #include #include #include #include #include #include #include #include "file/FCatalog.hxx" #include #include #include #include #include #include #include "resource/file_res.hrc" using namespace connectivity::file; using namespace dbtools; //------------------------------------------------------------------------------ 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::ucb; using namespace ::ucbhelper; using rtl::OUString; typedef connectivity::OMetaConnection OConnection_BASE; // -------------------------------------------------------------------------------- OConnection::OConnection(OFileDriver* _pDriver) : OSubComponent((::cppu::OWeakObject*)_pDriver, this) ,m_pDriver(_pDriver) ,m_bClosed(sal_False) ,m_bShowDeleted(sal_False) ,m_bCaseSensitiveExtension( sal_True ) ,m_bCheckSQL92(sal_False) ,m_bDefaultTextEncoding(false) { m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW; } //----------------------------------------------------------------------------- OConnection::~OConnection() { if(!isClosed( )) close(); } //----------------------------------------------------------------------------- void SAL_CALL OConnection::release() throw() { relase_ChildImpl(); } //----------------------------------------------------------------------------- sal_Bool OConnection::matchesExtension( const String& _rExt ) const { if ( isCaseSensitveExtension() ) return ( getExtension() == _rExt ); String sMyExtension( getExtension() ); sMyExtension.ToLowerAscii(); String sExt( _rExt ); sExt.ToLowerAscii(); return sMyExtension == sExt; } //----------------------------------------------------------------------------- void OConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException) { osl_incrementInterlockedCount( &m_refCount ); ::rtl::OUString aExt; const PropertyValue *pIter = info.getConstArray(); const PropertyValue *pEnd = pIter + info.getLength(); for(;pIter != pEnd;++pIter) { if(0 == pIter->Name.compareToAscii("Extension")) OSL_VERIFY( pIter->Value >>= aExt ); else if(0 == pIter->Name.compareToAscii("CharSet")) { ::rtl::OUString sIanaName; OSL_VERIFY( pIter->Value >>= sIanaName ); ::dbtools::OCharsetMap aLookupIanaName; ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA()); if (aLookup != aLookupIanaName.end()) m_nTextEncoding = (*aLookup).getEncoding(); else m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW; } else if (0 == pIter->Name.compareToAscii("ShowDeleted")) { OSL_VERIFY( pIter->Value >>= m_bShowDeleted ); } else if (0 == pIter->Name.compareToAscii("EnableSQL92Check")) { pIter->Value >>= m_bCheckSQL92; } } // for(;pIter != pEnd;++pIter) { sal_Int32 nLen = url.indexOf(':'); nLen = url.indexOf(':',nLen+1); ::rtl::OUString aDSN(url.copy(nLen+1)),aUID,aPWD; String aFileName = aDSN; INetURLObject aURL; aURL.SetSmartProtocol(INET_PROT_FILE); { SvtPathOptions aPathOptions; aFileName = aPathOptions.SubstituteVariable(aFileName); } aURL.SetSmartURL(aFileName); setURL(aURL.GetMainURL(INetURLObject::NO_DECODE)); } if ( m_nTextEncoding == RTL_TEXTENCODING_DONTKNOW ) { //m_nTextEncoding = osl_getTextEncodingFromLocale(NULL); m_nTextEncoding = osl_getThreadTextEncoding(); m_bDefaultTextEncoding = true; } if ( aExt.getLength() ) m_aFilenameExtension = aExt; try { ::ucbhelper::Content aFile; try { aFile = ::ucbhelper::Content(getURL(),Reference< XCommandEnvironment >()); } catch(ContentCreationException& e) { throwUrlNotValid(getURL(),e.Message); } // set fields to fetch Sequence< OUString > aProps(1); OUString* pProps = aProps.getArray(); pProps[ 0 ] = OUString::createFromAscii( "Title" ); try { if (aFile.isFolder()) { m_xDir = aFile.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ); m_xContent = aFile.get(); } else if (aFile.isDocument()) { Reference xParent(Reference(aFile.get(),UNO_QUERY)->getParent(),UNO_QUERY); Reference xIdent = xParent->getIdentifier(); m_xContent = xParent; ::ucbhelper::Content aParent(xIdent->getContentIdentifier(),Reference< XCommandEnvironment >()); m_xDir = aParent.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ); } else { OSL_ENSURE(0,"OConnection::construct: ::ucbhelper::Content isn't a folde nor a document! How that?!"); throw SQLException(); } } catch(Exception& e) // a execption is thrown when no file exists { throwUrlNotValid(getURL(),e.Message); } if(!m_xDir.is() || !m_xContent.is()) throwUrlNotValid(getURL(),::rtl::OUString()); if (m_aFilenameExtension.Search('*') != STRING_NOTFOUND || m_aFilenameExtension.Search('?') != STRING_NOTFOUND) throw SQLException(); } catch(const Exception&) { osl_decrementInterlockedCount( &m_refCount ); throw; } osl_decrementInterlockedCount( &m_refCount ); } // XServiceInfo // -------------------------------------------------------------------------------- IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.file.Connection", "com.sun.star.sdbc.Connection") // -------------------------------------------------------------------------------- Reference< XStatement > SAL_CALL OConnection::createStatement( ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); Reference< XStatement > xReturn = new OStatement(this); m_aStatements.push_back(WeakReferenceHelper(xReturn)); return xReturn; } // -------------------------------------------------------------------------------- Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); OPreparedStatement* pStmt = new OPreparedStatement(this); Reference< XPreparedStatement > xHoldAlive = pStmt; pStmt->construct(sql); m_aStatements.push_back(WeakReferenceHelper(*pStmt)); return pStmt; } // -------------------------------------------------------------------------------- Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException) { throwFeatureNotImplementedException( "XConnection::prepareCall", *this ); return NULL; } // -------------------------------------------------------------------------------- ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException) { return sql; } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); m_bAutoCommit = autoCommit; } // -------------------------------------------------------------------------------- sal_Bool SAL_CALL OConnection::getAutoCommit( ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); return m_bAutoCommit; } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::commit( ) throw(SQLException, RuntimeException) { } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::rollback( ) throw(SQLException, RuntimeException) { } // -------------------------------------------------------------------------------- sal_Bool SAL_CALL OConnection::isClosed( ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); return OConnection_BASE::rBHelper.bDisposed; } // -------------------------------------------------------------------------------- Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData( ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); Reference< XDatabaseMetaData > xMetaData = m_xMetaData; if(!xMetaData.is()) { xMetaData = new ODatabaseMetaData(this); m_xMetaData = xMetaData; } return xMetaData; } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); m_bReadOnly = readOnly; } // -------------------------------------------------------------------------------- sal_Bool SAL_CALL OConnection::isReadOnly( ) throw(SQLException, RuntimeException) { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); return m_bReadOnly; } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& /*catalog*/ ) throw(SQLException, RuntimeException) { throwFeatureNotImplementedException( "XConnection::setCatalog", *this ); } // -------------------------------------------------------------------------------- ::rtl::OUString SAL_CALL OConnection::getCatalog( ) throw(SQLException, RuntimeException) { return ::rtl::OUString(); } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 /*level*/ ) throw(SQLException, RuntimeException) { throwFeatureNotImplementedException( "XConnection::setTransactionIsolation", *this ); } // -------------------------------------------------------------------------------- sal_Int32 SAL_CALL OConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException) { return 0; } // -------------------------------------------------------------------------------- Reference< XNameAccess > SAL_CALL OConnection::getTypeMap( ) throw(SQLException, RuntimeException) { return NULL; } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::setTypeMap( const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException) { } // -------------------------------------------------------------------------------- // XCloseable void SAL_CALL OConnection::close( ) throw(SQLException, RuntimeException) { { ::osl::MutexGuard aGuard( m_aMutex ); checkDisposed(OConnection_BASE::rBHelper.bDisposed); } dispose(); } // -------------------------------------------------------------------------------- // XWarningsSupplier Any SAL_CALL OConnection::getWarnings( ) throw(SQLException, RuntimeException) { return Any(); } // -------------------------------------------------------------------------------- void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException) { } //------------------------------------------------------------------------------ void OConnection::disposing() { ::osl::MutexGuard aGuard(m_aMutex); OConnection_BASE::disposing(); m_bClosed = sal_True; m_xDir.clear(); m_xContent.clear(); m_xCatalog = WeakReference< XTablesSupplier>(); dispose_ChildImpl(); } //------------------------------------------------------------------------------ Reference< XTablesSupplier > OConnection::createCatalog() { ::osl::MutexGuard aGuard( m_aMutex ); Reference< XTablesSupplier > xTab = m_xCatalog; if(!xTab.is()) { xTab = new OFileCatalog(this); m_xCatalog = xTab; } return xTab; } // ----------------------------------------------------------------------------- Reference< XDynamicResultSet > OConnection::getDir() const { Reference xContent; Sequence< ::rtl::OUString > aProps(1); ::rtl::OUString* pProps = aProps.getArray(); pProps[ 0 ] = ::rtl::OUString::createFromAscii( "Title" ); try { Reference xIdent = getContent()->getIdentifier(); ::ucbhelper::Content aParent(xIdent->getContentIdentifier(),Reference< XCommandEnvironment >()); xContent = aParent.createDynamicCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ); } catch(Exception&) { } return xContent; } // ----------------------------------------------------------------------------- sal_Int64 SAL_CALL OConnection::getSomething( const Sequence< sal_Int8 >& rId ) throw (RuntimeException) { return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) ? reinterpret_cast< sal_Int64 >( this ) : (sal_Int64)0; } // ----------------------------------------------------------------------------- Sequence< sal_Int8 > OConnection::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(); } // ----------------------------------------------------------------------------- void OConnection::throwUrlNotValid(const ::rtl::OUString & _rsUrl,const ::rtl::OUString & _rsMessage) { SQLException aError; aError.Message = getResources().getResourceStringWithSubstitution( STR_NO_VALID_FILE_URL, "$URL$", _rsUrl ); aError.SQLState = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")); aError.ErrorCode = 0; aError.Context = static_cast< XConnection* >(this); if (_rsMessage.getLength()) aError.NextException <<= SQLException(_rsMessage, aError.Context, ::rtl::OUString(), 0, Any()); throw aError; } // -----------------------------------------------------------------------------