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