diff options
Diffstat (limited to 'connectivity/source/drivers/hsqldb')
29 files changed, 5764 insertions, 0 deletions
diff --git a/connectivity/source/drivers/hsqldb/HCatalog.cxx b/connectivity/source/drivers/hsqldb/HCatalog.cxx new file mode 100644 index 000000000000..48ae5dbdb9a3 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HCatalog.cxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * 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 "hsqldb/HCatalog.hxx" +#include "hsqldb/HUsers.hxx" +#include "hsqldb/HTables.hxx" +#include "hsqldb/HViews.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <comphelper/types.hxx> + + +// ------------------------------------------------------------------------- +using namespace connectivity; +using namespace connectivity::hsqldb; +//using namespace connectivity::sdbcx; +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; +// ------------------------------------------------------------------------- +OHCatalog::OHCatalog(const Reference< XConnection >& _xConnection) : sdbcx::OCatalog(_xConnection) + ,m_xConnection(_xConnection) +{ +} +// ----------------------------------------------------------------------------- +void OHCatalog::refreshObjects(const Sequence< ::rtl::OUString >& _sKindOfObject,TStringVector& _rNames) +{ + Reference< XResultSet > xResult = m_xMetaData->getTables(Any(), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")), + _sKindOfObject); + fillNames(xResult,_rNames); +} +// ------------------------------------------------------------------------- +void OHCatalog::refreshTables() +{ + TStringVector aVector; + static const ::rtl::OUString s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW")); + static const ::rtl::OUString s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE")); + + Sequence< ::rtl::OUString > sTableTypes(2); + sTableTypes[0] = s_sTableTypeView; + sTableTypes[1] = s_sTableTypeTable; + + refreshObjects(sTableTypes,aVector); + + if ( m_pTables ) + m_pTables->reFill(aVector); + else + m_pTables = new OTables(m_xMetaData,*this,m_aMutex,aVector); +} +// ------------------------------------------------------------------------- +void OHCatalog::refreshViews() +{ + Sequence< ::rtl::OUString > aTypes(1); + aTypes[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")); + + sal_Bool bSupportsViews = sal_False; + try + { + Reference<XResultSet> xRes = m_xMetaData->getTableTypes(); + Reference<XRow> xRow(xRes,UNO_QUERY); + while ( xRow.is() && xRes->next() ) + { + if ( (bSupportsViews = xRow->getString(1).equalsIgnoreAsciiCase(aTypes[0])) ) + { + break; + } + } + } + catch(const SQLException&) + { + } + + TStringVector aVector; + if ( bSupportsViews ) + refreshObjects(aTypes,aVector); + + if ( m_pViews ) + m_pViews->reFill(aVector); + else + m_pViews = new HViews( m_xConnection, *this, m_aMutex, aVector ); +} +// ------------------------------------------------------------------------- +void OHCatalog::refreshGroups() +{ +} +// ------------------------------------------------------------------------- +void OHCatalog::refreshUsers() +{ + TStringVector aVector; + Reference< XStatement > xStmt = m_xConnection->createStatement( ); + Reference< XResultSet > xResult = xStmt->executeQuery(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("select User from hsqldb.user group by User"))); + if ( xResult.is() ) + { + Reference< XRow > xRow(xResult,UNO_QUERY); + TString2IntMap aMap; + while( xResult->next() ) + aVector.push_back(xRow->getString(1)); + ::comphelper::disposeComponent(xResult); + } + ::comphelper::disposeComponent(xStmt); + + if(m_pUsers) + m_pUsers->reFill(aVector); + else + m_pUsers = new OUsers(*this,m_aMutex,aVector,m_xConnection,this); +} +// ----------------------------------------------------------------------------- +Any SAL_CALL OHCatalog::queryInterface( const Type & rType ) throw(RuntimeException) +{ + if ( rType == ::getCppuType((const Reference<XGroupsSupplier>*)0) ) + return Any(); + + return OCatalog::queryInterface(rType); +} +// ----------------------------------------------------------------------------- +Sequence< Type > SAL_CALL OHCatalog::getTypes( ) throw(RuntimeException) +{ + Sequence< Type > aTypes = OCatalog::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<XGroupsSupplier>*)0))) + { + aOwnTypes.push_back(*pBegin); + } + } + const Type* pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0]; + return Sequence< Type >(pTypes, aOwnTypes.size()); +} +// ----------------------------------------------------------------------------- + + diff --git a/connectivity/source/drivers/hsqldb/HColumns.cxx b/connectivity/source/drivers/hsqldb/HColumns.cxx new file mode 100644 index 000000000000..be9bf65b3f69 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HColumns.cxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * 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 "hsqldb/HColumns.hxx" +#include "TConnection.hxx" + + +using namespace ::comphelper; +using namespace connectivity::hsqldb; +using namespace connectivity::sdbcx; +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; +using namespace ::com::sun::star::lang; + +OHSQLColumns::OHSQLColumns( ::cppu::OWeakObject& _rParent + ,sal_Bool _bCase + ,::osl::Mutex& _rMutex + ,const TStringVector &_rVector + ,sal_Bool _bUseHardRef + ) : OColumnsHelper(_rParent,_bCase,_rMutex,_rVector,_bUseHardRef) +{ +} +// ----------------------------------------------------------------------------- +Reference< XPropertySet > OHSQLColumns::createDescriptor() +{ + return new OHSQLColumn(sal_True); +} +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +OHSQLColumn::OHSQLColumn( sal_Bool _bCase) + : connectivity::sdbcx::OColumn( _bCase ) +{ + construct(); +} +// ------------------------------------------------------------------------- +void OHSQLColumn::construct() +{ + m_sAutoIncrement = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IDENTITY")); + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION),PROPERTY_ID_AUTOINCREMENTCREATION,0,&m_sAutoIncrement, ::getCppuType(&m_sAutoIncrement)); +} +// ----------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper* OHSQLColumn::createArrayHelper( sal_Int32 /*_nId*/ ) const +{ + return doCreateArrayHelper(); +} +// ----------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper & SAL_CALL OHSQLColumn::getInfoHelper() +{ + return *OHSQLColumn_PROP::getArrayHelper(isNew() ? 1 : 0); +} +// ----------------------------------------------------------------------------- +Sequence< ::rtl::OUString > SAL_CALL OHSQLColumn::getSupportedServiceNames( ) throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(1); + aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Column"); + + return aSupported; +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/HConnection.cxx b/connectivity/source/drivers/hsqldb/HConnection.cxx new file mode 100644 index 000000000000..a786eac84398 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HConnection.cxx @@ -0,0 +1,422 @@ +/************************************************************************* + * + * 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 "hsqldb/HConnection.hxx" +#include "hsqldb/HTools.hxx" +#include "hsqlui.hrc" + +#include <connectivity/dbtools.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/graphic/GraphicColorMode.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/sdbc/XDatabaseMetaData2.hpp> +/** === end UNO includes === **/ + +#include <comphelper/componentcontext.hxx> +#include <comphelper/listenernotification.hxx> +#include <comphelper/sequence.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <rtl/ustrbuf.hxx> +#include <tools/diagnose_ex.h> + +#include "resource/sharedresources.hxx" +#include "resource/hsqldb_res.hrc" + +/** === begin UNO using === **/ +using ::com::sun::star::util::XFlushListener; +using ::com::sun::star::lang::EventObject; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::sdbc::XStatement; +using ::com::sun::star::sdbc::XConnection; +using ::com::sun::star::sdbcx::XDataDefinitionSupplier; +using ::com::sun::star::sdbcx::XTablesSupplier; +using ::com::sun::star::container::XNameAccess; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::lang::WrappedTargetException; +using ::com::sun::star::lang::ServiceNotRegisteredException; +using ::com::sun::star::sdbc::XDriver; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::graphic::XGraphic; +using ::com::sun::star::graphic::XGraphicProvider; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::ui::dialogs::XExecutableDialog; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::sdbc::XResultSet; +using ::com::sun::star::sdbc::XDatabaseMetaData; +using ::com::sun::star::sdbc::XDatabaseMetaData2; +using ::com::sun::star::sdbc::XRow; +using ::com::sun::star::sdb::application::XDatabaseDocumentUI; +using ::com::sun::star::beans::PropertyValue; +/** === end UNO using === **/ +namespace GraphicColorMode = ::com::sun::star::graphic::GraphicColorMode; + +namespace connectivity { namespace hsqldb +{ + // ============================================================================= + // = FlushListeners + // ============================================================================= + typedef ::comphelper::OListenerContainerBase< XFlushListener, EventObject > FlushListeners_Base; + class FlushListeners : public FlushListeners_Base + { + public: + FlushListeners( ::osl::Mutex& _rMutex ) :FlushListeners_Base( _rMutex ) { } + + protected: + virtual bool implTypedNotify( + const Reference< XFlushListener >& _rxListener, + const EventObject& _rEvent + ) SAL_THROW( ( Exception ) ); + }; + + // ----------------------------------------------------------------------------- + bool FlushListeners::implTypedNotify( const Reference< XFlushListener >& _rxListener, const EventObject& _rEvent ) SAL_THROW( ( Exception ) ) + { + _rxListener->flushed( _rEvent ); + return true; // continue notifying the other listeners, if any + } + + // ============================================================================= + // = OHsqlConnection + // ============================================================================= + // ----------------------------------------------------------------------------- + void SAL_CALL OHsqlConnection::disposing(void) + { + m_aFlushListeners.disposeAndClear( EventObject( *this ) ); + OHsqlConnection_BASE::disposing(); + OConnectionWrapper::disposing(); + } + // ----------------------------------------------------------------------------- + OHsqlConnection::OHsqlConnection( const Reference< XDriver > _rxDriver, + const Reference< XConnection >& _xConnection ,const Reference< XMultiServiceFactory>& _xORB ) + :OHsqlConnection_BASE( m_aMutex ) + ,m_aFlushListeners( m_aMutex ) + ,m_xDriver( _rxDriver ) + ,m_xORB( _xORB ) + ,m_bIni(true) + ,m_bReadOnly(false) + { + setDelegation(_xConnection,_xORB,m_refCount); + } + // ----------------------------------------------------------------------------- + OHsqlConnection::~OHsqlConnection() + { + if ( !OHsqlConnection_BASE::rBHelper.bDisposed ) + { + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } + } + // ----------------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2(OHsqlConnection,OHsqlConnection_BASE,OConnectionWrapper) + IMPLEMENT_SERVICE_INFO(OHsqlConnection, "com.sun.star.sdbc.drivers.hsqldb.OHsqlConnection", "com.sun.star.sdbc.Connection") + IMPLEMENT_FORWARD_XTYPEPROVIDER2(OHsqlConnection,OHsqlConnection_BASE,OConnectionWrapper) + + //-------------------------------------------------------------------- + ::osl::Mutex& OHsqlConnection::getMutex() const + { + return m_aMutex; + } + + //-------------------------------------------------------------------- + void OHsqlConnection::checkDisposed() const + { + ::connectivity::checkDisposed( rBHelper.bDisposed ); + } + + // XFlushable + //-------------------------------------------------------------------- + void SAL_CALL OHsqlConnection::flush( ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + try + { + if ( m_xConnection.is() ) + { + if ( m_bIni ) + { + m_bIni = false; + Reference< XDatabaseMetaData2 > xMeta2(m_xConnection->getMetaData(),UNO_QUERY_THROW); + const Sequence< PropertyValue > aInfo = xMeta2->getConnectionInfo(); + const PropertyValue* pIter = aInfo.getConstArray(); + const PropertyValue* pEnd = pIter + aInfo.getLength(); + for(;pIter != pEnd;++pIter) + { + if ( pIter->Name.compareToAscii("readonly") == 0 ) + m_bReadOnly = true; + } + } + if ( !m_bReadOnly ) + { + Reference< XStatement > xStmt( m_xConnection->createStatement(), UNO_QUERY_THROW ); + xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CHECKPOINT" ) ) ); + } + } + + EventObject aFlushedEvent( *this ); + m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent ); + } + catch(const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL OHsqlConnection::addFlushListener( const Reference< XFlushListener >& l ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aFlushListeners.addInterface( l ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OHsqlConnection::removeFlushListener( const Reference< XFlushListener >& l ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aFlushListeners.removeInterface( l ); + } + + // ------------------------------------------------------------------- + Reference< XGraphic > SAL_CALL OHsqlConnection::getTableIcon( const ::rtl::OUString& _TableName, ::sal_Int32 _ColorMode ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + impl_checkExistingTable_throw( _TableName ); + if ( !impl_isTextTable_nothrow( _TableName ) ) + return NULL; + + return impl_getTextTableIcon_nothrow( _ColorMode ); + } + + // ------------------------------------------------------------------- + Reference< XInterface > SAL_CALL OHsqlConnection::getTableEditor( const Reference< XDatabaseDocumentUI >& _DocumentUI, const ::rtl::OUString& _TableName ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException) + { + MethodGuard aGuard( *this ); + + impl_checkExistingTable_throw( _TableName ); + if ( !impl_isTextTable_nothrow( _TableName ) ) + return NULL; + + if ( !_DocumentUI.is() ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceString(STR_NO_DOCUMENTUI)); + throw IllegalArgumentException( + sError, + *this, + 0 + ); + } // if ( !_DocumentUI.is() ) + + +// Reference< XExecutableDialog > xEditor = impl_createLinkedTableEditor_throw( _DocumentUI, _TableName ); +// return xEditor.get(); + return NULL; + // editor not yet implemented in this CWS + } + + // ------------------------------------------------------------------- + Reference< XNameAccess > OHsqlConnection::impl_getTableContainer_throw() + { + Reference< XNameAccess > xTables; + try + { + Reference< XConnection > xMe( *this, UNO_QUERY ); + Reference< XDataDefinitionSupplier > xDefinitionsSupp( m_xDriver, UNO_QUERY_THROW ); + Reference< XTablesSupplier > xTablesSupp( xDefinitionsSupp->getDataDefinitionByConnection( xMe ), UNO_QUERY_THROW ); + xTables.set( xTablesSupp->getTables(), UNO_QUERY_THROW ); + } + catch( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceString(STR_NO_TABLE_CONTAINER)); + throw WrappedTargetException( sError ,*this, ::cppu::getCaughtException() ); + } + + OSL_POSTCOND( xTables.is(), "OHsqlConnection::impl_getTableContainer_throw: post condition not met!" ); + return xTables; + } + + //TODO: resource +#if 0 + // ------------------------------------------------------------------- + Reference< XExecutableDialog > OHsqlConnection::impl_createLinkedTableEditor_throw( const Reference< XDatabaseDocumentUI >& _rxDocumentUI, const ::rtl::OUString& _rTableName ) + { + OSL_PRECOND( _rxDocumentUI.is(), "OHsqlConnection::impl_createLinkedTableEditor_throw: illegal document UI!" ); + Reference< XExecutableDialog > xDialog; + try + { + ::comphelper::ComponentContext aContext( m_xORB ); + Sequence< Any > aArguments(3); + aArguments[0] <<= NamedValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableContainer" ) ), + makeAny( impl_getTableContainer_throw() ) + ); + aArguments[1] <<= NamedValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TableName" ) ), + makeAny( _rTableName ) + ); + aArguments[2] <<= NamedValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ), + makeAny( _rxDocumentUI->getApplicationMainWindow() ) + ); + + aContext.createComponentWithArguments( "com.sun.star.sdb.hsql.LinkedTableEditor", aArguments, xDialog ); + if ( !xDialog.is() ) + throw ServiceNotRegisteredException( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.hsql.LinkedTableEditor" ), *this ); + } + catch( const RuntimeException& ) { throw; } + catch( const Exception& ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceString(STR_NO_TABLE_EDITOR_DIALOG)); + throw WrappedTargetException( sError ,*this, ::cppu::getCaughtException() ); + } + return xDialog; + } +#endif + + // ------------------------------------------------------------------- + void OHsqlConnection::impl_checkExistingTable_throw( const ::rtl::OUString& _rTableName ) + { + bool bDoesExist = false; + try + { + Reference< XNameAccess > xTables( impl_getTableContainer_throw(), UNO_QUERY_THROW ); + if ( xTables.is() ) + bDoesExist = xTables->hasByName( _rTableName ); + } + catch( const Exception& ) + { + // that's a serious error in impl_getTableContainer_throw, or hasByName, however, we're only + // allowed to throw an IllegalArgumentException ourself + DBG_UNHANDLED_EXCEPTION(); + } + + if ( !bDoesExist ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution( + STR_NO_TABLENAME, + "$tablename$", _rTableName + )); + throw IllegalArgumentException( sError,*this, 0 ); + } // if ( !bDoesExist ) + } + + // ------------------------------------------------------------------- + bool OHsqlConnection::impl_isTextTable_nothrow( const ::rtl::OUString& _rTableName ) + { + bool bIsTextTable = false; + try + { + Reference< XConnection > xMe( *this, UNO_QUERY_THROW ); + + // split the fully qualified name + Reference< XDatabaseMetaData > xMetaData( xMe->getMetaData(), UNO_QUERY_THROW ); + ::rtl::OUString sCatalog, sSchema, sName; + ::dbtools::qualifiedNameComponents( xMetaData, _rTableName, sCatalog, sSchema, sName, ::dbtools::eComplete ); + + // get the table information + ::rtl::OUStringBuffer sSQL; + sSQL.appendAscii( "SELECT HSQLDB_TYPE FROM INFORMATION_SCHEMA.SYSTEM_TABLES" ); + HTools::appendTableFilterCrit( sSQL, sCatalog, sSchema, sName, true ); + sSQL.appendAscii( " AND TABLE_TYPE = 'TABLE'" ); + + Reference< XStatement > xStatement( xMe->createStatement(), UNO_QUERY_THROW ); + Reference< XResultSet > xTableHsqlType( xStatement->executeQuery( sSQL.makeStringAndClear() ), UNO_QUERY_THROW ); + + if ( xTableHsqlType->next() ) // might not succeed in case of VIEWs + { + Reference< XRow > xValueAccess( xTableHsqlType, UNO_QUERY_THROW ); + ::rtl::OUString sTableType = xValueAccess->getString( 1 ); + bIsTextTable = sTableType.equalsAscii( "TEXT" ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return bIsTextTable; + } + + // ------------------------------------------------------------------- + Reference< XGraphic > OHsqlConnection::impl_getTextTableIcon_nothrow( ::sal_Int32 _ColorMode ) + { + Reference< XGraphic > xGraphic; + try + { + // create a graphic provider + Reference< XGraphicProvider > xProvider; + if ( m_xORB.is() ) + xProvider.set( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ), UNO_QUERY_THROW ); + + // assemble the image URL + ::rtl::OUStringBuffer aImageURL; + aImageURL.appendAscii( "private:graphicrepository/" ); // load the graphic from the global graphic repository + aImageURL.appendAscii( "database/" ); // the relative path within the images.zip + if ( _ColorMode == GraphicColorMode::NORMAL ) + aImageURL.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE ); + else + aImageURL.appendAscii( LINKED_TEXT_TABLE_IMAGE_RESOURCE_HC ); + // the name of the graphic to use + ::rtl::OUString sImageURL( aImageURL.makeStringAndClear() ); + + // ask the provider to obtain a graphic + Sequence< PropertyValue > aMediaProperties( 1 ); + aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aMediaProperties[0].Value <<= sImageURL; + xGraphic = xProvider->queryGraphic( aMediaProperties ); + OSL_ENSURE( xGraphic.is(), "OHsqlConnection::impl_getTextTableIcon_nothrow: the provider did not give us a graphic object!" ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xGraphic; + } + +} } // namespace connectivity::hsqldb diff --git a/connectivity/source/drivers/hsqldb/HDriver.cxx b/connectivity/source/drivers/hsqldb/HDriver.cxx new file mode 100644 index 000000000000..14758afafb3f --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HDriver.cxx @@ -0,0 +1,886 @@ +/************************************************************************* + * + * 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 "hsqldb/HDriver.hxx" +#include "hsqldb/HConnection.hxx" +#include <osl/diagnose.h> +#include "connectivity/dbexception.hxx" +#include <com/sun/star/sdbc/XDriverAccess.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/embed/XTransactionBroadcaster.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include "TConnection.hxx" +#include "hsqldb/HStorageMap.hxx" +#include <jvmfwk/framework.h> +#include <com/sun/star/reflection/XProxyFactory.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include "HTerminateListener.hxx" +#include "hsqldb/HCatalog.hxx" +#include "diagnose_ex.h" +#include <rtl/ustrbuf.hxx> +#include <osl/file.h> +#include <osl/process.h> +#include <connectivity/dbexception.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <unotools/confignode.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include "resource/hsqldb_res.hrc" +#include "resource/sharedresources.hxx" + +//........................................................................ +namespace connectivity +{ +//........................................................................ + using namespace hsqldb; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::sdbcx; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::embed; + using namespace ::com::sun::star::io; + using namespace ::com::sun::star::task; + using namespace ::com::sun::star::reflection; + + namespace hsqldb + { + Reference< XInterface > SAL_CALL ODriverDelegator_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFac) throw( Exception ) + { + return *(new ODriverDelegator(_rxFac)); + } + } + + + + //==================================================================== + //= ODriverDelegator + //==================================================================== + //-------------------------------------------------------------------- + ODriverDelegator::ODriverDelegator(const Reference< XMultiServiceFactory >& _rxFactory) + : ODriverDelegator_BASE(m_aMutex) + ,m_xFactory(_rxFactory) + ,m_bInShutDownConnections(sal_False) + { + } + + //-------------------------------------------------------------------- + ODriverDelegator::~ODriverDelegator() + { + try + { + ::comphelper::disposeComponent(m_xDriver); + } + catch(const Exception&) + { + } + } + + // -------------------------------------------------------------------------------- + void SAL_CALL ODriverDelegator::disposing() + { + ::osl::MutexGuard aGuard(m_aMutex); + + try + { + for (TWeakPairVector::iterator i = m_aConnections.begin(); m_aConnections.end() != i; ++i) + { + Reference<XInterface > xTemp = i->first.get(); + ::comphelper::disposeComponent(xTemp); + } + } + catch(Exception&) + { + // not interested in + } + m_aConnections.clear(); + TWeakPairVector().swap(m_aConnections); + + cppu::WeakComponentImplHelperBase::disposing(); + } + //-------------------------------------------------------------------- + Reference< XDriver > ODriverDelegator::loadDriver( ) + { + if ( !m_xDriver.is() ) + { + ::rtl::OUString sURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:db")); + Reference<XDriverAccess> xDriverAccess(m_xFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.DriverManager")) ),UNO_QUERY); + OSL_ENSURE(xDriverAccess.is(),"Could not load driver manager!"); + if ( xDriverAccess.is() ) + m_xDriver = xDriverAccess->getDriverByURL(sURL); + } + + return m_xDriver; + } + + //-------------------------------------------------------------------- + namespace + { + ::rtl::OUString lcl_getPermittedJavaMethods_nothrow( const Reference< XMultiServiceFactory >& _rxORB ) + { + ::rtl::OUStringBuffer aConfigPath; + aConfigPath.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" ); + aConfigPath.append ( ODriverDelegator::getImplementationName_Static() ); + aConfigPath.appendAscii( "/PermittedJavaMethods" ); + ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( + _rxORB, aConfigPath.makeStringAndClear() ) ); + + ::rtl::OUStringBuffer aPermittedMethods; + Sequence< ::rtl::OUString > aNodeNames( aConfig.getNodeNames() ); + for ( const ::rtl::OUString* pNodeNames = aNodeNames.getConstArray(); + pNodeNames != aNodeNames.getConstArray() + aNodeNames.getLength(); + ++pNodeNames + ) + { + ::rtl::OUString sPermittedMethod; + OSL_VERIFY( aConfig.getNodeValue( *pNodeNames ) >>= sPermittedMethod ); + + if ( aPermittedMethods.getLength() ) + aPermittedMethods.append( (sal_Unicode)';' ); + aPermittedMethods.append( sPermittedMethod ); + } + + return aPermittedMethods.makeStringAndClear();; + } + } + + //-------------------------------------------------------------------- + Reference< XConnection > SAL_CALL ODriverDelegator::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException) + { + Reference< XConnection > xConnection; + if ( acceptsURL(url) ) + { + Reference< XDriver > xDriver = loadDriver(); + if ( xDriver.is() ) + { + ::rtl::OUString sURL; + Reference<XStorage> xStorage; + const PropertyValue* pIter = info.getConstArray(); + const PropertyValue* pEnd = pIter + info.getLength(); + + for (;pIter != pEnd; ++pIter) + { + if ( pIter->Name.equalsAscii("Storage") ) + { + xStorage.set(pIter->Value,UNO_QUERY); + } + else if ( pIter->Name.equalsAscii("URL") ) + { + pIter->Value >>= sURL; + } + } + + if ( !xStorage.is() || !sURL.getLength() ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sMessage = aResources.getResourceString(STR_NO_STROAGE); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + ::rtl::OUString sSystemPath; + osl_getSystemPathFromFileURL( sURL.pData, &sSystemPath.pData ); + sal_Int32 nIndex = sSystemPath.lastIndexOf('.'); + if ( !sURL.getLength() || !sSystemPath.getLength() ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sMessage = aResources.getResourceString(STR_INVALID_FILE_URL); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + bool bIsNewDatabase = !xStorage->hasElements(); + + ::comphelper::NamedValueCollection aProperties; + + // properties for accessing the embedded storage + ::rtl::OUString sConnPartURL = sSystemPath.copy( 0, ::std::max< sal_Int32 >( nIndex, sSystemPath.getLength() ) ); + ::rtl::OUString sKey = StorageContainer::registerStorage( xStorage, sConnPartURL ); + aProperties.put( "storage_key", sKey ); + aProperties.put( "storage_class_name", + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageAccess" ) ) ); + aProperties.put( "fileaccess_class_name", + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageFileAccess" ) ) ); + + // JDBC driver and driver's classpath + aProperties.put( "JavaDriverClass", + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.hsqldb.jdbcDriver" ) ) ); + aProperties.put( "JavaDriverClassPath", + ::rtl::OUString( +#ifdef SYSTEM_HSQLDB + RTL_CONSTASCII_USTRINGPARAM(HSQLDB_JAR + " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" ) +#else + RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/hsqldb.jar" + " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" ) +#endif + ) ); + + // auto increment handling + aProperties.put( "IsAutoRetrievingEnabled", true ); + aProperties.put( "AutoRetrievingStatement", + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CALL IDENTITY()" ) ) ); + aProperties.put( "IgnoreDriverPrivileges", true ); + + // don't want to expose HSQLDB's schema capabilities which exist since 1.8.0RC10 + aProperties.put( "default_schema", + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) ); + + // security: permitted Java classes + NamedValue aPermittedClasses( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hsqldb.method_class_names" ) ), + makeAny( lcl_getPermittedJavaMethods_nothrow( m_xFactory ) ) + ); + aProperties.put( "SystemProperties", Sequence< NamedValue >( &aPermittedClasses, 1 ) ); + + const ::rtl::OUString sProperties( RTL_CONSTASCII_USTRINGPARAM( "properties" ) ); + ::rtl::OUString sMessage; + try + { + if ( !bIsNewDatabase && xStorage->isStreamElement(sProperties) ) + { + Reference<XStream > xStream = xStorage->openStreamElement(sProperties,ElementModes::READ); + if ( xStream.is() ) + { + ::std::auto_ptr<SvStream> pStream( ::utl::UcbStreamHelper::CreateStream(xStream) ); + if ( pStream.get() ) + { + ByteString sLine; + while ( pStream->ReadLine(sLine) ) + { + if ( sLine.Equals("version=",0,sizeof("version=")-1) ) + { + sLine = sLine.GetToken(1,'='); + const sal_Int32 nMajor = sLine.GetToken(0,'.').ToInt32(); + const sal_Int32 nMinor = sLine.GetToken(1,'.').ToInt32(); + const sal_Int32 nMicro = sLine.GetToken(2,'.').ToInt32(); + if ( nMajor > 1 + || ( nMajor == 1 && nMinor > 8 ) + || ( nMajor == 1 && nMinor == 8 && nMicro > 0 ) ) + { + ::connectivity::SharedResources aResources; + sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION); + } + break; + } + } + } + } // if ( xStream.is() ) + ::comphelper::disposeComponent(xStream); + } + } + catch(Exception&) + { + } + if ( sMessage.getLength() ) + { + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + // readonly? + Reference<XPropertySet> xProp(xStorage,UNO_QUERY); + if ( xProp.is() ) + { + sal_Int32 nMode = 0; + xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode"))) >>= nMode; + if ( (nMode & ElementModes::WRITE) != ElementModes::WRITE ) + { + aProperties.put( "readonly", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) ); + } + } + + Sequence< PropertyValue > aConnectionArgs; + aProperties >>= aConnectionArgs; + + ::rtl::OUString sConnectURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:")); + + sConnectURL += sConnPartURL; + Reference<XConnection> xOrig; + try + { + xOrig = xDriver->connect( sConnectURL, aConnectionArgs ); + } + catch(const Exception& e) + { + StorageContainer::revokeStorage(sKey,NULL); + (void)e; + throw; + } + + // if the storage is completely empty, then we just created a new HSQLDB + // In this case, do some initializations. + if ( bIsNewDatabase && xOrig.is() ) + onConnectedNewDatabase( xOrig ); + + if ( xOrig.is() ) + { + OMetaConnection* pMetaConnection = NULL; + // now we have to set the URL to get the correct answer for metadata()->getURL() + Reference< XUnoTunnel> xTunnel(xOrig,UNO_QUERY); + if ( xTunnel.is() ) + { + pMetaConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() )); + if ( pMetaConnection ) + pMetaConnection->setURL(url); + } + + Reference<XComponent> xComp(xOrig,UNO_QUERY); + if ( xComp.is() ) + xComp->addEventListener(this); + + // we want to close all connections when the office shuts down + static Reference< XTerminateListener> s_xTerminateListener; + if( !s_xTerminateListener.is() ) + { + Reference< XDesktop > xDesktop( m_xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY ); + + if( xDesktop.is() ) + { + s_xTerminateListener = new OConnectionController(this); + xDesktop->addTerminateListener(s_xTerminateListener); + } + } + Reference< XComponent> xIfc = new OHsqlConnection( this, xOrig, m_xFactory ); + xConnection.set(xIfc,UNO_QUERY); + m_aConnections.push_back(TWeakPair(WeakReferenceHelper(xOrig),TWeakConnectionPair(sKey,TWeakRefPair(WeakReferenceHelper(xConnection),WeakReferenceHelper())))); + + Reference<XTransactionBroadcaster> xBroad(xStorage,UNO_QUERY); + if ( xBroad.is() ) + { + Reference<XTransactionListener> xListener(*this,UNO_QUERY); + xBroad->addTransactionListener(xListener); + } + } + } + } + return xConnection; + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL ODriverDelegator::acceptsURL( const ::rtl::OUString& url ) throw (SQLException, RuntimeException) + { + sal_Bool bEnabled = sal_False; + OSL_VERIFY_EQUALS( jfw_getEnabled( &bEnabled ), JFW_E_NONE, "error in jfw_getEnabled" ); + return bEnabled && url.compareToAscii("sdbc:embedded:hsqldb",sizeof("sdbc:embedded:hsqldb")) == 0; + } + + //-------------------------------------------------------------------- + Sequence< DriverPropertyInfo > SAL_CALL ODriverDelegator::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, RuntimeException) + { + if ( !acceptsURL(url) ) + return Sequence< DriverPropertyInfo >(); + ::std::vector< DriverPropertyInfo > aDriverInfo; + aDriverInfo.push_back(DriverPropertyInfo( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Storage")) + ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the storage where the database will be stored.")) + ,sal_True + ,::rtl::OUString() + ,Sequence< ::rtl::OUString >()) + ); + aDriverInfo.push_back(DriverPropertyInfo( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) + ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the url of the data source.")) + ,sal_True + ,::rtl::OUString() + ,Sequence< ::rtl::OUString >()) + ); + aDriverInfo.push_back(DriverPropertyInfo( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement")) + ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the statement which will be executed to retrieve auto increment values.")) + ,sal_False + ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CALL IDENTITY()")) + ,Sequence< ::rtl::OUString >()) + ); + return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size()); + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion( ) throw (RuntimeException) + { + return 1; + } + + //-------------------------------------------------------------------- + sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion( ) throw (RuntimeException) + { + return 0; + } + + //-------------------------------------------------------------------- + Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByConnection( const Reference< XConnection >& connection ) throw (SQLException, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(ODriverDelegator_BASE::rBHelper.bDisposed); + + Reference< XTablesSupplier > xTab; + + TWeakPairVector::iterator aEnd = m_aConnections.end(); + for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i) + { + if ( i->second.second.first.get() == connection.get() ) + { + xTab = Reference< XTablesSupplier >(i->second.second.second.get().get(),UNO_QUERY); + if ( !xTab.is() ) + { + xTab = new OHCatalog(connection); + i->second.second.second = WeakReferenceHelper(xTab); + } + break; + } + } + + return xTab; + } + + //-------------------------------------------------------------------- + Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByURL( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException) + { + if ( ! acceptsURL(url) ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR); + ::dbtools::throwGenericSQLException(sMessage ,*this); + } + + return getDataDefinitionByConnection(connect(url,info)); + } + + // XServiceInfo + // -------------------------------------------------------------------------------- + //------------------------------------------------------------------------------ + rtl::OUString ODriverDelegator::getImplementationName_Static( ) throw(RuntimeException) + { + return rtl::OUString::createFromAscii("com.sun.star.sdbcx.comp.hsqldb.Driver"); + } + //------------------------------------------------------------------------------ + Sequence< ::rtl::OUString > ODriverDelegator::getSupportedServiceNames_Static( ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aSNS( 2 ); + aSNS[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.Driver")); + aSNS[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Driver"); + return aSNS; + } + //------------------------------------------------------------------ + ::rtl::OUString SAL_CALL ODriverDelegator::getImplementationName( ) throw(RuntimeException) + { + return getImplementationName_Static(); + } + + //------------------------------------------------------------------ + sal_Bool SAL_CALL ODriverDelegator::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; + } + //------------------------------------------------------------------ + Sequence< ::rtl::OUString > SAL_CALL ODriverDelegator::getSupportedServiceNames( ) throw(RuntimeException) + { + return getSupportedServiceNames_Static(); + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::createCatalog( const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, ::com::sun::star::container::ElementExistException, RuntimeException) + { + ::dbtools::throwFeatureNotImplementedException( "XCreateCatalog::createCatalog", *this ); + } + //------------------------------------------------------------------ + void ODriverDelegator::shutdownConnection(const TWeakPairVector::iterator& _aIter ) + { + OSL_ENSURE(m_aConnections.end() != _aIter,"Iterator equals .end()"); + sal_Bool bLastOne = sal_True; + try + { + Reference<XConnection> _xConnection(_aIter->first.get(),UNO_QUERY); + + if ( _xConnection.is() ) + { + Reference<XStatement> xStmt = _xConnection->createStatement(); + if ( xStmt.is() ) + { + Reference<XResultSet> xRes(xStmt->executeQuery(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS WHERE USER_NAME ='SA'"))),UNO_QUERY); + Reference<XRow> xRow(xRes,UNO_QUERY); + if ( xRow.is() && xRes->next() ) + bLastOne = xRow->getInt(1) == 1; + if ( bLastOne ) + xStmt->execute(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SHUTDOWN"))); + } + } + } + catch(Exception&) + { + } + if ( bLastOne ) + { + // Reference<XTransactionListener> xListener(*this,UNO_QUERY); + // a shutdown should commit all changes to the db files + StorageContainer::revokeStorage(_aIter->second.first,NULL); + } + if ( !m_bInShutDownConnections ) + m_aConnections.erase(_aIter); + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) + { + ::osl::MutexGuard aGuard(m_aMutex); + Reference<XConnection> xCon(Source.Source,UNO_QUERY); + if ( xCon.is() ) + { + TWeakPairVector::iterator i = m_aConnections.begin(); + for (; m_aConnections.end() != i; ++i) + { + if ( i->first.get() == xCon.get() ) + { + shutdownConnection(i); + break; + } + } + } + else + { + Reference< XStorage> xStorage(Source.Source,UNO_QUERY); + if ( xStorage.is() ) + { + ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage); + TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::std::compose1( + ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey) + ,::std::compose1(::std::select1st<TWeakConnectionPair>(),::std::select2nd< TWeakPair >()))); + if ( i != m_aConnections.end() ) + shutdownConnection(i); + } + } + } + //------------------------------------------------------------------ + void ODriverDelegator::shutdownConnections() + { + m_bInShutDownConnections = sal_True; + TWeakPairVector::iterator aEnd = m_aConnections.end(); + for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i) + { + try + { + Reference<XConnection> xCon(i->first,UNO_QUERY); + ::comphelper::disposeComponent(xCon); + } + catch(Exception&) + { + } + } + m_aConnections.clear(); + m_bInShutDownConnections = sal_True; + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) + { + ::osl::MutexGuard aGuard(m_aMutex); + + Reference< XStorage> xStorage(aEvent.Source,UNO_QUERY); + ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage); + if ( sKey.getLength() ) + { + TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::std::compose1( + ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey) + ,::std::compose1(::std::select1st<TWeakConnectionPair>(),::std::select2nd< TWeakPair >()))); + OSL_ENSURE( i != m_aConnections.end(), "ODriverDelegator::preCommit: they're committing a storage which I do not know!" ); + if ( i != m_aConnections.end() ) + { + try + { + Reference<XConnection> xConnection(i->first,UNO_QUERY); + if ( xConnection.is() ) + { + Reference< XStatement> xStmt = xConnection->createStatement(); + OSL_ENSURE( xStmt.is(), "ODriverDelegator::preCommit: no statement!" ); + if ( xStmt.is() ) + xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 0" ) ) ); + + sal_Bool bPreviousAutoCommit = xConnection->getAutoCommit(); + xConnection->setAutoCommit( sal_False ); + xConnection->commit(); + xConnection->setAutoCommit( bPreviousAutoCommit ); + + if ( xStmt.is() ) + xStmt->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 60" ) ) ); + } + } + catch(Exception&) + { + OSL_ENSURE( false, "ODriverDelegator::preCommit: caught an exception!" ); + } + } + } + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::commited( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException) + { + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::preRevert( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) + { + } + //------------------------------------------------------------------ + void SAL_CALL ODriverDelegator::reverted( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException) + { + } + //------------------------------------------------------------------ + namespace + { + //.............................................................. + const sal_Char* lcl_getCollationForLocale( const ::rtl::OUString& _rLocaleString, bool _bAcceptCountryMismatch = false ) + { + static const sal_Char* pTranslations[] = + { + "af-ZA", "Afrikaans", + "am-ET", "Amharic", + "ar", "Arabic", + "as-IN", "Assamese", + "az-AZ", "Azerbaijani_Latin", + "az-cyrillic", "Azerbaijani_Cyrillic", + "be-BY", "Belarusian", + "bg-BG", "Bulgarian", + "bn-IN", "Bengali", + "bo-CN", "Tibetan", + "bs-BA", "Bosnian", + "ca-ES", "Catalan", + "cs-CZ", "Czech", + "cy-GB", "Welsh", + "da-DK", "Danish", + "de-DE", "German", + "el-GR", "Greek", + "en-US", "Latin1_General", + "es-ES", "Spanish", + "et-EE", "Estonian", + "eu", "Basque", + "fi-FI", "Finnish", + "fr-FR", "French", + "gn-PY", "Guarani", + "gu-IN", "Gujarati", + "ha-NG", "Hausa", + "he-IL", "Hebrew", + "hi-IN", "Hindi", + "hr-HR", "Croatian", + "hu-HU", "Hungarian", + "hy-AM", "Armenian", + "id-ID", "Indonesian", + "ig-NG", "Igbo", + "is-IS", "Icelandic", + "it-IT", "Italian", + "iu-CA", "Inuktitut", + "ja-JP", "Japanese", + "ka-GE", "Georgian", + "kk-KZ", "Kazakh", + "km-KH", "Khmer", + "kn-IN", "Kannada", + "ko-KR", "Korean", + "kok-IN", "Konkani", + "ks", "Kashmiri", + "ky-KG", "Kirghiz", + "lo-LA", "Lao", + "lt-LT", "Lithuanian", + "lv-LV", "Latvian", + "mi-NZ", "Maori", + "mk-MK", "Macedonian", + "ml-IN", "Malayalam", + "mn-MN", "Mongolian", + "mni-IN", "Manipuri", + "mr-IN", "Marathi", + "ms-MY", "Malay", + "mt-MT", "Maltese", + "my-MM", "Burmese", + "nb-NO", "Danish_Norwegian", + "ne-NP", "Nepali", + "nl-NL", "Dutch", + "nn-NO", "Norwegian", + "or-IN", "Oriya", + "pa-IN", "Punjabi", + "pl-PL", "Polish", + "ps-AF", "Pashto", + "pt-PT", "Portuguese", + "ro-RO", "Romanian", + "ru-RU", "Russian", + "sa-IN", "Sanskrit", + "sd-IN", "Sindhi", + "sk-SK", "Slovak", + "sl-SI", "Slovenian", + "so-SO", "Somali", + "sq-AL", "Albanian", + "sr-YU", "Serbian_Cyrillic", + "sv-SE", "Swedish", + "sw-KE", "Swahili", + "ta-IN", "Tamil", + "te-IN", "Telugu", + "tg-TJ", "Tajik", + "th-TH", "Thai", + "tk-TM", "Turkmen", + "tn-BW", "Tswana", + "tr-TR", "Turkish", + "tt-RU", "Tatar", + "uk-UA", "Ukrainian", + "ur-PK", "Urdu", + "uz-UZ", "Uzbek_Latin", + "ven-ZA", "Venda", + "vi-VN", "Vietnamese", + "yo-NG", "Yoruba", + "zh-CN", "Chinese", + "zu-ZA", "Zulu", + NULL, NULL + }; + + ::rtl::OUString sLocaleString( _rLocaleString ); + sal_Char nCompareTermination = 0; + + if ( _bAcceptCountryMismatch ) + { + // strip the country part from the compare string + sal_Int32 nCountrySep = sLocaleString.indexOf( '-' ); + if ( nCountrySep > -1 ) + sLocaleString = sLocaleString.copy( 0, nCountrySep ); + + // the entries in the translation table are compared until the + // - character only, not until the terminating 0 + nCompareTermination = '-'; + } + + const sal_Char** pLookup = pTranslations; + for ( ; *pLookup; pLookup +=2 ) + { + sal_Int32 nCompareUntil = 0; + while ( (*pLookup)[ nCompareUntil ] != nCompareTermination && (*pLookup)[ nCompareUntil ] != 0 ) + ++nCompareUntil; + + if ( sLocaleString.equalsAsciiL( *pLookup, nCompareUntil ) ) + return *( pLookup + 1 ); + } + + if ( !_bAcceptCountryMismatch ) + // second round, this time without matching the country + return lcl_getCollationForLocale( _rLocaleString, true ); + + OSL_ENSURE( false, "lcl_getCollationForLocale: unknown locale string, falling back to Latin1_General!" ); + return "Latin1_General"; + } + + //.............................................................. + ::rtl::OUString lcl_getSystemLocale( const Reference< XMultiServiceFactory >& _rxORB ) + { + ::rtl::OUString sLocaleString = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en-US" ) ); + try + { + //......................................................... + Reference< XMultiServiceFactory > xConfigProvider( + _rxORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ), + UNO_QUERY + ); + OSL_ENSURE( xConfigProvider.is(), "lcl_getSystemLocale: could not create the config provider!" ); + + if ( !xConfigProvider.is() ) + return sLocaleString; + + //......................................................... + // arguments for creating the config access + Sequence< Any > aArguments(2); + // the path to the node to open + ::rtl::OUString sNodePath = ::rtl::OUString::createFromAscii ("/org.openoffice.Setup/L10N" ); + aArguments[0] <<= PropertyValue( ::rtl::OUString::createFromAscii( "nodepath"), 0, + makeAny( sNodePath ), PropertyState_DIRECT_VALUE + ); + // the depth: -1 means unlimited + aArguments[1] <<= PropertyValue( + ::rtl::OUString::createFromAscii( "depth"), 0, + makeAny( (sal_Int32)-1 ), PropertyState_DIRECT_VALUE + ); + + //......................................................... + // create the access + Reference< XPropertySet > xNode( + xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ), + aArguments ), + UNO_QUERY ); + OSL_ENSURE( xNode.is(), "lcl_getSystemLocale: invalid access returned (should throw an exception instead)!" ); + + //......................................................... + // ask for the system locale setting + if ( xNode.is() ) + xNode->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupSystemLocale" ) ) ) >>= sLocaleString; + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "lcl_getSystemLocale: caught an exception!" ); + } + if ( !sLocaleString.getLength() ) + { + rtl_Locale* pProcessLocale = NULL; + osl_getProcessLocale( &pProcessLocale ); + + ::rtl::OUStringBuffer aProcLocale; + aProcLocale.append( pProcessLocale->Language->buffer, pProcessLocale->Language->length ); + if ( pProcessLocale->Country->length ) + { + aProcLocale.appendAscii( "-" ); + aProcLocale.append( pProcessLocale->Country->buffer, pProcessLocale->Country->length ); + } + sLocaleString = aProcLocale.makeStringAndClear(); + } + return sLocaleString; + } + } + //------------------------------------------------------------------ + void ODriverDelegator::onConnectedNewDatabase( const Reference< XConnection >& _rxConnection ) + { + try + { + Reference< XStatement > xStatement = _rxConnection->createStatement(); + OSL_ENSURE( xStatement.is(), "ODriverDelegator::onConnectedNewDatabase: could not create a statement!" ); + if ( xStatement.is() ) + { + ::rtl::OUStringBuffer aStatement; + aStatement.appendAscii( "SET DATABASE COLLATION \"" ); + aStatement.appendAscii( lcl_getCollationForLocale( lcl_getSystemLocale( m_xFactory ) ) ); + aStatement.appendAscii( "\"" ); + + xStatement->execute( aStatement.makeStringAndClear() ); + } + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "ODriverDelegator::onConnectedNewDatabase: caught an exception!" ); + } + } + + //------------------------------------------------------------------ + //------------------------------------------------------------------ +//........................................................................ +} // namespace connectivity +//........................................................................ + diff --git a/connectivity/source/drivers/hsqldb/HStorage.hxx b/connectivity/source/drivers/hsqldb/HStorage.hxx new file mode 100644 index 000000000000..5dd8b4288b69 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HStorage.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef CONNECTIVITY_HSQLDB_STORAGE_HXX +#define CONNECTIVITY_HSQLDB_STORAGE_HXX + +#include <cppuhelper/compbase6.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include "connectivity/CommonTools.hxx" +#include <comphelper/broadcasthelper.hxx> + + +#define DECLARE_SERVICE_INFO_STATIC() \ + DECLARE_SERVICE_INFO(); \ + static ::rtl::OUString SAL_CALL getImplementationName_Static( ) throw (::com::sun::star::uno::RuntimeException); \ + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_Static( ) throw(::com::sun::star::uno::RuntimeException); \ + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > \ + SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&) \ + + +namespace connectivity +{ + namespace hsqldb + { + typedef ::cppu::WeakComponentImplHelper6< ::com::sun::star::io::XStream + , ::com::sun::star::io::XInputStream + , ::com::sun::star::io::XOutputStream + , ::com::sun::star::io::XSeekable + , ::com::sun::star::lang::XInitialization + , ::com::sun::star::lang::XServiceInfo> OStorage_Base; + class OStorage : public ::comphelper::OBaseMutex + ,public OStorage_Base + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory; + ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentSubStorageSupplier> m_xDS; + + + ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage> m_xStorge; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xIn; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > m_xOut; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xSeek; + + OStorage(); // never implemented + OStorage(const OStorage&); // never implemented + int operator= (const OStorage&); // never implemented + + OStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory); + protected: + /** this function is called upon disposing the component + */ + virtual void SAL_CALL disposing(); + public: + // ::com::sun::star::lang::XServiceInfo + DECLARE_SERVICE_INFO_STATIC(); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XStream + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException); + + // XInputStream + virtual ::sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData, ::sal_Int32 nMaxBytesToRead ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( ::sal_Int32 nBytesToSkip ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL available( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XOutputStream + virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XSeekable + virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL getPosition( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Int64 SAL_CALL getLength( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + }; + } +// ....................................................................... +} // connectivity +// ....................................................................... +#endif // CONNECTIVITY_HSQLDB_STORAGE_HXX + diff --git a/connectivity/source/drivers/hsqldb/HStorageAccess.cxx b/connectivity/source/drivers/hsqldb/HStorageAccess.cxx new file mode 100644 index 000000000000..e7fab6acb6c0 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HStorageAccess.cxx @@ -0,0 +1,551 @@ +/************************************************************************* + * + * 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 "hsqldb/HStorageAccess.hxx" +#include <comphelper/processfactory.hxx> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/io/XStream.hpp> +#include "hsqldb/HStorageMap.hxx" +#include "hsqldb/StorageNativeInputStream.h" +#include "accesslog.hxx" +#include "diagnose_ex.h" + +#include <string.h> + +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::connectivity::hsqldb; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +#define ThrowException(env, type, msg) { \ + env->ThrowNew(env->FindClass(type), msg); } + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: openStream + * Signature: (Ljava/lang/String;Ljava/lang/String;I)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_openStream + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jint mode) +{ +#ifdef HSQLDB_DBG + { + OperationLogFile( env, name, "data" ).logOperation( "openStream" ); + LogFile( env, name, "data" ).create(); + } +#endif + + StorageContainer::registerStream(env,name,key,mode); +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: close + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_close + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key) +{ +#ifdef HSQLDB_DBG + { + ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key); + ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name); + } +#endif + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XOutputStream> xFlush = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>(); + if ( xFlush.is() ) + try + { + xFlush->flush(); + } + catch(Exception&) + { + OSL_ENSURE( false, "NativeStorageAccess::close: caught an exception while flushing!" ); + } +#ifdef HSQLDB_DBG + { + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "close" ); + aOpLog.close(); + + LogFile aDataLog( env, name, "data" ); + aDataLog.close(); + } +#endif + + StorageContainer::revokeStream(env,name,key); +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: getFilePointer + * Signature: (Ljava/lang/String;Ljava/lang/String;)J + */ +SAL_DLLPUBLIC_EXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_getFilePointer + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "getFilePointer" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + OSL_ENSURE(pHelper.get(),"No stream helper!"); + + jlong nReturn = pHelper.get() ? pHelper->getSeek()->getPosition() : jlong(0); +#ifdef HSQLDB_DBG + aOpLog.logReturn( nReturn ); +#endif + return nReturn; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: length + * Signature: (Ljava/lang/String;Ljava/lang/String;)J + */ +SAL_DLLPUBLIC_EXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_length + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "length" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + OSL_ENSURE(pHelper.get(),"No stream helper!"); + + jlong nReturn = pHelper.get() ? pHelper->getSeek()->getLength() :jlong(0); +#ifdef HSQLDB_DBG + aOpLog.logReturn( nReturn ); +#endif + return nReturn; +} + +// ----------------------------------------------------------------------------- + +jint read_from_storage_stream( JNIEnv * env, jobject /*obj_this*/, jstring name, jstring key, DataLogFile* logger ) +{ + OSL_UNUSED( logger ); + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>(); + OSL_ENSURE(xIn.is(),"Input stream is NULL!"); + if ( xIn.is() ) + { + Sequence< ::sal_Int8 > aData(1); + sal_Int32 nBytesRead = -1; + try + { + nBytesRead = xIn->readBytes(aData,1); + } + catch(Exception& e) + { + StorageContainer::throwJavaException(e,env); + return -1; + + } + if (nBytesRead <= 0) + { + return (-1); + } + else + { + sal_Int32 tmpInt = aData[0]; + if (tmpInt < 0 ) + tmpInt = 256 +tmpInt; + +#ifdef HSQLDB_DBG + if ( logger ) + logger->write( tmpInt ); +#endif + return(tmpInt); + } + } + return -1; +} + +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: read + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2 + (JNIEnv* env, jobject obj_this, jstring name, jstring key) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "read" ); + + DataLogFile aDataLog( env, name, "data" ); + return read_from_storage_stream( env, obj_this, name, key, &aDataLog ); +#else + return read_from_storage_stream( env, obj_this, name, key ); +#endif +} + +// ----------------------------------------------------------------------------- + +jint read_from_storage_stream_into_buffer( JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jbyteArray buffer, jint off, jint len, DataLogFile* logger ) +{ + OSL_UNUSED( logger ); +#ifdef HSQLDB_DBG + { + ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key); + ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name); + } +#endif + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>(); + OSL_ENSURE(xIn.is(),"Input stream is NULL!"); + if ( xIn.is() ) + { + jsize nLen = env->GetArrayLength(buffer); + if ( nLen < len || len <= 0 ) + { + ThrowException( env, + "java/io/IOException", + "len is greater or equal to the buffer size"); + return -1; + } + sal_Int32 nBytesRead = -1; + + Sequence< ::sal_Int8 > aData(nLen); + try + { + nBytesRead = xIn->readBytes(aData, len); + } + catch(Exception& e) + { + StorageContainer::throwJavaException(e,env); + return -1; + } + + if (nBytesRead <= 0) + return -1; + env->SetByteArrayRegion(buffer,off,nBytesRead,&aData[0]); + +#ifdef HSQLDB_DBG + if ( logger ) + logger->write( aData.getConstArray(), nBytesRead ); +#endif + return nBytesRead; + } + ThrowException( env, + "java/io/IOException", + "Stream is not valid"); + return -1; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: read + * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII + (JNIEnv * env, jobject obj_this,jstring name, jstring key, jbyteArray buffer, jint off, jint len) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "read( byte[], int, int )" ); + + DataLogFile aDataLog( env, name, "data" ); + return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog ); +#else + return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len ); +#endif +} + +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: readInt + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_readInt + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "readInt" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>(); + OSL_ENSURE(xIn.is(),"Input stream is NULL!"); + if ( xIn.is() ) + { + Sequence< ::sal_Int8 > aData(4); + sal_Int32 nBytesRead = -1; + try + { + nBytesRead = xIn->readBytes(aData, 4); + } + catch(Exception& e) + { + StorageContainer::throwJavaException(e,env); + return -1; + } + + if ( nBytesRead != 4 ) { + ThrowException( env, + "java/io/IOException", + "Bytes read != 4"); + return -1; + } + + Sequence< sal_Int32 > ch(4); + for(sal_Int32 i = 0;i < 4; ++i) + { + ch[i] = aData[i]; + if (ch[i] < 0 ) + ch[i] = 256 + ch[i]; + } + + if ((ch[0] | ch[1] | ch[2] | ch[3]) < 0) + { + ThrowException( env, + "java/io/IOException", + "One byte is < 0"); + return -1; + } + jint nRet = ((ch[0] << 24) + (ch[1] << 16) + (ch[2] << 8) + (ch[3] << 0)); +#ifdef HSQLDB_DBG + DataLogFile aDataLog( env, name, "data" ); + aDataLog.write( nRet ); + + aOpLog.logReturn( nRet ); +#endif + return nRet; + } + ThrowException( env, + "java/io/IOException", + "No InputStream"); + return -1; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: seek + * Signature: (Ljava/lang/String;Ljava/lang/String;J)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_seek + (JNIEnv * env, jobject /*obj_this*/,jstring name, jstring key, jlong position) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "seek", position ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XSeekable> xSeek = pHelper.get() ? pHelper->getSeek() : Reference< XSeekable>(); + + OSL_ENSURE(xSeek.is(),"No Seekable stream!"); + if ( xSeek.is() ) + { + #ifdef HSQLDB_DBG + DataLogFile aDataLog( env, name, "data" ); + #endif + + ::sal_Int64 nLen = xSeek->getLength(); + if ( nLen < position) + { + static ::sal_Int64 BUFFER_SIZE = 9192; + #ifdef HSQLDB_DBG + aDataLog.seek( nLen ); + #endif + xSeek->seek(nLen); + Reference< XOutputStream> xOut = pHelper->getOutputStream(); + OSL_ENSURE(xOut.is(),"No output stream!"); + + ::sal_Int64 diff = position - nLen; + sal_Int32 n; + while( diff != 0 ) + { + if ( BUFFER_SIZE < diff ) + { + n = static_cast<sal_Int32>(BUFFER_SIZE); + diff = diff - BUFFER_SIZE; + } + else + { + n = static_cast<sal_Int32>(diff); + diff = 0; + } + Sequence< ::sal_Int8 > aData(n); + memset(aData.getArray(),0,n); + xOut->writeBytes(aData); + #ifdef HSQLDB_DBG + aDataLog.write( aData.getConstArray(), n ); + #endif + } + } + xSeek->seek(position); + OSL_ENSURE(xSeek->getPosition() == position,"Wrong position after seeking the stream"); + + #ifdef HSQLDB_DBG + aDataLog.seek( position ); + OSL_ENSURE( xSeek->getPosition() == aDataLog.tell(), "Wrong position after seeking the stream" ); + #endif + } +} +// ----------------------------------------------------------------------------- + +void write_to_storage_stream_from_buffer( JNIEnv* env, jobject /*obj_this*/, jstring name, jstring key, jbyteArray buffer, jint off, jint len, DataLogFile* logger ) +{ + OSL_UNUSED( logger ); + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XOutputStream> xOut = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>(); + OSL_ENSURE(xOut.is(),"Stream is NULL"); + + try + { + if ( xOut.is() ) + { + jbyte *buf = env->GetByteArrayElements(buffer,NULL); + if (JNI_FALSE != env->ExceptionCheck()) + { + env->ExceptionClear(); + OSL_ENSURE(0,"ExceptionClear"); + } + OSL_ENSURE(buf,"buf is NULL"); + if ( buf && len > 0 && len <= env->GetArrayLength(buffer)) + { + Sequence< ::sal_Int8 > aData(buf + off,len); + env->ReleaseByteArrayElements(buffer, buf, JNI_ABORT); + xOut->writeBytes(aData); +#ifdef HSQLDB_DBG + if ( logger ) + logger->write( aData.getConstArray(), len ); +#endif + } + } + else + { + ThrowException( env, + "java/io/IOException", + "No OutputStream"); + } + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception caught! : write [BII)V"); + StorageContainer::throwJavaException(e,env); + } +} + +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: write + * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_write + (JNIEnv * env, jobject obj_this,jstring name, jstring key, jbyteArray buffer, jint off, jint len) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "write( byte[], int, int )" ); + + DataLogFile aDataLog( env, name, "data" ); + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog ); +#else + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len ); +#endif +} +// ----------------------------------------------------------------------------- + +void write_to_storage_stream( JNIEnv* env, jobject /*obj_this*/, jstring name, jstring key, jint v, DataLogFile* logger ) +{ + OSL_UNUSED( logger ); + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XOutputStream> xOut = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>(); + OSL_ENSURE(xOut.is(),"Stream is NULL"); + try + { + if ( xOut.is() ) + { + Sequence< ::sal_Int8 > oneByte(4); + oneByte[0] = (sal_Int8) ((v >> 24) & 0xFF); + oneByte[1] = (sal_Int8) ((v >> 16) & 0xFF); + oneByte[2] = (sal_Int8) ((v >> 8) & 0xFF); + oneByte[3] = (sal_Int8) ((v >> 0) & 0xFF); + + xOut->writeBytes(oneByte); +#ifdef HSQLDB_DBG + if ( logger ) + logger->write( oneByte.getConstArray(), 4 ); +#endif + } + else + { + ThrowException( env, + "java/io/IOException", + "No OutputStream"); + } + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : writeBytes(aData);"); + StorageContainer::throwJavaException(e,env); + } +} + +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess + * Method: writeInt + * Signature: (Ljava/lang/String;Ljava/lang/String;I)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_writeInt + (JNIEnv * env, jobject obj_this,jstring name, jstring key, jint v) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "data" ); + aOpLog.logOperation( "writeInt" ); + + DataLogFile aDataLog( env, name, "data" ); + write_to_storage_stream( env, obj_this, name, key, v, &aDataLog ); +#else + write_to_storage_stream( env, obj_this, name, key, v ); +#endif +} diff --git a/connectivity/source/drivers/hsqldb/HStorageMap.cxx b/connectivity/source/drivers/hsqldb/HStorageMap.cxx new file mode 100644 index 000000000000..57ed88b1dda8 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HStorageMap.cxx @@ -0,0 +1,362 @@ +/************************************************************************* + * + * 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 "hsqldb/HStorageMap.hxx" +#include <comphelper/types.hxx> +#include <com/sun/star/embed/XTransactionBroadcaster.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include "diagnose_ex.h" +#include <osl/thread.h> + +//........................................................................ +namespace connectivity +{ +//........................................................................ + namespace hsqldb + { + //........................................................................ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::embed; + using namespace ::com::sun::star::io; + +#define ThrowException(env, type, msg) { \ + env->ThrowNew(env->FindClass(type), msg); } + + + StreamHelper::StreamHelper(const Reference< XStream>& _xStream) + : m_xStream(_xStream) + { + } + // ----------------------------------------------------------------------------- + StreamHelper::~StreamHelper() + { + try + { + m_xStream.clear(); + m_xSeek.clear(); + if ( m_xInputStream.is() ) + { + m_xInputStream->closeInput(); + m_xInputStream.clear(); + } + // this is done implicity by the closing of the input stream + else if ( m_xOutputStream.is() ) + { + m_xOutputStream->closeOutput(); + try + { + ::comphelper::disposeComponent(m_xOutputStream); + } + catch(DisposedException&) + { + } + catch(const Exception& e) + { + OSL_UNUSED( e ); + OSL_ENSURE(0,"Could not dispose OutputStream"); + } + m_xOutputStream.clear(); + } + } + catch(Exception& ex) + { + OSL_UNUSED( ex ); + OSL_ENSURE(0,"Exception catched!"); + } + } + // ----------------------------------------------------------------------------- + Reference< XInputStream> StreamHelper::getInputStream() + { + if ( !m_xInputStream.is() ) + m_xInputStream = m_xStream->getInputStream(); + return m_xInputStream; + } + // ----------------------------------------------------------------------------- + Reference< XOutputStream> StreamHelper::getOutputStream() + { + if ( !m_xOutputStream.is() ) + m_xOutputStream = m_xStream->getOutputStream(); + return m_xOutputStream; + } + // ----------------------------------------------------------------------------- + Reference< XSeekable> StreamHelper::getSeek() + { + if ( !m_xSeek.is() ) + m_xSeek.set(m_xStream,UNO_QUERY); + return m_xSeek; + } + // ----------------------------------------------------------------------------- + TStorages& lcl_getStorageMap() + { + static TStorages s_aMap; + return s_aMap; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString lcl_getNextCount() + { + static sal_Int32 s_nCount = 0; + return ::rtl::OUString::valueOf(s_nCount++); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString StorageContainer::removeURLPrefix(const ::rtl::OUString& _sURL,const ::rtl::OUString& _sFileURL) + { + return _sURL.copy(_sFileURL.getLength()+1); + } + // ----------------------------------------------------------------------------- + ::rtl::OUString StorageContainer::removeOldURLPrefix(const ::rtl::OUString& _sURL) + { + ::rtl::OUString sRet = _sURL; +#if defined(WIN) || defined(WNT) + sal_Int32 nIndex = sRet.lastIndexOf('\\'); +#else + sal_Int32 nIndex = sRet.lastIndexOf('/'); +#endif + if ( nIndex != -1 ) + { + sRet = _sURL.copy(nIndex+1); + } + return sRet; + + } + /*****************************************************************************/ + /* convert jstring to rtl_uString */ + + ::rtl::OUString StorageContainer::jstring2ustring(JNIEnv * env, jstring jstr) + { + if (JNI_FALSE != env->ExceptionCheck()) + { + env->ExceptionClear(); + OSL_ENSURE(0,"ExceptionClear"); + } + ::rtl::OUString aStr; + if ( jstr ) + { + jboolean bCopy(sal_True); + const jchar* pChar = env->GetStringChars(jstr,&bCopy); + jsize len = env->GetStringLength(jstr); + aStr = ::rtl::OUString(pChar,len); + + if(bCopy) + env->ReleaseStringChars(jstr,pChar); + } + + if (JNI_FALSE != env->ExceptionCheck()) + { + env->ExceptionClear(); + OSL_ENSURE(0,"ExceptionClear"); + } + return aStr; + } + + // ----------------------------------------------------------------------------- + ::rtl::OUString StorageContainer::registerStorage(const Reference< XStorage>& _xStorage,const ::rtl::OUString& _sURL) + { + OSL_ENSURE(_xStorage.is(),"Storage is NULL!"); + TStorages& rMap = lcl_getStorageMap(); + // check if the storage is already in our map + TStorages::iterator aFind = ::std::find_if(rMap.begin(),rMap.end(), + ::std::compose1( + ::std::bind2nd(::std::equal_to<Reference<XStorage> >(),_xStorage) + ,::std::compose1(::std::select1st<TStorageURLPair>(),::std::compose1(::std::select1st<TStorages::mapped_type>(),::std::select2nd<TStorages::value_type>()))) + ); + if ( aFind == rMap.end() ) + { + aFind = rMap.insert(TStorages::value_type(lcl_getNextCount(),TStorages::mapped_type(TStorageURLPair(_xStorage,_sURL),TStreamMap()))).first; + } + + return aFind->first; + } + // ----------------------------------------------------------------------------- + TStorages::mapped_type StorageContainer::getRegisteredStorage(const ::rtl::OUString& _sKey) + { + TStorages::mapped_type aRet; + TStorages& rMap = lcl_getStorageMap(); + TStorages::iterator aFind = rMap.find(_sKey); + OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!"); + if ( aFind != rMap.end() ) + aRet = aFind->second; + + return aRet; + } + // ----------------------------------------------------------------------------- + ::rtl::OUString StorageContainer::getRegisteredKey(const Reference< XStorage>& _xStorage) + { + ::rtl::OUString sKey; + OSL_ENSURE(_xStorage.is(),"Storage is NULL!"); + TStorages& rMap = lcl_getStorageMap(); + // check if the storage is already in our map + TStorages::iterator aFind = ::std::find_if(rMap.begin(),rMap.end(), + ::std::compose1( + ::std::bind2nd(::std::equal_to<Reference<XStorage> >(),_xStorage) + ,::std::compose1(::std::select1st<TStorageURLPair>(),::std::compose1(::std::select1st<TStorages::mapped_type>(),::std::select2nd<TStorages::value_type>()))) + ); + if ( aFind != rMap.end() ) + sKey = aFind->first; + return sKey; + } + // ----------------------------------------------------------------------------- + void StorageContainer::revokeStorage(const ::rtl::OUString& _sKey,const Reference<XTransactionListener>& _xListener) + { + TStorages& rMap = lcl_getStorageMap(); + TStorages::iterator aFind = rMap.find(_sKey); + if ( aFind != rMap.end() ) + { + try + { + if ( _xListener.is() ) + { + Reference<XTransactionBroadcaster> xBroad(aFind->second.first.first,UNO_QUERY); + if ( xBroad.is() ) + xBroad->removeTransactionListener(_xListener); + Reference<XTransactedObject> xTrans(aFind->second.first.first,UNO_QUERY); + if ( xTrans.is() ) + xTrans->commit(); + } + } + catch(Exception&) + { + } + rMap.erase(aFind); + } + } + // ----------------------------------------------------------------------------- + TStreamMap::mapped_type StorageContainer::registerStream(JNIEnv * env,jstring name, jstring key,sal_Int32 _nMode) + { + TStreamMap::mapped_type pHelper; + TStorages& rMap = lcl_getStorageMap(); + ::rtl::OUString sKey = jstring2ustring(env,key); + TStorages::iterator aFind = rMap.find(sKey); + OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!"); + if ( aFind != rMap.end() ) + { + TStorages::mapped_type aStoragePair = StorageContainer::getRegisteredStorage(sKey); + OSL_ENSURE(aStoragePair.first.first.is(),"No Storage available!"); + if ( aStoragePair.first.first.is() ) + { + ::rtl::OUString sOrgName = StorageContainer::jstring2ustring(env,name); + ::rtl::OUString sName = removeURLPrefix(sOrgName,aStoragePair.first.second); + TStreamMap::iterator aStreamFind = aFind->second.second.find(sName); + OSL_ENSURE( aStreamFind == aFind->second.second.end(),"A Stream was already registered for this object!"); + if ( aStreamFind != aFind->second.second.end() ) + { + pHelper = aStreamFind->second; + } + else + { + try + { + try + { + pHelper.reset(new StreamHelper(aStoragePair.first.first->openStreamElement(sName,_nMode))); + } + catch(Exception& ) + { + ::rtl::OUString sStrippedName = removeOldURLPrefix(sOrgName); + + if ( ((_nMode & ElementModes::WRITE) != ElementModes::WRITE ) ) + { + sal_Bool bIsStream = sal_True; + try + { + bIsStream = aStoragePair.first.first->isStreamElement(sStrippedName); + } + catch(Exception& ) + { + bIsStream = sal_False; + } + if ( !bIsStream ) + return pHelper; // readonly file without data stream + } + pHelper.reset( new StreamHelper(aStoragePair.first.first->openStreamElement( sStrippedName, _nMode ) ) ); + } + aFind->second.second.insert(TStreamMap::value_type(sName,pHelper)); + } + catch(Exception& e) + { +#if OSL_DEBUG_LEVEL > 0 + ::rtl::OString sMessage( "[HSQLDB-SDBC] caught an exception while opening a stream\n" ); + sMessage += "Name: "; + sMessage += ::rtl::OString( sName.getStr(), sName.getLength(), osl_getThreadTextEncoding() ); + sMessage += "\nMode: 0x"; + if ( _nMode < 16 ) + sMessage += "0"; + sMessage += ::rtl::OString::valueOf( _nMode, 16 ).toAsciiUpperCase(); + OSL_ENSURE( false, sMessage.getStr() ); +#endif + StorageContainer::throwJavaException(e,env); + } + } + } + } + return pHelper; + } + // ----------------------------------------------------------------------------- + void StorageContainer::revokeStream( JNIEnv * env,jstring name, jstring key) + { + TStorages& rMap = lcl_getStorageMap(); + TStorages::iterator aFind = rMap.find(jstring2ustring(env,key)); + OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!"); + if ( aFind != rMap.end() ) + aFind->second.second.erase(removeURLPrefix(jstring2ustring(env,name),aFind->second.first.second)); + } + // ----------------------------------------------------------------------------- + TStreamMap::mapped_type StorageContainer::getRegisteredStream( JNIEnv * env,jstring name, jstring key) + { + TStreamMap::mapped_type pRet; + TStorages& rMap = lcl_getStorageMap(); + TStorages::iterator aFind = rMap.find(jstring2ustring(env,key)); + OSL_ENSURE(aFind != rMap.end(),"Storage could not be found in list!"); + if ( aFind != rMap.end() ) + { + TStreamMap::iterator aStreamFind = aFind->second.second.find(removeURLPrefix(jstring2ustring(env,name),aFind->second.first.second)); + if ( aStreamFind != aFind->second.second.end() ) + pRet = aStreamFind->second; + } + + return pRet; + } + // ----------------------------------------------------------------------------- + void StorageContainer::throwJavaException(const Exception& _aException,JNIEnv * env) + { + if (JNI_FALSE != env->ExceptionCheck()) + env->ExceptionClear(); + ::rtl::OString cstr( ::rtl::OUStringToOString(_aException.Message, RTL_TEXTENCODING_JAVA_UTF8 ) ); + OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() ); + env->ThrowNew(env->FindClass("java/io/IOException"), cstr.getStr()); + } + //........................................................................ + } // namespace hsqldb + //........................................................................ +//........................................................................ +} +// namespace connectivity +//........................................................................ diff --git a/connectivity/source/drivers/hsqldb/HTable.cxx b/connectivity/source/drivers/hsqldb/HTable.cxx new file mode 100644 index 000000000000..fdf16c8b975a --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HTable.cxx @@ -0,0 +1,427 @@ +/************************************************************************* + * + * 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 "hsqldb/HTable.hxx" +#include "hsqldb/HTables.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <cppuhelper/typeprovider.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <comphelper/property.hxx> +#include <comphelper/extract.hxx> +#include <comphelper/types.hxx> +#include "connectivity/dbtools.hxx" +#include "connectivity/sdbcx/VColumn.hxx" +#include "connectivity/TKeys.hxx" +#include "connectivity/TIndexes.hxx" +#include "connectivity/TColumnsHelper.hxx" +#include "hsqldb/HCatalog.hxx" +#include "hsqldb/HColumns.hxx" +#include "TConnection.hxx" + +#include <tools/diagnose_ex.h> + + +using namespace ::comphelper; +using namespace connectivity::hsqldb; +using namespace connectivity::sdbcx; +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; +using namespace ::com::sun::star::lang; + +OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables, + const Reference< XConnection >& _xConnection) + :OTableHelper(_pTables,_xConnection,sal_True) +{ + // we create a new table here, so we should have all the rights or ;-) + m_nPrivileges = Privilege::DROP | + Privilege::REFERENCE | + Privilege::ALTER | + Privilege::CREATE | + Privilege::READ | + Privilege::DELETE | + Privilege::UPDATE | + Privilege::INSERT | + Privilege::SELECT; + construct(); +} +// ------------------------------------------------------------------------- +OHSQLTable::OHSQLTable( sdbcx::OCollection* _pTables, + const Reference< XConnection >& _xConnection, + const ::rtl::OUString& _Name, + const ::rtl::OUString& _Type, + const ::rtl::OUString& _Description , + const ::rtl::OUString& _SchemaName, + const ::rtl::OUString& _CatalogName, + sal_Int32 _nPrivileges + ) : OTableHelper( _pTables, + _xConnection, + sal_True, + _Name, + _Type, + _Description, + _SchemaName, + _CatalogName) + , m_nPrivileges(_nPrivileges) +{ + construct(); +} +// ------------------------------------------------------------------------- +void OHSQLTable::construct() +{ + OTableHelper::construct(); + if ( !isNew() ) + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRIVILEGES), PROPERTY_ID_PRIVILEGES,PropertyAttribute::READONLY,&m_nPrivileges, ::getCppuType(&m_nPrivileges)); +} +// ----------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper* OHSQLTable::createArrayHelper( sal_Int32 /*_nId*/ ) const +{ + return doCreateArrayHelper(); +} +// ------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper & OHSQLTable::getInfoHelper() +{ + return *static_cast<OHSQLTable_PROP*>(const_cast<OHSQLTable*>(this))->getArrayHelper(isNew() ? 1 : 0); +} +// ----------------------------------------------------------------------------- +sdbcx::OCollection* OHSQLTable::createColumns(const TStringVector& _rNames) +{ + OHSQLColumns* pColumns = new OHSQLColumns(*this,sal_True,m_aMutex,_rNames); + pColumns->setParent(this); + return pColumns; +} +// ----------------------------------------------------------------------------- +sdbcx::OCollection* OHSQLTable::createKeys(const TStringVector& _rNames) +{ + return new OKeysHelper(this,m_aMutex,_rNames); +} +// ----------------------------------------------------------------------------- +sdbcx::OCollection* OHSQLTable::createIndexes(const TStringVector& _rNames) +{ + return new OIndexesHelper(this,m_aMutex,_rNames); +} +//-------------------------------------------------------------------------- +Sequence< sal_Int8 > OHSQLTable::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 OHSQLTable::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 ) + : OTable_TYPEDEF::getSomething(rId); +} +// ------------------------------------------------------------------------- +// XAlterTable +void SAL_CALL OHSQLTable::alterColumnByName( const ::rtl::OUString& colName, const Reference< XPropertySet >& descriptor ) throw(SQLException, NoSuchElementException, RuntimeException) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed( +#ifdef GCC + ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed +#else + rBHelper.bDisposed +#endif + ); + + if ( m_pColumns && !m_pColumns->hasByName(colName) ) + throw NoSuchElementException(colName,*this); + + + if ( !isNew() ) + { + // first we have to check what should be altered + Reference<XPropertySet> xProp; + m_pColumns->getByName(colName) >>= xProp; + // first check the types + sal_Int32 nOldType = 0,nNewType = 0,nOldPrec = 0,nNewPrec = 0,nOldScale = 0,nNewScale = 0; + ::rtl::OUString sOldTypeName, sNewTypeName; + + ::dbtools::OPropertyMap& rProp = OMetaConnection::getPropMap(); + + // type/typename + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nOldType; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPE)) >>= nNewType; + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sOldTypeName; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_TYPENAME))>>= sNewTypeName; + + // and precsions and scale + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nOldPrec; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_PRECISION))>>= nNewPrec; + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nOldScale; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_SCALE)) >>= nNewScale; + + // second: check the "is nullable" value + sal_Int32 nOldNullable = 0,nNewNullable = 0; + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nOldNullable; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISNULLABLE)) >>= nNewNullable; + + // check also the auto_increment + sal_Bool bOldAutoIncrement = sal_False,bAutoIncrement = sal_False; + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bOldAutoIncrement; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bAutoIncrement; + + // now we should look if the name of the column changed + ::rtl::OUString sNewColumnName; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_NAME)) >>= sNewColumnName; + if ( !sNewColumnName.equals(colName) ) + { + const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + + ::rtl::OUString sSql = getAlterTableColumnPart(); + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ALTER COLUMN ")); + sSql += ::dbtools::quoteName(sQuote,colName); + + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" RENAME TO ")); + sSql += ::dbtools::quoteName(sQuote,sNewColumnName); + + executeStatement(sSql); + } + + if ( nOldType != nNewType + || sOldTypeName != sNewTypeName + || nOldPrec != nNewPrec + || nOldScale != nNewScale + || nNewNullable != nOldNullable + || bOldAutoIncrement != bAutoIncrement ) + { + // special handling because they change the type names to distinguish + // if a column should be an auto_incmrement one + if ( bOldAutoIncrement != bAutoIncrement ) + { + /// TODO: insert special handling for auto increment "IDENTITY" and primary key + } + alterColumnType(nNewType,sNewColumnName,descriptor); + } + + // third: check the default values + ::rtl::OUString sNewDefault,sOldDefault; + xProp->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sOldDefault; + descriptor->getPropertyValue(rProp.getNameByIndex(PROPERTY_ID_DEFAULTVALUE)) >>= sNewDefault; + + if(sOldDefault.getLength()) + { + dropDefaultValue(colName); + if(sNewDefault.getLength() && sOldDefault != sNewDefault) + alterDefaultValue(sNewDefault,sNewColumnName); + } + else if(!sOldDefault.getLength() && sNewDefault.getLength()) + alterDefaultValue(sNewDefault,sNewColumnName); + + m_pColumns->refresh(); + } + else + { + if(m_pColumns) + { + m_pColumns->dropByName(colName); + m_pColumns->appendByDescriptor(descriptor); + } + } + +} +// ----------------------------------------------------------------------------- +void OHSQLTable::alterColumnType(sal_Int32 nNewType,const ::rtl::OUString& _rColName, const Reference<XPropertySet>& _xDescriptor) +{ + ::rtl::OUString sSql = getAlterTableColumnPart(); + + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ALTER COLUMN ")); +#if OSL_DEBUG_LEVEL > 0 + try + { + ::rtl::OUString sDescriptorName; + OSL_ENSURE( _xDescriptor.is() + && ( _xDescriptor->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= sDescriptorName ) + && ( sDescriptorName == _rColName ), + "OHSQLTable::alterColumnType: unexpected column name!" ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +#else + (void)_rColName; +#endif + + OHSQLColumn* pColumn = new OHSQLColumn(sal_True); + Reference<XPropertySet> xProp = pColumn; + ::comphelper::copyProperties(_xDescriptor,xProp); + xProp->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE),makeAny(nNewType)); + + sSql += ::dbtools::createStandardColumnPart(xProp,getConnection()); + executeStatement(sSql); +} +// ----------------------------------------------------------------------------- +void OHSQLTable::alterDefaultValue(const ::rtl::OUString& _sNewDefault,const ::rtl::OUString& _rColName) +{ + ::rtl::OUString sSql = getAlterTableColumnPart(); + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ALTER COLUMN ")); + + const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + sSql += ::dbtools::quoteName(sQuote,_rColName); + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" SET DEFAULT '")) + _sNewDefault; + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'")); + + executeStatement(sSql); +} +// ----------------------------------------------------------------------------- +void OHSQLTable::dropDefaultValue(const ::rtl::OUString& _rColName) +{ + ::rtl::OUString sSql = getAlterTableColumnPart(); + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ALTER COLUMN ")); + + const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + sSql += ::dbtools::quoteName(sQuote,_rColName); + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DROP DEFAULT")); + + executeStatement(sSql); +} +// ----------------------------------------------------------------------------- +::rtl::OUString OHSQLTable::getAlterTableColumnPart() +{ + ::rtl::OUString sSql = ::rtl::OUString::createFromAscii("ALTER TABLE "); + const ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + + ::rtl::OUString sComposedName( ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, sal_True, ::dbtools::eInTableDefinitions ) ); + sSql += sComposedName; + + return sSql; +} +// ----------------------------------------------------------------------------- +void OHSQLTable::executeStatement(const ::rtl::OUString& _rStatement ) +{ + ::rtl::OUString sSQL = _rStatement; + if(sSQL.lastIndexOf(',') == (sSQL.getLength()-1)) + sSQL = sSQL.replaceAt(sSQL.getLength()-1,1,::rtl::OUString::createFromAscii(")")); + + Reference< XStatement > xStmt = getConnection()->createStatement( ); + if ( xStmt.is() ) + { + try { xStmt->execute(sSQL); } + catch( const Exception& ) + { + ::comphelper::disposeComponent(xStmt); + throw; + } + ::comphelper::disposeComponent(xStmt); + } +} +// ----------------------------------------------------------------------------- +Sequence< Type > SAL_CALL OHSQLTable::getTypes( ) throw(RuntimeException) +{ + if ( ! m_Type.compareToAscii("VIEW") ) + { + Sequence< Type > aTypes = OTableHelper::getTypes(); + ::std::vector<Type> aOwnTypes; + aOwnTypes.reserve(aTypes.getLength()); + const Type* pIter = aTypes.getConstArray(); + const Type* pEnd = pIter + aTypes.getLength(); + for(;pIter != pEnd;++pIter) + { + if( *pIter != ::getCppuType((const Reference<XRename>*)0) ) + { + aOwnTypes.push_back(*pIter); + } + } + Type *pTypes = aOwnTypes.empty() ? 0 : &aOwnTypes[0]; + return Sequence< Type >(pTypes, aOwnTypes.size()); + } + return OTableHelper::getTypes(); +} +// ------------------------------------------------------------------------- +// XRename +void SAL_CALL OHSQLTable::rename( const ::rtl::OUString& newName ) throw(SQLException, ElementExistException, RuntimeException) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed( +#ifdef GCC + ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed +#else + rBHelper.bDisposed +#endif + ); + + if(!isNew()) + { + ::rtl::OUString sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ALTER ")); + if ( m_Type == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VIEW")) ) + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" VIEW ")); + else + sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" TABLE ")); + + ::rtl::OUString sQuote = getMetaData()->getIdentifierQuoteString( ); + + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + + ::rtl::OUString sComposedName( + ::dbtools::composeTableName( getMetaData(), m_CatalogName, m_SchemaName, m_Name, sal_True, ::dbtools::eInDataManipulation ) ); + sSql += sComposedName + + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" RENAME TO ")); + sSql += ::dbtools::composeTableName( getMetaData(), sCatalog, sSchema, sTable, sal_True, ::dbtools::eInDataManipulation ); + + executeStatement(sSql); + + ::connectivity::OTable_TYPEDEF::rename(newName); + } + else + ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::eInTableDefinitions); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL OHSQLTable::queryInterface( const Type & rType ) throw(RuntimeException) +{ + if( !m_Type.compareToAscii("VIEW") && rType == ::getCppuType((const Reference<XRename>*)0) ) + return Any(); + + return OTableHelper::queryInterface(rType); +} +// ------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/hsqldb/HTables.cxx b/connectivity/source/drivers/hsqldb/HTables.cxx new file mode 100644 index 000000000000..3013d2838fb0 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HTables.cxx @@ -0,0 +1,200 @@ +/************************************************************************* + * + * 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 "hsqldb/HTables.hxx" +#include "hsqldb/HViews.hxx" +#include "hsqldb/HTable.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include "hsqldb/HCatalog.hxx" +#include <comphelper/extract.hxx> +#include "connectivity/dbtools.hxx" +#include "connectivity/dbexception.hxx" +#include <cppuhelper/interfacecontainer.h> +#include <comphelper/types.hxx> +#include "TConnection.hxx" + +using namespace ::comphelper; +using namespace connectivity; +using namespace ::cppu; +using namespace connectivity::hsqldb; +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 dbtools; +typedef connectivity::sdbcx::OCollection OCollection_TYPE; + +sdbcx::ObjectType OTables::createObject(const ::rtl::OUString& _rName) +{ + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(m_xMetaData,_rName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + + static const ::rtl::OUString s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW")); + static const ::rtl::OUString s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE")); + static const ::rtl::OUString s_sAll(RTL_CONSTASCII_USTRINGPARAM("%")); + + Sequence< ::rtl::OUString > sTableTypes(3); + sTableTypes[0] = s_sTableTypeView; + sTableTypes[1] = s_sTableTypeTable; + sTableTypes[2] = s_sAll; // just to be sure to include anything else .... + + Any aCatalog; + if ( sCatalog.getLength() ) + aCatalog <<= sCatalog; + Reference< XResultSet > xResult = m_xMetaData->getTables(aCatalog,sSchema,sTable,sTableTypes); + + sdbcx::ObjectType xRet = NULL; + if ( xResult.is() ) + { + Reference< XRow > xRow(xResult,UNO_QUERY); + if ( xResult->next() ) // there can be only one table with this name + { + sal_Int32 nPrivileges = ::dbtools::getTablePrivileges( m_xMetaData, sCatalog, sSchema, sTable ); + if ( m_xMetaData->isReadOnly() ) + nPrivileges &= ~( Privilege::INSERT | Privilege::UPDATE | Privilege::DELETE | Privilege::CREATE | Privilege::ALTER | Privilege::DROP ); + + // obtain privileges + OHSQLTable* pRet = new OHSQLTable( this + ,static_cast<OHCatalog&>(m_rParent).getConnection() + ,sTable + ,xRow->getString(4) + ,xRow->getString(5) + ,sSchema + ,sCatalog + ,nPrivileges); + xRet = pRet; + } + ::comphelper::disposeComponent(xResult); + } + + return xRet; +} +// ------------------------------------------------------------------------- +void OTables::impl_refresh( ) throw(RuntimeException) +{ + static_cast<OHCatalog&>(m_rParent).refreshTables(); +} +// ------------------------------------------------------------------------- +void OTables::disposing(void) +{ +m_xMetaData.clear(); + OCollection::disposing(); +} +// ------------------------------------------------------------------------- +Reference< XPropertySet > OTables::createDescriptor() +{ + return new OHSQLTable(this,static_cast<OHCatalog&>(m_rParent).getConnection()); +} +// ------------------------------------------------------------------------- +// XAppend +sdbcx::ObjectType OTables::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + createTable(descriptor); + return createObject( _rForName ); +} +// ------------------------------------------------------------------------- +// XDrop +void OTables::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName) +{ + Reference< XInterface > xObject( getObject( _nPos ) ); + sal_Bool bIsNew = connectivity::sdbcx::ODescriptor::isNew( xObject ); + if (!bIsNew) + { + Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection(); + + + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(m_xMetaData,_sElementName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + + ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP "); + + Reference<XPropertySet> xProp(xObject,UNO_QUERY); + sal_Bool bIsView; + if((bIsView = (xProp.is() && ::comphelper::getString(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))) == ::rtl::OUString::createFromAscii("VIEW")))) // here we have a view + aSql += ::rtl::OUString::createFromAscii("VIEW "); + else + aSql += ::rtl::OUString::createFromAscii("TABLE "); + + ::rtl::OUString sComposedName( + ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInDataManipulation ) ); + aSql += sComposedName; + Reference< XStatement > xStmt = xConnection->createStatement( ); + if ( xStmt.is() ) + { + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } + // if no exception was thrown we must delete it from the views + if ( bIsView ) + { + HViews* pViews = static_cast<HViews*>(static_cast<OHCatalog&>(m_rParent).getPrivateViews()); + if ( pViews && pViews->hasByName(_sElementName) ) + pViews->dropByNameImpl(_sElementName); + } + } +} +// ------------------------------------------------------------------------- +void OTables::createTable( const Reference< XPropertySet >& descriptor ) +{ + Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection(); + ::rtl::OUString aSql = ::dbtools::createSqlCreateTableStatement(descriptor,xConnection); + + Reference< XStatement > xStmt = xConnection->createStatement( ); + if ( xStmt.is() ) + { + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } +} +// ----------------------------------------------------------------------------- +void OTables::appendNew(const ::rtl::OUString& _rsNewTable) +{ + insertElement(_rsNewTable,NULL); + + // notify our container listeners + ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_rsNewTable), Any(), Any()); + OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners); + while (aListenerLoop.hasMoreElements()) + static_cast<XContainerListener*>(aListenerLoop.next())->elementInserted(aEvent); +} +// ----------------------------------------------------------------------------- +::rtl::OUString OTables::getNameForObject(const sdbcx::ObjectType& _xObject) +{ + OSL_ENSURE(_xObject.is(),"OTables::getNameForObject: Object is NULL!"); + return ::dbtools::composeTableName( m_xMetaData, _xObject, ::dbtools::eInDataManipulation, false, false, false ); +} +// ----------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/hsqldb/HTerminateListener.cxx b/connectivity/source/drivers/hsqldb/HTerminateListener.cxx new file mode 100644 index 000000000000..c386334acd70 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HTerminateListener.cxx @@ -0,0 +1,64 @@ +/************************************************************************* + * + * 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 "HTerminateListener.hxx" +#include "hsqldb/HDriver.hxx" + +//........................................................................ +namespace connectivity +{ +//........................................................................ + using namespace hsqldb; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::lang; + using namespace ::rtl; + +// XEventListener +void SAL_CALL OConnectionController::disposing( const EventObject& /*Source*/ ) +throw( RuntimeException ) +{ +} + +// XTerminateListener +void SAL_CALL OConnectionController::queryTermination( const EventObject& /*aEvent*/ ) +throw( TerminationVetoException, RuntimeException ) +{ +} + +void SAL_CALL OConnectionController::notifyTermination( const EventObject& /*aEvent*/ ) +throw( RuntimeException ) +{ + m_pDriver->shutdownConnections(); +} + +//........................................................................ +} // namespace connectivity +//........................................................................ diff --git a/connectivity/source/drivers/hsqldb/HTerminateListener.hxx b/connectivity/source/drivers/hsqldb/HTerminateListener.hxx new file mode 100644 index 000000000000..9bec7c02d57f --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HTerminateListener.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifndef CONNECTIVITY_HSQLDB_TERMINATELISTENER_HXX +#define CONNECTIVITY_HSQLDB_TERMINATELISTENER_HXX + +#include <cppuhelper/compbase1.hxx> +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/frame/XTerminateListener.hpp> +#endif + +//........................................................................ +namespace connectivity +{ +//........................................................................ + + namespace hsqldb + { + class ODriverDelegator; + class OConnectionController : public ::cppu::WeakImplHelper1< + ::com::sun::star::frame::XTerminateListener > + { + ODriverDelegator* m_pDriver; + protected: + virtual ~OConnectionController() {m_pDriver = NULL;} + public: + OConnectionController(ODriverDelegator* _pDriver) : m_pDriver(_pDriver){} + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw( ::com::sun::star::uno::RuntimeException ); + + // XTerminateListener + virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) + throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) + throw( ::com::sun::star::uno::RuntimeException ); + }; + } +//........................................................................ +} // namespace connectivity +//........................................................................ +#endif // CONNECTIVITY_HSQLDB_TERMINATELISTENER_HXX diff --git a/connectivity/source/drivers/hsqldb/HTools.cxx b/connectivity/source/drivers/hsqldb/HTools.cxx new file mode 100644 index 000000000000..c5e31e5ef1a4 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HTools.cxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * 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 "hsqldb/HTools.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +//........................................................................ +namespace connectivity { namespace hsqldb +{ +//........................................................................ + + /** === begin UNO using === **/ + /** === end UNO using === **/ + + //==================================================================== + //= HTools + //==================================================================== + //-------------------------------------------------------------------- + void HTools::appendTableFilterCrit( ::rtl::OUStringBuffer& _inout_rBuffer, const ::rtl::OUString& _rCatalog, + const ::rtl::OUString _rSchema, const ::rtl::OUString _rName, bool _bShortForm ) + { + _inout_rBuffer.appendAscii( " WHERE " ); + if ( _rCatalog.getLength() ) + { + _inout_rBuffer.appendAscii( _bShortForm ? "TABLE_CAT" : "TABLE_CATALOG" ); + _inout_rBuffer.appendAscii( " = '" ); + _inout_rBuffer.append ( _rCatalog ); + _inout_rBuffer.appendAscii( "' AND " ); + } + if ( _rSchema.getLength() ) + { + _inout_rBuffer.appendAscii( _bShortForm ? "TABLE_SCHEM" : "TABLE_SCHEMA" ); + _inout_rBuffer.appendAscii( " = '" ); + _inout_rBuffer.append ( _rSchema ); + _inout_rBuffer.appendAscii( "' AND " ); + } + _inout_rBuffer.appendAscii( "TABLE_NAME = '" ); + _inout_rBuffer.append ( _rName ); + _inout_rBuffer.appendAscii( "'" ); + } + +//........................................................................ +} } // namespace connectivity::hsqldb +//........................................................................ diff --git a/connectivity/source/drivers/hsqldb/HUser.cxx b/connectivity/source/drivers/hsqldb/HUser.cxx new file mode 100644 index 000000000000..90f914e77307 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HUser.cxx @@ -0,0 +1,351 @@ +/************************************************************************* + * + * 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 "hsqldb/HUser.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include "connectivity/dbtools.hxx" +#include "connectivity/dbexception.hxx" +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/PrivilegeObject.hpp> +#include "TConnection.hxx" +#include "resource/hsqldb_res.hrc" + +using namespace connectivity; +using namespace connectivity::hsqldb; +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; +// ------------------------------------------------------------------------- +OHSQLUser::OHSQLUser( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection) : connectivity::sdbcx::OUser(sal_True) + ,m_xConnection(_xConnection) +{ + construct(); +} +// ------------------------------------------------------------------------- +OHSQLUser::OHSQLUser( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection, + const ::rtl::OUString& _Name + ) : connectivity::sdbcx::OUser(_Name,sal_True) + ,m_xConnection(_xConnection) +{ + construct(); +} +// ------------------------------------------------------------------------- +void OHSQLUser::refreshGroups() +{ +} +// ------------------------------------------------------------------------- +OUserExtend::OUserExtend( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection) : OHSQLUser(_xConnection) +{ + construct(); +} +// ------------------------------------------------------------------------- +typedef connectivity::sdbcx::OUser OUser_TYPEDEF; +void OUserExtend::construct() +{ + registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), PROPERTY_ID_PASSWORD,0,&m_Password,::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL))); +} +// ----------------------------------------------------------------------------- +cppu::IPropertyArrayHelper* OUserExtend::createArrayHelper() const +{ + Sequence< Property > aProps; + describeProperties(aProps); + return new cppu::OPropertyArrayHelper(aProps); +} +// ------------------------------------------------------------------------- +cppu::IPropertyArrayHelper & OUserExtend::getInfoHelper() +{ + return *OUserExtend_PROP::getArrayHelper(); +} +typedef connectivity::sdbcx::OUser_BASE OUser_BASE_RBHELPER; +// ----------------------------------------------------------------------------- +sal_Int32 SAL_CALL OHSQLUser::getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed); + + sal_Int32 nRights,nRightsWithGrant; + findPrivilegesAndGrantPrivileges(objName,objType,nRights,nRightsWithGrant); + return nRights; +} +// ----------------------------------------------------------------------------- +void OHSQLUser::findPrivilegesAndGrantPrivileges(const ::rtl::OUString& objName, sal_Int32 objType,sal_Int32& nRights,sal_Int32& nRightsWithGrant) throw(SQLException, RuntimeException) +{ + nRightsWithGrant = nRights = 0; + // first we need to create the sql stmt to select the privs + Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(xMeta,objName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation); + Reference<XResultSet> xRes; + switch(objType) + { + case PrivilegeObject::TABLE: + case PrivilegeObject::VIEW: + { + Any aCatalog; + if ( sCatalog.getLength() ) + aCatalog <<= sCatalog; + xRes = xMeta->getTablePrivileges(aCatalog,sSchema,sTable); + } + break; + + case PrivilegeObject::COLUMN: + { + Any aCatalog; + if ( sCatalog.getLength() ) + aCatalog <<= sCatalog; + xRes = xMeta->getColumnPrivileges(aCatalog,sSchema,sTable,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%"))); + } + break; + } + + if ( xRes.is() ) + { + static const ::rtl::OUString sSELECT = ::rtl::OUString::createFromAscii("SELECT"); + static const ::rtl::OUString sINSERT = ::rtl::OUString::createFromAscii("INSERT"); + static const ::rtl::OUString sUPDATE = ::rtl::OUString::createFromAscii("UPDATE"); + static const ::rtl::OUString sDELETE = ::rtl::OUString::createFromAscii("DELETE"); + static const ::rtl::OUString sREAD = ::rtl::OUString::createFromAscii("READ"); + static const ::rtl::OUString sCREATE = ::rtl::OUString::createFromAscii("CREATE"); + static const ::rtl::OUString sALTER = ::rtl::OUString::createFromAscii("ALTER"); + static const ::rtl::OUString sREFERENCE = ::rtl::OUString::createFromAscii("REFERENCE"); + static const ::rtl::OUString sDROP = ::rtl::OUString::createFromAscii("DROP"); + static const ::rtl::OUString sYes = ::rtl::OUString::createFromAscii("YES"); + + nRightsWithGrant = nRights = 0; + + Reference<XRow> xCurrentRow(xRes,UNO_QUERY); + while( xCurrentRow.is() && xRes->next() ) + { + ::rtl::OUString sGrantee = xCurrentRow->getString(5); + ::rtl::OUString sPrivilege = xCurrentRow->getString(6); + ::rtl::OUString sGrantable = xCurrentRow->getString(7); + + if (!m_Name.equalsIgnoreAsciiCase(sGrantee)) + continue; + + if (sPrivilege.equalsIgnoreAsciiCase(sSELECT)) + { + nRights |= Privilege::SELECT; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::SELECT; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT)) + { + nRights |= Privilege::INSERT; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::INSERT; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE)) + { + nRights |= Privilege::UPDATE; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::UPDATE; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE)) + { + nRights |= Privilege::DELETE; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::DELETE; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sREAD)) + { + nRights |= Privilege::READ; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::READ; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE)) + { + nRights |= Privilege::CREATE; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::CREATE; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sALTER)) + { + nRights |= Privilege::ALTER; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::ALTER; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE)) + { + nRights |= Privilege::REFERENCE; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::REFERENCE; + } + else if (sPrivilege.equalsIgnoreAsciiCase(sDROP)) + { + nRights |= Privilege::DROP; + if ( sGrantable.equalsIgnoreAsciiCase(sYes) ) + nRightsWithGrant |= Privilege::DROP; + } + } + ::comphelper::disposeComponent(xRes); + } +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL OHSQLUser::getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed); + + sal_Int32 nRights,nRightsWithGrant; + findPrivilegesAndGrantPrivileges(objName,objType,nRights,nRightsWithGrant); + return nRightsWithGrant; +} +// ------------------------------------------------------------------------- +void SAL_CALL OHSQLUser::grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException) +{ + if ( objType != PrivilegeObject::TABLE ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceString(STR_PRIVILEGE_NOT_GRANTED)); + ::dbtools::throwGenericSQLException(sError,*this); + } // if ( objType != PrivilegeObject::TABLE ) + + + ::osl::MutexGuard aGuard(m_aMutex); + + ::rtl::OUString sPrivs = getPrivilegeString(objPrivileges); + if(sPrivs.getLength()) + { + ::rtl::OUString sGrant; + sGrant += ::rtl::OUString::createFromAscii("GRANT "); + sGrant += sPrivs; + sGrant += ::rtl::OUString::createFromAscii(" ON "); + Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); + sGrant += ::dbtools::quoteTableName(xMeta,objName,::dbtools::eInDataManipulation); + sGrant += ::rtl::OUString::createFromAscii(" TO "); + sGrant += m_Name; + + Reference<XStatement> xStmt = m_xConnection->createStatement(); + if(xStmt.is()) + xStmt->execute(sGrant); + ::comphelper::disposeComponent(xStmt); + } +} +// ------------------------------------------------------------------------- +void SAL_CALL OHSQLUser::revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException) +{ + if ( objType != PrivilegeObject::TABLE ) + { + ::connectivity::SharedResources aResources; + const ::rtl::OUString sError( aResources.getResourceString(STR_PRIVILEGE_NOT_REVOKED)); + ::dbtools::throwGenericSQLException(sError,*this); + } // if ( objType != PrivilegeObject::TABLE ) + + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed); + ::rtl::OUString sPrivs = getPrivilegeString(objPrivileges); + if(sPrivs.getLength()) + { + ::rtl::OUString sGrant; + sGrant += ::rtl::OUString::createFromAscii("REVOKE "); + sGrant += sPrivs; + sGrant += ::rtl::OUString::createFromAscii(" ON "); + Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData(); + sGrant += ::dbtools::quoteTableName(xMeta,objName,::dbtools::eInDataManipulation); + sGrant += ::rtl::OUString::createFromAscii(" FROM "); + sGrant += m_Name; + + Reference<XStatement> xStmt = m_xConnection->createStatement(); + if(xStmt.is()) + xStmt->execute(sGrant); + ::comphelper::disposeComponent(xStmt); + } +} +// ----------------------------------------------------------------------------- +// XUser +void SAL_CALL OHSQLUser::changePassword( const ::rtl::OUString& /*oldPassword*/, const ::rtl::OUString& newPassword ) throw(SQLException, RuntimeException) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed); + ::rtl::OUString sAlterPwd; + sAlterPwd = ::rtl::OUString::createFromAscii("SET PASSWORD FOR "); + sAlterPwd += m_Name; + sAlterPwd += ::rtl::OUString::createFromAscii("@\"%\" = PASSWORD('") ; + sAlterPwd += newPassword; + sAlterPwd += ::rtl::OUString::createFromAscii("')") ; + + + Reference<XStatement> xStmt = m_xConnection->createStatement(); + if ( xStmt.is() ) + { + xStmt->execute(sAlterPwd); + ::comphelper::disposeComponent(xStmt); + } +} +// ----------------------------------------------------------------------------- +::rtl::OUString OHSQLUser::getPrivilegeString(sal_Int32 nRights) const +{ + ::rtl::OUString sPrivs; + if((nRights & Privilege::INSERT) == Privilege::INSERT) + sPrivs += ::rtl::OUString::createFromAscii("INSERT"); + + if((nRights & Privilege::DELETE) == Privilege::DELETE) + { + if(sPrivs.getLength()) + sPrivs += ::rtl::OUString::createFromAscii(","); + sPrivs += ::rtl::OUString::createFromAscii("DELETE"); + } + + if((nRights & Privilege::UPDATE) == Privilege::UPDATE) + { + if(sPrivs.getLength()) + sPrivs += ::rtl::OUString::createFromAscii(","); + sPrivs += ::rtl::OUString::createFromAscii("UPDATE"); + } + + if((nRights & Privilege::ALTER) == Privilege::ALTER) + { + if(sPrivs.getLength()) + sPrivs += ::rtl::OUString::createFromAscii(","); + sPrivs += ::rtl::OUString::createFromAscii("ALTER"); + } + + if((nRights & Privilege::SELECT) == Privilege::SELECT) + { + if(sPrivs.getLength()) + sPrivs += ::rtl::OUString::createFromAscii(","); + sPrivs += ::rtl::OUString::createFromAscii("SELECT"); + } + + if((nRights & Privilege::REFERENCE) == Privilege::REFERENCE) + { + if(sPrivs.getLength()) + sPrivs += ::rtl::OUString::createFromAscii(","); + sPrivs += ::rtl::OUString::createFromAscii("REFERENCES"); + } + + return sPrivs; +} +// ----------------------------------------------------------------------------- + diff --git a/connectivity/source/drivers/hsqldb/HUsers.cxx b/connectivity/source/drivers/hsqldb/HUsers.cxx new file mode 100644 index 000000000000..151528457ac0 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HUsers.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * 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 "hsqldb/HUsers.hxx" +#include "hsqldb/HUser.hxx" +#include "hsqldb/HTable.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include "connectivity/sdbcx/IRefreshable.hxx" +#include <comphelper/types.hxx> +#include "connectivity/dbexception.hxx" +#include "connectivity/dbtools.hxx" +#include "TConnection.hxx" + +using namespace ::comphelper; +using namespace connectivity; +using namespace connectivity::hsqldb; +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; +typedef connectivity::sdbcx::OCollection OCollection_TYPE; + +OUsers::OUsers( ::cppu::OWeakObject& _rParent, + ::osl::Mutex& _rMutex, + const TStringVector &_rVector, + const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _xConnection, + connectivity::sdbcx::IRefreshableUsers* _pParent) + : sdbcx::OCollection(_rParent,sal_True,_rMutex,_rVector) + ,m_xConnection(_xConnection) + ,m_pParent(_pParent) +{ +} +// ----------------------------------------------------------------------------- + +sdbcx::ObjectType OUsers::createObject(const ::rtl::OUString& _rName) +{ + return new OHSQLUser(m_xConnection,_rName); +} +// ------------------------------------------------------------------------- +void OUsers::impl_refresh() throw(RuntimeException) +{ + m_pParent->refreshUsers(); +} +// ------------------------------------------------------------------------- +Reference< XPropertySet > OUsers::createDescriptor() +{ + OUserExtend* pNew = new OUserExtend(m_xConnection); + return pNew; +} +// ------------------------------------------------------------------------- +// XAppend +sdbcx::ObjectType OUsers::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("GRANT USAGE ON * TO "); + ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString( ); + ::rtl::OUString sUserName( _rForName ); + aSql += ::dbtools::quoteName(aQuote,sUserName) + + ::rtl::OUString::createFromAscii(" @\"%\" "); + ::rtl::OUString sPassword; + descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPassword; + if ( sPassword.getLength() ) + { + aSql += ::rtl::OUString::createFromAscii(" IDENTIFIED BY '"); + aSql += sPassword; + aSql += ::rtl::OUString::createFromAscii("'"); + } + + Reference< XStatement > xStmt = m_xConnection->createStatement( ); + if(xStmt.is()) + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + + return createObject( _rForName ); +} +// ------------------------------------------------------------------------- +// XDrop +void OUsers::dropObject(sal_Int32 /*nPos*/,const ::rtl::OUString _sElementName) +{ + { + ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("REVOKE ALL ON * FROM "); + ::rtl::OUString aQuote = m_xConnection->getMetaData()->getIdentifierQuoteString( ); + aSql += ::dbtools::quoteName(aQuote,_sElementName); + + Reference< XStatement > xStmt = m_xConnection->createStatement( ); + if(xStmt.is()) + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } +} + +// ------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/HView.cxx b/connectivity/source/drivers/hsqldb/HView.cxx new file mode 100644 index 000000000000..229e9c9218d9 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HView.cxx @@ -0,0 +1,213 @@ +/************************************************************************* + * + * 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 "hsqldb/HView.hxx" +#include "hsqldb/HTools.hxx" + +#include "propertyids.hxx" + +#include "connectivity/dbexception.hxx" +#include "connectivity/dbtools.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/WrappedTargetException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/exc_hlp.hxx> +#include <tools/diagnose_ex.h> +#include <unotools/sharedunocomponent.hxx> + +//........................................................................ +namespace connectivity { namespace hsqldb +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::sdbc::XDatabaseMetaData; + using ::com::sun::star::sdbc::SQLException; + using ::com::sun::star::sdbc::XConnection; + using ::com::sun::star::lang::WrappedTargetException; + using ::com::sun::star::sdbc::XResultSet; + using ::com::sun::star::sdbc::XStatement; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::sdbc::XRow; + /** === end UNO using === **/ + + //==================================================================== + //= HView + //==================================================================== + //-------------------------------------------------------------------- + HView::HView( const Reference< XConnection >& _rxConnection, sal_Bool _bCaseSensitive, + const ::rtl::OUString& _rSchemaName, const ::rtl::OUString& _rName ) + :HView_Base( _bCaseSensitive, _rName, _rxConnection->getMetaData(), 0, ::rtl::OUString(), _rSchemaName, ::rtl::OUString() ) + ,m_xConnection( _rxConnection ) + { + } + + //-------------------------------------------------------------------- + HView::~HView() + { + } + + //-------------------------------------------------------------------- + IMPLEMENT_FORWARD_XINTERFACE2( HView, HView_Base, HView_IBASE ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( HView, HView_Base, HView_IBASE ) + + //-------------------------------------------------------------------- + void SAL_CALL HView::alterCommand( const ::rtl::OUString& _rNewCommand ) throw (SQLException, RuntimeException) + { + // not really atomic ... as long as we do not have something like + // ALTER VIEW <name> TO <command> + // in HSQL, we need to do it this way ... + // + // I can imagine scenarios where this fails, e.g. when dropping the view + // succeedes, re-creating it fails, some other thread alters a table which + // the view was based on, and then we try to restore the view with the + // original command, which then fails, too. + // + // However, there's not much chance to prevent this kind of errors without + // backend support. + + ::rtl::OUString sQualifiedName( ::dbtools::composeTableName( + m_xMetaData, m_CatalogName, m_SchemaName, m_Name, true, ::dbtools::eInDataManipulation ) ); + + ::utl::SharedUNOComponent< XStatement > xStatement; xStatement.set( m_xConnection->createStatement(), UNO_QUERY_THROW ); + + // create a statement which can be used to re-create the original view, in case + // dropping it succeeds, but creating it with a new statement fails + ::rtl::OUStringBuffer aRestoreCommand; + aRestoreCommand.appendAscii( "CREATE VIEW " ); + aRestoreCommand.append ( sQualifiedName ); + aRestoreCommand.appendAscii( " AS " ); + aRestoreCommand.append ( impl_getCommand_throw( true ) ); + ::rtl::OUString sRestoreCommand( aRestoreCommand.makeStringAndClear() ); + + bool bDropSucceeded( false ); + try + { + // drop the existing view + ::rtl::OUStringBuffer aCommand; + aCommand.appendAscii( "DROP VIEW " ); + aCommand.append ( sQualifiedName ); + xStatement->execute( aCommand.makeStringAndClear() ); + bDropSucceeded = true; + + // create a new one with the same name + aCommand.appendAscii( "CREATE VIEW " ); + aCommand.append ( sQualifiedName ); + aCommand.appendAscii( " AS " ); + aCommand.append ( _rNewCommand ); + xStatement->execute( aCommand.makeStringAndClear() ); + } + catch( const SQLException& ) + { + if ( bDropSucceeded ) + // drop succeeded, but creation failed -> re-create the view with the original + // statemnet + xStatement->execute( sRestoreCommand ); + throw; + } + catch( const RuntimeException& ) + { + if ( bDropSucceeded ) + xStatement->execute( sRestoreCommand ); + throw; + } + catch( const Exception& ) + { + if ( bDropSucceeded ) + xStatement->execute( sRestoreCommand ); + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL HView::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const + { + if ( _nHandle == PROPERTY_ID_COMMAND ) + { + // retrieve the very current command, don't rely on the base classes cached value + // (which we initialized empty, anyway) + _rValue <<= impl_getCommand_throw( false ); + return; + } + + HView_Base::getFastPropertyValue( _rValue, _nHandle ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString HView::impl_getCommand_throw( bool _bAllowSQLException ) const + { + ::rtl::OUString sCommand; + + try + { + ::rtl::OUStringBuffer aCommand; + aCommand.appendAscii( "SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.SYSTEM_VIEWS " ); + HTools::appendTableFilterCrit( aCommand, m_CatalogName, m_SchemaName, m_Name, false ); + ::utl::SharedUNOComponent< XStatement > xStatement; xStatement.set( m_xConnection->createStatement(), UNO_QUERY_THROW ); + Reference< XResultSet > xResult( xStatement->executeQuery( aCommand.makeStringAndClear() ), UNO_QUERY_THROW ); + if ( !xResult->next() ) + { + // hmm. There is no view view the name as we know it. Can only mean some other instance + // dropped this view meanwhile ... + throw DisposedException(); + } + + Reference< XRow > xRow( xResult, UNO_QUERY_THROW ); + sCommand = xRow->getString( 1 ); + } + catch( const RuntimeException& ) { throw; } + catch( const SQLException& e ) + { + if ( _bAllowSQLException ) + throw; + throw WrappedTargetException( e.Message, static_cast< XAlterView* >( const_cast< HView* >( this ) ), ::cppu::getCaughtException() ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return sCommand; + } + +//........................................................................ +} } // namespace connectivity::hsqldb +//........................................................................ diff --git a/connectivity/source/drivers/hsqldb/HViews.cxx b/connectivity/source/drivers/hsqldb/HViews.cxx new file mode 100644 index 000000000000..d604947e016e --- /dev/null +++ b/connectivity/source/drivers/hsqldb/HViews.cxx @@ -0,0 +1,169 @@ +/************************************************************************* + * + * 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 "hsqldb/HTables.hxx" +#include "hsqldb/HViews.hxx" +#include "hsqldb/HView.hxx" +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbcx/CheckOption.hpp> +#include "hsqldb/HCatalog.hxx" +#include <comphelper/extract.hxx> +#include "connectivity/dbtools.hxx" +#include "connectivity/dbexception.hxx" +#include <cppuhelper/interfacecontainer.h> +#include <comphelper/types.hxx> +#include "TConnection.hxx" + +using namespace ::comphelper; + +using namespace ::cppu; +using namespace connectivity; +using namespace connectivity::hsqldb; +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 dbtools; +typedef connectivity::sdbcx::OCollection OCollection_TYPE; + +// ------------------------------------------------------------------------- +HViews::HViews( const Reference< XConnection >& _rxConnection, ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, + const TStringVector &_rVector ) + :sdbcx::OCollection( _rParent, sal_True, _rMutex, _rVector ) + ,m_xConnection( _rxConnection ) + ,m_xMetaData( _rxConnection->getMetaData() ) + ,m_bInDrop( sal_False ) +{ +} + +// ------------------------------------------------------------------------- +sdbcx::ObjectType HViews::createObject(const ::rtl::OUString& _rName) +{ + ::rtl::OUString sCatalog,sSchema,sTable; + ::dbtools::qualifiedNameComponents(m_xMetaData, + _rName, + sCatalog, + sSchema, + sTable, + ::dbtools::eInDataManipulation); + return new HView( m_xConnection, isCaseSensitive(), sSchema, sTable ); +} + +// ------------------------------------------------------------------------- +void HViews::impl_refresh( ) throw(RuntimeException) +{ + static_cast<OHCatalog&>(m_rParent).refreshTables(); +} +// ------------------------------------------------------------------------- +void HViews::disposing(void) +{ +m_xMetaData.clear(); + OCollection::disposing(); +} +// ------------------------------------------------------------------------- +Reference< XPropertySet > HViews::createDescriptor() +{ + Reference<XConnection> xConnection = static_cast<OHCatalog&>(m_rParent).getConnection(); + connectivity::sdbcx::OView* pNew = new connectivity::sdbcx::OView(sal_True,xConnection->getMetaData()); + return pNew; +} +// ------------------------------------------------------------------------- +// XAppend +sdbcx::ObjectType HViews::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor ) +{ + createView(descriptor); + return createObject( _rForName ); +} +// ------------------------------------------------------------------------- +// XDrop +void HViews::dropObject(sal_Int32 _nPos,const ::rtl::OUString /*_sElementName*/) +{ + if ( m_bInDrop ) + return; + + Reference< XInterface > xObject( getObject( _nPos ) ); + sal_Bool bIsNew = connectivity::sdbcx::ODescriptor::isNew( xObject ); + if (!bIsNew) + { + ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP VIEW"); + + Reference<XPropertySet> xProp(xObject,UNO_QUERY); + aSql += ::dbtools::composeTableName( m_xMetaData, xProp, ::dbtools::eInTableDefinitions, false, false, true ); + + Reference<XConnection> xConnection = static_cast<OHCatalog&>(m_rParent).getConnection(); + Reference< XStatement > xStmt = xConnection->createStatement( ); + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } +} +// ----------------------------------------------------------------------------- +void HViews::dropByNameImpl(const ::rtl::OUString& elementName) +{ + m_bInDrop = sal_True; + OCollection_TYPE::dropByName(elementName); + m_bInDrop = sal_False; +} +// ----------------------------------------------------------------------------- +void HViews::createView( const Reference< XPropertySet >& descriptor ) +{ + Reference<XConnection> xConnection = static_cast<OHCatalog&>(m_rParent).getConnection(); + + ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("CREATE VIEW "); + ::rtl::OUString aQuote = xConnection->getMetaData()->getIdentifierQuoteString( ); + ::rtl::OUString sSchema,sCommand; + + aSql += ::dbtools::composeTableName( m_xMetaData, descriptor, ::dbtools::eInTableDefinitions, false, false, true ); + + aSql += ::rtl::OUString::createFromAscii(" AS "); + descriptor->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_COMMAND)) >>= sCommand; + aSql += sCommand; + + Reference< XStatement > xStmt = xConnection->createStatement( ); + if ( xStmt.is() ) + { + xStmt->execute(aSql); + ::comphelper::disposeComponent(xStmt); + } + + // insert the new view also in the tables collection + OTables* pTables = static_cast<OTables*>(static_cast<OHCatalog&>(m_rParent).getPrivateTables()); + if ( pTables ) + { + ::rtl::OUString sName = ::dbtools::composeTableName( m_xMetaData, descriptor, ::dbtools::eInDataManipulation, false, false, false ); + pTables->appendNew(sName); + } +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/Hservices.cxx b/connectivity/source/drivers/hsqldb/Hservices.cxx new file mode 100644 index 000000000000..a3e783a3e9a7 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/Hservices.cxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * 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 "hsqldb/HDriver.hxx" +#include <cppuhelper/factory.hxx> +#include <osl/diagnose.h> + +using namespace connectivity::hsqldb; +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(), "ADABAS::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( + ODriverDelegator::getImplementationName_Static(), + ODriverDelegator::getSupportedServiceNames_Static(), xKey); + + return sal_True; + } + catch (::com::sun::star::registry::InvalidRegistryException& ) + { + OSL_ENSURE(sal_False, "ODBC::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( + ODriverDelegator::getImplementationName_Static(), + ODriverDelegator::getSupportedServiceNames_Static(), + ODriverDelegator_CreateInstance, ::cppu::createSingleFactory) + ; + + if(aReq.xRet.is()) + aReq.xRet->acquire(); + + pRet = aReq.getProvider(); + } + + return pRet; +}; + + diff --git a/connectivity/source/drivers/hsqldb/StorageFileAccess.cxx b/connectivity/source/drivers/hsqldb/StorageFileAccess.cxx new file mode 100644 index 000000000000..a95ee058d4b2 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/StorageFileAccess.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * 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" + +#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H +#include <config.h> +#endif +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include "hsqldb/StorageFileAccess.h" +#include "hsqldb/HStorageMap.hxx" + +#include <rtl/logfile.hxx> + +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::connectivity::hsqldb; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +/*****************************************************************************/ +/* exception macros */ + +#define ThrowException(env, type, msg) { \ + env->ThrowNew(env->FindClass(type), msg); } + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess + * Method: isStreamElement + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ +SAL_DLLPUBLIC_EXPORT jboolean JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_isStreamElement + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name) +{ + TStorages::mapped_type aStoragePair = StorageContainer::getRegisteredStorage(StorageContainer::jstring2ustring(env,key)); + if ( aStoragePair.first.first.is() ) + { + try + { + ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name); + try + { + ::rtl::OUString sOldName = StorageContainer::removeOldURLPrefix(sName); + if ( aStoragePair.first.first->isStreamElement(sOldName) ) + { + try + { + aStoragePair.first.first->renameElement(sOldName,StorageContainer::removeURLPrefix(sName,aStoragePair.first.second)); + } + catch(Exception&) + { + } + } + } + catch(NoSuchElementException&) + { + } + return aStoragePair.first.first->isStreamElement(StorageContainer::removeURLPrefix(sName,aStoragePair.first.second)); + } + catch(NoSuchElementException&) + { + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_isStreamElement"); + if (JNI_FALSE != env->ExceptionCheck()) + env->ExceptionClear(); + ::rtl::OString cstr( ::rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_JAVA_UTF8 ) ); + OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() ); + } + } + return JNI_FALSE; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess + * Method: removeElement + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_removeElement + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + { + ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key); + ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name); + } +#endif + TStorages::mapped_type aStoragePair = StorageContainer::getRegisteredStorage(StorageContainer::jstring2ustring(env,key)); + if ( aStoragePair.first.first.is() ) + { + try + { + aStoragePair.first.first->removeElement(StorageContainer::removeURLPrefix(StorageContainer::jstring2ustring(env,name),aStoragePair.first.second)); + } + catch(NoSuchElementException&) + { + if (JNI_FALSE != env->ExceptionCheck()) + env->ExceptionClear(); + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_removeElement"); + StorageContainer::throwJavaException(e,env); + } + } +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess + * Method: renameElement + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_renameElement + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring oldname, jstring newname) +{ +#ifdef HSQLDB_DBG + { + ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key); + ::rtl::OUString sNewName = StorageContainer::jstring2ustring(env,newname); + ::rtl::OUString sOldName = StorageContainer::jstring2ustring(env,oldname); + } +#endif + TStorages::mapped_type aStoragePair = StorageContainer::getRegisteredStorage(StorageContainer::jstring2ustring(env,key)); + if ( aStoragePair.first.first.is() ) + { + try + { + aStoragePair.first.first->renameElement( + StorageContainer::removeURLPrefix(StorageContainer::jstring2ustring(env,oldname),aStoragePair.first.second), + StorageContainer::removeURLPrefix(StorageContainer::jstring2ustring(env,newname),aStoragePair.first.second) + ); +#ifdef HSQLDB_DBG + { + ::rtl::OUString sNewName = StorageContainer::removeURLPrefix(StorageContainer::jstring2ustring(env,newname),aStoragePair.first.second); + OSL_ENSURE(aStoragePair.first.first->isStreamElement(sNewName),"Stream could not be renamed"); + } +#endif + } + catch(NoSuchElementException&) + { + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_renameElement"); + StorageContainer::throwJavaException(e,env); + } + } +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/StorageNativeInputStream.cxx b/connectivity/source/drivers/hsqldb/StorageNativeInputStream.cxx new file mode 100644 index 000000000000..99ac75290d94 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/StorageNativeInputStream.cxx @@ -0,0 +1,306 @@ +/************************************************************************* + * + * 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" + +#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H +#include <config.h> +#endif +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <comphelper/stl_types.hxx> +#include <comphelper/types.hxx> +#include "hsqldb/HStorageAccess.hxx" +#include "hsqldb/HStorageMap.hxx" +#include "hsqldb/StorageNativeInputStream.h" + +#include "jvmaccess/virtualmachine.hxx" +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include "accesslog.hxx" + +#include <limits> + + +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::connectivity::hsqldb; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +/*****************************************************************************/ +/* exception macros */ + +#define ThrowException(env, type, msg) { \ + env->ThrowNew(env->FindClass(type), msg); } +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: openStream + * Signature: (Ljava/lang/String;Ljava/lang/String;I)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_openStream + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name, jint mode) +{ +#ifdef HSQLDB_DBG + { + OperationLogFile( env, name, "input" ).logOperation( "openStream" ); + LogFile( env, name, "input" ).create(); + } +#endif + StorageContainer::registerStream(env,name,key,mode); +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: read + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2 + (JNIEnv * env, jobject obj_this,jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "input" ).logOperation( "read()" ); + + DataLogFile aDataLog( env, name, "input" ); + return read_from_storage_stream( env, obj_this, name, key, &aDataLog ); +#else + return read_from_storage_stream( env, obj_this, name, key ); +#endif +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: read + * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3BII + (JNIEnv * env, jobject obj_this,jstring key, jstring name, jbyteArray buffer, jint off, jint len) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "input" ).logOperation( "read( byte[], int, int )" ); + + DataLogFile aDataLog( env, name, "input" ); + return read_from_storage_stream_into_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog ); +#else + return read_from_storage_stream_into_buffer(env,obj_this,name,key,buffer,off,len); +#endif +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: close + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_close + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "input" ); + aOpLog.logOperation( "close" ); + aOpLog.close(); + + LogFile aDataLog( env, name, "input" ); + aDataLog.close(); +#endif + StorageContainer::revokeStream(env,name,key); +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: skip + * Signature: (Ljava/lang/String;Ljava/lang/String;J)J + */ +SAL_DLLPUBLIC_EXPORT jlong JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_skip + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name, jlong n) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "input" ).logOperation( "skip()" ); +#endif + + if ( n < 0 ) + ThrowException( env, + "java/io/IOException", + "n < 0"); + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + OSL_ENSURE(pHelper.get(),"No stream helper!"); + if ( pHelper.get() ) + { + Reference<XInputStream> xIn = pHelper->getInputStream(); + if ( xIn.is() ) + { + try + { + sal_Int64 tmpLongVal = n; + sal_Int32 tmpIntVal; + + try + { + do { + if (tmpLongVal >= ::std::numeric_limits<sal_Int64>::max() ) + tmpIntVal = ::std::numeric_limits<sal_Int32>::max(); + else // Casting is safe here. + tmpIntVal = static_cast<sal_Int32>(tmpLongVal); + + tmpLongVal -= tmpIntVal; + + xIn->skipBytes(tmpIntVal); + + } while (tmpLongVal > 0); + } + catch(Exception& ) + { + } + + return n - tmpLongVal; + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : skip();"); + StorageContainer::throwJavaException(e,env); + } + } + } + else + { + ThrowException( env, + "java/io/IOException", + "Stream is not valid"); + } + return 0; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: available + * Signature: (Ljava/lang/String;Ljava/lang/String;)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_available + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "input" ); + aOpLog.logOperation( "available" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + OSL_ENSURE(pHelper.get(),"No stream helper!"); + Reference<XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference<XInputStream>(); + if ( xIn.is() ) + { + try + { + jint nAvailable = xIn->available(); +#ifdef HSQLDB_DBG + aOpLog.logReturn( nAvailable ); +#endif + return nAvailable; + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception caught! : available();"); + StorageContainer::throwJavaException(e,env); + } + } + else + { + ThrowException( env, + "java/io/IOException", + "Stream is not valid"); + } + return 0; +} +// ----------------------------------------------------------------------------- + +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream + * Method: read + * Signature: (Ljava/lang/String;Ljava/lang/String;[B)I + */ +SAL_DLLPUBLIC_EXPORT jint JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3B + (JNIEnv * env, jobject /*obj_this*/,jstring key, jstring name, jbyteArray buffer) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "input" ); + aOpLog.logOperation( "read( byte[] )" ); + + DataLogFile aDataLog( env, name, "input" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XInputStream> xIn = pHelper.get() ? pHelper->getInputStream() : Reference< XInputStream>(); + OSL_ENSURE(xIn.is(),"Input stream is NULL!"); + jint nBytesRead = 0; + if ( xIn.is() ) + { + jsize nLen = env->GetArrayLength(buffer); + Sequence< ::sal_Int8 > aData(nLen); + + try + { + nBytesRead = xIn->readBytes(aData,nLen); + } + catch(Exception& e) + { + OSL_ENSURE(0,"Exception catched! : skip();"); + StorageContainer::throwJavaException(e,env); + } + + // Casting bytesRead to an int is okay, since the user can + // only pass in an integer length to read, so the bytesRead + // must <= len. + // + if (nBytesRead <= 0) { +#ifdef HSQLDB_DBG + aOpLog.logReturn( (jint)-1 ); +#endif + return -1; + } + OSL_ENSURE(nLen >= nBytesRead,"Buffer is too small!"); + OSL_ENSURE(aData.getLength() >= nBytesRead,"Buffer is too small!"); + env->SetByteArrayRegion(buffer,0,nBytesRead,&aData[0]); +#ifdef HSQLDB_DBG + aDataLog.write( &aData[0], nBytesRead ); +#endif + } +#ifdef HSQLDB_DBG + aOpLog.logReturn( nBytesRead ); +#endif + return nBytesRead; +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/StorageNativeOutputStream.cxx b/connectivity/source/drivers/hsqldb/StorageNativeOutputStream.cxx new file mode 100644 index 000000000000..ec7428d14fef --- /dev/null +++ b/connectivity/source/drivers/hsqldb/StorageNativeOutputStream.cxx @@ -0,0 +1,219 @@ +/************************************************************************* + * + * 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" +#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H +#include <config.h> +#endif + +#include "uno/mapping.hxx" +#include "uno/environment.hxx" +#include "cppuhelper/bootstrap.hxx" +#include "cppuhelper/compbase1.hxx" +#include "cppuhelper/component_context.hxx" +#include "accesslog.hxx" +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XDocumentSubStorageSupplier.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <comphelper/stl_types.hxx> +#include <comphelper/types.hxx> +#include "hsqldb/HStorageAccess.hxx" +#include "hsqldb/HStorageMap.hxx" + +#include "jvmaccess/virtualmachine.hxx" +#include "com/sun/star/lang/XSingleComponentFactory.hpp" +#include "diagnose_ex.h" + +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::connectivity::hsqldb; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) +/*****************************************************************************/ +/* exception macros */ + +#define ThrowException(env, type, msg) { \ + env->ThrowNew(env->FindClass(type), msg); } + +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: openStream + * Signature: (Ljava/lang/String;Ljava/lang/String;I)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_openStream + (JNIEnv * env, jobject /*obj_this*/, jstring name, jstring key, jint mode) +{ +#ifdef HSQLDB_DBG + { + OperationLogFile( env, name, "output" ).logOperation( "openStream" ); + LogFile( env, name, "output" ).create(); + } +#endif + StorageContainer::registerStream(env,name,key,mode); +} +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: write + * Signature: (Ljava/lang/String;Ljava/lang/String;[BII)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3BII + (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer, jint off, jint len) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "output" ).logOperation( "write( byte[], int, int )" ); + + DataLogFile aDataLog( env, name, "output" ); + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len, &aDataLog ); +#else + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, off, len ); +#endif +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: write + * Signature: (Ljava/lang/String;Ljava/lang/String;[B)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3B + (JNIEnv * env, jobject obj_this, jstring key, jstring name, jbyteArray buffer) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "output" ).logOperation( "write( byte[] )" ); + + DataLogFile aDataLog( env, name, "output" ); + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ), &aDataLog ); +#else + write_to_storage_stream_from_buffer( env, obj_this, name, key, buffer, 0, env->GetArrayLength( buffer ) ); +#endif +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: close + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_close + (JNIEnv * env, jobject /*obj_this*/, jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + OperationLogFile aOpLog( env, name, "output" ); + aOpLog.logOperation( "close" ); + + LogFile aDataLog( env, name, "output" ); +#endif + + ::boost::shared_ptr<StreamHelper> pHelper = StorageContainer::getRegisteredStream(env,name,key); + Reference< XOutputStream> xFlush = pHelper.get() ? pHelper->getOutputStream() : Reference< XOutputStream>(); + if ( xFlush.is() ) + try + { + xFlush->flush(); + } + catch(Exception&) + {} + +#ifdef HSQLDB_DBG + aDataLog.close(); + aOpLog.close(); +#endif + StorageContainer::revokeStream(env,name,key); +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: write + * Signature: (Ljava/lang/String;Ljava/lang/String;I)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2I + (JNIEnv * env, jobject obj_this, jstring key, jstring name,jint b) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "output" ).logOperation( "write( int )" ); + + DataLogFile aDataLog( env, name, "output" ); + write_to_storage_stream( env, obj_this, name, key, b, &aDataLog ); +#else + write_to_storage_stream( env, obj_this, name, key, b ); +#endif +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: flush + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_flush + (JNIEnv * env, jobject /*obj_this*/, jstring key, jstring name) +{ + OSL_UNUSED( env ); + OSL_UNUSED( key ); + OSL_UNUSED( name ); +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "output" ).logOperation( "flush" ); + + ::rtl::OUString sKey = StorageContainer::jstring2ustring(env,key); + ::rtl::OUString sName = StorageContainer::jstring2ustring(env,name); +#endif +} +// ----------------------------------------------------------------------------- +/* + * Class: com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream + * Method: sync + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +extern "C" SAL_DLLPUBLIC_EXPORT void JNICALL Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_sync + (JNIEnv * env, jobject /*obj_this*/, jstring key, jstring name) +{ +#ifdef HSQLDB_DBG + OperationLogFile( env, name, "output" ).logOperation( "sync" ); +#endif + ::boost::shared_ptr< StreamHelper > pStream = StorageContainer::getRegisteredStream( env, name, key ); + Reference< XOutputStream > xFlush = pStream.get() ? pStream->getOutputStream() : Reference< XOutputStream>(); + OSL_ENSURE( xFlush.is(), "StorageNativeOutputStream::sync: could not retrieve an output stream!" ); + if ( xFlush.is() ) + { + try + { + xFlush->flush(); + } + catch(Exception&) + { + OSL_ENSURE( false, "StorageNativeOutputStream::sync: could not flush output stream!" ); + } + } +} +// ----------------------------------------------------------------------------- diff --git a/connectivity/source/drivers/hsqldb/accesslog.cxx b/connectivity/source/drivers/hsqldb/accesslog.cxx new file mode 100644 index 000000000000..8ac77d5be4c2 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/accesslog.cxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * 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" + +#ifdef HSQLDB_DBG +#include "accesslog.hxx" +#include "hsqldb/HStorageMap.hxx" + +#include <osl/thread.h> + +namespace connectivity { namespace hsqldb +{ + DECLARE_STL_USTRINGACCESS_MAP(FILE *,TDebugStreamMap); + TDebugStreamMap& getStreams() + { + static TDebugStreamMap streams; + return streams; + } + + //--------------------------------------------------------------------- + LogFile::LogFile( JNIEnv* env, jstring streamName, const sal_Char* _pAsciiSuffix ) + { + m_sFileName = StorageContainer::jstring2ustring(env,streamName); + m_sFileName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".")); + m_sFileName += ::rtl::OUString::createFromAscii( _pAsciiSuffix ); + } + + //--------------------------------------------------------------------- + FILE*& LogFile::getLogFile() + { + FILE*& pLogFile = getStreams()[m_sFileName]; + if ( !pLogFile ) + { + ::rtl::OString sByteLogName = ::rtl::OUStringToOString(m_sFileName,osl_getThreadTextEncoding()); + pLogFile = fopen( sByteLogName.getStr(), "a+" ); + } + return pLogFile; + } + + //--------------------------------------------------------------------- + void LogFile::writeString( const sal_Char* _pString, bool _bEndLine ) + { + FILE* pLogFile = getLogFile(); + fwrite( _pString, sizeof( *_pString ), strlen( _pString ), pLogFile ); + if ( _bEndLine ) + fwrite( "\n", sizeof( *_pString ), strlen( "\n" ), pLogFile ); + fflush( pLogFile ); + } + + //--------------------------------------------------------------------- + void LogFile::close() + { + fclose( getLogFile() ); + getLogFile() = NULL; + } +} } +#endif diff --git a/connectivity/source/drivers/hsqldb/accesslog.hxx b/connectivity/source/drivers/hsqldb/accesslog.hxx new file mode 100644 index 000000000000..524394a8b885 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/accesslog.hxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef CONNECTIVITY_HSQLDB_ACCESSLOG_HXX +#define CONNECTIVITY_HSQLDB_ACCESSLOG_HXX + +#ifdef HSQLDB_DBG + +#include <stdio.h> +#include <jni.h> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> + +namespace connectivity { namespace hsqldb +{ + class LogFile + { + private: + ::rtl::OUString m_sFileName; + + public: + LogFile( JNIEnv* env, jstring streamName, const sal_Char* _pAsciiSuffix ); + + public: + void writeString( const sal_Char* _pString, bool _bEndLine = true ); + void create() { getLogFile(); } + virtual void close(); + + protected: + FILE*& getLogFile(); + }; + + class OperationLogFile : public LogFile + { + public: + OperationLogFile( JNIEnv* env, jstring streamName, const sal_Char* _pAsciiSuffix ) + :LogFile( env, streamName, ( ::rtl::OString( _pAsciiSuffix ) += ".op" ).getStr() ) + { + } + + void logOperation( const sal_Char* _pOp ) + { + writeString( _pOp, true ); + } + + void logOperation( const sal_Char* _pOp, jlong _nLongArg ) + { + ::rtl::OString sLine( _pOp ); + sLine += "( "; + sLine += ::rtl::OString::valueOf( _nLongArg ); + sLine += " )"; + writeString( sLine.getStr(), true ); + } + + void logReturn( jlong _nRetVal ) + { + ::rtl::OString sLine( " -> " ); + sLine += ::rtl::OString::valueOf( _nRetVal ); + writeString( sLine.getStr(), true ); + } + + void logReturn( jint _nRetVal ) + { + ::rtl::OString sLine( " -> " ); + sLine += ::rtl::OString::valueOf( _nRetVal ); + writeString( sLine.getStr(), true ); + } + + virtual void close() + { + writeString( "-------------------------------", true ); + writeString( "", true ); + LogFile::close(); + } + }; + + class DataLogFile : public LogFile + { + public: + DataLogFile( JNIEnv* env, jstring streamName, const sal_Char* _pAsciiSuffix ) + :LogFile( env, streamName, _pAsciiSuffix ) + { + } + + void write( jint value ) + { + fputc( value, getLogFile() ); + fflush( getLogFile() ); + } + + void write( const sal_Int8* buffer, sal_Int32 bytesRead ) + { + fwrite( buffer, sizeof(sal_Int8), bytesRead, getLogFile() ); + fflush( getLogFile() ); + } + + sal_Int64 seek( sal_Int64 pos ) + { + FILE* pFile = getLogFile(); + fseek( pFile, 0, SEEK_END ); + if ( ftell( pFile ) < pos ) + { + sal_Int8 filler( 0 ); + while ( ftell( pFile ) < pos ) + fwrite( &filler, sizeof( sal_Int8 ), 1, pFile ); + fflush( pFile ); + } + fseek( pFile, pos, SEEK_SET ); + return ftell( pFile ); + } + + sal_Int64 tell() + { + return ftell( getLogFile() ); + } + }; + +} } +#endif + +#endif // CONNECTIVITY_HSQLDB_ACCESSLOG_HXX diff --git a/connectivity/source/drivers/hsqldb/exports.dxp b/connectivity/source/drivers/hsqldb/exports.dxp new file mode 100644 index 000000000000..7ff56f4f9977 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/exports.dxp @@ -0,0 +1,30 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_openStream +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3BII +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3B +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_close +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2I +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_flush +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_sync +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_openStream +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_close +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_getFilePointer +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_length +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2 +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_readInt +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_seek +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_write +Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_writeInt +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_openStream +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2 +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3BII +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_close +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_skip +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_available +Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3B +Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_isStreamElement +Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_removeElement +Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_renameElement diff --git a/connectivity/source/drivers/hsqldb/hsqldb.map b/connectivity/source/drivers/hsqldb/hsqldb.map new file mode 100644 index 000000000000..b4fc53b320ef --- /dev/null +++ b/connectivity/source/drivers/hsqldb/hsqldb.map @@ -0,0 +1,35 @@ +UDK_3_0_0 { + global: + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_openStream; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3BII; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2_3B; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_close; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_write__Ljava_lang_String_2Ljava_lang_String_2I; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_flush; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeOutputStream_sync; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_openStream; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_close; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_getFilePointer; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_length; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_read__Ljava_lang_String_2Ljava_lang_String_2_3BII; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_readInt; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_seek; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_write; + Java_com_sun_star_sdbcx_comp_hsqldb_NativeStorageAccess_writeInt; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_openStream; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3BII; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_close; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_skip; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_available; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageNativeInputStream_read__Ljava_lang_String_2Ljava_lang_String_2_3B; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_isStreamElement; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_removeElement; + Java_com_sun_star_sdbcx_comp_hsqldb_StorageFileAccess_renameElement; + local: + *; +}; diff --git a/connectivity/source/drivers/hsqldb/hsqldb.xcu b/connectivity/source/drivers/hsqldb/hsqldb.xcu new file mode 100755 index 000000000000..f97b5e357179 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/hsqldb.xcu @@ -0,0 +1,78 @@ +<?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:embedded:hsqldb" oor:op="replace"> + <prop oor:name="Driver"> + <value>com.sun.star.sdbcx.comp.hsqldb.Driver</value> + </prop> + <prop oor:name="DriverTypeDisplayName" oor:type="xs:string"> + <value xml:lang="en-US">HSQL database engine</value> + </prop> + <node oor:name="Features"> + <node oor:name="UseDOSLineEnds" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="FormsCheckRequiredFields" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="EscapeDateTime" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="AddIndexAppendix" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>false</value> + </prop> + </node> + </node> + <node oor:name="MetaData"> + <node oor:name="SupportsTableCreation" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="UseJava" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + <node oor:name="AutoIncrementIsPrimaryKey" oor:op="replace"> + <prop oor:name="Value" oor:type="xs:boolean"> + <value>true</value> + </prop> + </node> + </node> + </node> + </node> +</oor:component-data> diff --git a/connectivity/source/drivers/hsqldb/hsqldb.xml b/connectivity/source/drivers/hsqldb/hsqldb.xml new file mode 100644 index 000000000000..720e9e30dbd4 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/hsqldb.xml @@ -0,0 +1,28 @@ +<?xml version='1.0' encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//W3C//DTD HTML 3.2//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name>hsqldb</module-name> + <component-description> + <author>Ocke Janssen</author> + <name>com.sun.star.sdbcx.comp.hsqldb.Driver</name> + <description> + This is the implementation of the HSQLDB driver. + </description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="final"/> + <supported-service>com.sun.star.sdbcx.Driver</supported-service> + </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>dbtools</runtime-module-dependency> + <runtime-module-dependency>comphelper</runtime-module-dependency> +</module-description> + + diff --git a/connectivity/source/drivers/hsqldb/hsqlui.hrc b/connectivity/source/drivers/hsqldb/hsqlui.hrc new file mode 100644 index 000000000000..fe20ec5eaf21 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/hsqlui.hrc @@ -0,0 +1,36 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef CONNECTIVITY_HSQLUI_HRC +#define CONNECTIVITY_HSQLUI_HRC + +#define LINKED_TEXT_TABLE_IMAGE_RESOURCE "linked_text_table.png" +#define LINKED_TEXT_TABLE_IMAGE_RESOURCE_HC "linked_text_table_hc.png" + +#endif // CONNECTIVITY_HSQLUI_HRC + + diff --git a/connectivity/source/drivers/hsqldb/hsqlui.src b/connectivity/source/drivers/hsqldb/hsqlui.src new file mode 100644 index 000000000000..a2886c1a18cf --- /dev/null +++ b/connectivity/source/drivers/hsqldb/hsqlui.src @@ -0,0 +1,53 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef CONNECTIVITY_HSQLUI_HRC +#include "hsqlui.hrc" +#endif + +/* Note: + The resource file built here (hsqldb.res, finally) is *not* included + in the final OOo installation. Instead, it is only built to ensure that + the two images below are included in the application-wide image repository + (images.zip). This way, they can be accessed at runtime, but without the + indirection via a resource file - the GraphicProvider service supports + a "private:imagerepository/*" protocol meanwhile, which allows this. + + If there were another possibility to ensure that the images are + put into the repository, instead of creating a resource file for them, + then we would use this other way ... +*/ + +Image 1000 +{ + ImageBitmap = Bitmap { File = LINKED_TEXT_TABLE_IMAGE_RESOURCE; }; +}; + +Image 1001 +{ + ImageBitmap = Bitmap { File = LINKED_TEXT_TABLE_IMAGE_RESOURCE_HC; }; +}; diff --git a/connectivity/source/drivers/hsqldb/makefile.mk b/connectivity/source/drivers/hsqldb/makefile.mk new file mode 100644 index 000000000000..e1a953055c04 --- /dev/null +++ b/connectivity/source/drivers/hsqldb/makefile.mk @@ -0,0 +1,117 @@ +#************************************************************************* +# +# 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=hsqldb + +ENABLE_EXCEPTIONS=TRUE +VISIBILITY_HIDDEN=TRUE +USE_DEFFILE=TRUE + +# --- Settings ---------------------------------- +.INCLUDE : $(PRJ)$/makefile.pmk +.INCLUDE : $(PRJ)$/version.mk + +.IF "$(SOLAR_JAVA)"=="" +nojava: + @echo "Not building jurt because Java is disabled" +.ENDIF + +.IF "$(SYSTEM_HSQLDB)" == "YES" +CDEFS+=-DSYSTEM_HSQLDB -DHSQLDB_JAR=\""file://$(HSQLDB_JAR)"\" +.ENDIF +# --- Resources --------------------------------- + +SRS1NAME=$(TARGET) +SRC1FILES = \ + hsqlui.src + +RES1FILELIST=\ + $(SRS)$/$(TARGET).srs + +RESLIB1NAME=$(TARGET) +RESLIB1IMAGES=$(SOLARSRC)$/$(RSCDEFIMG)$/database +RESLIB1SRSFILES=$(RES1FILELIST) + +# Note that the resource file built here is currently *not* included +# in installation sets. See hsqlui.src for an explanation + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/HStorageMap.obj \ + $(SLO)$/HStorageAccess.obj \ + $(SLO)$/HDriver.obj \ + $(SLO)$/HConnection.obj \ + $(SLO)$/HTerminateListener.obj \ + $(SLO)$/StorageNativeOutputStream.obj \ + $(SLO)$/StorageNativeInputStream.obj \ + $(SLO)$/StorageFileAccess.obj \ + $(SLO)$/HTables.obj \ + $(SLO)$/HTable.obj \ + $(SLO)$/HView.obj \ + $(SLO)$/HViews.obj \ + $(SLO)$/HCatalog.obj \ + $(SLO)$/HColumns.obj \ + $(SLO)$/HUser.obj \ + $(SLO)$/HUsers.obj \ + $(SLO)$/Hservices.obj \ + $(SLO)$/HTools.obj \ + $(SLO)$/accesslog.obj + +SHL1VERSIONMAP=$(HSQLDB_TARGET).map + +# --- Library ----------------------------------- +# NO $(DLLPOSTFIX) otherwise we have to find on which plattform we are for the java files +SHL1TARGET= $(HSQLDB_TARGET) +SHL1OBJS=$(SLOFILES) +SHL1STDLIBS=\ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(DBTOOLSLIB) \ + $(JVMFWKLIB) \ + $(COMPHELPERLIB) \ + $(TOOLSLIB) \ + $(UNOTOOLSLIB) + + +SHL1DEPN= +SHL1IMPLIB= i$(HSQLDB_TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ---------------------------------- + +.INCLUDE : $(PRJ)$/target.pmk + + |