1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #include "dbastrings.hrc" 32 33 #include <com/sun/star/lang/DisposedException.hpp> 34 #include <com/sun/star/sdbc/XConnection.hpp> 35 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp> 36 37 #include <comphelper/property.hxx> 38 #include <comphelper/sequence.hxx> 39 #include <cppuhelper/typeprovider.hxx> 40 #include <preparedstatement.hxx> 41 #include <resultcolumn.hxx> 42 #include <resultset.hxx> 43 #include <tools/debug.hxx> 44 #include <tools/diagnose_ex.h> 45 46 using namespace ::com::sun::star::sdbc; 47 using namespace ::com::sun::star::sdbcx; 48 using namespace ::com::sun::star::beans; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::lang; 51 using namespace ::cppu; 52 using namespace ::osl; 53 using namespace dbaccess; 54 55 DBG_NAME(OPreparedStatement) 56 57 //-------------------------------------------------------------------------- 58 OPreparedStatement::OPreparedStatement(const Reference< XConnection > & _xConn, 59 const Reference< XInterface > & _xStatement) 60 :OStatementBase(_xConn, _xStatement) 61 { 62 DBG_CTOR(OPreparedStatement, NULL); 63 m_xAggregateAsParameters = Reference< XParameters >( m_xAggregateAsSet, UNO_QUERY_THROW ); 64 65 Reference<XDatabaseMetaData> xMeta = _xConn->getMetaData(); 66 m_pColumns = new OColumns(*this, m_aMutex, xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),::std::vector< ::rtl::OUString>(), NULL,NULL); 67 } 68 69 //-------------------------------------------------------------------------- 70 OPreparedStatement::~OPreparedStatement() 71 { 72 m_pColumns->acquire(); 73 m_pColumns->disposing(); 74 delete m_pColumns; 75 76 DBG_DTOR(OPreparedStatement, NULL); 77 } 78 79 // com::sun::star::lang::XTypeProvider 80 //-------------------------------------------------------------------------- 81 Sequence< Type > OPreparedStatement::getTypes() throw (RuntimeException) 82 { 83 OTypeCollection aTypes(::getCppuType( (const Reference< XServiceInfo > *)0 ), 84 ::getCppuType( (const Reference< XPreparedStatement > *)0 ), 85 ::getCppuType( (const Reference< XParameters > *)0 ), 86 ::getCppuType( (const Reference< XResultSetMetaDataSupplier > *)0 ), 87 ::getCppuType( (const Reference< XColumnsSupplier > *)0 ), 88 OStatementBase::getTypes() ); 89 90 return aTypes.getTypes(); 91 } 92 93 //-------------------------------------------------------------------------- 94 Sequence< sal_Int8 > OPreparedStatement::getImplementationId() throw (RuntimeException) 95 { 96 static OImplementationId * pId = 0; 97 if (! pId) 98 { 99 MutexGuard aGuard( Mutex::getGlobalMutex() ); 100 if (! pId) 101 { 102 static OImplementationId aId; 103 pId = &aId; 104 } 105 } 106 return pId->getImplementationId(); 107 } 108 109 // com::sun::star::uno::XInterface 110 //-------------------------------------------------------------------------- 111 Any OPreparedStatement::queryInterface( const Type & rType ) throw (RuntimeException) 112 { 113 Any aIface = OStatementBase::queryInterface( rType ); 114 if (!aIface.hasValue()) 115 aIface = ::cppu::queryInterface( 116 rType, 117 static_cast< XServiceInfo * >( this ), 118 static_cast< XParameters * >( this ), 119 static_cast< XColumnsSupplier * >( this ), 120 static_cast< XResultSetMetaDataSupplier * >( this ), 121 static_cast< XPreparedBatchExecution * >( this ), 122 static_cast< XMultipleResults * >( this ), 123 static_cast< XPreparedStatement * >( this )); 124 return aIface; 125 } 126 127 //-------------------------------------------------------------------------- 128 void OPreparedStatement::acquire() throw () 129 { 130 OStatementBase::acquire(); 131 } 132 133 //-------------------------------------------------------------------------- 134 void OPreparedStatement::release() throw () 135 { 136 OStatementBase::release(); 137 } 138 139 // XServiceInfo 140 //------------------------------------------------------------------------------ 141 rtl::OUString OPreparedStatement::getImplementationName( ) throw(RuntimeException) 142 { 143 return rtl::OUString::createFromAscii("com.sun.star.sdb.OPreparedStatement"); 144 } 145 146 //------------------------------------------------------------------------------ 147 sal_Bool OPreparedStatement::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 148 { 149 return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0; 150 } 151 152 //------------------------------------------------------------------------------ 153 Sequence< ::rtl::OUString > OPreparedStatement::getSupportedServiceNames( ) throw (RuntimeException) 154 { 155 Sequence< ::rtl::OUString > aSNS( 2 ); 156 aSNS.getArray()[0] = SERVICE_SDBC_PREPAREDSTATEMENT; 157 aSNS.getArray()[1] = SERVICE_SDB_PREPAREDSTATMENT; 158 return aSNS; 159 } 160 161 // OComponentHelper 162 //------------------------------------------------------------------------------ 163 void OPreparedStatement::disposing() 164 { 165 { 166 MutexGuard aGuard(m_aMutex); 167 m_pColumns->disposing(); 168 m_xAggregateAsParameters = NULL; 169 } 170 OStatementBase::disposing(); 171 } 172 173 // ::com::sun::star::sdbcx::XColumnsSupplier 174 //------------------------------------------------------------------------------ 175 Reference< ::com::sun::star::container::XNameAccess > OPreparedStatement::getColumns(void) throw( RuntimeException ) 176 { 177 MutexGuard aGuard(m_aMutex); 178 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 179 180 // do we have to populate the columns 181 if (!m_pColumns->isInitialized()) 182 { 183 try 184 { 185 Reference< XResultSetMetaDataSupplier > xSuppMeta( m_xAggregateAsSet, UNO_QUERY_THROW ); 186 Reference< XResultSetMetaData > xMetaData( xSuppMeta->getMetaData(), UNO_SET_THROW ); 187 188 Reference< XConnection > xConn( getConnection(), UNO_SET_THROW ); 189 Reference< XDatabaseMetaData > xDBMeta( xConn->getMetaData(), UNO_SET_THROW ); 190 191 for (sal_Int32 i = 0, nCount = xMetaData->getColumnCount(); i < nCount; ++i) 192 { 193 // retrieve the name of the column 194 rtl::OUString aName = xMetaData->getColumnName(i + 1); 195 OResultColumn* pColumn = new OResultColumn(xMetaData, i + 1, xDBMeta); 196 m_pColumns->append(aName, pColumn); 197 } 198 } 199 catch (const SQLException& ) 200 { 201 DBG_UNHANDLED_EXCEPTION(); 202 } 203 m_pColumns->setInitialized(); 204 } 205 return m_pColumns; 206 } 207 208 // XResultSetMetaDataSupplier 209 //------------------------------------------------------------------------------ 210 Reference< XResultSetMetaData > OPreparedStatement::getMetaData(void) throw( SQLException, RuntimeException ) 211 { 212 MutexGuard aGuard(m_aMutex); 213 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 214 return Reference< XResultSetMetaDataSupplier >( m_xAggregateAsSet, UNO_QUERY_THROW )->getMetaData(); 215 } 216 217 // XPreparedStatement 218 //------------------------------------------------------------------------------ 219 Reference< XResultSet > OPreparedStatement::executeQuery() throw( SQLException, RuntimeException ) 220 { 221 MutexGuard aGuard(m_aMutex); 222 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 223 224 disposeResultSet(); 225 226 Reference< XResultSet > xResultSet; 227 Reference< XResultSet > xDrvResultSet = Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->executeQuery(); 228 if (xDrvResultSet.is()) 229 { 230 xResultSet = new OResultSet(xDrvResultSet, *this, m_pColumns->isCaseSensitive()); 231 232 // keep the resultset weak 233 m_aResultSet = xResultSet; 234 } 235 return xResultSet; 236 } 237 238 //------------------------------------------------------------------------------ 239 sal_Int32 OPreparedStatement::executeUpdate() throw( SQLException, RuntimeException ) 240 { 241 MutexGuard aGuard(m_aMutex); 242 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 243 244 disposeResultSet(); 245 246 return Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->executeUpdate(); 247 } 248 249 //------------------------------------------------------------------------------ 250 sal_Bool OPreparedStatement::execute() throw( SQLException, RuntimeException ) 251 { 252 MutexGuard aGuard(m_aMutex); 253 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 254 255 disposeResultSet(); 256 257 return Reference< XPreparedStatement >( m_xAggregateAsSet, UNO_QUERY_THROW )->execute(); 258 } 259 260 //------------------------------------------------------------------------------ 261 Reference< XConnection > OPreparedStatement::getConnection(void) throw( SQLException, RuntimeException ) 262 { 263 return Reference< XConnection > (m_xParent, UNO_QUERY); 264 } 265 266 // XParameters 267 //------------------------------------------------------------------------------ 268 void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) throw(SQLException, RuntimeException) 269 { 270 MutexGuard aGuard(m_aMutex); 271 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 272 273 m_xAggregateAsParameters->setNull(parameterIndex, sqlType); 274 } 275 276 //------------------------------------------------------------------------------ 277 void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName ) throw(SQLException, RuntimeException) 278 { 279 MutexGuard aGuard(m_aMutex); 280 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 281 282 m_xAggregateAsParameters->setObjectNull(parameterIndex, sqlType, typeName); 283 } 284 285 //------------------------------------------------------------------------------ 286 void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException) 287 { 288 MutexGuard aGuard(m_aMutex); 289 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 290 291 m_xAggregateAsParameters->setBoolean(parameterIndex, x); 292 } 293 294 //------------------------------------------------------------------------------ 295 void SAL_CALL OPreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException) 296 { 297 MutexGuard aGuard(m_aMutex); 298 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 299 300 m_xAggregateAsParameters->setByte(parameterIndex, x); 301 } 302 303 //------------------------------------------------------------------------------ 304 void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException) 305 { 306 MutexGuard aGuard(m_aMutex); 307 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 308 309 m_xAggregateAsParameters->setShort(parameterIndex, x); 310 } 311 312 //------------------------------------------------------------------------------ 313 void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException) 314 { 315 MutexGuard aGuard(m_aMutex); 316 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 317 318 m_xAggregateAsParameters->setInt(parameterIndex, x); 319 } 320 321 //------------------------------------------------------------------------------ 322 void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException) 323 { 324 MutexGuard aGuard(m_aMutex); 325 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 326 327 m_xAggregateAsParameters->setLong(parameterIndex, x); 328 } 329 330 //------------------------------------------------------------------------------ 331 void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException) 332 { 333 MutexGuard aGuard(m_aMutex); 334 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 335 336 m_xAggregateAsParameters->setFloat(parameterIndex, x); 337 } 338 339 //------------------------------------------------------------------------------ 340 void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException) 341 { 342 MutexGuard aGuard(m_aMutex); 343 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 344 345 m_xAggregateAsParameters->setDouble(parameterIndex, x); 346 } 347 348 //------------------------------------------------------------------------------ 349 void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException) 350 { 351 MutexGuard aGuard(m_aMutex); 352 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 353 354 m_xAggregateAsParameters->setString(parameterIndex, x); 355 } 356 357 //------------------------------------------------------------------------------ 358 void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException) 359 { 360 MutexGuard aGuard(m_aMutex); 361 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 362 363 m_xAggregateAsParameters->setBytes(parameterIndex, x); 364 } 365 366 //------------------------------------------------------------------------------ 367 void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x ) throw(SQLException, RuntimeException) 368 { 369 MutexGuard aGuard(m_aMutex); 370 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 371 372 m_xAggregateAsParameters->setDate(parameterIndex, x); 373 } 374 375 //------------------------------------------------------------------------------ 376 void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x ) throw(SQLException, RuntimeException) 377 { 378 MutexGuard aGuard(m_aMutex); 379 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 380 381 m_xAggregateAsParameters->setTime(parameterIndex, x); 382 } 383 384 //------------------------------------------------------------------------------ 385 void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x ) throw(SQLException, RuntimeException) 386 { 387 MutexGuard aGuard(m_aMutex); 388 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 389 390 m_xAggregateAsParameters->setTimestamp(parameterIndex, x); 391 } 392 393 //------------------------------------------------------------------------------ 394 void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 395 { 396 MutexGuard aGuard(m_aMutex); 397 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 398 399 m_xAggregateAsParameters->setBinaryStream(parameterIndex, x, length); 400 } 401 402 //------------------------------------------------------------------------------ 403 void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException) 404 { 405 MutexGuard aGuard(m_aMutex); 406 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 407 408 m_xAggregateAsParameters->setCharacterStream(parameterIndex, x, length); 409 } 410 411 //------------------------------------------------------------------------------ 412 void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException) 413 { 414 MutexGuard aGuard(m_aMutex); 415 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 416 417 m_xAggregateAsParameters->setObject(parameterIndex, x); 418 } 419 420 //------------------------------------------------------------------------------ 421 void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 scale ) throw(SQLException, RuntimeException) 422 { 423 MutexGuard aGuard(m_aMutex); 424 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 425 426 m_xAggregateAsParameters->setObjectWithInfo(parameterIndex, x, targetSqlType, scale); 427 } 428 429 //------------------------------------------------------------------------------ 430 void SAL_CALL OPreparedStatement::setRef( sal_Int32 parameterIndex, const Reference< XRef >& x ) throw(SQLException, RuntimeException) 431 { 432 MutexGuard aGuard(m_aMutex); 433 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 434 435 m_xAggregateAsParameters->setRef(parameterIndex, x); 436 } 437 438 //------------------------------------------------------------------------------ 439 void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException) 440 { 441 MutexGuard aGuard(m_aMutex); 442 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 443 444 m_xAggregateAsParameters->setBlob(parameterIndex, x); 445 } 446 447 //------------------------------------------------------------------------------ 448 void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException) 449 { 450 MutexGuard aGuard(m_aMutex); 451 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 452 453 m_xAggregateAsParameters->setClob(parameterIndex, x); 454 } 455 456 //------------------------------------------------------------------------------ 457 void SAL_CALL OPreparedStatement::setArray( sal_Int32 parameterIndex, const Reference< XArray >& x ) throw(SQLException, RuntimeException) 458 { 459 MutexGuard aGuard(m_aMutex); 460 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 461 462 m_xAggregateAsParameters->setArray(parameterIndex, x); 463 } 464 465 //------------------------------------------------------------------------------ 466 void SAL_CALL OPreparedStatement::clearParameters( ) throw(SQLException, RuntimeException) 467 { 468 MutexGuard aGuard(m_aMutex); 469 ::connectivity::checkDisposed(OComponentHelper::rBHelper.bDisposed); 470 471 m_xAggregateAsParameters->clearParameters(); 472 } 473 474