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_connection.cxx,v $
9 *
10 * $Revision: 1.1.2.6 $*
11 * This file is part of OpenOffice.org.
12 *
13 * OpenOffice.org is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 3
15 * only, as published by the Free Software Foundation.
16 *
17 * OpenOffice.org is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU Lesser General Public License version 3 for more details
21 * (a copy is included in the LICENSE file that accompanied this code).
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * version 3 along with OpenOffice.org.  If not, see
25 * <http://www.openoffice.org/license.html>
26 * for a copy of the LGPLv3 License.
27 ************************************************************************/
28 
29 #include "mysqlc_connection.hxx"
30 #include "mysqlc_databasemetadata.hxx"
31 
32 
33 #include "mysqlc_driver.hxx"
34 #include "mysqlc_statement.hxx"
35 #include "mysqlc_preparedstatement.hxx"
36 #include "mysqlc_general.hxx"
37 
38 #include <preextstl.h>
39 #include <cppconn/driver.h>
40 #include <cppconn/connection.h>
41 #include <cppconn/statement.h>
42 #include <cppconn/metadata.h>
43 #include <cppconn/exception.h>
44 #include <postextstl.h>
45 
46 #include <com/sun/star/sdbc/ColumnValue.hpp>
47 #include <com/sun/star/sdbc/XRow.hpp>
48 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
49 #include <com/sun/star/lang/DisposedException.hpp>
50 #include <com/sun/star/beans/NamedValue.hpp>
51 
52 #include <osl/module.hxx>
53 #include <osl/thread.h>
54 #include <osl/file.h>
55 #include <rtl/uri.hxx>
56 #include <rtl/ustrbuf.hxx>
57 
58 using namespace connectivity::mysqlc;
59 
60 #include <stdio.h>
61 
62 //------------------------------------------------------------------------------
63 using namespace com::sun::star::uno;
64 using namespace com::sun::star::container;
65 using namespace com::sun::star::lang;
66 using namespace com::sun::star::beans;
67 using namespace com::sun::star::sdbc;
68 using ::osl::MutexGuard;
69 using ::rtl::OUString;
70 
71 
72 #define MYSQLC_URI_PREFIX "sdbc:mysqlc:"
73 
74 
75 /* {{{ OConnection::OConnection() -I- */
76 OConnection::OConnection(MysqlCDriver& _rDriver, sql::Driver * _cppDriver)
77 	:OMetaConnection_BASE(m_aMutex)
78 	,OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)&_rDriver, this)
79 	,m_xMetaData(NULL)
80 	,m_rDriver(_rDriver)
81 	,cppDriver(_cppDriver)
82 	,m_bClosed(sal_False)
83 	,m_bUseCatalog(sal_False)
84 	,m_bUseOldDateFormat(sal_False)
85 {
86 	OSL_TRACE("OConnection::OConnection");
87 	m_rDriver.acquire();
88 }
89 /* }}} */
90 
91 
92 /* {{{ OConnection::OConnection() -I- */
93 OConnection::~OConnection()
94 {
95 	OSL_TRACE("OConnection::~OConnection");
96 	if (!isClosed()) {
97 		close();
98 	}
99 	m_rDriver.release();
100 }
101 /* }}} */
102 
103 
104 /* {{{ OConnection::release() -I- */
105 void SAL_CALL OConnection::release()
106 	throw()
107 {
108 	OSL_TRACE("OConnection::release");
109 	relase_ChildImpl();
110 }
111 /* }}} */
112 
113 #ifndef SYSTEM_MYSQL
114     extern "C" { void SAL_CALL thisModule() {} }
115 #endif
116 
117 /* {{{ OConnection::construct() -I- */
118 void OConnection::construct(const OUString& url, const Sequence< PropertyValue >& info)
119 	throw(SQLException)
120 {
121 	OSL_TRACE("OConnection::construct");
122 	MutexGuard aGuard(m_aMutex);
123 
124 	sal_Int32 nIndex;
125 	sal_Bool  bEmbedded = sal_False;
126 	OUString token;
127 	OUString aHostName(RTL_CONSTASCII_USTRINGPARAM("localhost"));
128     sal_Int32 nPort = 3306;
129 	OUString aDbName;
130 
131 	m_settings.encoding = m_rDriver.getDefaultEncoding();
132 	m_settings.quoteIdentifier = OUString();
133 
134 	// parse url. Url has the following format:
135 	// external server: sdbc:mysqlc:[hostname]:[port]/[dbname]
136 
137 	if (!url.compareTo(OUString::createFromAscii(MYSQLC_URI_PREFIX), sizeof(MYSQLC_URI_PREFIX)-1)) {
138 		nIndex = 12;
139 	} else {
140 		bEmbedded = sal_True;
141 		nIndex = 20;
142 		mysqlc_sdbc_driver::throwFeatureNotImplementedException("OConnection::construct (embedded MySQL)", *this);
143 	}
144 
145 	token = url.getToken(0, '/', nIndex);
146 	if (token.getLength()) {
147 		sal_Int32 nIndex1 = 0;
148 		OUString hostandport = token.getToken(0,':', nIndex1);
149 		if (hostandport.getLength()) {
150 			aHostName = hostandport;
151 			hostandport = token.getToken(0, ':', nIndex1);
152 			if (hostandport.getLength() && nIndex1) {
153                 nPort = hostandport.toInt32();
154 			}
155 			token = url.getToken(0, '/', nIndex);
156 			if (token.getLength() && nIndex) {
157 				aDbName = token;
158 			}
159 		}
160 	}
161 
162 	// get user and password for mysql connection
163 	const PropertyValue *pIter	= info.getConstArray();
164 	const PropertyValue *pEnd	= pIter + info.getLength();
165 	OUString aUser, aPass, sUnixSocket, sNamedPipe;
166 	bool unixSocketPassed = false;
167 	bool namedPipePassed = false;
168 
169 	m_settings.connectionURL = url;
170 	for (;pIter != pEnd;++pIter) {
171 		if (!pIter->Name.compareToAscii("user")) {
172 			OSL_VERIFY( pIter->Value >>= aUser );
173 		} else if (!pIter->Name.compareToAscii("password")) {
174 			OSL_VERIFY( pIter->Value >>= aPass );
175 		} else if (!pIter->Name.compareToAscii("LocalSocket")) {
176 			OSL_VERIFY( pIter->Value >>= sUnixSocket );
177 			unixSocketPassed = true;
178 		} else if (!pIter->Name.compareToAscii("NamedPipe")) {
179 			OSL_VERIFY( pIter->Value >>= sNamedPipe );
180 			namedPipePassed = true;
181 		} else if ( !pIter->Name.compareToAscii("PublicConnectionURL")) {
182 			OSL_VERIFY( pIter->Value >>= m_settings.connectionURL );
183 		} else if ( !pIter->Name.compareToAscii("NewURL")) {    // legacy name for "PublicConnectionURL"
184 			OSL_VERIFY( pIter->Value >>= m_settings.connectionURL );
185         }
186 	}
187 
188 	if (bEmbedded == sal_False) {
189 		try {
190             sql::ConnectOptionsMap connProps;
191 			ext_std::string host_str = OUStringToOString(aHostName, m_settings.encoding).getStr();
192 			ext_std::string user_str = OUStringToOString(aUser, m_settings.encoding).getStr();
193 			ext_std::string pass_str = OUStringToOString(aPass, m_settings.encoding).getStr();
194 			ext_std::string schema_str = OUStringToOString(aDbName, m_settings.encoding).getStr();
195 			connProps["hostName"] = sql::ConnectPropertyVal(host_str);
196 			connProps["userName"] = sql::ConnectPropertyVal(user_str);
197 			connProps["password"] = sql::ConnectPropertyVal(pass_str);
198 			connProps["schema"] = sql::ConnectPropertyVal(schema_str);
199 			connProps["port"] = sql::ConnectPropertyVal((int)(nPort));
200 			if (unixSocketPassed) {
201 				sql::SQLString socket_str = OUStringToOString(sUnixSocket, m_settings.encoding).getStr();
202 				connProps["socket"] = socket_str;
203 			} else if (namedPipePassed) {
204 				sql::SQLString pipe_str = OUStringToOString(sNamedPipe, m_settings.encoding).getStr();
205 				connProps["socket"] = pipe_str;
206 			}
207 
208 #ifndef SYSTEM_MYSQL
209             ::rtl::OUString sMySQLClientLib( RTL_CONSTASCII_USTRINGPARAM( MYSQL_LIB ) );
210 
211             ::rtl::OUString moduleBase;
212             OSL_VERIFY( ::osl::Module::getUrlFromAddress( &thisModule, moduleBase ) );
213             ::rtl::OUString sMySQLClientLibURL;
214             try
215             {
216                 sMySQLClientLibURL = ::rtl::Uri::convertRelToAbs( moduleBase, sMySQLClientLib.pData );
217             }
218             catch ( const ::rtl::MalformedUriException& e )
219             {
220                 (void)e; // silence compiler
221             #if OSL_DEBUG_LEVEL > 0
222                 ::rtl::OString sMessage( "OConnection::construct: malformed URI: " );
223                 sMessage += ::rtl::OUStringToOString( e.getMessage(), osl_getThreadTextEncoding() );
224                 OSL_ENSURE( false, sMessage.getStr() );
225             #endif
226             }
227 
228             ::rtl::OUString sMySQLClientLibPath;
229             osl_getSystemPathFromFileURL( sMySQLClientLibURL.pData, &sMySQLClientLibPath.pData );
230 
231             sql::SQLString mysqlLib = ::rtl::OUStringToOString( sMySQLClientLibPath, osl_getThreadTextEncoding() ).getStr();
232             connProps["clientlib"] = mysqlLib;
233 
234             OSL_TRACE("clientlib=%s", mysqlLib.c_str());
235 #endif
236 
237 			OSL_TRACE("hostName=%s", host_str.c_str());
238             OSL_TRACE("port=%i", int(nPort));
239 			OSL_TRACE("userName=%s", user_str.c_str());
240 			OSL_TRACE("password=%s", pass_str.c_str());
241             OSL_TRACE("schema=%s", schema_str.c_str());
242 
243 			m_settings.cppConnection.reset(cppDriver->connect(connProps));
244 		} catch (sql::SQLException &e) {
245 			mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
246 		}
247 	} else {
248 		// TODO: support for embedded server
249 	}
250 
251 	m_settings.schema = aDbName;
252 	OSL_TRACE(OUStringToOString(m_settings.schema, getConnectionEncoding()).getStr());
253 
254 	// Check if the server is 4.1 or above
255 	if (this->getMysqlVersion() < 40100) {
256 		throw SQLException(
257 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MySQL Connector/OO.org requires MySQL Server 4.1 or above" ) ),
258 			*this,
259 			::rtl::OUString(),
260 			0,
261 			Any());
262 	}
263 	std::auto_ptr<sql::Statement> stmt(m_settings.cppConnection->createStatement());
264 	stmt->executeUpdate("SET session sql_mode='ANSI_QUOTES'");
265 	stmt->executeUpdate("SET NAMES utf8");
266 }
267 /* }}} */
268 
269 
270 // XServiceInfo
271 IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.mysqlc.OConnection", "com.sun.star.sdbc.Connection")
272 
273 
274 /* {{{ OConnection::createStatement() -I- */
275 Reference< XStatement > SAL_CALL OConnection::createStatement()
276 	throw(SQLException, RuntimeException)
277 {
278 	OSL_TRACE("OConnection::createStatement");
279 	MutexGuard aGuard(m_aMutex);
280 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
281 
282 	// create a statement
283 	Reference< XStatement > xReturn;
284 	// the statement can only be executed once
285 	try {
286 		xReturn = new OStatement(this, m_settings.cppConnection->createStatement());
287 		m_aStatements.push_back(WeakReferenceHelper(xReturn));
288 		return xReturn;
289 	} catch (sql::SQLException & e) {
290 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
291 	}
292 	return xReturn;
293 }
294 /* }}} */
295 
296 
297 /* {{{ OConnection::createStatement() -I- */
298 Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement(const OUString& _sSql)
299 	throw(SQLException, RuntimeException)
300 {
301 	OSL_TRACE("OConnection::prepareStatement");
302 	MutexGuard aGuard(m_aMutex);
303 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
304 	const ::rtl::OUString sSqlStatement = transFormPreparedStatement( _sSql );
305 
306 	Reference< XPreparedStatement > xStatement;
307 	try {
308 		// create a statement
309 		// the statement can only be executed more than once
310 		xStatement = new OPreparedStatement(this,
311 					m_settings.cppConnection->prepareStatement(OUStringToOString(sSqlStatement, getConnectionEncoding()).getStr()));
312 		m_aStatements.push_back( WeakReferenceHelper( xStatement ) );
313 	} catch (sql::SQLException & e) {
314 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
315 	}
316 	return xStatement;
317 }
318 /* }}} */
319 
320 
321 /* {{{ OConnection::prepareCall() -U- */
322 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall(const OUString& /*_sSql*/ )
323 	throw(SQLException, RuntimeException)
324 {
325 	OSL_TRACE("OConnection::prepareCall");
326 	MutexGuard aGuard(m_aMutex);
327 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
328 
329 	mysqlc_sdbc_driver::throwFeatureNotImplementedException("OConnection::prepareCall", *this);
330 	return Reference< XPreparedStatement >();
331 }
332 /* }}} */
333 
334 
335 /* {{{ OConnection::nativeSQL() -I- */
336 OUString SAL_CALL OConnection::nativeSQL(const OUString& _sSql)
337 	throw(SQLException, RuntimeException)
338 {
339 	OSL_TRACE("OConnection::nativeSQL");
340 	MutexGuard aGuard(m_aMutex);
341 
342 	const ::rtl::OUString sSqlStatement = transFormPreparedStatement( _sSql );
343     ::rtl::OUString sNativeSQL;
344 	try {
345 		sNativeSQL = mysqlc_sdbc_driver::convert(m_settings.cppConnection->nativeSQL(mysqlc_sdbc_driver::convert(sSqlStatement, getConnectionEncoding())),
346 																				getConnectionEncoding());
347 	} catch (sql::SQLException & e) {
348 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
349 	}
350     return sNativeSQL;
351 }
352 /* }}} */
353 
354 
355 /* {{{ OConnection::setAutoCommit() -I- */
356 void SAL_CALL OConnection::setAutoCommit(sal_Bool autoCommit)
357 	throw(SQLException, RuntimeException)
358 {
359 	OSL_TRACE("OConnection::setAutoCommit");
360 	MutexGuard aGuard(m_aMutex);
361 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
362 	try {
363 		m_settings.cppConnection->setAutoCommit(autoCommit == sal_True? true:false);
364 	} catch (sql::SQLException & e) {
365 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
366 	}
367 }
368 /* }}} */
369 
370 
371 /* {{{ OConnection::getAutoCommit() -I- */
372 sal_Bool SAL_CALL OConnection::getAutoCommit()
373 	throw(SQLException, RuntimeException)
374 {
375 	OSL_TRACE("OConnection::getAutoCommit");
376 	// you have to distinguish which if you are in autocommit mode or not
377 	// at normal case true should be fine here
378 
379 	MutexGuard aGuard(m_aMutex);
380 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
381 
382 	sal_Bool autoCommit = sal_False;
383 	try {
384 		autoCommit = m_settings.cppConnection->getAutoCommit() == true ? sal_True : sal_False;
385 	} catch (sql::SQLException & e) {
386 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
387 	}
388 	return autoCommit;
389 }
390 /* }}} */
391 
392 
393 /* {{{ OConnection::commit() -I- */
394 void SAL_CALL OConnection::commit()
395 	throw(SQLException, RuntimeException)
396 {
397 	OSL_TRACE("OConnection::commit");
398 	MutexGuard aGuard(m_aMutex);
399 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
400 	try {
401 		m_settings.cppConnection->commit();
402 	} catch (sql::SQLException & e) {
403 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
404 	}
405 }
406 /* }}} */
407 
408 
409 /* {{{ OConnection::rollback() -I- */
410 void SAL_CALL OConnection::rollback()
411 	throw(SQLException, RuntimeException)
412 {
413 	OSL_TRACE("OConnection::rollback");
414 	MutexGuard aGuard(m_aMutex);
415 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
416 	try {
417 		m_settings.cppConnection->rollback();
418 	} catch (sql::SQLException & e) {
419 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
420 	}
421 }
422 /* }}} */
423 
424 
425 /* {{{ OConnection::isClosed() -I- */
426 sal_Bool SAL_CALL OConnection::isClosed()
427 	throw(SQLException, RuntimeException)
428 {
429 	OSL_TRACE("OConnection::isClosed");
430 	MutexGuard aGuard(m_aMutex);
431 
432 	// just simple -> we are close when we are disposed taht means someone called dispose(); (XComponent)
433 	return (OConnection_BASE::rBHelper.bDisposed);
434 }
435 /* }}} */
436 
437 
438 /* {{{ OConnection::createStatement() -I- */
439 Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData()
440 	throw(SQLException, RuntimeException)
441 {
442 	OSL_TRACE("OConnection::getMetaData");
443 	MutexGuard aGuard(m_aMutex);
444 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
445 
446 	Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
447 	if (!xMetaData.is()) {
448 		try {
449 			xMetaData = new ODatabaseMetaData(*this); // need the connection because it can return it
450 		} catch (sql::SQLException & e) {
451 			mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
452 		}
453 		m_xMetaData = xMetaData;
454 	}
455 
456 	return xMetaData;
457 }
458 /* }}} */
459 
460 
461 /* {{{ OConnection::createStatement() -I- */
462 void SAL_CALL OConnection::setReadOnly(sal_Bool readOnly)
463 	throw(SQLException, RuntimeException)
464 {
465 	OSL_TRACE("OConnection::setReadOnly");
466 	MutexGuard aGuard(m_aMutex);
467 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
468 
469 	m_settings.readOnly = readOnly;
470 }
471 /* }}} */
472 
473 
474 /* {{{ OConnection::createStatement() -I- */
475 sal_Bool SAL_CALL OConnection::isReadOnly()
476 	throw(SQLException, RuntimeException)
477 {
478 	OSL_TRACE("OConnection::isReadOnly");
479 	MutexGuard aGuard(m_aMutex);
480 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
481 
482 	// return if your connection to readonly
483 	return (m_settings.readOnly);
484 }
485 /* }}} */
486 
487 
488 /* {{{ OConnection::createStatement() -I- */
489 void SAL_CALL OConnection::setCatalog(const OUString& catalog)
490 	throw(SQLException, RuntimeException)
491 {
492 	OSL_TRACE("OConnection::setCatalog");
493 	MutexGuard aGuard(m_aMutex);
494 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
495 
496 	try {
497 //		m_settings.cppConnection->setCatalog(OUStringToOString(catalog, m_settings.encoding).getStr());
498 		m_settings.cppConnection->setSchema(OUStringToOString(catalog, getConnectionEncoding()).getStr());
499 	} catch (sql::SQLException & e) {
500 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
501 	}
502 }
503 /* }}} */
504 
505 
506 /* {{{ OConnection::createStatement() -I- */
507 OUString SAL_CALL OConnection::getCatalog()
508 	throw(SQLException, RuntimeException)
509 {
510 	OSL_TRACE("OConnection::getCatalog");
511 	MutexGuard aGuard(m_aMutex);
512 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
513 
514 	OUString catalog;
515 	try {
516 		catalog = mysqlc_sdbc_driver::convert(m_settings.cppConnection->getSchema(), getConnectionEncoding());
517 	} catch (sql::SQLException & e) {
518 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
519 	}
520 	return catalog;
521 }
522 /* }}} */
523 
524 
525 /* {{{ OConnection::createStatement() -I- */
526 void SAL_CALL OConnection::setTransactionIsolation(sal_Int32 level)
527 	throw(SQLException, RuntimeException)
528 {
529 	OSL_TRACE("OConnection::setTransactionIsolation");
530 	MutexGuard aGuard(m_aMutex);
531 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
532 
533 	sql::enum_transaction_isolation cpplevel = sql::TRANSACTION_SERIALIZABLE;
534 
535 	switch (level) {
536 		case TransactionIsolation::READ_UNCOMMITTED:
537 			cpplevel = sql::TRANSACTION_READ_UNCOMMITTED;
538 			break;
539 		case TransactionIsolation::READ_COMMITTED:
540 			cpplevel = sql::TRANSACTION_READ_COMMITTED;
541 			break;
542 		case TransactionIsolation::REPEATABLE_READ:
543 			cpplevel = sql::TRANSACTION_REPEATABLE_READ;
544 			break;
545 		case TransactionIsolation::SERIALIZABLE:
546 			cpplevel = sql::TRANSACTION_SERIALIZABLE;
547 			break;
548 		case TransactionIsolation::NONE:
549 			cpplevel = sql::TRANSACTION_SERIALIZABLE;
550 			break;
551 		default:;
552 			/* XXX: Exception ?? */
553 	}
554 	try {
555 		m_settings.cppConnection->setTransactionIsolation(cpplevel);
556 	} catch (sql::SQLException & e) {
557 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
558 	}
559 }
560 /* }}} */
561 
562 
563 /* {{{ OConnection::createStatement() -I- */
564 sal_Int32 SAL_CALL OConnection::getTransactionIsolation()
565 	throw(SQLException, RuntimeException)
566 {
567 	OSL_TRACE("OConnection::getTransactionIsolation");
568 	MutexGuard aGuard(m_aMutex);
569 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
570 
571 	try {
572 		switch (m_settings.cppConnection->getTransactionIsolation()) {
573 			case sql::TRANSACTION_SERIALIZABLE:		return TransactionIsolation::SERIALIZABLE;
574 			case sql::TRANSACTION_REPEATABLE_READ:	return TransactionIsolation::REPEATABLE_READ;
575 			case sql::TRANSACTION_READ_COMMITTED:	return TransactionIsolation::READ_COMMITTED;
576 			case sql::TRANSACTION_READ_UNCOMMITTED:	return TransactionIsolation::READ_UNCOMMITTED;
577 			default:
578 				;
579 		}
580 	} catch (sql::SQLException & e) {
581 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
582 	}
583 	return TransactionIsolation::NONE;
584 }
585 /* }}} */
586 
587 
588 /* {{{ OConnection::getTypeMap() -I- */
589 Reference<XNameAccess> SAL_CALL OConnection::getTypeMap()
590 	throw(SQLException, RuntimeException)
591 {
592 	OSL_TRACE("OConnection::getTypeMap");
593 	MutexGuard aGuard(m_aMutex);
594 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
595 
596 	Reference<XNameAccess > t;
597 	{
598 		t = m_typeMap;
599 	}
600 	return (t);
601 }
602 /* }}} */
603 
604 
605 /* {{{ OConnection::setTypeMap() -I- */
606 void SAL_CALL OConnection::setTypeMap(const Reference<XNameAccess >& typeMap)
607 	throw(SQLException, RuntimeException)
608 {
609 	OSL_TRACE("OConnection::setTypeMap");
610 	MutexGuard aGuard(m_aMutex);
611 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
612 
613 	m_typeMap = typeMap;
614 }
615 /* }}} */
616 
617 
618 // XCloseable
619 /* {{{ OConnection::close() -I- */
620 void SAL_CALL OConnection::close()
621 	throw(SQLException, RuntimeException)
622 {
623 	OSL_TRACE("OConnection::close");
624 	/*
625 	  we need block, because the mutex is a local variable,
626 	  which will guard the block
627 	*/
628 	{
629 		// we just dispose us
630 		MutexGuard aGuard(m_aMutex);
631 		checkDisposed(OConnection_BASE::rBHelper.bDisposed);
632 	}
633 	dispose();
634 }
635 /* }}} */
636 
637 
638 // XWarningsSupplier
639 /* {{{ OConnection::getWarnings() -I- */
640 Any SAL_CALL OConnection::getWarnings()
641 	throw(SQLException, RuntimeException)
642 {
643 	Any x = Any();
644 	OSL_TRACE("OConnection::getWarnings");
645 	// when you collected some warnings -> return it
646 	return x;
647 }
648 /* }}} */
649 
650 
651 /* {{{ OConnection::clearWarnings() -I- */
652 void SAL_CALL OConnection::clearWarnings()
653 	throw(SQLException, RuntimeException)
654 {
655 	OSL_TRACE("OConnection::clearWarnings");
656 	// you should clear your collected warnings here#
657 }
658 /* }}} */
659 
660 
661 /* {{{ OConnection::buildTypeInfo() -I- */
662 void OConnection::buildTypeInfo()
663 	throw(SQLException)
664 {
665 	OSL_TRACE("OConnection::buildTypeInfo");
666 }
667 /* }}} */
668 
669 
670 /* {{{ OConnection::disposing() -I- */
671 void OConnection::disposing()
672 {
673 	OSL_TRACE("OConnection::disposing");
674 	// we noticed that we should be destroied in near future so we have to dispose our statements
675 	MutexGuard aGuard(m_aMutex);
676 
677 	for (OWeakRefArray::iterator i = m_aStatements.begin(); i != m_aStatements.end() ; ++i) {
678 		Reference< XComponent > xComp(i->get(), UNO_QUERY);
679 		if (xComp.is()) {
680 			xComp->dispose();
681 		}
682 	}
683 	m_aStatements.clear();
684 
685 	m_bClosed	= sal_True;
686 	m_xMetaData	= WeakReference< XDatabaseMetaData >();
687 
688 	dispose_ChildImpl();
689 	OConnection_BASE::disposing();
690 }
691 /* }}} */
692 
693 
694 /* ToDo - upcast the connection to MySQL_Connection and use ::getSessionVariable() */
695 
696 /* {{{ OConnection::getMysqlVariable() -I- */
697 OUString OConnection::getMysqlVariable(const char *varname)
698 	throw(SQLException, RuntimeException)
699 {
700 	OSL_TRACE("OConnection::getMysqlVariable");
701 	MutexGuard aGuard(m_aMutex);
702 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
703 
704 	OUString ret;
705 	::rtl::OUStringBuffer aStatement;
706 	aStatement.appendAscii( "SHOW SESSION VARIABLES LIKE '" );
707 	aStatement.appendAscii( varname );
708 	aStatement.append( sal_Unicode( '\'' ) );
709 
710 	try {
711 		XStatement * stmt = new OStatement(this, m_settings.cppConnection->createStatement());
712 		Reference< XResultSet > rs = stmt->executeQuery( aStatement.makeStringAndClear() );
713 		if (rs.is() && rs->next()) {
714 			Reference< XRow > xRow(rs, UNO_QUERY);
715 			ret = xRow->getString(2);
716 		}
717 	} catch (sql::SQLException & e) {
718 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
719 	}
720 
721 	return ret;
722 }
723 /* }}} */
724 
725 
726 /* {{{ OConnection::getMysqlVersion() -I- */
727 sal_Int32 OConnection::getMysqlVersion()
728 	throw(SQLException, RuntimeException)
729 {
730 	OSL_TRACE("OConnection::getMysqlVersion");
731 	MutexGuard aGuard(m_aMutex);
732 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
733 
734 	sal_Int32 version(0);
735 	try {
736 		version = 10000 * m_settings.cppConnection->getMetaData()->getDatabaseMajorVersion();
737 		version += 100 * m_settings.cppConnection->getMetaData()->getDatabaseMinorVersion();
738 		version += m_settings.cppConnection->getMetaData()->getDatabasePatchVersion();
739 	} catch (sql::SQLException & e) {
740 		mysqlc_sdbc_driver::translateAndThrow(e, *this, getConnectionEncoding());
741 	}
742 	return version;
743 }
744 /* }}} */
745 
746 
747 /* {{{ OConnection::sdbcColumnType() -I- */
748 // TODO: Not used
749 //sal_Int32 OConnection::sdbcColumnType(OUString typeName)
750 //{
751 //	OSL_TRACE("OConnection::sdbcColumnType");
752 //	int i = 0;
753 //	while (mysqlc_types[i].typeName) {
754 //		if (OUString::createFromAscii(mysqlc_types[i].typeName).equals(
755 //			typeName.toAsciiUpperCase()))
756 //		{
757 //			return mysqlc_types[i].dataType;
758 //		}
759 //		i++;
760 //	}
761 //	return 0;
762 //}
763 // -----------------------------------------------------------------------------
764 ::rtl::OUString OConnection::transFormPreparedStatement(const ::rtl::OUString& _sSQL)
765 {
766 	::rtl::OUString sSqlStatement = _sSQL;
767 	if ( !m_xParameterSubstitution.is() ) {
768 		try {
769 			Sequence< Any > aArgs(1);
770 			Reference< XConnection> xCon = this;
771 			aArgs[0] <<= NamedValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ActiveConnection")), makeAny(xCon));
772 
773 			m_xParameterSubstitution.set(m_rDriver.getFactory()->createInstanceWithArguments(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.helper.ParameterSubstitution")),aArgs),UNO_QUERY);
774 		} catch(const Exception&) {}
775 	}
776 	if ( m_xParameterSubstitution.is() ) {
777 		try	{
778 			sSqlStatement = m_xParameterSubstitution->substituteVariables(sSqlStatement,sal_True);
779 		} catch(const Exception&) { }
780 	}
781 	return sSqlStatement;
782 }
783 
784 /* }}} */
785 
786 /*
787  * Local variables:
788  * tab-width: 4
789  * c-basic-offset: 4
790  * End:
791  * vim600: noet sw=4 ts=4 fdm=marker
792  * vim<600: noet sw=4 ts=4
793  */
794