diff options
Diffstat (limited to 'connectivity/source/drivers/postgresql/pq_driver.cxx')
-rw-r--r-- | connectivity/source/drivers/postgresql/pq_driver.cxx | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/connectivity/source/drivers/postgresql/pq_driver.cxx b/connectivity/source/drivers/postgresql/pq_driver.cxx new file mode 100644 index 000000000..99571112c --- /dev/null +++ b/connectivity/source/drivers/postgresql/pq_driver.cxx @@ -0,0 +1,314 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * Effective License of whole file: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Parts "Copyright by Sun Microsystems, Inc" prior to August 2011: + * + * The Contents of this file are made available subject to the terms of + * the GNU Lesser General Public License Version 2.1 + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * Contributor(s): Joerg Budischewski + * + * All parts contributed on or after August 2011: + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + ************************************************************************/ + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include "pq_driver.hxx" + +using osl::MutexGuard; + +using com::sun::star::lang::XSingleComponentFactory; +using com::sun::star::lang::XServiceInfo; +using com::sun::star::lang::XComponent; + +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; +using com::sun::star::uno::UNO_QUERY; +using com::sun::star::uno::XComponentContext; +using com::sun::star::uno::Any; + +using com::sun::star::beans::PropertyValue; + +using com::sun::star::sdbc::XConnection; +using com::sun::star::sdbc::DriverPropertyInfo; + +using com::sun::star::sdbcx::XTablesSupplier; + + +namespace pq_sdbc_driver +{ + +static OUString DriverGetImplementationName() +{ + return "org.openoffice.comp.connectivity.pq.Driver.noext"; +} + +static Sequence< OUString > DriverGetSupportedServiceNames() +{ + return Sequence< OUString > { "com.sun.star.sdbc.Driver" }; +} + +Reference< XConnection > Driver::connect( + const OUString& url,const Sequence< PropertyValue >& info ) +{ + if( ! acceptsURL( url ) ) // XDriver spec tells me to do so ... + return Reference< XConnection > (); + + Sequence< Any > seq ( 2 ); + seq[0] <<= url; + seq[1] <<= info; + return Reference< XConnection> ( + m_smgr->createInstanceWithArgumentsAndContext( + "org.openoffice.comp.connectivity.pq.Connection.noext", + seq, m_ctx ), + UNO_QUERY ); +} + +sal_Bool Driver::acceptsURL( const OUString& url ) +{ + return url.startsWith( "sdbc:postgresql:" ); +} + +Sequence< DriverPropertyInfo > Driver::getPropertyInfo( + const OUString&,const Sequence< PropertyValue >& ) +{ + return Sequence< DriverPropertyInfo > (); +} + +sal_Int32 Driver::getMajorVersion( ) +{ + return PQ_SDBC_MAJOR; +} + + +sal_Int32 Driver::getMinorVersion( ) +{ + return PQ_SDBC_MINOR; +} + + // XServiceInfo +OUString SAL_CALL Driver::getImplementationName() +{ + return DriverGetImplementationName(); +} + +sal_Bool Driver::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString > Driver::getSupportedServiceNames() +{ + return DriverGetSupportedServiceNames(); +} + +// XComponent +void Driver::disposing() +{ + +} + + +Reference< XTablesSupplier > Driver::getDataDefinitionByConnection( + const Reference< XConnection >& connection ) +{ + return Reference< XTablesSupplier >( connection , UNO_QUERY ); +} + +Reference< XTablesSupplier > Driver::getDataDefinitionByURL( + const OUString& url, const Sequence< PropertyValue >& info ) +{ + return Reference< XTablesSupplier > ( connect( url, info ), UNO_QUERY ); +} + + +static Reference< XInterface > DriverCreateInstance( const Reference < XComponentContext > & ctx ) +{ + Reference< XInterface > ret = * new Driver( ctx ); + return ret; +} + +namespace { + +class OOneInstanceComponentFactory : + public MutexHolder, + public cppu::WeakComponentImplHelper< XSingleComponentFactory, XServiceInfo > +{ +public: + OOneInstanceComponentFactory( + const OUString & rImplementationName_, + cppu::ComponentFactoryFunc fptr, + const Sequence< OUString > & serviceNames, + const Reference< XComponentContext > & defaultContext) : + cppu::WeakComponentImplHelper< XSingleComponentFactory, XServiceInfo >( m_mutex ), + m_create( fptr ), + m_serviceNames( serviceNames ), + m_implName( rImplementationName_ ), + m_defaultContext( defaultContext ) + { + } + + // XSingleComponentFactory + virtual Reference< XInterface > SAL_CALL createInstanceWithContext( + Reference< XComponentContext > const & xContext ) override; + virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext( + Sequence< Any > const & rArguments, + Reference< XComponentContext > const & xContext ) override; + + // XServiceInfo + OUString SAL_CALL getImplementationName() override + { + return m_implName; + } + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override + { + return cppu::supportsService(this, ServiceName); + } + Sequence< OUString > SAL_CALL getSupportedServiceNames() override + { + return m_serviceNames; + } + + // XComponent + virtual void SAL_CALL disposing() override; + +private: + cppu::ComponentFactoryFunc m_create; + Sequence< OUString > m_serviceNames; + OUString m_implName; + Reference< XInterface > m_theInstance; + Reference< XComponentContext > m_defaultContext; +}; + +} + +Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithArgumentsAndContext( + Sequence< Any > const &, const Reference< XComponentContext > & ctx ) +{ + return createInstanceWithContext( ctx ); +} + +Reference< XInterface > OOneInstanceComponentFactory::createInstanceWithContext( + const Reference< XComponentContext > & ctx ) +{ + if( ! m_theInstance.is() ) + { + // work around the problem in sdbc + Reference< XComponentContext > useCtx = ctx; + if( ! useCtx.is() ) + useCtx = m_defaultContext; + Reference< XInterface > theInstance = m_create( useCtx ); + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + if( ! m_theInstance.is () ) + { + m_theInstance = theInstance; + } + } + return m_theInstance; +} + +void OOneInstanceComponentFactory::disposing() +{ + Reference< XComponent > rComp; + { + MutexGuard guard( osl::Mutex::getGlobalMutex() ); + rComp.set( m_theInstance, UNO_QUERY ); + m_theInstance.clear(); + } + if( rComp.is() ) + rComp->dispose(); +} + +// Reference< XSingleComponentFactory > createOneInstanceComponentFactory( +// cppu::ComponentFactoryFunc fptr, +// OUString const & rImplementationName, +// css::uno::Sequence< OUString > const & rServiceNames, +// rtl_ModuleCount * pModCount = 0 ) +// +// { +// return new OOneInstanceComponentFactory( rImplementationName, fptr , rServiceNames); +// } + +} + +static const struct cppu::ImplementationEntry g_entries[] = +{ + { + pq_sdbc_driver::DriverCreateInstance, pq_sdbc_driver::DriverGetImplementationName, + pq_sdbc_driver::DriverGetSupportedServiceNames, nullptr, + nullptr , 0 + }, + { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } +}; + +extern "C" +{ + +SAL_DLLPUBLIC_EXPORT void * postgresql_sdbc_component_getFactory( + const char * pImplName, void * pServiceManager, void * ) +{ + // need to extract the defaultcontext, because the way, sdbc + // bypasses the servicemanager, does not allow to use the + // XSingleComponentFactory interface ... + void * pRet = nullptr; + Reference< XSingleComponentFactory > xFactory; + Reference< css::lang::XMultiServiceFactory > xSmgr( + static_cast< XInterface * >(pServiceManager), + css::uno::UNO_QUERY_THROW ); + + for( sal_Int32 i = 0 ; g_entries[i].create ; i ++ ) + { + OUString implName = g_entries[i].getImplementationName(); + if( implName.equalsAscii( pImplName ) ) + { + Reference< XComponentContext > defaultContext( + comphelper::getComponentContext( xSmgr ) ); + xFactory = new pq_sdbc_driver::OOneInstanceComponentFactory( + implName, + g_entries[i].create, + g_entries[i].getSupportedServiceNames(), + defaultContext ); + } + } + + if( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + return pRet; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |