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