xref: /AOO41X/main/mysqlc/source/mysqlc_connection.cxx (revision 079eb5772d0a9e49bbf5c2cd738fc5b5d43e5181)
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 taht 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