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