xref: /aoo41x/main/mysqlc/source/mysqlc_driver.cxx (revision cdf0e10c)
1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * Copyright 2008 by Sun Microsystems, Inc.
5 *
6 * OpenOffice.org - a multi-platform office productivity suite
7 *
8 * $RCSfile: mysqlc_driver.cxx,v $
9 *
10 * $Revision: 1.1.2.5 $
11 *
12 * This file is part of OpenOffice.org.
13 *
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
17 *
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org.  If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
28 ************************************************************************/
29 #include "mysqlc_driver.hxx"
30 #include "mysqlc_connection.hxx"
31 #include "mysqlc_general.hxx"
32 
33 using namespace com::sun::star::uno;
34 using namespace com::sun::star::lang;
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::sdbc;
37 using namespace connectivity::mysqlc;
38 using ::rtl::OUString;
39 #include <stdio.h>
40 
41 #include <preextstl.h>
42 #include <cppconn/exception.h>
43 #ifdef SYSTEM_MYSQL_CPPCONN
44     #include <mysql_driver.h>
45 #endif
46 #include <postextstl.h>
47 
48 
49 /* {{{ MysqlCDriver::MysqlCDriver() -I- */
50 MysqlCDriver::MysqlCDriver(const Reference< XMultiServiceFactory >& _rxFactory)
51 	: ODriver_BASE(m_aMutex)
52     ,m_xFactory(_rxFactory)
53 #ifndef SYSTEM_MYSQL_CPPCONN
54     ,m_hCppConnModule( NULL )
55     ,m_bAttemptedLoadCppConn( false )
56 #endif
57 {
58 	OSL_TRACE("MysqlCDriver::MysqlCDriver");
59 	cppDriver = NULL;
60 }
61 /* }}} */
62 
63 
64 /* {{{ MysqlCDriver::disposing() -I- */
65 void MysqlCDriver::disposing()
66 {
67 	OSL_TRACE("MysqlCDriver::disposing");
68 	::osl::MutexGuard aGuard(m_aMutex);
69 
70 	// when driver will be destroied so all our connections have to be destroied as well
71 	for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
72 	{
73 		Reference< XComponent > xComp(i->get(), UNO_QUERY);
74 		if (xComp.is()) {
75 			xComp->dispose();
76 		}
77 	}
78 	m_xConnections.clear();
79 
80 	ODriver_BASE::disposing();
81 }
82 /* }}} */
83 
84 
85 // static ServiceInfo
86 /* {{{ MysqlCDriver::getImplementationName_Static() -I- */
87 OUString MysqlCDriver::getImplementationName_Static()
88 	throw(RuntimeException)
89 {
90 	OSL_TRACE("MysqlCDriver::getImplementationName_Static");
91     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sdbc.mysqlc.MysqlCDriver" ) );
92 }
93 /* }}} */
94 
95 
96 /* {{{ MysqlCDriver::getSupportedServiceNames_Static() -I- */
97 Sequence< OUString > MysqlCDriver::getSupportedServiceNames_Static()
98 	throw(RuntimeException)
99 {
100 	OSL_TRACE("MysqlCDriver::getSupportedServiceNames_Static");
101 	// which service is supported
102 	// for more information @see com.sun.star.sdbc.Driver
103 	Sequence< OUString > aSNS(1);
104 	aSNS[0] = OUString::createFromAscii("com.sun.star.sdbc.Driver");
105 	return aSNS;
106 }
107 /* }}} */
108 
109 
110 /* {{{ MysqlCDriver::getImplementationName() -I- */
111 OUString SAL_CALL MysqlCDriver::getImplementationName()
112 	throw(RuntimeException)
113 {
114 	OSL_TRACE("MysqlCDriver::getImplementationName");
115 	return getImplementationName_Static();
116 }
117 /* }}} */
118 
119 
120 /* {{{ MysqlCDriver::supportsService() -I- */
121 sal_Bool SAL_CALL MysqlCDriver::supportsService(const OUString& _rServiceName)
122 	throw(RuntimeException)
123 {
124 	OSL_TRACE("MysqlCDriver::supportsService");
125 	Sequence< OUString > aSupported(getSupportedServiceNames());
126 	const OUString* pSupported = aSupported.getConstArray();
127 	const OUString* pEnd = pSupported + aSupported.getLength();
128 	for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported){}
129 
130 	return (pSupported != pEnd);
131 }
132 /* }}} */
133 
134 
135 /* {{{ MysqlCDriver::getSupportedServiceNames() -I- */
136 Sequence< OUString > SAL_CALL MysqlCDriver::getSupportedServiceNames()
137 	throw(RuntimeException)
138 {
139 	OSL_TRACE("MysqlCDriver::getSupportedServiceNames");
140 	return getSupportedServiceNames_Static();
141 }
142 /* }}} */
143 
144 
145 extern "C" { static void SAL_CALL thisModule() {} }
146 
147 void MysqlCDriver::impl_initCppConn_lck_throw()
148 {
149 #ifdef SYSTEM_MYSQL_CPPCONN
150     cppDriver = get_driver_instance();
151 #else
152     if ( !m_bAttemptedLoadCppConn )
153     {
154         const ::rtl::OUString sModuleName = ::rtl::OUString::createFromAscii( CPPCONN_LIB );
155         m_hCppConnModule = osl_loadModuleRelative( &thisModule, sModuleName.pData, 0 );
156         m_bAttemptedLoadCppConn = true;
157     }
158 
159     // attempted to load - was it successful?
160     if ( !m_hCppConnModule )
161     {
162         OSL_ENSURE( false, "MysqlCDriver::impl_initCppConn_lck_throw: could not load the " CPPCONN_LIB " library!");
163         throw SQLException(
164             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to load the " CPPCONN_LIB " library." ) ),
165             *this,
166             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "08001" ) ),  // "unable to connect"
167             0,
168             Any()
169         );
170     }
171 
172     // find the factory symbol
173     const ::rtl::OUString sSymbolName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "sql_mysql_get_driver_instance" ) );
174 	typedef void* (* FGetMySQLDriver)();
175 
176     const FGetMySQLDriver pFactoryFunction = (FGetMySQLDriver)( osl_getFunctionSymbol( m_hCppConnModule, sSymbolName.pData ) );
177     if ( !pFactoryFunction )
178     {
179         OSL_ENSURE( false, "MysqlCDriver::impl_initCppConn_lck_throw: could not find the factory symbol in " CPPCONN_LIB "!");
180         throw SQLException(
181             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CPPCONN_LIB " is invalid: missing the driver factory function." ) ),
182             *this,
183             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "08001" ) ),  // "unable to connect"
184             0,
185             Any()
186         );
187     }
188 
189     cppDriver = static_cast< sql::Driver* >( (*pFactoryFunction)() );
190 #endif
191     if ( !cppDriver )
192     {
193         throw SQLException(
194             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain the MySQL_Driver instance from Connector/C++." ) ),
195             *this,
196             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "08001" ) ),  // "unable to connect"
197             0,
198             Any()
199         );
200     }
201 }
202 
203 /* {{{ MysqlCDriver::connect() -I- */
204 Reference< XConnection > SAL_CALL MysqlCDriver::connect(const OUString& url, const Sequence< PropertyValue >& info)
205 	throw(SQLException, RuntimeException)
206 {
207     ::osl::MutexGuard aGuard( m_aMutex );
208 
209 	OSL_TRACE("MysqlCDriver::connect");
210 	if (!acceptsURL(url)) {
211 		return NULL;
212 	}
213 
214     if ( !cppDriver )
215     {
216         impl_initCppConn_lck_throw();
217         OSL_POSTCOND( cppDriver, "MySQLCDriver::connect: internal error." );
218         if ( !cppDriver )
219             throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MySQLCDriver::connect: internal error." ) ), *this );
220     }
221 
222     Reference< XConnection > xConn;
223 	// create a new connection with the given properties and append it to our vector
224 	try {
225 		OConnection* pCon = new OConnection(*this, cppDriver);
226 		xConn = pCon;
227 
228         pCon->construct(url,info);
229         m_xConnections.push_back(WeakReferenceHelper(*pCon));
230 	}
231     catch (sql::SQLException &e)
232     {
233 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getDefaultEncoding());
234 	}
235     return xConn;
236 }
237 /* }}} */
238 
239 
240 /* {{{ MysqlCDriver::acceptsURL() -I- */
241 sal_Bool SAL_CALL MysqlCDriver::acceptsURL(const OUString& url)
242 		throw(SQLException, RuntimeException)
243 {
244 	OSL_TRACE("MysqlCDriver::acceptsURL");
245 	return (!url.compareTo(OUString::createFromAscii("sdbc:mysqlc:"), sizeof("sdbc:mysqlc:")-1));
246 }
247 /* }}} */
248 
249 
250 /* {{{ MysqlCDriver::getPropertyInfo() -I- */
251 Sequence< DriverPropertyInfo > SAL_CALL MysqlCDriver::getPropertyInfo(const OUString& url, const Sequence< PropertyValue >& /* info */)
252 	throw(SQLException, RuntimeException)
253 {
254 	OSL_TRACE("MysqlCDriver::getPropertyInfo");
255 	if (acceptsURL(url)) {
256 		::std::vector< DriverPropertyInfo > aDriverInfo;
257 
258 		aDriverInfo.push_back(DriverPropertyInfo(
259 				OUString(RTL_CONSTASCII_USTRINGPARAM("Hostname"))
260 				,OUString(RTL_CONSTASCII_USTRINGPARAM("Name of host"))
261 				,sal_True
262 				,OUString::createFromAscii("localhost")
263 				,Sequence< OUString >())
264 			);
265 		aDriverInfo.push_back(DriverPropertyInfo(
266 				OUString(RTL_CONSTASCII_USTRINGPARAM("Port"))
267 				,OUString(RTL_CONSTASCII_USTRINGPARAM("Port"))
268 				,sal_True
269 				,OUString::createFromAscii("3306")
270 				,Sequence< OUString >())
271 			);
272 		return Sequence< DriverPropertyInfo >(&(aDriverInfo[0]),aDriverInfo.size());
273 	}
274 
275 	return Sequence< DriverPropertyInfo >();
276 }
277 /* }}} */
278 
279 
280 /* {{{ MysqlCDriver::getMajorVersion() -I- */
281 sal_Int32 SAL_CALL MysqlCDriver::getMajorVersion()
282 	throw(RuntimeException)
283 {
284 	OSL_TRACE("MysqlCDriver::getMajorVersion");
285 	return MYSQLC_VERSION_MAJOR;
286 }
287 /* }}} */
288 
289 
290 /* {{{ MysqlCDriver::getMinorVersion() -I- */
291 sal_Int32 SAL_CALL MysqlCDriver::getMinorVersion()
292 	throw(RuntimeException)
293 {
294 	OSL_TRACE("MysqlCDriver::getMinorVersion");
295 	return MYSQLC_VERSION_MINOR;
296 }
297 /* }}} */
298 
299 
300 namespace connectivity
301 {
302 namespace mysqlc
303 {
304 
305 Reference< XInterface >  SAL_CALL MysqlCDriver_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory)
306 	throw(::com::sun::star::uno::Exception)
307 {
308 	return(*(new MysqlCDriver(_rxFactory)));
309 }
310 
311 /* {{{ connectivity::mysqlc::release() -I- */
312 void release(oslInterlockedCount& _refCount,
313 			 ::cppu::OBroadcastHelper& rBHelper,
314 			 Reference< XInterface >& _xInterface,
315 			 ::com::sun::star::lang::XComponent* _pObject)
316 {
317 	if (osl_decrementInterlockedCount(&_refCount) == 0) {
318 		osl_incrementInterlockedCount(&_refCount);
319 
320 		if (!rBHelper.bDisposed && !rBHelper.bInDispose) {
321 			// remember the parent
322 			Reference< XInterface > xParent;
323 			{
324 				::osl::MutexGuard aGuard(rBHelper.rMutex);
325 				xParent = _xInterface;
326 				_xInterface = NULL;
327 			}
328 
329 			// First dispose
330 			_pObject->dispose();
331 
332 			// only the alive ref holds the object
333 			OSL_ASSERT(_refCount == 1);
334 
335 			// release the parent in the destructor
336 			if (xParent.is()) {
337 				::osl::MutexGuard aGuard(rBHelper.rMutex);
338 				_xInterface = xParent;
339 			}
340 		}
341 	} else {
342 		osl_incrementInterlockedCount(&_refCount);
343 	}
344 }
345 /* }}} */
346 
347 
348 
349 /* {{{ connectivity::mysqlc::checkDisposed() -I- */
350 void checkDisposed(sal_Bool _bThrow)
351 	throw (DisposedException)
352 {
353 	if (_bThrow) {
354 		throw DisposedException();
355 	}
356 }
357 /* }}} */
358 
359 } /* mysqlc */
360 } /* connectivity */
361 
362 /*
363  * Local variables:
364  * tab-width: 4
365  * c-basic-offset: 4
366  * End:
367  * vim600: noet sw=4 ts=4 fdm=marker
368  * vim<600: noet sw=4 ts=4
369  */
370