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- */ 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- */ 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- */ 98 void SAL_CALL OConnection::release() 99 throw() 100 { 101 OSL_TRACE("OConnection::release"); 102 relase_ChildImpl(); 103 } 104 /* }}} */ 105 106 #ifndef SYSTEM_MYSQL 107 extern "C" { void SAL_CALL thisModule() {} } 108 #endif 109 110 /* {{{ OConnection::construct() -I- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 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- */ 633 void OConnection::buildTypeInfo() 634 { 635 OSL_TRACE("OConnection::buildTypeInfo"); 636 } 637 /* }}} */ 638 639 640 /* {{{ OConnection::disposing() -I- */ 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- */ 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- */ 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 // ----------------------------------------------------------------------------- 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