bump product version to 4.1.6.2
[LibreOffice.git] / connectivity / source / drivers / mysql / YDriver.cxx
blobb55f4640ddbb3f8ee37b2b65a24c4862f6683f98
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "mysql/YDriver.hxx"
21 #include "mysql/YCatalog.hxx"
22 #include <osl/diagnose.h>
23 #include <comphelper/namedvaluecollection.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include "connectivity/dbexception.hxx"
26 #include <connectivity/dbcharset.hxx>
27 #include <com/sun/star/sdbc/DriverManager.hpp>
28 #include <com/sun/star/uno/XComponentContext.hpp>
29 #include "TConnection.hxx"
30 #include "resource/common_res.hrc"
31 #include "resource/sharedresources.hxx"
33 //........................................................................
34 namespace connectivity
36 //........................................................................
37 using namespace mysql;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::sdbc;
40 using namespace ::com::sun::star::sdbcx;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star::lang;
44 namespace mysql
46 Reference< XInterface > SAL_CALL ODriverDelegator_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFac) throw( Exception )
48 return *(new ODriverDelegator( comphelper::getComponentContext(_rxFac) ));
52 namespace
54 OUString getJavaDriverClass(
55 css::uno::Sequence<css::beans::PropertyValue> const & info)
57 return comphelper::NamedValueCollection(info).getOrDefault(
58 "JavaDriverClass", OUString("com.mysql.jdbc.Driver"));
62 //====================================================================
63 //= ODriverDelegator
64 //====================================================================
65 //--------------------------------------------------------------------
66 ODriverDelegator::ODriverDelegator(const Reference< XComponentContext >& _rxContext)
67 : ODriverDelegator_BASE(m_aMutex)
68 ,m_xContext(_rxContext)
72 //--------------------------------------------------------------------
73 ODriverDelegator::~ODriverDelegator()
75 try
77 ::comphelper::disposeComponent(m_xODBCDriver);
78 ::comphelper::disposeComponent(m_xNativeDriver);
79 TJDBCDrivers::iterator aIter = m_aJdbcDrivers.begin();
80 TJDBCDrivers::iterator aEnd = m_aJdbcDrivers.end();
81 for ( ;aIter != aEnd;++aIter )
82 ::comphelper::disposeComponent(aIter->second);
84 catch(const Exception&)
89 // --------------------------------------------------------------------------------
90 void ODriverDelegator::disposing()
92 ::osl::MutexGuard aGuard(m_aMutex);
95 for (TWeakPairVector::iterator i = m_aConnections.begin(); m_aConnections.end() != i; ++i)
97 Reference<XInterface > xTemp = i->first.get();
98 ::comphelper::disposeComponent(xTemp);
100 m_aConnections.clear();
101 TWeakPairVector().swap(m_aConnections);
103 ODriverDelegator_BASE::disposing();
106 namespace
108 typedef enum
110 D_ODBC,
111 D_JDBC,
112 D_NATIVE
113 } T_DRIVERTYPE;
115 sal_Bool isOdbcUrl(const OUString& _sUrl)
117 return _sUrl.copy(0,16) == "sdbc:mysql:odbc:";
119 //--------------------------------------------------------------------
120 sal_Bool isNativeUrl(const OUString& _sUrl)
122 return (!_sUrl.compareTo(OUString("sdbc:mysql:mysqlc:"), sizeof("sdbc:mysql:mysqlc:")-1));
124 //--------------------------------------------------------------------
125 T_DRIVERTYPE lcl_getDriverType(const OUString& _sUrl)
127 T_DRIVERTYPE eRet = D_JDBC;
128 if ( isOdbcUrl(_sUrl ) )
129 eRet = D_ODBC;
130 else if ( isNativeUrl(_sUrl ) )
131 eRet = D_NATIVE;
132 return eRet;
134 //--------------------------------------------------------------------
135 OUString transformUrl(const OUString& _sUrl)
137 OUString sNewUrl = _sUrl.copy(11);
138 if ( isOdbcUrl( _sUrl ) )
139 sNewUrl = OUString("sdbc:") + sNewUrl;
140 else if ( isNativeUrl( _sUrl ) )
141 sNewUrl = OUString("sdbc:") + sNewUrl;
142 else
144 sNewUrl = sNewUrl.copy(5);
146 OUString sTempUrl = OUString("jdbc:mysql://");
148 sTempUrl += sNewUrl;
149 sNewUrl = sTempUrl;
151 return sNewUrl;
153 //--------------------------------------------------------------------
154 Reference< XDriver > lcl_loadDriver(const Reference< XComponentContext >& _rxContext,const OUString& _sUrl)
156 Reference<XDriverManager2> xDriverAccess = DriverManager::create(_rxContext);
157 Reference< XDriver > xDriver = xDriverAccess->getDriverByURL(_sUrl);
158 return xDriver;
160 //--------------------------------------------------------------------
161 Sequence< PropertyValue > lcl_convertProperties(T_DRIVERTYPE _eType,const Sequence< PropertyValue >& info,const OUString& _sUrl)
163 ::std::vector<PropertyValue> aProps;
164 const PropertyValue* pSupported = info.getConstArray();
165 const PropertyValue* pEnd = pSupported + info.getLength();
167 aProps.reserve(info.getLength() + 5);
168 bool jdc = false;
169 for (;pSupported != pEnd; ++pSupported)
171 aProps.push_back( *pSupported );
172 if (pSupported->Name == "JavaDriverClass")
174 jdc = true;
178 if ( _eType == D_ODBC )
180 aProps.push_back( PropertyValue(
181 OUString("Silent")
183 ,makeAny(sal_True)
184 ,PropertyState_DIRECT_VALUE) );
185 aProps.push_back( PropertyValue(
186 OUString("PreventGetVersionColumns")
188 ,makeAny(sal_True)
189 ,PropertyState_DIRECT_VALUE) );
191 else if ( _eType == D_JDBC )
193 if (!jdc)
195 aProps.push_back( PropertyValue(
196 OUString("JavaDriverClass")
198 ,makeAny(OUString("com.mysql.jdbc.Driver"))
199 ,PropertyState_DIRECT_VALUE) );
202 else
204 aProps.push_back( PropertyValue(
205 OUString("PublicConnectionURL")
207 ,makeAny(_sUrl)
208 ,PropertyState_DIRECT_VALUE) );
210 aProps.push_back( PropertyValue(
211 OUString("IsAutoRetrievingEnabled")
213 ,makeAny(sal_True)
214 ,PropertyState_DIRECT_VALUE) );
215 aProps.push_back( PropertyValue(
216 OUString("AutoRetrievingStatement")
218 ,makeAny(OUString("SELECT LAST_INSERT_ID()"))
219 ,PropertyState_DIRECT_VALUE) );
220 aProps.push_back( PropertyValue(
221 OUString("ParameterNameSubstitution")
223 ,makeAny(sal_True)
224 ,PropertyState_DIRECT_VALUE) );
225 PropertyValue* pProps = aProps.empty() ? 0 : &aProps[0];
226 return Sequence< PropertyValue >(pProps, aProps.size());
229 //--------------------------------------------------------------------
230 Reference< XDriver > ODriverDelegator::loadDriver( const OUString& url, const Sequence< PropertyValue >& info )
232 Reference< XDriver > xDriver;
233 const OUString sCuttedUrl = transformUrl(url);
234 const T_DRIVERTYPE eType = lcl_getDriverType( url );
235 if ( eType == D_ODBC )
237 if ( !m_xODBCDriver.is() )
238 m_xODBCDriver = lcl_loadDriver(m_xContext,sCuttedUrl);
239 xDriver = m_xODBCDriver;
240 } // if ( bIsODBC )
241 else if ( eType == D_NATIVE )
243 if ( !m_xNativeDriver.is() )
244 m_xNativeDriver = lcl_loadDriver(m_xContext,sCuttedUrl);
245 xDriver = m_xNativeDriver;
247 else
249 OUString sDriverClass(getJavaDriverClass(info));
250 TJDBCDrivers::iterator aFind = m_aJdbcDrivers.find(sDriverClass);
251 if ( aFind == m_aJdbcDrivers.end() )
252 aFind = m_aJdbcDrivers.insert(TJDBCDrivers::value_type(sDriverClass,lcl_loadDriver(m_xContext,sCuttedUrl))).first;
253 xDriver = aFind->second;
256 return xDriver;
259 //--------------------------------------------------------------------
260 Reference< XConnection > SAL_CALL ODriverDelegator::connect( const OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
262 Reference< XConnection > xConnection;
263 if ( acceptsURL(url) )
265 Reference< XDriver > xDriver;
266 xDriver = loadDriver(url,info);
267 if ( xDriver.is() )
269 OUString sCuttedUrl = transformUrl(url);
270 const T_DRIVERTYPE eType = lcl_getDriverType( url );
271 Sequence< PropertyValue > aConvertedProperties = lcl_convertProperties(eType,info,url);
272 if ( eType == D_JDBC )
274 ::comphelper::NamedValueCollection aSettings( info );
275 OUString sIanaName = aSettings.getOrDefault( "CharSet", OUString() );
276 if ( !sIanaName.isEmpty() )
278 ::dbtools::OCharsetMap aLookupIanaName;
279 ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA());
280 if (aLookup != aLookupIanaName.end() )
282 OUString sAdd;
283 if ( RTL_TEXTENCODING_UTF8 == (*aLookup).getEncoding() )
285 static const OUString s_sCharSetOp("useUnicode=true&");
286 if ( !sCuttedUrl.matchIgnoreAsciiCase(s_sCharSetOp) )
288 sAdd = s_sCharSetOp;
289 } // if ( !sCuttedUrl.matchIgnoreAsciiCase(s_sCharSetOp) )
290 } // if ( RTL_TEXTENCODING_UTF8 == (*aLookup).getEncoding() )
291 if ( sCuttedUrl.indexOf('?') == -1 )
292 sCuttedUrl += OUString("?");
293 else
294 sCuttedUrl += OUString("&");
295 sCuttedUrl += sAdd;
296 sCuttedUrl += OUString("characterEncoding=");
297 sCuttedUrl += sIanaName;
300 } // if ( !bIsODBC )
302 xConnection = xDriver->connect( sCuttedUrl, aConvertedProperties );
303 if ( xConnection.is() )
305 OMetaConnection* pMetaConnection = NULL;
306 // now we have to set the URL to get the correct answer for metadata()->getURL()
307 Reference< XUnoTunnel> xTunnel(xConnection,UNO_QUERY);
308 if ( xTunnel.is() )
310 pMetaConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
311 if ( pMetaConnection )
312 pMetaConnection->setURL(url);
314 m_aConnections.push_back(TWeakPair(WeakReferenceHelper(xConnection),TWeakConnectionPair(WeakReferenceHelper(),pMetaConnection)));
318 return xConnection;
321 //--------------------------------------------------------------------
322 sal_Bool SAL_CALL ODriverDelegator::acceptsURL( const OUString& url ) throw (SQLException, RuntimeException)
324 Sequence< PropertyValue > info;
326 sal_Bool bOK = url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:odbc:" ) )
327 || url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:jdbc:" ) )
328 || ( url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:mysqlc:" ) )
329 && loadDriver( url, info ).is()
331 return bOK;
334 //--------------------------------------------------------------------
335 Sequence< DriverPropertyInfo > SAL_CALL ODriverDelegator::getPropertyInfo( const OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
337 ::std::vector< DriverPropertyInfo > aDriverInfo;
338 if ( !acceptsURL(url) )
339 return Sequence< DriverPropertyInfo >();
341 Sequence< OUString > aBoolean(2);
342 aBoolean[0] = OUString("0");
343 aBoolean[1] = OUString("1");
346 aDriverInfo.push_back(DriverPropertyInfo(
347 OUString("CharSet")
348 ,OUString("CharSet of the database.")
349 ,sal_False
350 ,OUString()
351 ,Sequence< OUString >())
353 aDriverInfo.push_back(DriverPropertyInfo(
354 OUString("SuppressVersionColumns")
355 ,OUString("Display version columns (when available).")
356 ,sal_False
357 ,OUString("0")
358 ,aBoolean)
360 const T_DRIVERTYPE eType = lcl_getDriverType( url );
361 if ( eType == D_JDBC )
363 aDriverInfo.push_back(DriverPropertyInfo(
364 OUString("JavaDriverClass")
365 ,OUString("The JDBC driver class name.")
366 ,sal_True
367 ,getJavaDriverClass(info)
368 ,Sequence< OUString >())
372 return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
375 //--------------------------------------------------------------------
376 sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion( ) throw (RuntimeException)
378 return 1;
381 //--------------------------------------------------------------------
382 sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion( ) throw (RuntimeException)
384 return 0;
387 //--------------------------------------------------------------------
388 Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByConnection( const Reference< XConnection >& connection ) throw (SQLException, RuntimeException)
390 ::osl::MutexGuard aGuard( m_aMutex );
391 checkDisposed(ODriverDelegator_BASE::rBHelper.bDisposed);
393 Reference< XTablesSupplier > xTab;
394 Reference< XUnoTunnel> xTunnel(connection,UNO_QUERY);
395 if ( xTunnel.is() )
397 OMetaConnection* pConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
398 if ( pConnection )
400 TWeakPairVector::iterator aEnd = m_aConnections.end();
401 for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
403 if ( i->second.second == pConnection )
405 xTab = Reference< XTablesSupplier >(i->second.first.get().get(),UNO_QUERY);
406 if ( !xTab.is() )
408 xTab = new OMySQLCatalog(connection);
409 i->second.first = WeakReferenceHelper(xTab);
411 break;
415 } // if ( xTunnel.is() )
416 if ( !xTab.is() )
418 TWeakPairVector::iterator aEnd = m_aConnections.end();
419 for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
421 Reference< XConnection > xTemp(i->first.get(),UNO_QUERY);
422 if ( xTemp == connection )
424 xTab = Reference< XTablesSupplier >(i->second.first.get().get(),UNO_QUERY);
425 if ( !xTab.is() )
427 xTab = new OMySQLCatalog(connection);
428 i->second.first = WeakReferenceHelper(xTab);
430 break;
434 return xTab;
437 //--------------------------------------------------------------------
438 Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByURL( const OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
440 if ( ! acceptsURL(url) )
442 ::connectivity::SharedResources aResources;
443 const OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
444 ::dbtools::throwGenericSQLException(sMessage ,*this);
445 } // if ( ! acceptsURL(url) )
447 return getDataDefinitionByConnection(connect(url,info));
450 // XServiceInfo
451 // --------------------------------------------------------------------------------
452 //------------------------------------------------------------------------------
453 OUString ODriverDelegator::getImplementationName_Static( ) throw(RuntimeException)
455 return OUString("org.openoffice.comp.drivers.MySQL.Driver");
457 //------------------------------------------------------------------------------
458 Sequence< OUString > ODriverDelegator::getSupportedServiceNames_Static( ) throw (RuntimeException)
460 Sequence< OUString > aSNS( 2 );
461 aSNS[0] = OUString("com.sun.star.sdbc.Driver");
462 aSNS[1] = OUString("com.sun.star.sdbcx.Driver");
463 return aSNS;
465 //------------------------------------------------------------------
466 OUString SAL_CALL ODriverDelegator::getImplementationName( ) throw(RuntimeException)
468 return getImplementationName_Static();
471 //------------------------------------------------------------------
472 sal_Bool SAL_CALL ODriverDelegator::supportsService( const OUString& _rServiceName ) throw(RuntimeException)
474 Sequence< OUString > aSupported(getSupportedServiceNames());
475 const OUString* pSupported = aSupported.getConstArray();
476 const OUString* pEnd = pSupported + aSupported.getLength();
477 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
480 return pSupported != pEnd;
482 //------------------------------------------------------------------
483 Sequence< OUString > SAL_CALL ODriverDelegator::getSupportedServiceNames( ) throw(RuntimeException)
485 return getSupportedServiceNames_Static();
487 //------------------------------------------------------------------
488 //........................................................................
489 } // namespace connectivity
490 //........................................................................
492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */