Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / mysqlc / source / mysqlc_driver.cxx
blob029fe0faa341db7b03adfd692712702e1aa741f8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
25 ************************************************************************/
26 #include "mysqlc_driver.hxx"
27 #include "mysqlc_connection.hxx"
28 #include "mysqlc_general.hxx"
30 using namespace com::sun::star::uno;
31 using namespace com::sun::star::lang;
32 using namespace com::sun::star::beans;
33 using namespace com::sun::star::sdbc;
34 using namespace connectivity::mysqlc;
35 using ::rtl::OUString;
36 #include <stdio.h>
38 #include <cppconn/exception.h>
39 #ifdef SYSTEM_MYSQL_CPPCONN
40 #include <mysql_driver.h>
41 #endif
44 /* {{{ MysqlCDriver::MysqlCDriver() -I- */
45 MysqlCDriver::MysqlCDriver(const Reference< XMultiServiceFactory >& _rxFactory)
46 : ODriver_BASE(m_aMutex)
47 ,m_xFactory(_rxFactory)
48 #ifndef SYSTEM_MYSQL_CPPCONN
49 ,m_hCppConnModule( NULL )
50 ,m_bAttemptedLoadCppConn( false )
51 #endif
53 OSL_TRACE("MysqlCDriver::MysqlCDriver");
54 cppDriver = NULL;
56 /* }}} */
59 /* {{{ MysqlCDriver::disposing() -I- */
60 void MysqlCDriver::disposing()
62 OSL_TRACE("MysqlCDriver::disposing");
63 ::osl::MutexGuard aGuard(m_aMutex);
65 // when driver will be destroied so all our connections have to be destroied as well
66 for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
68 Reference< XComponent > xComp(i->get(), UNO_QUERY);
69 if (xComp.is()) {
70 xComp->dispose();
73 m_xConnections.clear();
75 ODriver_BASE::disposing();
77 /* }}} */
80 // static ServiceInfo
81 /* {{{ MysqlCDriver::getImplementationName_Static() -I- */
82 OUString MysqlCDriver::getImplementationName_Static()
83 throw(RuntimeException)
85 OSL_TRACE("MysqlCDriver::getImplementationName_Static");
86 return ::rtl::OUString( "com.sun.star.comp.sdbc.mysqlc.MysqlCDriver" );
88 /* }}} */
91 /* {{{ MysqlCDriver::getSupportedServiceNames_Static() -I- */
92 Sequence< OUString > MysqlCDriver::getSupportedServiceNames_Static()
93 throw(RuntimeException)
95 OSL_TRACE("MysqlCDriver::getSupportedServiceNames_Static");
96 // which service is supported
97 // for more information @see com.sun.star.sdbc.Driver
98 Sequence< OUString > aSNS(1);
99 aSNS[0] = OUString("com.sun.star.sdbc.Driver");
100 return aSNS;
102 /* }}} */
105 /* {{{ MysqlCDriver::getImplementationName() -I- */
106 OUString SAL_CALL MysqlCDriver::getImplementationName()
107 throw(RuntimeException)
109 OSL_TRACE("MysqlCDriver::getImplementationName");
110 return getImplementationName_Static();
112 /* }}} */
115 /* {{{ MysqlCDriver::supportsService() -I- */
116 sal_Bool SAL_CALL MysqlCDriver::supportsService(const OUString& _rServiceName)
117 throw(RuntimeException)
119 OSL_TRACE("MysqlCDriver::supportsService");
120 Sequence< OUString > aSupported(getSupportedServiceNames());
121 const OUString* pSupported = aSupported.getConstArray();
122 const OUString* pEnd = pSupported + aSupported.getLength();
123 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported){}
125 return (pSupported != pEnd);
127 /* }}} */
130 /* {{{ MysqlCDriver::getSupportedServiceNames() -I- */
131 Sequence< OUString > SAL_CALL MysqlCDriver::getSupportedServiceNames()
132 throw(RuntimeException)
134 OSL_TRACE("MysqlCDriver::getSupportedServiceNames");
135 return getSupportedServiceNames_Static();
137 /* }}} */
140 extern "C" { static void SAL_CALL thisModule() {} }
142 void MysqlCDriver::impl_initCppConn_lck_throw()
144 #ifdef SYSTEM_MYSQL_CPPCONN
145 cppDriver = get_driver_instance();
146 #else
147 if ( !m_bAttemptedLoadCppConn )
149 const ::rtl::OUString sModuleName(CPPCONN_LIB );
150 m_hCppConnModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
151 m_bAttemptedLoadCppConn = true;
154 // attempted to load - was it successful?
155 if ( !m_hCppConnModule )
157 OSL_FAIL( "MysqlCDriver::impl_initCppConn_lck_throw: could not load the " CPPCONN_LIB " library!");
158 throw SQLException(
159 ::rtl::OUString( "Unable to load the " CPPCONN_LIB " library." ),
160 *this,
161 ::rtl::OUString( "08001" ), // "unable to connect"
163 Any()
167 // find the factory symbol
168 const ::rtl::OUString sSymbolName = ::rtl::OUString( "sql_mysql_get_driver_instance" );
169 typedef void* (* FGetMySQLDriver)();
171 const FGetMySQLDriver pFactoryFunction = (FGetMySQLDriver)( osl_getFunctionSymbol( m_hCppConnModule, sSymbolName.pData ) );
172 if ( !pFactoryFunction )
174 OSL_FAIL( "MysqlCDriver::impl_initCppConn_lck_throw: could not find the factory symbol in " CPPCONN_LIB "!");
175 throw SQLException(
176 ::rtl::OUString( CPPCONN_LIB " is invalid: missing the driver factory function." ),
177 *this,
178 ::rtl::OUString( "08001" ), // "unable to connect"
180 Any()
184 cppDriver = static_cast< sql::Driver* >( (*pFactoryFunction)() );
185 #endif
186 if ( !cppDriver )
188 throw SQLException(
189 ::rtl::OUString( "Unable to obtain the MySQL_Driver instance from Connector/C++." ),
190 *this,
191 ::rtl::OUString( "08001" ), // "unable to connect"
193 Any()
198 /* {{{ MysqlCDriver::connect() -I- */
199 Reference< XConnection > SAL_CALL MysqlCDriver::connect(const OUString& url, const Sequence< PropertyValue >& info)
200 throw(SQLException, RuntimeException)
202 ::osl::MutexGuard aGuard( m_aMutex );
204 OSL_TRACE("MysqlCDriver::connect");
205 if (!acceptsURL(url)) {
206 return NULL;
209 if ( !cppDriver )
211 impl_initCppConn_lck_throw();
212 OSL_POSTCOND( cppDriver, "MySQLCDriver::connect: internal error." );
213 if ( !cppDriver )
214 throw RuntimeException( ::rtl::OUString( "MySQLCDriver::connect: internal error." ), *this );
217 Reference< XConnection > xConn;
218 // create a new connection with the given properties and append it to our vector
219 try {
220 OConnection* pCon = new OConnection(*this, cppDriver);
221 xConn = pCon;
223 pCon->construct(url,info);
224 m_xConnections.push_back(WeakReferenceHelper(*pCon));
226 catch (const sql::SQLException &e)
228 mysqlc_sdbc_driver::translateAndThrow(e, *this, getDefaultEncoding());
230 return xConn;
232 /* }}} */
235 /* {{{ MysqlCDriver::acceptsURL() -I- */
236 sal_Bool SAL_CALL MysqlCDriver::acceptsURL(const OUString& url)
237 throw(SQLException, RuntimeException)
239 OSL_TRACE("MysqlCDriver::acceptsURL");
240 return (!url.compareTo(OUString("sdbc:mysqlc:"), sizeof("sdbc:mysqlc:")-1));
242 /* }}} */
245 /* {{{ MysqlCDriver::getPropertyInfo() -I- */
246 Sequence< DriverPropertyInfo > SAL_CALL MysqlCDriver::getPropertyInfo(const OUString& url, const Sequence< PropertyValue >& /* info */)
247 throw(SQLException, RuntimeException)
249 OSL_TRACE("MysqlCDriver::getPropertyInfo");
250 if (acceptsURL(url)) {
251 ::std::vector< DriverPropertyInfo > aDriverInfo;
253 aDriverInfo.push_back(DriverPropertyInfo(
254 OUString("Hostname")
255 ,OUString("Name of host")
256 ,sal_True
257 ,OUString("localhost")
258 ,Sequence< OUString >())
260 aDriverInfo.push_back(DriverPropertyInfo(
261 OUString("Port")
262 ,OUString("Port")
263 ,sal_True
264 ,OUString("3306")
265 ,Sequence< OUString >())
267 return Sequence< DriverPropertyInfo >(&(aDriverInfo[0]),aDriverInfo.size());
270 return Sequence< DriverPropertyInfo >();
272 /* }}} */
275 /* {{{ MysqlCDriver::getMajorVersion() -I- */
276 sal_Int32 SAL_CALL MysqlCDriver::getMajorVersion()
277 throw(RuntimeException)
279 OSL_TRACE("MysqlCDriver::getMajorVersion");
280 return MYSQLC_VERSION_MAJOR;
282 /* }}} */
285 /* {{{ MysqlCDriver::getMinorVersion() -I- */
286 sal_Int32 SAL_CALL MysqlCDriver::getMinorVersion()
287 throw(RuntimeException)
289 OSL_TRACE("MysqlCDriver::getMinorVersion");
290 return MYSQLC_VERSION_MINOR;
292 /* }}} */
295 namespace connectivity
297 namespace mysqlc
300 Reference< XInterface > SAL_CALL MysqlCDriver_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory)
301 throw(::com::sun::star::uno::Exception)
303 return(*(new MysqlCDriver(_rxFactory)));
306 /* {{{ connectivity::mysqlc::release() -I- */
307 void release(oslInterlockedCount& _refCount,
308 ::cppu::OBroadcastHelper& rBHelper,
309 Reference< XInterface >& _xInterface,
310 ::com::sun::star::lang::XComponent* _pObject)
312 if (osl_atomic_decrement(&_refCount) == 0) {
313 osl_atomic_increment(&_refCount);
315 if (!rBHelper.bDisposed && !rBHelper.bInDispose) {
316 // remember the parent
317 Reference< XInterface > xParent;
319 ::osl::MutexGuard aGuard(rBHelper.rMutex);
320 xParent = _xInterface;
321 _xInterface = NULL;
324 // First dispose
325 _pObject->dispose();
327 // only the alive ref holds the object
328 OSL_ASSERT(_refCount == 1);
330 // release the parent in the destructor
331 if (xParent.is()) {
332 ::osl::MutexGuard aGuard(rBHelper.rMutex);
333 _xInterface = xParent;
336 } else {
337 osl_atomic_increment(&_refCount);
340 /* }}} */
344 /* {{{ connectivity::mysqlc::checkDisposed() -I- */
345 void checkDisposed(sal_Bool _bThrow)
346 throw (DisposedException)
348 if (_bThrow) {
349 throw DisposedException();
352 /* }}} */
354 } /* mysqlc */
355 } /* connectivity */
358 * Local variables:
359 * tab-width: 4
360 * c-basic-offset: 4
361 * End:
362 * vim600: noet sw=4 ts=4 fdm=marker
363 * vim<600: noet sw=4 ts=4
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */