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