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_statement.cxx,v $ 9 * 10 * $Revision: 1.1.2.4 $ 11 * 12 * This file is part of OpenOffice.org. 13 * 14 * OpenOffice.org is free software: you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License version 3 16 * only, as published by the Free Software Foundation. 17 * 18 * OpenOffice.org is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License version 3 for more details 22 * (a copy is included in the LICENSE file that accompanied this code). 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * version 3 along with OpenOffice.org. If not, see 26 * <http://www.openoffice.org/license.html> 27 * for a copy of the LGPLv3 License. 28 ************************************************************************/ 29 #include <stdio.h> 30 #include "mysqlc_connection.hxx" 31 #include "mysqlc_propertyids.hxx" 32 #include "mysqlc_resultset.hxx" 33 #include "mysqlc_statement.hxx" 34 #include "mysqlc_general.hxx" 35 36 #include <com/sun/star/lang/DisposedException.hpp> 37 #include <com/sun/star/sdbc/FetchDirection.hpp> 38 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp> 39 #include <com/sun/star/sdbc/ResultSetType.hpp> 40 41 #include <cppconn/connection.h> 42 #include <cppconn/exception.h> 43 #include <cppconn/statement.h> 44 #include <cppuhelper/typeprovider.hxx> 45 #include <osl/diagnose.h> 46 #include <osl/thread.h> 47 48 #define USE_CPP_CONN 1 49 50 using namespace connectivity::mysqlc; 51 //------------------------------------------------------------------------------ 52 using namespace com::sun::star::uno; 53 using namespace com::sun::star::lang; 54 using namespace com::sun::star::beans; 55 using namespace com::sun::star::sdbc; 56 using namespace com::sun::star::sdbcx; 57 using namespace com::sun::star::container; 58 using namespace com::sun::star::io; 59 using namespace com::sun::star::util; 60 using ::osl::MutexGuard; 61 using ::rtl::OUString; 62 63 #include <stdio.h> 64 65 /* {{{ OConnection::OCommonStatement() -I- */ 66 OCommonStatement::OCommonStatement(OConnection* _pConnection, sql::Statement *_cppStatement) 67 :OCommonStatement_IBase(m_aMutex) 68 ,OPropertySetHelper(OCommonStatement_IBase::rBHelper) 69 ,OStatement_CBase( (::cppu::OWeakObject*)_pConnection, this ) 70 ,m_pConnection(_pConnection) 71 ,cppStatement(_cppStatement) 72 ,rBHelper(OCommonStatement_IBase::rBHelper) 73 { 74 OSL_TRACE("OCommonStatement::OCommonStatement"); 75 m_pConnection->acquire(); 76 } 77 /* }}} */ 78 79 80 /* {{{ OConnection::~OCommonStatement() -I- */ 81 OCommonStatement::~OCommonStatement() 82 { 83 OSL_TRACE("OCommonStatement::~OCommonStatement"); 84 } 85 /* }}} */ 86 87 88 /* {{{ OConnection::disposeResultSet() -I- */ 89 void OCommonStatement::disposeResultSet() 90 { 91 OSL_TRACE("OCommonStatement::disposeResultSet"); 92 // free the cursor if alive 93 delete cppStatement; 94 cppStatement = NULL; 95 } 96 /* }}} */ 97 98 99 /* {{{ OConnection::disposing() -I- */ 100 void OCommonStatement::disposing() 101 { 102 OSL_TRACE("OCommonStatement::disposing"); 103 MutexGuard aGuard(m_aMutex); 104 105 disposeResultSet(); 106 107 if (m_pConnection) { 108 m_pConnection->release(); 109 m_pConnection = NULL; 110 } 111 delete cppStatement; 112 113 dispose_ChildImpl(); 114 OCommonStatement_IBase::disposing(); 115 } 116 /* }}} */ 117 118 119 /* {{{ OCommonStatement::queryInterface() -I- */ 120 Any SAL_CALL OCommonStatement::queryInterface(const Type & rType) 121 throw(RuntimeException) 122 { 123 OSL_TRACE("OCommonStatement::queryInterface"); 124 Any aRet = OCommonStatement_IBase::queryInterface(rType); 125 if (!aRet.hasValue()) { 126 aRet = OPropertySetHelper::queryInterface(rType); 127 } 128 return aRet; 129 } 130 /* }}} */ 131 132 133 /* {{{ OCommonStatement::getTypes() -I- */ 134 Sequence< Type > SAL_CALL OCommonStatement::getTypes() 135 throw(RuntimeException) 136 { 137 OSL_TRACE("OCommonStatement::getTypes"); 138 ::cppu::OTypeCollection aTypes( ::getCppuType( (const Reference< XMultiPropertySet > *)0 ), 139 ::getCppuType( (const Reference< XFastPropertySet > *)0 ), 140 ::getCppuType( (const Reference< XPropertySet > *)0 )); 141 142 return concatSequences(aTypes.getTypes(), OCommonStatement_IBase::getTypes()); 143 } 144 /* }}} */ 145 146 147 /* {{{ OCommonStatement::cancel() -I- */ 148 void SAL_CALL OCommonStatement::cancel() 149 throw(RuntimeException) 150 { 151 OSL_TRACE("OCommonStatement::cancel"); 152 MutexGuard aGuard(m_aMutex); 153 checkDisposed(rBHelper.bDisposed); 154 // cancel the current sql statement 155 } 156 /* }}} */ 157 158 159 /* {{{ OCommonStatement::close() -I- */ 160 void SAL_CALL OCommonStatement::close() 161 throw(SQLException, RuntimeException) 162 { 163 OSL_TRACE("OCommonStatement::close"); 164 /* 165 We need a block for the checkDisposed call. 166 After the check we can call dispose() as we are not under lock ?? 167 */ 168 { 169 MutexGuard aGuard(m_aMutex); 170 checkDisposed(rBHelper.bDisposed); 171 } 172 dispose(); 173 } 174 /* }}} */ 175 176 177 /* {{{ OStatement::clearBatch() -I- */ 178 void SAL_CALL OStatement::clearBatch() 179 throw(SQLException, RuntimeException) 180 { 181 OSL_TRACE("OStatement::clearBatch"); 182 // if you support batches clear it here 183 } 184 /* }}} */ 185 186 187 /* {{{ OStatement::execute() -I- */ 188 sal_Bool SAL_CALL OCommonStatement::execute(const OUString& sql) 189 throw(SQLException, RuntimeException) 190 { 191 OSL_TRACE("OCommonStatement::execute"); 192 MutexGuard aGuard(m_aMutex); 193 checkDisposed(rBHelper.bDisposed); 194 const ::rtl::OUString sSqlStatement = m_pConnection->transFormPreparedStatement( sql ); 195 196 sal_Bool success = false; 197 try { 198 success = cppStatement->execute(OUStringToOString(sSqlStatement, m_pConnection->getConnectionSettings().encoding).getStr())? sal_True:sal_False; 199 } catch (sql::SQLException &e) { 200 mysqlc_sdbc_driver::translateAndThrow(e, *this, m_pConnection->getConnectionEncoding()); 201 } 202 return success; 203 } 204 /* }}} */ 205 206 207 /* {{{ OStatement::executeQuery() -I- */ 208 Reference< XResultSet > SAL_CALL OCommonStatement::executeQuery(const OUString& sql) 209 throw(SQLException, RuntimeException) 210 { 211 OSL_TRACE("OCommonStatement::executeQuery"); 212 213 MutexGuard aGuard(m_aMutex); 214 checkDisposed(rBHelper.bDisposed); 215 const ::rtl::OUString sSqlStatement = m_pConnection->transFormPreparedStatement(sql); 216 217 Reference< XResultSet > xResultSet; 218 try { 219 std::auto_ptr< sql::ResultSet > rset(cppStatement->executeQuery(OUStringToOString(sSqlStatement, m_pConnection->getConnectionEncoding()).getStr())); 220 xResultSet = new OResultSet(this, rset.get(), m_pConnection->getConnectionEncoding()); 221 rset.release(); 222 } catch (sql::SQLException &e) { 223 mysqlc_sdbc_driver::translateAndThrow(e, *this, m_pConnection->getConnectionEncoding()); 224 } 225 return xResultSet; 226 } 227 /* }}} */ 228 229 230 /* {{{ OStatement::getConnection() -I- */ 231 Reference< XConnection > SAL_CALL OCommonStatement::getConnection() 232 throw(SQLException, RuntimeException) 233 { 234 OSL_TRACE("OCommonStatement::getConnection"); 235 MutexGuard aGuard(m_aMutex); 236 checkDisposed(rBHelper.bDisposed); 237 238 // just return(our connection here 239 return ((Reference< XConnection >)m_pConnection); 240 } 241 /* }}} */ 242 243 244 /* {{{ OStatement::getUpdateCount() -I- */ 245 sal_Int32 SAL_CALL OCommonStatement::getUpdateCount() 246 throw(SQLException, RuntimeException) 247 { 248 OSL_TRACE("OCommonStatement::getUpdateCount"); 249 return 0; 250 } 251 /* }}} */ 252 253 254 /* {{{ OStatement::queryInterface() -I- */ 255 Any SAL_CALL OStatement::queryInterface(const Type & rType) 256 throw(RuntimeException) 257 { 258 OSL_TRACE("OStatement::queryInterface"); 259 Any aRet = ::cppu::queryInterface(rType,static_cast< XBatchExecution*> (this)); 260 if (!aRet.hasValue()) { 261 aRet = OCommonStatement::queryInterface(rType); 262 } 263 return (aRet); 264 } 265 /* }}} */ 266 267 268 /* {{{ OStatement::addBatch() -I- */ 269 void SAL_CALL OStatement::addBatch(const OUString& sql) 270 throw(SQLException, RuntimeException) 271 { 272 OSL_TRACE("OStatement::addBatch"); 273 MutexGuard aGuard(m_aMutex); 274 checkDisposed(rBHelper.bDisposed); 275 276 m_aBatchList.push_back(sql); 277 } 278 /* }}} */ 279 280 281 /* {{{ OStatement::executeBatch() -I- */ 282 Sequence< sal_Int32 > SAL_CALL OStatement::executeBatch() 283 throw(SQLException, RuntimeException) 284 { 285 OSL_TRACE("OStatement::executeBatch"); 286 MutexGuard aGuard(m_aMutex); 287 checkDisposed(rBHelper.bDisposed); 288 289 Sequence< sal_Int32 > aRet = Sequence< sal_Int32 >(); 290 return aRet; 291 } 292 /* }}} */ 293 294 295 /* {{{ OCommonStatement::executeUpdate() -I- */ 296 sal_Int32 SAL_CALL OCommonStatement::executeUpdate(const OUString& sql) 297 throw(SQLException, RuntimeException) 298 { 299 OSL_TRACE("OCommonStatement::executeUpdate"); 300 MutexGuard aGuard(m_aMutex); 301 checkDisposed(rBHelper.bDisposed); 302 const ::rtl::OUString sSqlStatement = m_pConnection->transFormPreparedStatement(sql); 303 304 sal_Int32 affectedRows = 0; 305 try { 306 affectedRows = cppStatement->executeUpdate(OUStringToOString(sSqlStatement, m_pConnection->getConnectionEncoding()).getStr()); 307 } catch (sql::SQLException &e) { 308 mysqlc_sdbc_driver::translateAndThrow(e, *this, m_pConnection->getConnectionEncoding()); 309 } 310 return affectedRows; 311 } 312 /* }}} */ 313 314 315 /* {{{ OCommonStatement::getResultSet() -I- */ 316 Reference< XResultSet > SAL_CALL OCommonStatement::getResultSet() 317 throw(SQLException, RuntimeException) 318 { 319 OSL_TRACE("OCommonStatement::getResultSet"); 320 MutexGuard aGuard(m_aMutex); 321 checkDisposed(rBHelper.bDisposed); 322 323 Reference< XResultSet > xResultSet; 324 try { 325 std::auto_ptr< sql::ResultSet > rset(cppStatement->getResultSet()); 326 xResultSet = new OResultSet(this, rset.get(), m_pConnection->getConnectionEncoding()); 327 rset.release(); 328 } catch (sql::SQLException &e) { 329 mysqlc_sdbc_driver::translateAndThrow(e, *this, m_pConnection->getConnectionEncoding()); 330 } 331 return xResultSet; 332 } 333 /* }}} */ 334 335 336 /* {{{ OCommonStatement::getMoreResults() -I- */ 337 sal_Bool SAL_CALL OCommonStatement::getMoreResults() 338 throw(SQLException, RuntimeException) 339 { 340 OSL_TRACE("OCommonStatement::getMoreResults"); 341 MutexGuard aGuard(m_aMutex); 342 checkDisposed(rBHelper.bDisposed); 343 344 // if your driver supports more than only one resultset 345 // and has one more at this moment return(true 346 return (sal_False); 347 } 348 /* }}} */ 349 350 351 /* {{{ OCommonStatement::getWarnings() -I- */ 352 Any SAL_CALL OCommonStatement::getWarnings() 353 throw(SQLException, RuntimeException) 354 { 355 OSL_TRACE("OCommonStatement::getWarnings"); 356 MutexGuard aGuard(m_aMutex); 357 checkDisposed(rBHelper.bDisposed); 358 359 return makeAny(m_aLastWarning); 360 } 361 /* }}} */ 362 363 364 /* {{{ OCommonStatement::clearWarnings() -I- */ 365 void SAL_CALL OCommonStatement::clearWarnings() 366 throw(SQLException, RuntimeException) 367 { 368 OSL_TRACE("OCommonStatement::clearWarnings"); 369 MutexGuard aGuard(m_aMutex); 370 checkDisposed(rBHelper.bDisposed); 371 372 m_aLastWarning = SQLWarning(); 373 } 374 /* }}} */ 375 376 377 /* {{{ OCommonStatement::createArrayHelper() -I- */ 378 ::cppu::IPropertyArrayHelper* OCommonStatement::createArrayHelper( ) const 379 { 380 OSL_TRACE("OCommonStatement::createArrayHelper"); 381 // this properties are define by the service statement 382 // they must in alphabetic order 383 Sequence< Property > aProps(10); 384 Property* pProperties = aProps.getArray(); 385 sal_Int32 nPos = 0; 386 DECL_PROP0(CURSORNAME, OUString); 387 DECL_BOOL_PROP0(ESCAPEPROCESSING); 388 DECL_PROP0(FETCHDIRECTION,sal_Int32); 389 DECL_PROP0(FETCHSIZE, sal_Int32); 390 DECL_PROP0(MAXFIELDSIZE,sal_Int32); 391 DECL_PROP0(MAXROWS, sal_Int32); 392 DECL_PROP0(QUERYTIMEOUT,sal_Int32); 393 DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32); 394 DECL_PROP0(RESULTSETTYPE,sal_Int32); 395 DECL_BOOL_PROP0(USEBOOKMARKS); 396 397 return new ::cppu::OPropertyArrayHelper(aProps); 398 } 399 /* }}} */ 400 401 402 /* {{{ OCommonStatement::getInfoHelper() -I- */ 403 ::cppu::IPropertyArrayHelper & OCommonStatement::getInfoHelper() 404 { 405 OSL_TRACE("OCommonStatement::getInfoHelper"); 406 return(*const_cast<OCommonStatement*>(this)->getArrayHelper()); 407 } 408 /* }}} */ 409 410 411 /* {{{ OCommonStatement::convertFastPropertyValue() -I- */ 412 sal_Bool OCommonStatement::convertFastPropertyValue( 413 Any & /* rConvertedValue */, Any & /* rOldValue */, 414 sal_Int32 /* nHandle */, const Any& /* rValue */) 415 throw (IllegalArgumentException) 416 { 417 OSL_TRACE("OCommonStatement::convertFastPropertyValue"); 418 sal_Bool bConverted = sal_False; 419 // here we have to try to convert 420 return bConverted; 421 } 422 /* }}} */ 423 424 425 /* {{{ OCommonStatement::setFastPropertyValue_NoBroadcast() -I- */ 426 void OCommonStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& /* rValue */) 427 throw (Exception) 428 { 429 OSL_TRACE("OCommonStatement::setFastPropertyValue_NoBroadcast"); 430 // set the value to what ever is nescessary 431 switch (nHandle) { 432 case PROPERTY_ID_QUERYTIMEOUT: 433 case PROPERTY_ID_MAXFIELDSIZE: 434 case PROPERTY_ID_MAXROWS: 435 case PROPERTY_ID_CURSORNAME: 436 case PROPERTY_ID_RESULTSETCONCURRENCY: 437 case PROPERTY_ID_RESULTSETTYPE: 438 case PROPERTY_ID_FETCHDIRECTION: 439 case PROPERTY_ID_FETCHSIZE: 440 case PROPERTY_ID_ESCAPEPROCESSING: 441 case PROPERTY_ID_USEBOOKMARKS: 442 default: 443 ; 444 } 445 } 446 /* }}} */ 447 448 449 /* {{{ OCommonStatement::getFastPropertyValue() -I- */ 450 void OCommonStatement::getFastPropertyValue(Any& _rValue, sal_Int32 nHandle) const 451 { 452 OSL_TRACE("OCommonStatement::getFastPropertyValue"); 453 switch (nHandle) { 454 case PROPERTY_ID_QUERYTIMEOUT: 455 case PROPERTY_ID_MAXFIELDSIZE: 456 case PROPERTY_ID_MAXROWS: 457 case PROPERTY_ID_CURSORNAME: 458 case PROPERTY_ID_RESULTSETCONCURRENCY: 459 case PROPERTY_ID_RESULTSETTYPE: 460 case PROPERTY_ID_FETCHDIRECTION: 461 case PROPERTY_ID_FETCHSIZE: 462 case PROPERTY_ID_ESCAPEPROCESSING: 463 break; 464 case PROPERTY_ID_USEBOOKMARKS: 465 _rValue <<= sal_False; 466 break; 467 default: 468 ; 469 } 470 } 471 /* }}} */ 472 473 IMPLEMENT_SERVICE_INFO(OStatement,"com.sun.star.sdbcx.OStatement","com.sun.star.sdbc.Statement"); 474 475 /* {{{ OCommonStatement::acquire() -I- */ 476 void SAL_CALL OCommonStatement::acquire() 477 throw() 478 { 479 OSL_TRACE("OCommonStatement::acquire"); 480 OCommonStatement_IBase::acquire(); 481 } 482 /* }}} */ 483 484 485 /* {{{ OCommonStatement::release() -I- */ 486 void SAL_CALL OCommonStatement::release() 487 throw() 488 { 489 OSL_TRACE("OCommonStatement::release"); 490 relase_ChildImpl(); 491 } 492 /* }}} */ 493 494 495 /* {{{ OStatement::acquire() -I- */ 496 void SAL_CALL OStatement::acquire() 497 throw() 498 { 499 OSL_TRACE("OStatement::acquire"); 500 OCommonStatement::acquire(); 501 } 502 /* }}} */ 503 504 505 /* {{{ OStatement::release() -I- */ 506 void SAL_CALL OStatement::release() 507 throw() 508 { 509 OSL_TRACE("OStatement::release"); 510 OCommonStatement::release(); 511 } 512 /* }}} */ 513 514 515 /* {{{ OCommonStatement::getPropertySetInfo() -I- */ 516 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OCommonStatement::getPropertySetInfo() 517 throw(RuntimeException) 518 { 519 OSL_TRACE("OCommonStatement::getPropertySetInfo"); 520 return(::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper())); 521 } 522 /* }}} */ 523 524 /* 525 * Local variables: 526 * tab-width: 4 527 * c-basic-offset: 4 528 * End: 529 * vim600: noet sw=4 ts=4 fdm=marker 530 * vim<600: noet sw=4 ts=4 531 */ 532