xref: /trunk/main/mysqlc/source/mysqlc_connection.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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