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_connectivity.hxx" 30 31 #include <stdio.h> 32 #include <osl/diagnose.h> 33 #include <osl/thread.h> 34 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp> 35 #include <com/sun/star/sdbc/ResultSetType.hpp> 36 #include <com/sun/star/sdbc/FetchDirection.hpp> 37 #include <com/sun/star/lang/DisposedException.hpp> 38 #include <cppuhelper/typeprovider.hxx> 39 #include "propertyids.hxx" 40 #include "NStatement.hxx" 41 #include "NConnection.hxx" 42 #include "NDatabaseMetaData.hxx" 43 #include "NResultSet.hxx" 44 #include "NDebug.hxx" 45 #include "resource/evoab2_res.hrc" 46 #include <resource/common_res.hrc> 47 #include <connectivity/dbexception.hxx> 48 #include <tools/diagnose_ex.h> 49 50 namespace connectivity { namespace evoab { 51 52 //------------------------------------------------------------------------------ 53 using namespace com::sun::star::uno; 54 using namespace com::sun::star::lang; 55 using namespace com::sun::star::beans; 56 using namespace com::sun::star::sdbc; 57 using namespace com::sun::star::sdbcx; 58 using namespace com::sun::star::container; 59 using namespace com::sun::star::io; 60 using namespace com::sun::star::util; 61 //------------------------------------------------------------------------------ 62 OCommonStatement::OCommonStatement(OEvoabConnection* _pConnection) 63 : OCommonStatement_IBase(m_aMutex) 64 , ::comphelper::OPropertyContainer(OCommonStatement_IBase::rBHelper) 65 , OStatement_CBase( (::cppu::OWeakObject*)_pConnection, this ) 66 , m_xResultSet(NULL) 67 , m_pResultSet(NULL) 68 , m_pConnection(_pConnection) 69 , m_aParser(_pConnection->getDriver().getMSFactory()) 70 , m_aSQLIterator( _pConnection, _pConnection->createCatalog()->getTables(), m_aParser, NULL ) 71 , m_pParseTree(NULL) 72 , m_nMaxFieldSize(0) 73 , m_nMaxRows(0) 74 , m_nQueryTimeOut(0) 75 , m_nFetchSize(0) 76 , m_nResultSetType(ResultSetType::FORWARD_ONLY) 77 , m_nFetchDirection(FetchDirection::FORWARD) 78 , m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE) 79 , m_bEscapeProcessing(sal_True) 80 , rBHelper(OCommonStatement_IBase::rBHelper) 81 { 82 m_pConnection->acquire(); 83 84 #define REGISTER_PROP( id, member ) \ 85 registerProperty( \ 86 OMetaConnection::getPropMap().getNameByIndex( id ), \ 87 id, \ 88 0, \ 89 &member, \ 90 ::getCppuType( &member ) \ 91 ); 92 93 REGISTER_PROP( PROPERTY_ID_CURSORNAME, m_aCursorName ); 94 REGISTER_PROP( PROPERTY_ID_MAXFIELDSIZE, m_nMaxFieldSize ); 95 REGISTER_PROP( PROPERTY_ID_MAXROWS, m_nMaxRows ); 96 REGISTER_PROP( PROPERTY_ID_QUERYTIMEOUT, m_nQueryTimeOut ); 97 REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize ); 98 REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType ); 99 REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection ); 100 REGISTER_PROP( PROPERTY_ID_ESCAPEPROCESSING, m_bEscapeProcessing ); 101 REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency ); 102 } 103 // ----------------------------------------------------------------------------- 104 OCommonStatement::~OCommonStatement() 105 { 106 } 107 //------------------------------------------------------------------------------ 108 void OCommonStatement::disposeResultSet() 109 { 110 // free the cursor if alive 111 Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY); 112 if (xComp.is()) 113 xComp->dispose(); 114 m_xResultSet = Reference< XResultSet>(); 115 } 116 //------------------------------------------------------------------------------ 117 void OCommonStatement::disposing() 118 { 119 ::osl::MutexGuard aGuard(m_aMutex); 120 121 disposeResultSet(); 122 123 if (m_pConnection) 124 m_pConnection->release(); 125 m_pConnection = NULL; 126 127 dispose_ChildImpl(); 128 OCommonStatement_IBase::disposing(); 129 } 130 //----------------------------------------------------------------------------- 131 Any SAL_CALL OCommonStatement::queryInterface( const Type & rType ) throw(RuntimeException) 132 { 133 Any aRet = OCommonStatement_IBase::queryInterface(rType); 134 if(!aRet.hasValue()) 135 aRet = ::comphelper::OPropertyContainer::queryInterface(rType); 136 return aRet; 137 } 138 // ------------------------------------------------------------------------- 139 Sequence< Type > SAL_CALL OCommonStatement::getTypes( ) throw(RuntimeException) 140 { 141 ::cppu::OTypeCollection aTypes( ::getCppuType( (const Reference< XMultiPropertySet > *)0 ), 142 ::getCppuType( (const Reference< XFastPropertySet > *)0 ), 143 ::getCppuType( (const Reference< XPropertySet > *)0 )); 144 145 return ::comphelper::concatSequences(aTypes.getTypes(),OCommonStatement_IBase::getTypes()); 146 } 147 // ------------------------------------------------------------------------- 148 149 //void SAL_CALL OCommonStatement::cancel( ) throw(RuntimeException) 150 //{ 151 //::osl::MutexGuard aGuard( m_aMutex ); 152 //checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 153 //// cancel the current sql statement 154 //} 155 156 // ------------------------------------------------------------------------- 157 void SAL_CALL OCommonStatement::close( ) throw(SQLException, RuntimeException) 158 { 159 { 160 ::osl::MutexGuard aGuard( m_aMutex ); 161 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 162 163 } 164 dispose(); 165 } 166 // ------------------------------------------------------------------------- 167 168 void OCommonStatement::reset() throw (SQLException) 169 { 170 ::osl::MutexGuard aGuard( m_aMutex ); 171 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 172 173 174 clearWarnings (); 175 176 if (m_xResultSet.get().is()) 177 clearMyResultSet(); 178 } 179 180 void OCommonStatement::clearMyResultSet () throw (SQLException) 181 { 182 ::osl::MutexGuard aGuard( m_aMutex ); 183 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 184 185 try 186 { 187 Reference<XCloseable> xCloseable; 188 if ( ::comphelper::query_interface( m_xResultSet.get(), xCloseable ) ) 189 xCloseable->close(); 190 } 191 catch( const DisposedException& ) { } 192 193 m_xResultSet = Reference< XResultSet >(); 194 } 195 196 EBookQuery * 197 OCommonStatement::createTrue() 198 { // Not the world's most efficient unconditional true but ... 199 return e_book_query_from_string("(exists \"full_name\")"); 200 } 201 202 EBookQuery * 203 OCommonStatement::createTest( const ::rtl::OUString &aColumnName, 204 EBookQueryTest eTest, 205 const ::rtl::OUString &aMatch ) 206 { 207 ::rtl::OString sMatch = rtl::OUStringToOString( aMatch, RTL_TEXTENCODING_UTF8 ); 208 ::rtl::OString sColumnName = rtl::OUStringToOString( aColumnName, RTL_TEXTENCODING_UTF8 ); 209 210 return e_book_query_field_test( e_contact_field_id( sColumnName ), 211 eTest, sMatch ); 212 } 213 214 // ------------------------------------------------------------------------- 215 216 ::rtl::OUString OCommonStatement::impl_getColumnRefColumnName_throw( const OSQLParseNode& _rColumnRef ) 217 { 218 ENSURE_OR_THROW( SQL_ISRULE( &_rColumnRef, column_ref ), "internal error: only column_refs supported as LHS" ); 219 220 ::rtl::OUString sColumnName; 221 switch ( _rColumnRef.count() ) 222 { 223 case 3: // SQL_TOKEN_NAME '.' column_val 224 { 225 const OSQLParseNode* pPunct = _rColumnRef.getChild( 1 ); 226 const OSQLParseNode* pColVal = _rColumnRef.getChild( 2 ); 227 if ( SQL_ISPUNCTUATION( pPunct, "." ) 228 && ( pColVal->count() == 1 ) 229 ) 230 { 231 sColumnName = pColVal->getChild( 0 )->getTokenValue(); 232 } 233 } 234 break; 235 236 case 1: // column 237 { 238 sColumnName = _rColumnRef.getChild( 0 )->getTokenValue(); 239 } 240 break; 241 } 242 243 if ( !sColumnName.getLength() ) 244 m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this ); 245 246 return sColumnName; 247 } 248 249 // ------------------------------------------------------------------------- 250 void OCommonStatement::orderByAnalysis( const OSQLParseNode* _pOrderByClause, SortDescriptor& _out_rSort ) 251 { 252 ENSURE_OR_THROW( _pOrderByClause, "NULL node" ); 253 ENSURE_OR_THROW( SQL_ISRULE( _pOrderByClause, opt_order_by_clause ), "wrong node type" ); 254 255 _out_rSort.clear(); 256 257 const OSQLParseNode* pOrderList = _pOrderByClause->getByRule( OSQLParseNode::ordering_spec_commalist ); 258 ENSURE_OR_THROW( pOrderList, "unexpected parse tree structure" ); 259 260 for ( sal_uInt32 i=0; i<pOrderList->count(); ++i ) 261 { 262 const OSQLParseNode* pOrderBy = pOrderList->getChild(i); 263 if ( !pOrderBy || !SQL_ISRULE( pOrderBy, ordering_spec ) ) 264 continue; 265 const OSQLParseNode* pColumnRef = pOrderBy->count() == 2 ? pOrderBy->getChild(0) : NULL; 266 const OSQLParseNode* pAscDesc = pOrderBy->count() == 2 ? pOrderBy->getChild(1) : NULL; 267 ENSURE_OR_THROW( 268 ( pColumnRef != NULL ) 269 && ( pAscDesc != NULL ) 270 && SQL_ISRULE( pAscDesc, opt_asc_desc ) 271 && ( pAscDesc->count() < 2 ), 272 "ordering_spec structure error" ); 273 274 // column name -> column field 275 if ( !SQL_ISRULE( pColumnRef, column_ref ) ) 276 m_pConnection->throwGenericSQLException( STR_SORT_BY_COL_ONLY, *this ); 277 const ::rtl::OUString sColumnName( impl_getColumnRefColumnName_throw( *pColumnRef ) ); 278 guint nField = evoab::findEvoabField( sColumnName ); 279 // ascending/descending? 280 bool bAscending = true; 281 if ( ( pAscDesc->count() == 1 ) 282 && SQL_ISTOKEN( pAscDesc->getChild( 0 ), DESC ) 283 ) 284 bAscending = false; 285 286 _out_rSort.push_back( FieldSort( nField, bAscending ) ); 287 } 288 } 289 290 // ------------------------------------------------------------------------- 291 EBookQuery *OCommonStatement::whereAnalysis( const OSQLParseNode* parseTree ) 292 { 293 EBookQuery *pResult = NULL; 294 295 ENSURE_OR_THROW( parseTree, "invalid parse tree" ); 296 297 // Nested brackets 298 if( parseTree->count() == 3 && 299 SQL_ISPUNCTUATION( parseTree->getChild( 0 ), "(" ) && 300 SQL_ISPUNCTUATION( parseTree->getChild( 2 ), ")" ) ) 301 { 302 pResult = whereAnalysis( parseTree->getChild( 1 ) ); 303 } 304 305 // SQL AND, OR 306 else if( ( SQL_ISRULE( parseTree, search_condition ) || 307 SQL_ISRULE( parseTree, boolean_term ) ) && 308 parseTree->count() == 3 ) 309 { 310 ENSURE_OR_THROW( SQL_ISTOKEN( parseTree->getChild( 1 ), OR ) 311 || SQL_ISTOKEN( parseTree->getChild( 1 ), AND ), 312 "unexpected search_condition structure" ); 313 314 EBookQuery *pArgs[2]; 315 pArgs[0] = whereAnalysis( parseTree->getChild( 0 ) ); 316 pArgs[1] = whereAnalysis( parseTree->getChild( 2 ) ); 317 318 if( SQL_ISTOKEN( parseTree->getChild( 1 ), OR ) ) 319 pResult = e_book_query_or( 2, pArgs, TRUE ); 320 else 321 pResult = e_book_query_and( 2, pArgs, TRUE ); 322 } 323 // SQL =, != 324 else if( SQL_ISRULE( parseTree, comparison_predicate ) ) 325 { 326 OSQLParseNode *pPrec = parseTree->getChild( 1 ); 327 328 ENSURE_OR_THROW( parseTree->count() == 3, "unexpected comparison_predicate structure" ); 329 330 OSQLParseNode* pLHS = parseTree->getChild( 0 ); 331 OSQLParseNode* pRHS = parseTree->getChild( 2 ); 332 333 if ( ( !( SQL_ISRULE( pLHS, column_ref ) ) // on the LHS, we accept a column or a constant int value 334 && ( pLHS->getNodeType() != SQL_NODE_INTNUM ) 335 ) 336 || ( ( pRHS->getNodeType() != SQL_NODE_STRING ) // on the RHS, certain literals are acceptable 337 && ( pRHS->getNodeType() != SQL_NODE_INTNUM ) 338 && ( pRHS->getNodeType() != SQL_NODE_APPROXNUM ) 339 && !( SQL_ISTOKEN( pRHS, TRUE ) ) 340 && !( SQL_ISTOKEN( pRHS, FALSE ) ) 341 ) 342 || ( ( pLHS->getNodeType() == SQL_NODE_INTNUM ) // an int on LHS requires an int on RHS 343 && ( pRHS->getNodeType() != SQL_NODE_INTNUM ) 344 ) 345 ) 346 { 347 m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this ); 348 } 349 350 if ( ( pPrec->getNodeType() != SQL_NODE_EQUAL ) 351 && ( pPrec->getNodeType() != SQL_NODE_NOTEQUAL ) 352 ) 353 { 354 m_pConnection->throwGenericSQLException( STR_OPERATOR_TOO_COMPLEX, *this ); 355 } 356 357 // recognize the special "0 = 1" condition 358 if ( ( pLHS->getNodeType() == SQL_NODE_INTNUM ) 359 && ( pRHS->getNodeType() == SQL_NODE_INTNUM ) 360 && ( pPrec->getNodeType() == SQL_NODE_EQUAL ) 361 ) 362 { 363 const sal_Int32 nLHS = pLHS->getTokenValue().toInt64(); 364 const sal_Int32 nRHS = pRHS->getTokenValue().toInt64(); 365 return ( nLHS == nRHS ) ? createTrue() : NULL; 366 } 367 368 ::rtl::OUString aColumnName( impl_getColumnRefColumnName_throw( *pLHS ) ); 369 370 ::rtl::OUString aMatchString; 371 if ( pRHS->isToken() ) 372 aMatchString = pRHS->getTokenValue(); 373 else 374 aMatchString = pRHS->getChild( 0 )->getTokenValue(); 375 376 pResult = createTest( aColumnName, E_BOOK_QUERY_IS, aMatchString ); 377 378 if ( pResult && ( pPrec->getNodeType() == SQL_NODE_NOTEQUAL ) ) 379 pResult = e_book_query_not( pResult, TRUE ); 380 } 381 // SQL like 382 else if( SQL_ISRULE( parseTree, like_predicate ) ) 383 { 384 ENSURE_OR_THROW( parseTree->count() == 2, "unexpected like_predicate structure" ); 385 const OSQLParseNode* pPart2 = parseTree->getChild(1); 386 387 if( ! SQL_ISRULE( parseTree->getChild( 0 ), column_ref) ) 388 m_pConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_COLUMN,*this); 389 390 ::rtl::OUString aColumnName( impl_getColumnRefColumnName_throw( *parseTree->getChild( 0 ) ) ); 391 392 OSQLParseNode *pAtom = pPart2->getChild( pPart2->count() - 2 ); // Match String 393 bool bNotLike = pPart2->getChild(0)->isToken(); 394 395 if( !( pAtom->getNodeType() == SQL_NODE_STRING || 396 pAtom->getNodeType() == SQL_NODE_NAME || 397 SQL_ISRULE( pAtom,parameter ) || 398 ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQL_NODE_NAME ) || 399 ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQL_NODE_STRING ) ) ) 400 { 401 OSL_TRACE( "analyseSQL : pAtom->count() = %d\n", pAtom->count() ); 402 m_pConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,*this); 403 } 404 405 const sal_Unicode WILDCARD = '%'; 406 407 rtl::OUString aMatchString; 408 aMatchString = pAtom->getTokenValue(); 409 410 // Determine where '%' character is... 411 if( aMatchString.equals( ::rtl::OUString::valueOf( WILDCARD ) ) ) 412 { 413 // String containing only a '%' and nothing else matches everything 414 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, 415 rtl::OUString::createFromAscii( "" ) ); 416 } 417 else if( aMatchString.indexOf( WILDCARD ) == -1 ) 418 { // Simple string , eg. "to match" "contains in evo" 419 EVO_TRACE_STRING( "Plain contains '%s'", aMatchString ); 420 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString ); 421 if( pResult && bNotLike ) 422 pResult = e_book_query_not( pResult, TRUE ); 423 } 424 else if( bNotLike ) 425 { 426 // We currently can't handle a 'NOT LIKE' when there are '%' 427 m_pConnection->throwGenericSQLException(STR_QUERY_NOT_LIKE_TOO_COMPLEX,*this); 428 } 429 else if( (aMatchString.indexOf ( WILDCARD ) == aMatchString.lastIndexOf ( WILDCARD ) ) ) 430 { // One occurance of '%' matches... 431 if ( aMatchString.indexOf ( WILDCARD ) == 0 ) 432 pResult = createTest( aColumnName, E_BOOK_QUERY_ENDS_WITH, aMatchString.copy( 1 ) ); 433 else if ( aMatchString.indexOf ( WILDCARD ) == aMatchString.getLength() - 1 ) 434 pResult = createTest( aColumnName, E_BOOK_QUERY_BEGINS_WITH, aMatchString.copy( 0, aMatchString.getLength() - 1 ) ); 435 else 436 m_pConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD,*this); 437 438 if( pResult && bNotLike ) 439 pResult = e_book_query_not( pResult, TRUE ); 440 } 441 else if( aMatchString.getLength() >= 3 && 442 aMatchString.indexOf ( WILDCARD ) == 0 && 443 aMatchString.indexOf ( WILDCARD, 1) == aMatchString.getLength() - 1 ) { 444 // one '%' at the start and another at the end 445 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString.copy (1, aMatchString.getLength() - 2) ); 446 } 447 else 448 m_pConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD_MANY,*this); 449 } 450 451 return pResult; 452 } 453 454 rtl::OUString OCommonStatement::getTableName() 455 { 456 ::rtl::OUString aTableName; 457 458 if( m_pParseTree && m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT ) 459 { 460 Any aCatalog; 461 ::rtl::OUString aSchema, aComposedName; 462 const OSQLParseNode *pSelectStmnt = m_aSQLIterator.getParseTree(); 463 const OSQLParseNode *pAllTableNames = pSelectStmnt->getChild( 3 )->getChild( 0 )->getChild( 1 ); 464 465 if( m_aSQLIterator.isTableNode( pAllTableNames->getChild( 0 ) ) ) 466 OSQLParseNode::getTableComponents( pAllTableNames->getChild( 0 ), 467 aCatalog,aSchema, aTableName,NULL ); 468 469 else if( SQL_ISRULE( pAllTableNames->getChild( 0 ), table_ref ) ) 470 { 471 OSQLParseNode *pNodeForTableName = pAllTableNames->getChild( 0 )->getChild( 0 ); 472 if( m_aSQLIterator.isTableNode( pNodeForTableName ) ) 473 { 474 aTableName = OSQLParseNode::getTableRange(pAllTableNames->getChild( 0 )); 475 if( !aTableName.getLength() ) 476 OSQLParseNode::getTableComponents( pNodeForTableName, aCatalog, aSchema, aTableName,NULL); 477 } 478 else 479 OSL_ENSURE( false, "odd table layout" ); 480 } 481 else 482 OSL_ENSURE( false, "unusual table layout" ); 483 } 484 return aTableName; 485 } 486 487 void OCommonStatement::parseSql( const rtl::OUString& sql, QueryData& _out_rQueryData ) 488 { 489 EVO_TRACE_STRING( "parsing %s", sql ); 490 491 _out_rQueryData.eFilterType = eFilterOther; 492 493 ::rtl::OUString aErr; 494 m_pParseTree = m_aParser.parseTree( aErr, sql ); 495 m_aSQLIterator.setParseTree( m_pParseTree ); 496 m_aSQLIterator.traverseAll(); 497 498 _out_rQueryData.sTable = getTableName(); 499 500 // to be sorted? 501 const OSQLParseNode* pOrderByClause = m_aSQLIterator.getOrderTree(); 502 if ( pOrderByClause ) 503 { 504 #if OSL_DEBUG_LEVEL > 0 505 ::rtl::OUString sTreeDebug; 506 pOrderByClause->showParseTree( sTreeDebug ); 507 EVO_TRACE_STRING( "found order-by tree:\n%s", sTreeDebug ); 508 #endif 509 orderByAnalysis( pOrderByClause, _out_rQueryData.aSortOrder ); 510 } 511 512 const OSQLParseNode* pWhereClause = m_aSQLIterator.getWhereTree(); 513 if ( pWhereClause && SQL_ISRULE( pWhereClause, where_clause ) ) 514 { 515 #if OSL_DEBUG_LEVEL > 0 516 ::rtl::OUString sTreeDebug; 517 pWhereClause->showParseTree( sTreeDebug ); 518 EVO_TRACE_STRING( "found where tree:\n%s", sTreeDebug ); 519 #endif 520 EBookQuery* pQuery = whereAnalysis( pWhereClause->getChild( 1 ) ); 521 if ( !pQuery ) 522 { 523 _out_rQueryData.eFilterType = eFilterAlwaysFalse; 524 pQuery = createTrue(); 525 } 526 _out_rQueryData.setQuery( pQuery ); 527 } 528 else 529 { 530 _out_rQueryData.eFilterType = eFilterNone; 531 _out_rQueryData.setQuery( createTrue() ); 532 } 533 } 534 535 // ------------------------------------------------------------------------- 536 537 Reference< XConnection > SAL_CALL OStatement::getConnection( ) throw(SQLException, RuntimeException) 538 { 539 ::osl::MutexGuard aGuard( m_aMutex ); 540 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 541 542 // just return our connection here 543 return impl_getConnection(); 544 } 545 546 // ------------------------------------------------------------------------- 547 Any SAL_CALL OCommonStatement::getWarnings( ) throw(SQLException, RuntimeException) 548 { 549 ::osl::MutexGuard aGuard( m_aMutex ); 550 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 551 552 553 return makeAny(SQLWarning()); 554 } 555 556 // ------------------------------------------------------------------------- 557 void SAL_CALL OCommonStatement::clearWarnings( ) throw(SQLException, RuntimeException) 558 { 559 ::osl::MutexGuard aGuard( m_aMutex ); 560 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 561 562 } 563 // ------------------------------------------------------------------------- 564 ::cppu::IPropertyArrayHelper* OCommonStatement::createArrayHelper( ) const 565 { 566 Sequence< Property > aProps; 567 describeProperties( aProps ); 568 return new ::cppu::OPropertyArrayHelper( aProps ); 569 } 570 // ------------------------------------------------------------------------- 571 ::cppu::IPropertyArrayHelper & OCommonStatement::getInfoHelper() 572 { 573 return *const_cast< OCommonStatement* >( this )->getArrayHelper(); 574 } 575 576 // ----------------------------------------------------------------------------- 577 void SAL_CALL OCommonStatement::acquire() throw() 578 { 579 OCommonStatement_IBase::acquire(); 580 } 581 // ----------------------------------------------------------------------------- 582 void SAL_CALL OCommonStatement::release() throw() 583 { 584 relase_ChildImpl(); 585 } 586 587 // ------------------------------------------------------------------------- 588 QueryData OCommonStatement::impl_getEBookQuery_throw( const ::rtl::OUString& _rSql ) 589 { 590 QueryData aData; 591 parseSql( _rSql, aData ); 592 593 #ifdef DEBUG 594 char *pSexpr = aData.getQuery() ? e_book_query_to_string( aData.getQuery() ) : g_strdup( "<map failed>" ); 595 g_message( "Parsed SQL to sexpr '%s'\n", pSexpr ); 596 g_free( pSexpr ); 597 #endif 598 599 if ( !aData.getQuery() ) 600 m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this ); 601 602 // a postcondition of this method is that we properly determined the SELECT columns 603 aData.xSelectColumns = m_aSQLIterator.getSelectColumns(); 604 if ( !aData.xSelectColumns.isValid() ) 605 m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this ); 606 607 return aData; 608 } 609 610 // ------------------------------------------------------------------------- 611 Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const QueryData& _rQueryData ) 612 { 613 // create result set 614 OEvoabResultSet* pResult = new OEvoabResultSet( this, m_pConnection ); 615 Reference< XResultSet > xRS = pResult; 616 pResult->construct( _rQueryData ); 617 618 // done 619 m_xResultSet = xRS; 620 return xRS; 621 } 622 623 // ------------------------------------------------------------------------- 624 Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const ::rtl::OUString& _rSql ) 625 { 626 EVO_TRACE_STRING( "OCommonStatement::impl_executeQuery_throw(%s)\n", _rSql ); 627 628 #ifdef DEBUG 629 g_message( "Parse SQL '%s'\n", 630 (const sal_Char *)OUStringToOString( _rSql, RTL_TEXTENCODING_UTF8 ) ); 631 #endif 632 633 return impl_executeQuery_throw( impl_getEBookQuery_throw( _rSql ) ); 634 } 635 636 // ----------------------------------------------------------------------------- 637 Reference< XPropertySetInfo > SAL_CALL OCommonStatement::getPropertySetInfo( ) throw(RuntimeException) 638 { 639 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() ); 640 } 641 642 // ============================================================================= 643 // = OStatement 644 // ============================================================================= 645 // ----------------------------------------------------------------------------- 646 IMPLEMENT_SERVICE_INFO( OStatement, "com.sun.star.comp.sdbcx.evoab.OStatement", "com.sun.star.sdbc.Statement" ); 647 648 // ----------------------------------------------------------------------------- 649 IMPLEMENT_FORWARD_XINTERFACE2( OStatement, OCommonStatement, OStatement_IBase ) 650 651 // ----------------------------------------------------------------------------- 652 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement, OCommonStatement, OStatement_IBase ) 653 654 // ------------------------------------------------------------------------- 655 sal_Bool SAL_CALL OStatement::execute( const ::rtl::OUString& _sql ) throw(SQLException, RuntimeException) 656 { 657 ::osl::MutexGuard aGuard( m_aMutex ); 658 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 659 660 Reference< XResultSet > xRS = impl_executeQuery_throw( _sql ); 661 return xRS.is(); 662 } 663 664 // ------------------------------------------------------------------------- 665 Reference< XResultSet > SAL_CALL OStatement::executeQuery( const ::rtl::OUString& _sql ) throw(SQLException, RuntimeException) 666 { 667 ::osl::MutexGuard aGuard( m_aMutex ); 668 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 669 670 return impl_executeQuery_throw( _sql ); 671 } 672 673 // ----------------------------------------------------------------------------- 674 sal_Int32 SAL_CALL OStatement::executeUpdate( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException) 675 { 676 ::osl::MutexGuard aGuard( m_aMutex ); 677 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed); 678 ::dbtools::throwFeatureNotImplementedException( "XStatement::executeUpdate", *this ); 679 return 0; 680 } 681 682 } } // namespace ::connectivity::evoab 683