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