/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. ************************************************************************/ #include "mysqlc_driver.hxx" #include "mysqlc_connection.hxx" #include "mysqlc_general.hxx" using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::beans; using namespace com::sun::star::sdbc; using namespace connectivity::mysqlc; #include #include #include #ifdef SYSTEM_MYSQL_CPPCONN #include #endif MysqlCDriver::MysqlCDriver(const Reference< XMultiServiceFactory >& _rxFactory) : ODriver_BASE(m_aMutex) ,m_xFactory(_rxFactory) #ifndef SYSTEM_MYSQL_CPPCONN ,m_hCppConnModule( nullptr ) ,m_bAttemptedLoadCppConn( false ) #endif { cppDriver = nullptr; } void MysqlCDriver::disposing() { ::osl::MutexGuard aGuard(m_aMutex); // when driver will be destroyed so all our connections have to be destroyed as well for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i) { Reference< XComponent > xComp(i->get(), UNO_QUERY); if (xComp.is()) { xComp->dispose(); } } m_xConnections.clear(); ODriver_BASE::disposing(); } // static ServiceInfo rtl::OUString MysqlCDriver::getImplementationName_Static() { return rtl::OUString( "com.sun.star.comp.sdbc.mysqlc.MysqlCDriver" ); } Sequence< rtl::OUString > MysqlCDriver::getSupportedServiceNames_Static() { // which service is supported // for more information @see com.sun.star.sdbc.Driver Sequence< rtl::OUString > aSNS(1); aSNS[0] = "com.sun.star.sdbc.Driver"; return aSNS; } rtl::OUString SAL_CALL MysqlCDriver::getImplementationName() { return getImplementationName_Static(); } sal_Bool SAL_CALL MysqlCDriver::supportsService(const rtl::OUString& _rServiceName) { return cppu::supportsService(this, _rServiceName); } Sequence< rtl::OUString > SAL_CALL MysqlCDriver::getSupportedServiceNames() { return getSupportedServiceNames_Static(); } #ifndef SYSTEM_MYSQL_CPPCONN extern "C" { static void SAL_CALL thisModule() {} } #endif void MysqlCDriver::impl_initCppConn_lck_throw() { #ifdef SYSTEM_MYSQL_CPPCONN cppDriver = get_driver_instance(); #else #ifdef BUNDLE_MARIADB if ( !m_bAttemptedLoadCConn ) { const rtl::OUString sModuleName(BUNDLE_MARIADB); m_hCConnModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 ); m_bAttemptedLoadCConn = true; } // attempted to load - was it successful? if ( !m_hCConnModule ) { OSL_FAIL( "MysqlCDriver::impl_initCppConn_lck_throw: could not load the " BUNDLE_MARIADB " library!"); throw SQLException( "Unable to load the " BUNDLE_MARIADB " library.", *this, rtl::OUString( "08001" ), // "unable to connect" 0, Any() ); } #endif if ( !m_bAttemptedLoadCppConn ) { const rtl::OUString sModuleName(CPPCONN_LIB); m_hCppConnModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 ); m_bAttemptedLoadCppConn = true; } // attempted to load - was it successful? if ( !m_hCppConnModule ) { OSL_FAIL( "MysqlCDriver::impl_initCppConn_lck_throw: could not load the " CPPCONN_LIB " library!"); throw SQLException( "Unable to load the " CPPCONN_LIB " library.", *this, rtl::OUString( "08001" ), // "unable to connect" 0, Any() ); } // find the factory symbol const rtl::OUString sSymbolName = "sql_mysql_get_driver_instance"; typedef void* (* FGetMySQLDriver)(); const FGetMySQLDriver pFactoryFunction = reinterpret_cast( osl_getFunctionSymbol( m_hCppConnModule, sSymbolName.pData ) ); if ( !pFactoryFunction ) { OSL_FAIL( "MysqlCDriver::impl_initCppConn_lck_throw: could not find the factory symbol in " CPPCONN_LIB "!"); throw SQLException( CPPCONN_LIB " is invalid: missing the driver factory function.", *this, rtl::OUString( "08001" ), // "unable to connect" 0, Any() ); } cppDriver = static_cast< sql::Driver* >( (*pFactoryFunction)() ); #endif if ( !cppDriver ) { throw SQLException( "Unable to obtain the MySQL_Driver instance from Connector/C++.", *this, rtl::OUString( "08001" ), // "unable to connect" 0, Any() ); } } Reference< XConnection > SAL_CALL MysqlCDriver::connect(const rtl::OUString& url, const Sequence< PropertyValue >& info) { ::osl::MutexGuard aGuard( m_aMutex ); if (!acceptsURL(url)) { return nullptr; } if ( !cppDriver ) { impl_initCppConn_lck_throw(); if ( !cppDriver ) throw RuntimeException("MySQLCDriver::connect: internal error.", *this ); } Reference< XConnection > xConn; // create a new connection with the given properties and append it to our vector try { OConnection* pCon = new OConnection(*this); xConn = pCon; pCon->construct(url,info); m_xConnections.push_back(WeakReferenceHelper(*pCon)); } catch (const sql::SQLException &e) { mysqlc_sdbc_driver::translateAndThrow(e, *this, getDefaultEncoding()); } return xConn; } sal_Bool SAL_CALL MysqlCDriver::acceptsURL(const rtl::OUString& url) { return url.startsWith("sdbc:mysqlc:"); } Sequence< DriverPropertyInfo > SAL_CALL MysqlCDriver::getPropertyInfo(const rtl::OUString& url, const Sequence< PropertyValue >& /* info */) { if (acceptsURL(url)) { ::std::vector< DriverPropertyInfo > aDriverInfo; aDriverInfo.push_back(DriverPropertyInfo( rtl::OUString("Hostname") ,rtl::OUString("Name of host") ,true ,rtl::OUString("localhost") ,Sequence< rtl::OUString >()) ); aDriverInfo.push_back(DriverPropertyInfo( rtl::OUString("Port") ,rtl::OUString("Port") ,true ,rtl::OUString("3306") ,Sequence< rtl::OUString >()) ); return Sequence< DriverPropertyInfo >(&(aDriverInfo[0]),aDriverInfo.size()); } return Sequence< DriverPropertyInfo >(); } sal_Int32 SAL_CALL MysqlCDriver::getMajorVersion() { return MARIADBC_VERSION_MAJOR; } sal_Int32 SAL_CALL MysqlCDriver::getMinorVersion() { return MARIADBC_VERSION_MINOR; } namespace connectivity { namespace mysqlc { Reference< XInterface > SAL_CALL MysqlCDriver_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory) { return(*(new MysqlCDriver(_rxFactory))); } void release(oslInterlockedCount& _refCount, ::cppu::OBroadcastHelper& rBHelper, Reference< XInterface >& _xInterface, css::lang::XComponent* _pObject) { if (osl_atomic_decrement(&_refCount) == 0) { osl_atomic_increment(&_refCount); if (!rBHelper.bDisposed && !rBHelper.bInDispose) { // remember the parent Reference< XInterface > xParent; { ::osl::MutexGuard aGuard(rBHelper.rMutex); xParent = _xInterface; _xInterface = nullptr; } // First dispose _pObject->dispose(); // only the alive ref holds the object OSL_ASSERT(_refCount == 1); // release the parent in the destructor if (xParent.is()) { ::osl::MutexGuard aGuard(rBHelper.rMutex); _xInterface = xParent; } } } else { osl_atomic_increment(&_refCount); } } void checkDisposed(bool _bThrow) { if (_bThrow) { throw DisposedException(); } } } /* mysqlc */ } /* connectivity */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */