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