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