1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 #include "mysqlc_driver.hxx"
22 #include "mysqlc_connection.hxx"
23 #include "mysqlc_general.hxx"
24 
25 using namespace com::sun::star::uno;
26 using namespace com::sun::star::lang;
27 using namespace com::sun::star::beans;
28 using namespace com::sun::star::sdbc;
29 using namespace connectivity::mysqlc;
30 using ::rtl::OUString;
31 #include <stdio.h>
32 
33 #include <preextstl.h>
34 #include <cppconn/exception.h>
35 #include <mysql_driver.h>
36 #include <postextstl.h>
37 
38 
39 /* {{{ MysqlCDriver::MysqlCDriver() -I- */
MysqlCDriver(const Reference<XMultiServiceFactory> & _rxFactory)40 MysqlCDriver::MysqlCDriver(const Reference< XMultiServiceFactory >& _rxFactory)
41 	: ODriver_BASE(m_aMutex)
42     ,m_xFactory(_rxFactory)
43 {
44 	OSL_TRACE("MysqlCDriver::MysqlCDriver");
45 	cppDriver = NULL;
46 }
47 /* }}} */
48 
49 
50 /* {{{ MysqlCDriver::disposing() -I- */
disposing()51 void MysqlCDriver::disposing()
52 {
53 	OSL_TRACE("MysqlCDriver::disposing");
54 	::osl::MutexGuard aGuard(m_aMutex);
55 
56 	// when driver will be destroied so all our connections have to be destroied as well
57 	for (OWeakRefArray::iterator i = m_xConnections.begin(); m_xConnections.end() != i; ++i)
58 	{
59 		Reference< XComponent > xComp(i->get(), UNO_QUERY);
60 		if (xComp.is()) {
61 			xComp->dispose();
62 		}
63 	}
64 	m_xConnections.clear();
65 
66 	ODriver_BASE::disposing();
67 }
68 /* }}} */
69 
70 
71 // static ServiceInfo
72 /* {{{ MysqlCDriver::getImplementationName_Static() -I- */
getImplementationName_Static()73 OUString MysqlCDriver::getImplementationName_Static()
74 	throw(RuntimeException)
75 {
76 	OSL_TRACE("MysqlCDriver::getImplementationName_Static");
77     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sdbc.mysqlc.MysqlCDriver" ) );
78 }
79 /* }}} */
80 
81 
82 /* {{{ MysqlCDriver::getSupportedServiceNames_Static() -I- */
getSupportedServiceNames_Static()83 Sequence< OUString > MysqlCDriver::getSupportedServiceNames_Static()
84 	throw(RuntimeException)
85 {
86 	OSL_TRACE("MysqlCDriver::getSupportedServiceNames_Static");
87 	// which service is supported
88 	// for more information @see com.sun.star.sdbc.Driver
89 	Sequence< OUString > aSNS(1);
90 	aSNS[0] = OUString::createFromAscii("com.sun.star.sdbc.Driver");
91 	return aSNS;
92 }
93 /* }}} */
94 
95 
96 /* {{{ MysqlCDriver::getImplementationName() -I- */
getImplementationName()97 OUString SAL_CALL MysqlCDriver::getImplementationName()
98 	throw(RuntimeException)
99 {
100 	OSL_TRACE("MysqlCDriver::getImplementationName");
101 	return getImplementationName_Static();
102 }
103 /* }}} */
104 
105 
106 /* {{{ MysqlCDriver::supportsService() -I- */
supportsService(const OUString & _rServiceName)107 sal_Bool SAL_CALL MysqlCDriver::supportsService(const OUString& _rServiceName)
108 	throw(RuntimeException)
109 {
110 	OSL_TRACE("MysqlCDriver::supportsService");
111 	Sequence< OUString > aSupported(getSupportedServiceNames());
112 	const OUString* pSupported = aSupported.getConstArray();
113 	const OUString* pEnd = pSupported + aSupported.getLength();
114 	for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported){}
115 
116 	return (pSupported != pEnd);
117 }
118 /* }}} */
119 
120 
121 /* {{{ MysqlCDriver::getSupportedServiceNames() -I- */
getSupportedServiceNames()122 Sequence< OUString > SAL_CALL MysqlCDriver::getSupportedServiceNames()
123 	throw(RuntimeException)
124 {
125 	OSL_TRACE("MysqlCDriver::getSupportedServiceNames");
126 	return getSupportedServiceNames_Static();
127 }
128 /* }}} */
129 
130 
thisModule()131 extern "C" { static void SAL_CALL thisModule() {} }
132 
impl_initCppConn_lck_throw()133 void MysqlCDriver::impl_initCppConn_lck_throw()
134 {
135     cppDriver = get_driver_instance();
136     if ( !cppDriver )
137     {
138         throw SQLException(
139             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain the MySQL_Driver instance from Connector/C++." ) ),
140             *this,
141             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "08001" ) ),  // "unable to connect"
142             0,
143             Any()
144         );
145     }
146 }
147 
148 /* {{{ MysqlCDriver::connect() -I- */
connect(const OUString & url,const Sequence<PropertyValue> & info)149 Reference< XConnection > SAL_CALL MysqlCDriver::connect(const OUString& url, const Sequence< PropertyValue >& info)
150 	throw(SQLException, RuntimeException)
151 {
152     ::osl::MutexGuard aGuard( m_aMutex );
153 
154 	OSL_TRACE("MysqlCDriver::connect");
155 	if (!acceptsURL(url)) {
156 		return NULL;
157 	}
158 
159     if ( !cppDriver )
160     {
161         impl_initCppConn_lck_throw();
162         OSL_POSTCOND( cppDriver, "MySQLCDriver::connect: internal error." );
163         if ( !cppDriver )
164             throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MySQLCDriver::connect: internal error." ) ), *this );
165     }
166 
167     Reference< XConnection > xConn;
168 	// create a new connection with the given properties and append it to our vector
169 	try {
170 		OConnection* pCon = new OConnection(*this, cppDriver);
171 		xConn = pCon;
172 
173         pCon->construct(url,info);
174         m_xConnections.push_back(WeakReferenceHelper(*pCon));
175 	}
176     catch (sql::SQLException &e)
177     {
178 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getDefaultEncoding());
179 	}
180     return xConn;
181 }
182 /* }}} */
183 
184 
185 /* {{{ MysqlCDriver::acceptsURL() -I- */
acceptsURL(const OUString & url)186 sal_Bool SAL_CALL MysqlCDriver::acceptsURL(const OUString& url)
187 		throw(SQLException, RuntimeException)
188 {
189 	OSL_TRACE("MysqlCDriver::acceptsURL");
190 	return (!url.compareTo(OUString::createFromAscii("sdbc:mysqlc:"), sizeof("sdbc:mysqlc:")-1));
191 }
192 /* }}} */
193 
194 
195 /* {{{ MysqlCDriver::getPropertyInfo() -I- */
getPropertyInfo(const OUString & url,const Sequence<PropertyValue> &)196 Sequence< DriverPropertyInfo > SAL_CALL MysqlCDriver::getPropertyInfo(const OUString& url, const Sequence< PropertyValue >& /* info */)
197 	throw(SQLException, RuntimeException)
198 {
199 	OSL_TRACE("MysqlCDriver::getPropertyInfo");
200 	if (acceptsURL(url)) {
201 		::std::vector< DriverPropertyInfo > aDriverInfo;
202 
203 		aDriverInfo.push_back(DriverPropertyInfo(
204 				OUString(RTL_CONSTASCII_USTRINGPARAM("Hostname"))
205 				,OUString(RTL_CONSTASCII_USTRINGPARAM("Name of host"))
206 				,sal_True
207 				,OUString::createFromAscii("localhost")
208 				,Sequence< OUString >())
209 			);
210 		aDriverInfo.push_back(DriverPropertyInfo(
211 				OUString(RTL_CONSTASCII_USTRINGPARAM("Port"))
212 				,OUString(RTL_CONSTASCII_USTRINGPARAM("Port"))
213 				,sal_True
214 				,OUString::createFromAscii("3306")
215 				,Sequence< OUString >())
216 			);
217 		return Sequence< DriverPropertyInfo >(&(aDriverInfo[0]),aDriverInfo.size());
218 	}
219 
220 	return Sequence< DriverPropertyInfo >();
221 }
222 /* }}} */
223 
224 
225 /* {{{ MysqlCDriver::getMajorVersion() -I- */
getMajorVersion()226 sal_Int32 SAL_CALL MysqlCDriver::getMajorVersion()
227 	throw(RuntimeException)
228 {
229 	OSL_TRACE("MysqlCDriver::getMajorVersion");
230 	return MYSQLC_VERSION_MAJOR;
231 }
232 /* }}} */
233 
234 
235 /* {{{ MysqlCDriver::getMinorVersion() -I- */
getMinorVersion()236 sal_Int32 SAL_CALL MysqlCDriver::getMinorVersion()
237 	throw(RuntimeException)
238 {
239 	OSL_TRACE("MysqlCDriver::getMinorVersion");
240 	return MYSQLC_VERSION_MINOR;
241 }
242 /* }}} */
243 
244 
245 namespace connectivity
246 {
247 namespace mysqlc
248 {
249 
MysqlCDriver_CreateInstance(const Reference<XMultiServiceFactory> & _rxFactory)250 Reference< XInterface >  SAL_CALL MysqlCDriver_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory)
251 	throw(::com::sun::star::uno::Exception)
252 {
253 	return(*(new MysqlCDriver(_rxFactory)));
254 }
255 
256 /* {{{ connectivity::mysqlc::release() -I- */
release(oslInterlockedCount & _refCount,::cppu::OBroadcastHelper & rBHelper,Reference<XInterface> & _xInterface,::com::sun::star::lang::XComponent * _pObject)257 void release(oslInterlockedCount& _refCount,
258 			 ::cppu::OBroadcastHelper& rBHelper,
259 			 Reference< XInterface >& _xInterface,
260 			 ::com::sun::star::lang::XComponent* _pObject)
261 {
262 	if (osl_decrementInterlockedCount(&_refCount) == 0) {
263 		osl_incrementInterlockedCount(&_refCount);
264 
265 		if (!rBHelper.bDisposed && !rBHelper.bInDispose) {
266 			// remember the parent
267 			Reference< XInterface > xParent;
268 			{
269 				::osl::MutexGuard aGuard(rBHelper.rMutex);
270 				xParent = _xInterface;
271 				_xInterface = NULL;
272 			}
273 
274 			// First dispose
275 			_pObject->dispose();
276 
277 			// only the alive ref holds the object
278 			OSL_ASSERT(_refCount == 1);
279 
280 			// release the parent in the destructor
281 			if (xParent.is()) {
282 				::osl::MutexGuard aGuard(rBHelper.rMutex);
283 				_xInterface = xParent;
284 			}
285 		}
286 	} else {
287 		osl_incrementInterlockedCount(&_refCount);
288 	}
289 }
290 /* }}} */
291 
292 
293 
294 /* {{{ connectivity::mysqlc::checkDisposed() -I- */
checkDisposed(sal_Bool _bThrow)295 void checkDisposed(sal_Bool _bThrow)
296 	throw (DisposedException)
297 {
298 	if (_bThrow) {
299 		throw DisposedException();
300 	}
301 }
302 /* }}} */
303 
304 } /* mysqlc */
305 } /* connectivity */
306 
307 /*
308  * Local variables:
309  * tab-width: 4
310  * c-basic-offset: 4
311  * End:
312  * vim600: noet sw=4 ts=4 fdm=marker
313  * vim<600: noet sw=4 ts=4
314  */
315