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 "composertools.hxx" 32 #include "core_resource.hrc" 33 #include "core_resource.hxx" 34 #include "dbastrings.hrc" 35 #include "HelperCollections.hxx" 36 #include "SingleSelectQueryComposer.hxx" 37 #include "sdbcoretools.hxx" 38 39 /** === begin UNO includes === **/ 40 #include <com/sun/star/beans/PropertyAttribute.hpp> 41 #include <com/sun/star/container/XChild.hpp> 42 #include <com/sun/star/i18n/XLocaleData.hpp> 43 #include <com/sun/star/lang/DisposedException.hpp> 44 #include <com/sun/star/sdb/BooleanComparisonMode.hpp> 45 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 46 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 47 #include <com/sun/star/sdb/CommandType.hpp> 48 #include <com/sun/star/sdbc/ColumnSearch.hpp> 49 #include <com/sun/star/sdbc/DataType.hpp> 50 #include <com/sun/star/sdbc/XResultSetMetaData.hpp> 51 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> 52 #include <com/sun/star/sdbc/XParameters.hpp> 53 #include <com/sun/star/uno/XAggregation.hpp> 54 #include <com/sun/star/util/XNumberFormatter.hpp> 55 /** === end UNO includes === **/ 56 57 #include <comphelper/processfactory.hxx> 58 #include <comphelper/sequence.hxx> 59 #include <comphelper/types.hxx> 60 #include <cppuhelper/typeprovider.hxx> 61 #include <connectivity/predicateinput.hxx> 62 #include <rtl/logfile.hxx> 63 #include <unotools/syslocale.hxx> 64 #include <tools/debug.hxx> 65 #include <tools/diagnose_ex.h> 66 #include <unotools/configmgr.hxx> 67 #include <unotools/sharedunocomponent.hxx> 68 69 #include <memory> 70 71 using namespace ::dbaccess; 72 using namespace ::dbtools; 73 using namespace ::comphelper; 74 using namespace ::connectivity; 75 using namespace ::com::sun::star::uno; 76 using namespace ::com::sun::star::beans; 77 using namespace ::com::sun::star::sdbc; 78 using namespace ::com::sun::star::sdb; 79 using namespace ::com::sun::star::sdbcx; 80 using namespace ::com::sun::star::container; 81 using namespace ::com::sun::star::i18n; 82 using namespace ::com::sun::star::lang; 83 using namespace ::com::sun::star::script; 84 using namespace ::com::sun::star::util; 85 using namespace ::cppu; 86 using namespace ::osl; 87 using namespace ::utl; 88 89 namespace dbaccess { 90 namespace BooleanComparisonMode = ::com::sun::star::sdb::BooleanComparisonMode; 91 } 92 93 #define STR_SELECT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) 94 #define STR_FROM ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM ")) 95 #define STR_WHERE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")) 96 #define STR_GROUP_BY ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" GROUP BY ")) 97 #define STR_HAVING ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" HAVING ")) 98 #define STR_ORDER_BY ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ORDER BY ")) 99 #define STR_AND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" AND ")) 100 #define STR_OR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" OR ")) 101 #define STR_LIKE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE ")) 102 #define STR_EQUAL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = ")) 103 #define L_BRACKET ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("(")) 104 #define R_BRACKET ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")")) 105 #define COMMA ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")) 106 107 // ------------------------------------------------------------------------- 108 namespace 109 { 110 // ..................................................................... 111 /** parses the given statement, using the given parser, returns a parse node representing 112 the statement 113 114 If the statement cannot be parsed, an error is thrown. 115 */ 116 const OSQLParseNode* parseStatement_throwError( OSQLParser& _rParser, const ::rtl::OUString& _rStatement, const Reference< XInterface >& _rxContext ) 117 { 118 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "SingleSelectQueryComposer.cxx::parseStatement_throwError" ); 119 ::rtl::OUString aErrorMsg; 120 const OSQLParseNode* pNewSqlParseNode = _rParser.parseTree( aErrorMsg, _rStatement ); 121 if ( !pNewSqlParseNode ) 122 { 123 ::rtl::OUString sSQLStateGeneralError( getStandardSQLState( SQL_GENERAL_ERROR ) ); 124 SQLException aError2( aErrorMsg, _rxContext, sSQLStateGeneralError, 1000, Any() ); 125 SQLException aError1( _rStatement, _rxContext, sSQLStateGeneralError, 1000, makeAny( aError2 ) ); 126 throw SQLException(_rParser.getContext().getErrorMessage(OParseContext::ERROR_GENERAL),_rxContext,sSQLStateGeneralError,1000,makeAny(aError1)); 127 } 128 return pNewSqlParseNode; 129 } 130 131 // ..................................................................... 132 /** checks whether the given parse node describes a valid single select statement, throws 133 an error if not 134 */ 135 void checkForSingleSelect_throwError( const OSQLParseNode* pStatementNode, OSQLParseTreeIterator& _rIterator, 136 const Reference< XInterface >& _rxContext, const ::rtl::OUString& _rOriginatingCommand ) 137 { 138 const OSQLParseNode* pOldNode = _rIterator.getParseTree(); 139 140 // determine the statement type 141 _rIterator.setParseTree( pStatementNode ); 142 _rIterator.traverseAll(); 143 bool bIsSingleSelect = ( _rIterator.getStatementType() == SQL_STATEMENT_SELECT ); 144 145 // throw the error, if necessary 146 if ( !bIsSingleSelect || SQL_ISRULE( pStatementNode, union_statement ) ) // #i4229# OJ 147 { 148 // restore the old node before throwing the exception 149 _rIterator.setParseTree( pOldNode ); 150 // and now really ... 151 SQLException aError1( _rOriginatingCommand, _rxContext, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, Any() ); 152 throw SQLException( DBACORE_RESSTRING( RID_STR_ONLY_QUERY ), _rxContext, 153 getStandardSQLState( SQL_GENERAL_ERROR ), 1000, makeAny( aError1 ) ); 154 } 155 156 delete pOldNode; 157 } 158 159 // ..................................................................... 160 /** combines parseStatement_throwError and checkForSingleSelect_throwError 161 */ 162 void parseAndCheck_throwError( OSQLParser& _rParser, const ::rtl::OUString& _rStatement, 163 OSQLParseTreeIterator& _rIterator, const Reference< XInterface >& _rxContext ) 164 { 165 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "SingleSelectQueryComposer.cxx::parseAndCheck_throwError" ); 166 const OSQLParseNode* pNode = parseStatement_throwError( _rParser, _rStatement, _rxContext ); 167 checkForSingleSelect_throwError( pNode, _rIterator, _rxContext, _rStatement ); 168 } 169 170 // ..................................................................... 171 /** transforms a parse node describing a complete statement into a pure select 172 statement, without any filter/order/groupby/having clauses 173 */ 174 ::rtl::OUString getPureSelectStatement( const OSQLParseNode* _pRootNode, Reference< XConnection > _rxConnection ) 175 { 176 ::rtl::OUString sSQL = STR_SELECT; 177 _pRootNode->getChild(1)->parseNodeToStr( sSQL, _rxConnection ); 178 _pRootNode->getChild(2)->parseNodeToStr( sSQL, _rxConnection ); 179 sSQL += STR_FROM; 180 _pRootNode->getChild(3)->getChild(0)->getChild(1)->parseNodeToStr( sSQL, _rxConnection ); 181 return sSQL; 182 } 183 184 /** resets an SQL iterator, including deletion of the parse tree, and disposal if desired 185 */ 186 void resetIterator( OSQLParseTreeIterator& _rIterator, bool _bDispose ) 187 { 188 const OSQLParseNode* pSqlParseNode = _rIterator.getParseTree(); 189 _rIterator.setParseTree(NULL); 190 delete pSqlParseNode; 191 if ( _bDispose ) 192 _rIterator.dispose(); 193 } 194 void lcl_addFilterCriteria_throw(sal_Int32 i_nFilterOperator,const ::rtl::OUString& i_sValue,::rtl::OUStringBuffer& o_sRet) 195 { 196 switch( i_nFilterOperator ) 197 { 198 case SQLFilterOperator::EQUAL: 199 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); 200 o_sRet.append(i_sValue); 201 break; 202 case SQLFilterOperator::NOT_EQUAL: 203 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); 204 o_sRet.append(i_sValue); 205 break; 206 case SQLFilterOperator::LESS: 207 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); 208 o_sRet.append(i_sValue); 209 break; 210 case SQLFilterOperator::GREATER: 211 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); 212 o_sRet.append(i_sValue); 213 break; 214 case SQLFilterOperator::LESS_EQUAL: 215 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); 216 o_sRet.append(i_sValue); 217 break; 218 case SQLFilterOperator::GREATER_EQUAL: 219 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); 220 o_sRet.append(i_sValue); 221 break; 222 case SQLFilterOperator::LIKE: 223 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); 224 o_sRet.append(i_sValue); 225 break; 226 case SQLFilterOperator::NOT_LIKE: 227 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); 228 o_sRet.append(i_sValue); 229 break; 230 case SQLFilterOperator::SQLNULL: 231 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); 232 break; 233 case SQLFilterOperator::NOT_SQLNULL: 234 o_sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); 235 break; 236 default: 237 throw SQLException(); 238 } 239 } 240 241 } 242 243 DBG_NAME(OSingleSelectQueryComposer) 244 // ------------------------------------------------------------------------- 245 OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAccess>& _rxTables, 246 const Reference< XConnection>& _xConnection, 247 const ::comphelper::ComponentContext& _rContext ) 248 :OSubComponent(m_aMutex,_xConnection) 249 ,OPropertyContainer(m_aBHelper) 250 ,m_aSqlParser( _rContext.getLegacyServiceFactory() ) 251 ,m_aSqlIterator( _xConnection, _rxTables, m_aSqlParser, NULL ) 252 ,m_aAdditiveIterator( _xConnection, _rxTables, m_aSqlParser, NULL ) 253 ,m_aElementaryParts( (size_t)SQLPartCount ) 254 ,m_xConnection(_xConnection) 255 ,m_xMetaData(_xConnection->getMetaData()) 256 ,m_xConnectionTables( _rxTables ) 257 ,m_aContext( _rContext ) 258 ,m_pTables(NULL) 259 ,m_nBoolCompareMode( BooleanComparisonMode::EQUAL_INTEGER ) 260 ,m_nCommandType(CommandType::COMMAND) 261 { 262 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::OSingleSelectQueryComposer" ); 263 DBG_CTOR(OSingleSelectQueryComposer,NULL); 264 265 if ( !m_aContext.is() || !m_xConnection.is() || !m_xConnectionTables.is() ) 266 throw IllegalArgumentException(); 267 268 registerProperty(PROPERTY_ORIGINAL,PROPERTY_ID_ORIGINAL,PropertyAttribute::BOUND|PropertyAttribute::READONLY,&m_sOrignal,::getCppuType(&m_sOrignal)); 269 270 m_aCurrentColumns.resize(4); 271 272 m_aLocale = SvtSysLocale().GetLocaleData().getLocale(); 273 m_xNumberFormatsSupplier = dbtools::getNumberFormats( m_xConnection, sal_True, m_aContext.getLegacyServiceFactory() ); 274 Reference< XLocaleData > xLocaleData; 275 m_aContext.createComponent( "com.sun.star.i18n.LocaleData", xLocaleData ); 276 LocaleDataItem aData = xLocaleData->getLocaleItem(m_aLocale); 277 m_sDecimalSep = aData.decimalSeparator; 278 OSL_ENSURE(m_sDecimalSep.getLength() == 1,"OSingleSelectQueryComposer::OSingleSelectQueryComposer decimal separator is not 1 length"); 279 try 280 { 281 Any aValue; 282 Reference<XInterface> xDs = dbaccess::getDataSource(_xConnection); 283 if ( dbtools::getDataSourceSetting(xDs,static_cast <rtl::OUString> (PROPERTY_BOOLEANCOMPARISONMODE),aValue) ) 284 { 285 OSL_VERIFY( aValue >>= m_nBoolCompareMode ); 286 } 287 Reference< XQueriesSupplier > xQueriesAccess(m_xConnection, UNO_QUERY); 288 if (xQueriesAccess.is()) 289 m_xConnectionQueries = xQueriesAccess->getQueries(); 290 } 291 catch(Exception&) 292 { 293 } 294 } 295 // ------------------------------------------------------------------------- 296 OSingleSelectQueryComposer::~OSingleSelectQueryComposer() 297 { 298 DBG_DTOR(OSingleSelectQueryComposer,NULL); 299 ::std::vector<OPrivateColumns*>::iterator aColIter = m_aColumnsCollection.begin(); 300 ::std::vector<OPrivateColumns*>::iterator aEnd = m_aColumnsCollection.end(); 301 for(;aColIter != aEnd;++aColIter) 302 delete *aColIter; 303 304 ::std::vector<OPrivateTables*>::iterator aTabIter = m_aTablesCollection.begin(); 305 ::std::vector<OPrivateTables*>::iterator aTabEnd = m_aTablesCollection.end(); 306 for(;aTabIter != aTabEnd;++aTabIter) 307 delete *aTabIter; 308 } 309 // ------------------------------------------------------------------------- 310 // OComponentHelper 311 void SAL_CALL OSingleSelectQueryComposer::disposing(void) 312 { 313 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::disposing" ); 314 OSubComponent::disposing(); 315 316 MutexGuard aGuard(m_aMutex); 317 318 resetIterator( m_aSqlIterator, true ); 319 resetIterator( m_aAdditiveIterator, true ); 320 321 m_xConnectionTables = NULL; 322 m_xConnection = NULL; 323 324 clearCurrentCollections(); 325 } 326 IMPLEMENT_FORWARD_XINTERFACE3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer) 327 IMPLEMENT_SERVICE_INFO1(OSingleSelectQueryComposer,"org.openoffice.comp.dba.OSingleSelectQueryComposer",SERVICE_NAME_SINGLESELECTQUERYCOMPOSER) 328 IMPLEMENT_TYPEPROVIDER3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer) 329 IMPLEMENT_PROPERTYCONTAINER_DEFAULTS(OSingleSelectQueryComposer) 330 331 // ------------------------------------------------------------------------- 332 // com::sun::star::lang::XUnoTunnel 333 sal_Int64 SAL_CALL OSingleSelectQueryComposer::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException) 334 { 335 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getSomething" ); 336 if (rId.getLength() == 16 && 0 == rtl_compareMemory(getImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 337 return reinterpret_cast<sal_Int64>(this); 338 339 return sal_Int64(0); 340 } 341 342 // ------------------------------------------------------------------------- 343 // XSingleSelectQueryAnalyzer 344 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getQuery( ) throw(RuntimeException) 345 { 346 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getQuery" ); 347 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 348 ::osl::MutexGuard aGuard( m_aMutex ); 349 350 TGetParseNode F_tmp(&OSQLParseTreeIterator::getParseTree); 351 return getStatementPart(F_tmp,m_aSqlIterator); 352 } 353 354 // ------------------------------------------------------------------------- 355 void SAL_CALL OSingleSelectQueryComposer::setQuery( const ::rtl::OUString& command ) throw(SQLException, RuntimeException) 356 { 357 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setQuery" ); 358 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 359 360 ::osl::MutexGuard aGuard( m_aMutex ); 361 m_nCommandType = CommandType::COMMAND; 362 // first clear the tables and columns 363 clearCurrentCollections(); 364 // now set the new one 365 setQuery_Impl(command); 366 m_sOrignal = command; 367 368 // reset the additive iterator to the same statement 369 parseAndCheck_throwError( m_aSqlParser, m_sOrignal, m_aAdditiveIterator, *this ); 370 371 // we have no "elementary" parts anymore (means filter/groupby/having/order clauses) 372 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 373 m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); 374 } 375 // ------------------------------------------------------------------------- 376 void SAL_CALL OSingleSelectQueryComposer::setCommand( const ::rtl::OUString& Command,sal_Int32 _nCommandType ) throw(SQLException, RuntimeException) 377 { 378 ::rtl::OUStringBuffer sSQL; 379 switch(_nCommandType) 380 { 381 case CommandType::COMMAND: 382 setElementaryQuery(Command); 383 return; 384 case CommandType::TABLE: 385 if ( m_xConnectionTables->hasByName(Command) ) 386 { 387 sSQL.appendAscii("SELECT * FROM "); 388 Reference< XPropertySet > xTable; 389 try 390 { 391 m_xConnectionTables->getByName( Command ) >>= xTable; 392 } 393 catch(const WrappedTargetException& e) 394 { 395 SQLException e2; 396 if ( e.TargetException >>= e2 ) 397 throw e2; 398 } 399 catch(Exception&) 400 { 401 DBG_UNHANDLED_EXCEPTION(); 402 } 403 404 sSQL.append(dbtools::composeTableNameForSelect(m_xConnection,xTable)); 405 } 406 else 407 { 408 String sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) ); 409 sMessage.SearchAndReplaceAscii( "$table$", Command ); 410 throwGenericSQLException(sMessage,*this); 411 } 412 break; 413 case CommandType::QUERY: 414 if ( m_xConnectionQueries->hasByName(Command) ) 415 { 416 417 Reference<XPropertySet> xQuery(m_xConnectionQueries->getByName(Command),UNO_QUERY); 418 ::rtl::OUString sCommand; 419 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand; 420 sSQL.append(sCommand); 421 } 422 else 423 { 424 String sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) ); 425 sMessage.SearchAndReplaceAscii( "$table$", Command ); 426 throwGenericSQLException(sMessage,*this); 427 } 428 429 break; 430 default: 431 break; 432 } 433 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 434 435 ::osl::MutexGuard aGuard( m_aMutex ); 436 m_nCommandType = _nCommandType; 437 m_sCommand = Command; 438 // first clear the tables and columns 439 clearCurrentCollections(); 440 // now set the new one 441 ::rtl::OUString sCommand = sSQL.makeStringAndClear(); 442 setElementaryQuery(sCommand); 443 m_sOrignal = sCommand; 444 /* 445 // reset the additive iterator to the same statement 446 parseAndCheck_throwError( m_aSqlParser, m_sOrignal, m_aAdditiveIterator, *this ); 447 448 // we have no "elementary" parts anymore (means filter/groupby/having/order clauses) 449 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 450 m_aElementaryParts[ eLoopParts ] = ::rtl::OUString(); 451 */ 452 } 453 // ----------------------------------------------------------------------------- 454 void OSingleSelectQueryComposer::setQuery_Impl( const ::rtl::OUString& command ) 455 { 456 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setQuery_Impl" ); 457 // parse this 458 parseAndCheck_throwError( m_aSqlParser, command, m_aSqlIterator, *this ); 459 460 // strip it from all clauses, to have the pure SELECT statement 461 m_aPureSelectSQL = getPureSelectStatement( m_aSqlIterator.getParseTree(), m_xConnection ); 462 463 // update columns and tables 464 // why? Shouldn't this be done on request only? 465 // otherwise nothing is working anymore :-) 466 // getColumns(); 467 getTables(); 468 } 469 // ----------------------------------------------------------------------------- 470 Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredHavingClause( ) throw (RuntimeException) 471 { 472 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredHavingClause" ); 473 TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleHavingTree); 474 return getStructuredCondition(F_tmp); 475 } 476 // ------------------------------------------------------------------------- 477 Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredFilter( ) throw(RuntimeException) 478 { 479 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredFilter" ); 480 TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree); 481 return getStructuredCondition(F_tmp); 482 } 483 // ----------------------------------------------------------------------------- 484 void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (SQLException, RuntimeException) 485 { 486 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendHavingClauseByColumn" ); 487 ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetHavingClause); 488 setConditionByColumn(column,andCriteria,F_tmp,filterOperator); 489 } 490 // ----------------------------------------------------------------------------- 491 void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw(SQLException, RuntimeException) 492 { 493 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendFilterByColumn" ); 494 ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> F_tmp(&OSingleSelectQueryComposer::implSetFilter); 495 setConditionByColumn(column,andCriteria,F_tmp,filterOperator); 496 } 497 // ----------------------------------------------------------------------------- 498 ::rtl::OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column) 499 { 500 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 501 502 getColumns(); 503 if ( !column.is() 504 || !m_aCurrentColumns[SelectColumns] 505 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) 506 ) 507 { 508 String sError(DBACORE_RESSTRING(RID_STR_COLUMN_UNKNOWN_PROP)); 509 sError.SearchAndReplaceAscii("%value", ::rtl::OUString(PROPERTY_NAME)); 510 SQLException aErr(sError,*this,SQLSTATE_GENERAL,1000,Any() ); 511 throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) ); 512 } 513 514 ::rtl::OUString aName,aNewName; 515 column->getPropertyValue(PROPERTY_NAME) >>= aName; 516 517 if ( !m_xMetaData->supportsOrderByUnrelated() && m_aCurrentColumns[SelectColumns] && !m_aCurrentColumns[SelectColumns]->hasByName(aName)) 518 { 519 String sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE)); 520 sError.SearchAndReplaceAscii("%name", aName); 521 throw SQLException(sError,*this,SQLSTATE_GENERAL,1000,Any() ); 522 } 523 524 // filter anhaengen 525 // select ohne where und order by aufbauen 526 ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString(); 527 if ( m_aCurrentColumns[SelectColumns]->hasByName(aName) ) 528 { 529 Reference<XPropertySet> xColumn; 530 m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn; 531 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!"); 532 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!"); 533 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function"))),"Property FUNCTION not available!"); 534 535 ::rtl::OUString sRealName,sTableName; 536 xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; 537 xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName; 538 sal_Bool bFunction = sal_False; 539 xColumn->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function"))) >>= bFunction; 540 if ( sRealName == aName ) 541 { 542 if ( bFunction ) 543 aNewName = aName; 544 else 545 { 546 if(sTableName.indexOf('.',0) != -1) 547 { 548 ::rtl::OUString aCatlog,aSchema,aTable; 549 ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation); 550 sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation ); 551 } 552 else 553 sTableName = ::dbtools::quoteName(aQuote,sTableName); 554 555 aNewName = sTableName; 556 aNewName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".")); 557 aNewName += ::dbtools::quoteName(aQuote,sRealName); 558 } 559 } 560 else 561 aNewName = ::dbtools::quoteName(aQuote,aName); 562 } 563 else 564 aNewName = getTableAlias(column) + ::dbtools::quoteName(aQuote,aName); 565 return aNewName; 566 } 567 // ------------------------------------------------------------------------- 568 void SAL_CALL OSingleSelectQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException) 569 { 570 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendOrderByColumn" ); 571 ::osl::MutexGuard aGuard( m_aMutex ); 572 ::rtl::OUString sColumnName( impl_getColumnName_throw(column) ); 573 ::rtl::OUString sOrder = getOrder(); 574 if ( (sOrder.getLength() != 0) && sColumnName.getLength() ) 575 sOrder += COMMA; 576 sOrder += sColumnName; 577 if ( !ascending && sColumnName.getLength() ) 578 sOrder += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DESC ")); 579 580 setOrder(sOrder); 581 } 582 583 // ------------------------------------------------------------------------- 584 void SAL_CALL OSingleSelectQueryComposer::appendGroupByColumn( const Reference< XPropertySet >& column) throw(SQLException, RuntimeException) 585 { 586 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::appendGroupByColumn" ); 587 ::osl::MutexGuard aGuard( m_aMutex ); 588 ::rtl::OUString sColumnName( impl_getColumnName_throw(column) ); 589 OrderCreator aComposer; 590 aComposer.append( getGroup() ); 591 aComposer.append( sColumnName ); 592 setGroup( aComposer.getComposedAndClear() ); 593 } 594 // ------------------------------------------------------------------------- 595 ::rtl::OUString OSingleSelectQueryComposer::composeStatementFromParts( const ::std::vector< ::rtl::OUString >& _rParts ) 596 { 597 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::composeStatementFromParts" ); 598 DBG_ASSERT( _rParts.size() == (size_t)SQLPartCount, "OSingleSelectQueryComposer::composeStatementFromParts: invalid parts array!" ); 599 600 ::rtl::OUStringBuffer aSql( m_aPureSelectSQL ); 601 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 602 if ( _rParts[ eLoopParts ].getLength() ) 603 { 604 aSql.append( getKeyword( eLoopParts ) ); 605 aSql.append( _rParts[ eLoopParts ] ); 606 } 607 608 return aSql.makeStringAndClear(); 609 } 610 611 // ------------------------------------------------------------------------- 612 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getElementaryQuery() throw (::com::sun::star::uno::RuntimeException) 613 { 614 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getElementaryQuery" ); 615 return composeStatementFromParts( m_aElementaryParts ); 616 } 617 618 // ------------------------------------------------------------------------- 619 void SAL_CALL OSingleSelectQueryComposer::setElementaryQuery( const ::rtl::OUString& _rElementary ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) 620 { 621 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", "OSingleSelectQueryComposer::setElementaryQuery" ); 622 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 623 ::osl::MutexGuard aGuard( m_aMutex ); 624 625 // remember the 4 current "additive" clauses 626 ::std::vector< ::rtl::OUString > aAdditiveClauses( SQLPartCount ); 627 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 628 aAdditiveClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, sal_False ); 629 630 // clear the tables and columns 631 clearCurrentCollections(); 632 // set and parse the new query 633 setQuery_Impl( _rElementary ); 634 635 // get the 4 elementary parts of the statement 636 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 637 m_aElementaryParts[ eLoopParts ] = getSQLPart( eLoopParts, m_aSqlIterator, sal_False ); 638 639 // reset the the AdditiveIterator: m_aPureSelectSQL may have changed 640 try 641 { 642 parseAndCheck_throwError( m_aSqlParser, composeStatementFromParts( aAdditiveClauses ), m_aAdditiveIterator, *this ); 643 } 644 catch( const Exception& e ) 645 { 646 (void)e; 647 DBG_ERROR( "OSingleSelectQueryComposer::setElementaryQuery: there should be no error anymore for the additive statement!" ); 648 // every part of the additive statement should have passed other tests already, and should not 649 // be able to cause any errors ... me thinks 650 } 651 } 652 653 // ------------------------------------------------------------------------- 654 namespace 655 { 656 ::rtl::OUString getComposedClause( const ::rtl::OUString _rElementaryClause, const ::rtl::OUString _rAdditionalClause, 657 TokenComposer& _rComposer, const ::rtl::OUString _rKeyword ) 658 { 659 _rComposer.clear(); 660 _rComposer.append( _rElementaryClause ); 661 _rComposer.append( _rAdditionalClause ); 662 ::rtl::OUString sComposed = _rComposer.getComposedAndClear(); 663 if ( sComposed.getLength() ) 664 sComposed = _rKeyword + sComposed; 665 return sComposed; 666 } 667 } 668 669 // ------------------------------------------------------------------------- 670 void OSingleSelectQueryComposer::setSingleAdditiveClause( SQLPart _ePart, const ::rtl::OUString& _rClause ) 671 { 672 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setSingleAdditiveClause" ); 673 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 674 ::osl::MutexGuard aGuard( m_aMutex ); 675 676 // if nothing is changed, do nothing 677 if ( getSQLPart( _ePart, m_aAdditiveIterator, sal_False ) == _rClause ) 678 return; 679 680 // collect the 4 single parts as they're currently set 681 ::std::vector< ::rtl::OUString > aClauses; 682 aClauses.reserve( (size_t)SQLPartCount ); 683 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 684 aClauses.push_back( getSQLPart( eLoopParts, m_aSqlIterator, sal_True ) ); 685 686 // overwrite the one part in question here 687 ::std::auto_ptr< TokenComposer > pComposer; 688 if ( ( _ePart == Where ) || ( _ePart == Having ) ) 689 pComposer.reset( new FilterCreator ); 690 else 691 pComposer.reset( new OrderCreator ); 692 aClauses[ _ePart ] = getComposedClause( m_aElementaryParts[ _ePart ], _rClause, 693 *pComposer, getKeyword( _ePart ) ); 694 695 // construct the complete statement 696 ::rtl::OUStringBuffer aSql(m_aPureSelectSQL); 697 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 698 aSql.append(aClauses[ eLoopParts ]); 699 700 // set the query 701 setQuery_Impl(aSql.makeStringAndClear()); 702 703 // clear column collections which (might) have changed 704 clearColumns( ParameterColumns ); 705 if ( _ePart == Order ) 706 clearColumns( OrderColumns ); 707 if ( _ePart == Group ) 708 clearColumns( GroupByColumns ); 709 710 // also, since the "additive filter" change, we need to rebuild our "additive" statement 711 aSql = m_aPureSelectSQL; 712 // again, first get all the old additive parts 713 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 714 aClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, sal_True ); 715 // then overwrite the one in question 716 aClauses[ _ePart ] = getComposedClause( ::rtl::OUString(), _rClause, *pComposer, getKeyword( _ePart ) ); 717 // and parse it, so that m_aAdditiveIterator is up to date 718 for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) 719 aSql.append(aClauses[ eLoopParts ]); 720 try 721 { 722 parseAndCheck_throwError( m_aSqlParser, aSql.makeStringAndClear(), m_aAdditiveIterator, *this ); 723 } 724 catch( const Exception& e ) 725 { 726 (void)e; 727 DBG_ERROR( "OSingleSelectQueryComposer::setSingleAdditiveClause: there should be no error anymore for the additive statement!" ); 728 // every part of the additive statement should have passed other tests already, and should not 729 // be able to cause any errors ... me thinks 730 } 731 } 732 733 // ------------------------------------------------------------------------- 734 void SAL_CALL OSingleSelectQueryComposer::setFilter( const ::rtl::OUString& filter ) throw(SQLException, RuntimeException) 735 { 736 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setFilter" ); 737 setSingleAdditiveClause( Where, filter ); 738 } 739 740 // ------------------------------------------------------------------------- 741 void SAL_CALL OSingleSelectQueryComposer::setOrder( const ::rtl::OUString& order ) throw(SQLException, RuntimeException) 742 { 743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setOrder" ); 744 setSingleAdditiveClause( Order, order ); 745 } 746 // ----------------------------------------------------------------------------- 747 void SAL_CALL OSingleSelectQueryComposer::setGroup( const ::rtl::OUString& group ) throw (SQLException, RuntimeException) 748 { 749 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setGroup" ); 750 setSingleAdditiveClause( Group, group ); 751 } 752 // ------------------------------------------------------------------------- 753 void SAL_CALL OSingleSelectQueryComposer::setHavingClause( const ::rtl::OUString& filter ) throw(SQLException, RuntimeException) 754 { 755 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setHavingClause" ); 756 setSingleAdditiveClause( Having, filter ); 757 } 758 759 // ------------------------------------------------------------------------- 760 // XTablesSupplier 761 Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getTables( ) throw(RuntimeException) 762 { 763 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getTables" ); 764 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 765 766 ::osl::MutexGuard aGuard( m_aMutex ); 767 if ( !m_pTables ) 768 { 769 const OSQLTables& aTables = m_aSqlIterator.getTables(); 770 ::std::vector< ::rtl::OUString> aNames; 771 OSQLTables::const_iterator aEnd = aTables.end(); 772 for(OSQLTables::const_iterator aIter = aTables.begin(); aIter != aEnd;++aIter) 773 aNames.push_back(aIter->first); 774 775 m_pTables = new OPrivateTables(aTables,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames); 776 } 777 778 return m_pTables; 779 } 780 // ------------------------------------------------------------------------- 781 // XColumnsSupplier 782 Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) throw(RuntimeException) 783 { 784 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getColumns" ); 785 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 786 ::osl::MutexGuard aGuard( m_aMutex ); 787 if ( !!m_aCurrentColumns[SelectColumns] ) 788 return m_aCurrentColumns[SelectColumns]; 789 790 ::std::vector< ::rtl::OUString> aNames; 791 ::vos::ORef< OSQLColumns> aSelectColumns; 792 sal_Bool bCase = sal_True; 793 Reference< XNameAccess> xQueryColumns; 794 if ( m_nCommandType == CommandType::QUERY ) 795 { 796 Reference<XColumnsSupplier> xSup(m_xConnectionQueries->getByName(m_sCommand),UNO_QUERY); 797 if(xSup.is()) 798 xQueryColumns = xSup->getColumns(); 799 } 800 801 do { 802 803 try 804 { 805 SharedUNOComponent< XStatement, DisposableComponent > xStatement; 806 SharedUNOComponent< XPreparedStatement, DisposableComponent > xPreparedStatement; 807 808 bCase = m_xMetaData->supportsMixedCaseQuotedIdentifiers(); 809 aSelectColumns = m_aSqlIterator.getSelectColumns(); 810 811 ::rtl::OUStringBuffer aSQL; 812 aSQL.append( m_aPureSelectSQL ); 813 aSQL.append( STR_WHERE ); 814 815 // preserve the original WHERE clause 816 // #i102234# / 2009-06-02 / frank.schoenheit@sun.com 817 ::rtl::OUString sOriginalWhereClause = getSQLPart( Where, m_aSqlIterator, sal_False ); 818 if ( sOriginalWhereClause.getLength() ) 819 { 820 aSQL.appendAscii( " ( 0 = 1 ) AND ( " ); 821 aSQL.append( sOriginalWhereClause ); 822 aSQL.appendAscii( " ) " ); 823 } 824 else 825 { 826 aSQL.appendAscii( " ( 0 = 1 ) " ); 827 } 828 829 ::rtl::OUString sGroupBy = getSQLPart( Group, m_aSqlIterator, sal_True ); 830 if ( sGroupBy.getLength() ) 831 aSQL.append( sGroupBy ); 832 833 ::rtl::OUString sSQL( aSQL.makeStringAndClear() ); 834 // normalize the statement so that it doesn't contain any application-level features anymore 835 ::rtl::OUString sError; 836 const ::std::auto_ptr< OSQLParseNode > pStatementTree( m_aSqlParser.parseTree( sError, sSQL, false ) ); 837 DBG_ASSERT( pStatementTree.get(), "OSingleSelectQueryComposer::getColumns: could not parse the column retrieval statement!" ); 838 if ( pStatementTree.get() ) 839 if ( !pStatementTree->parseNodeToExecutableStatement( sSQL, m_xConnection, m_aSqlParser, NULL ) ) 840 break; 841 842 Reference< XResultSetMetaData > xResultSetMeta; 843 Reference< XResultSetMetaDataSupplier > xResMetaDataSup; 844 try 845 { 846 xPreparedStatement.set( m_xConnection->prepareStatement( sSQL ), UNO_QUERY_THROW ); 847 xResMetaDataSup.set( xPreparedStatement, UNO_QUERY_THROW ); 848 xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW ); 849 } 850 catch( const Exception& ) { } 851 852 try 853 { 854 if ( !xResultSetMeta.is() ) 855 { 856 xStatement.reset( Reference< XStatement >( m_xConnection->createStatement(), UNO_QUERY_THROW ) ); 857 Reference< XPropertySet > xStatementProps( xStatement, UNO_QUERY_THROW ); 858 try { xStatementProps->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( sal_False ) ); } 859 catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } 860 xResMetaDataSup.set( xStatement->executeQuery( sSQL ), UNO_QUERY_THROW ); 861 xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW ); 862 } 863 } 864 catch( const Exception& ) 865 { 866 //@see issue http://qa.openoffice.org/issues/show_bug.cgi?id=110111 867 // access returns a different order of column names when executing select * from 868 // and asking the columns from the metadata. 869 Reference< XParameters > xParameters( xPreparedStatement, UNO_QUERY_THROW ); 870 Reference< XIndexAccess > xPara = getParameters(); 871 for(sal_Int32 i = 1;i <= xPara->getCount();++i) 872 xParameters->setNull(i,DataType::VARCHAR); 873 xResMetaDataSup.set(xPreparedStatement->executeQuery(), UNO_QUERY_THROW ); 874 xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW ); 875 } 876 877 if ( aSelectColumns->get().empty() ) 878 { 879 // This is a valid case. If we can syntactically parse the query, but not semantically 880 // (e.g. because it is based on a table we do not know), then there will be no SelectColumns 881 aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ,xQueryColumns); 882 break; 883 } 884 885 const ::comphelper::UStringMixEqual aCaseCompare( bCase ); 886 const ::comphelper::TStringMixEqualFunctor aCaseCompareFunctor( bCase ); 887 typedef ::std::set< size_t > SizeTSet; 888 SizeTSet aUsedSelectColumns; 889 ::connectivity::parse::OParseColumn::StringMap aColumnNames; 890 891 sal_Int32 nCount = xResultSetMeta->getColumnCount(); 892 OSL_ENSURE( (size_t) nCount == aSelectColumns->get().size(), "OSingleSelectQueryComposer::getColumns: inconsistent column counts, this might result in wrong columns!" ); 893 for(sal_Int32 i=1;i<=nCount;++i) 894 { 895 ::rtl::OUString sColumnName = xResultSetMeta->getColumnName(i); 896 ::rtl::OUString sColumnLabel; 897 if ( xQueryColumns.is() && xQueryColumns->hasByName(sColumnName) ) 898 { 899 Reference<XPropertySet> xQueryColumn(xQueryColumns->getByName(sColumnName),UNO_QUERY_THROW); 900 xQueryColumn->getPropertyValue(PROPERTY_LABEL) >>= sColumnLabel; 901 } 902 else 903 sColumnLabel = xResultSetMeta->getColumnLabel(i); 904 sal_Bool bFound = sal_False; 905 OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),sColumnLabel,aCaseCompare); 906 size_t nFoundSelectColumnPos = aFind - aSelectColumns->get().begin(); 907 if ( aFind != aSelectColumns->get().end() ) 908 { 909 if ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() ) 910 { // we found a column name which exists twice 911 // so we start after the first found 912 do 913 { 914 aFind = ::connectivity::findRealName(++aFind,aSelectColumns->get().end(),sColumnName,aCaseCompare); 915 nFoundSelectColumnPos = aFind - aSelectColumns->get().begin(); 916 } 917 while ( ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() ) 918 && ( aFind != aSelectColumns->get().end() ) 919 ); 920 } 921 if ( aFind != aSelectColumns->get().end() ) 922 { 923 (*aFind)->getPropertyValue(PROPERTY_NAME) >>= sColumnName; 924 aUsedSelectColumns.insert( nFoundSelectColumnPos ); 925 aNames.push_back(sColumnName); 926 bFound = sal_True; 927 } 928 } 929 930 if ( bFound ) 931 continue; 932 933 OSQLColumns::Vector::const_iterator aRealFind = ::connectivity::findRealName( 934 aSelectColumns->get().begin(), aSelectColumns->get().end(), sColumnName, aCaseCompare ); 935 936 if ( i > static_cast< sal_Int32>( aSelectColumns->get().size() ) ) 937 { 938 aSelectColumns->get().push_back( 939 ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ,aColumnNames) 940 ); 941 OSL_ENSURE( aSelectColumns->get().size() == (size_t)i, "OSingleSelectQueryComposer::getColumns: inconsistency!" ); 942 } 943 else if ( aRealFind == aSelectColumns->get().end() ) 944 { 945 // we can now only look if we found it under the realname propertery 946 // here we have to make the assumption that the position is correct 947 OSQLColumns::Vector::iterator aFind2 = aSelectColumns->get().begin() + i-1; 948 Reference<XPropertySet> xProp(*aFind2,UNO_QUERY); 949 if ( !xProp.is() || !xProp->getPropertySetInfo()->hasPropertyByName( PROPERTY_REALNAME ) ) 950 continue; 951 952 ::connectivity::parse::OParseColumn* pColumn = new ::connectivity::parse::OParseColumn(xProp,bCase); 953 pColumn->setFunction(::comphelper::getBOOL(xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function"))))); 954 pColumn->setAggregateFunction(::comphelper::getBOOL(xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"))))); 955 956 ::rtl::OUString sRealName; 957 xProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; 958 ::std::vector< ::rtl::OUString>::iterator aFindName; 959 if ( !sColumnName.getLength() ) 960 xProp->getPropertyValue(PROPERTY_NAME) >>= sColumnName; 961 962 963 aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompareFunctor,sColumnName)); 964 sal_Int32 j = 0; 965 while ( aFindName != aNames.end() ) 966 { 967 sColumnName += ::rtl::OUString::valueOf(++j); 968 aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompareFunctor,sColumnName)); 969 } 970 971 pColumn->setName(sColumnName); 972 pColumn->setRealName(sRealName); 973 pColumn->setTableName(::comphelper::getString(xProp->getPropertyValue(PROPERTY_TABLENAME))); 974 975 (aSelectColumns->get())[i-1] = pColumn; 976 } 977 else 978 continue; 979 980 aUsedSelectColumns.insert( (size_t)(i - 1) ); 981 aNames.push_back( sColumnName ); 982 } 983 } 984 catch(const Exception&) 985 { 986 } 987 988 } while ( false ); 989 990 if ( aNames.empty() ) 991 m_aCurrentColumns[ SelectColumns ] = OPrivateColumns::createWithIntrinsicNames( aSelectColumns, bCase, *this, m_aMutex ); 992 else 993 m_aCurrentColumns[ SelectColumns ] = new OPrivateColumns( aSelectColumns, bCase, *this, m_aMutex, aNames ); 994 995 return m_aCurrentColumns[SelectColumns]; 996 } 997 // ------------------------------------------------------------------------- 998 sal_Bool OSingleSelectQueryComposer::setORCriteria(OSQLParseNode* pCondition, OSQLParseTreeIterator& _rIterator, 999 ::std::vector< ::std::vector < PropertyValue > >& rFilters, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const 1000 { 1001 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setORCriteria" ); 1002 // Runde Klammern um den Ausdruck 1003 if (pCondition->count() == 3 && 1004 SQL_ISPUNCTUATION(pCondition->getChild(0),"(") && 1005 SQL_ISPUNCTUATION(pCondition->getChild(2),")")) 1006 { 1007 return setORCriteria(pCondition->getChild(1), _rIterator, rFilters, xFormatter); 1008 } 1009 // oder Verknuepfung 1010 // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term 1011 else if (SQL_ISRULE(pCondition,search_condition)) 1012 { 1013 sal_Bool bResult = sal_True; 1014 for (int i = 0; bResult && i < 3; i+=2) 1015 { 1016 // Ist das erste Element wieder eine OR-Verknuepfung? 1017 // Dann rekursiv absteigen ... 1018 //if (!i && SQL_ISRULE(pCondition->getChild(i),search_condition)) 1019 if (SQL_ISRULE(pCondition->getChild(i),search_condition)) 1020 bResult = setORCriteria(pCondition->getChild(i), _rIterator, rFilters, xFormatter); 1021 else 1022 { 1023 rFilters.push_back( ::std::vector < PropertyValue >()); 1024 bResult = setANDCriteria(pCondition->getChild(i), _rIterator, rFilters[rFilters.size() - 1], xFormatter); 1025 } 1026 } 1027 return bResult; 1028 } 1029 else 1030 { 1031 rFilters.push_back(::std::vector < PropertyValue >()); 1032 return setANDCriteria(pCondition, _rIterator, rFilters[rFilters.size() - 1], xFormatter); 1033 } 1034 } 1035 1036 //-------------------------------------------------------------------------------------------------- 1037 sal_Bool OSingleSelectQueryComposer::setANDCriteria( OSQLParseNode * pCondition, 1038 OSQLParseTreeIterator& _rIterator, ::std::vector < PropertyValue >& rFilter, const Reference< XNumberFormatter > & xFormatter) const 1039 { 1040 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setANDCriteria" ); 1041 // Runde Klammern 1042 if (SQL_ISRULE(pCondition,boolean_primary)) 1043 { 1044 // this should not occur 1045 DBG_ERROR("boolean_primary in And-Criteria"); 1046 return sal_False; 1047 } 1048 // Das erste Element ist (wieder) eine AND-Verknuepfung 1049 else if ( SQL_ISRULE(pCondition,boolean_term) && pCondition->count() == 3 ) 1050 { 1051 return setANDCriteria(pCondition->getChild(0), _rIterator, rFilter, xFormatter) && 1052 setANDCriteria(pCondition->getChild(2), _rIterator, rFilter, xFormatter); 1053 } 1054 else if (SQL_ISRULE(pCondition, comparison_predicate)) 1055 { 1056 return setComparsionPredicate(pCondition,_rIterator,rFilter,xFormatter); 1057 } 1058 else if (SQL_ISRULE(pCondition,like_predicate) || 1059 SQL_ISRULE(pCondition,test_for_null) || 1060 SQL_ISRULE(pCondition,in_predicate) || 1061 SQL_ISRULE(pCondition,all_or_any_predicate) || 1062 SQL_ISRULE(pCondition,between_predicate)) 1063 { 1064 if (SQL_ISRULE(pCondition->getChild(0), column_ref)) 1065 { 1066 PropertyValue aItem; 1067 ::rtl::OUString aValue; 1068 ::rtl::OUString aColumnName; 1069 1070 1071 // pCondition->parseNodeToStr(aValue,m_xMetaData, xFormatter, m_aLocale,static_cast<sal_Char>(m_sDecimalSep.toChar())); 1072 pCondition->parseNodeToStr( aValue, m_xConnection, NULL ); 1073 // pCondition->getChild(0)->parseNodeToStr(aColumnName,m_xMetaData, xFormatter, m_aLocale,static_cast<sal_Char>(m_sDecimalSep.toChar())); 1074 pCondition->getChild(0)->parseNodeToStr( aColumnName, m_xConnection, NULL ); 1075 1076 // don't display the column name 1077 aValue = aValue.copy(aColumnName.getLength()); 1078 aValue = aValue.trim(); 1079 1080 aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); 1081 aItem.Value <<= aValue; 1082 aItem.Handle = 0; // just to know that this is not one the known ones 1083 if ( SQL_ISRULE(pCondition,like_predicate) ) 1084 { 1085 if ( SQL_ISTOKEN(pCondition->getChild(1)->getChild(0),NOT) ) 1086 aItem.Handle = SQLFilterOperator::NOT_LIKE; 1087 else 1088 aItem.Handle = SQLFilterOperator::LIKE; 1089 } 1090 else if (SQL_ISRULE(pCondition,test_for_null)) 1091 { 1092 if (SQL_ISTOKEN(pCondition->getChild(1)->getChild(1),NOT) ) 1093 aItem.Handle = SQLFilterOperator::NOT_SQLNULL; 1094 else 1095 aItem.Handle = SQLFilterOperator::SQLNULL; 1096 } 1097 else if (SQL_ISRULE(pCondition,in_predicate)) 1098 { 1099 OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: in_predicate not implemented!" ); 1100 } 1101 else if (SQL_ISRULE(pCondition,all_or_any_predicate)) 1102 { 1103 OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: all_or_any_predicate not implemented!" ); 1104 } 1105 else if (SQL_ISRULE(pCondition,between_predicate)) 1106 { 1107 OSL_ENSURE( false, "OSingleSelectQueryComposer::setANDCriteria: between_predicate not implemented!" ); 1108 } 1109 1110 rFilter.push_back(aItem); 1111 } 1112 else 1113 return sal_False; 1114 } 1115 else if (SQL_ISRULE(pCondition,existence_test) || 1116 SQL_ISRULE(pCondition,unique_test)) 1117 { 1118 // this couldn't be handled here, too complex 1119 // as we need a field name 1120 return sal_False; 1121 } 1122 else 1123 return sal_False; 1124 1125 return sal_True; 1126 } 1127 // ----------------------------------------------------------------------------- 1128 sal_Int32 OSingleSelectQueryComposer::getPredicateType(OSQLParseNode * _pPredicate) const 1129 { 1130 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getPredicateType" ); 1131 sal_Int32 nPredicate = SQLFilterOperator::EQUAL; 1132 switch (_pPredicate->getNodeType()) 1133 { 1134 case SQL_NODE_EQUAL: 1135 nPredicate = SQLFilterOperator::EQUAL; 1136 break; 1137 case SQL_NODE_NOTEQUAL: 1138 nPredicate = SQLFilterOperator::NOT_EQUAL; 1139 break; 1140 case SQL_NODE_LESS: 1141 nPredicate = SQLFilterOperator::LESS; 1142 break; 1143 case SQL_NODE_LESSEQ: 1144 nPredicate = SQLFilterOperator::LESS_EQUAL; 1145 break; 1146 case SQL_NODE_GREAT: 1147 nPredicate = SQLFilterOperator::GREATER; 1148 break; 1149 case SQL_NODE_GREATEQ: 1150 nPredicate = SQLFilterOperator::GREATER_EQUAL; 1151 break; 1152 default: 1153 OSL_ENSURE(0,"Wrong NodeType!"); 1154 } 1155 return nPredicate; 1156 } 1157 //------------------------------------------------------------------------------ 1158 sal_Bool OSingleSelectQueryComposer::setComparsionPredicate(OSQLParseNode * pCondition, OSQLParseTreeIterator& _rIterator, 1159 ::std::vector < PropertyValue >& rFilter, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const 1160 { 1161 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setComparsionPredicate" ); 1162 DBG_ASSERT(SQL_ISRULE(pCondition, comparison_predicate),"setComparsionPredicate: pCondition ist kein ComparsionPredicate"); 1163 if (SQL_ISRULE(pCondition->getChild(0), column_ref) || 1164 SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref)) 1165 { 1166 PropertyValue aItem; 1167 ::rtl::OUString aValue; 1168 sal_uInt32 nPos; 1169 if (SQL_ISRULE(pCondition->getChild(0), column_ref)) 1170 { 1171 nPos = 0; 1172 sal_uInt32 i=1; 1173 1174 aItem.Handle = getPredicateType(pCondition->getChild(i)); 1175 // don't display the equal 1176 if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL) 1177 i++; 1178 1179 // go forward 1180 for (;i < pCondition->count();i++) 1181 pCondition->getChild(i)->parseNodeToPredicateStr( 1182 aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>(m_sDecimalSep.toChar() ) ); 1183 } 1184 else if (SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref)) 1185 { 1186 nPos = pCondition->count()-1; 1187 1188 sal_Int32 i = pCondition->count() - 2; 1189 switch (pCondition->getChild(i)->getNodeType()) 1190 { 1191 case SQL_NODE_EQUAL: 1192 // don't display the equal 1193 i--; 1194 aItem.Handle = SQLFilterOperator::EQUAL; 1195 break; 1196 case SQL_NODE_NOTEQUAL: 1197 i--; 1198 aItem.Handle = SQLFilterOperator::NOT_EQUAL; 1199 break; 1200 case SQL_NODE_LESS: 1201 // take the opposite as we change the order 1202 i--; 1203 aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">=")); 1204 aItem.Handle = SQLFilterOperator::GREATER_EQUAL; 1205 break; 1206 case SQL_NODE_LESSEQ: 1207 // take the opposite as we change the order 1208 i--; 1209 aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">")); 1210 aItem.Handle = SQLFilterOperator::GREATER; 1211 break; 1212 case SQL_NODE_GREAT: 1213 // take the opposite as we change the order 1214 i--; 1215 aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<=")); 1216 aItem.Handle = SQLFilterOperator::LESS_EQUAL; 1217 break; 1218 case SQL_NODE_GREATEQ: 1219 // take the opposite as we change the order 1220 i--; 1221 aValue = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<")); 1222 aItem.Handle = SQLFilterOperator::LESS; 1223 break; 1224 default: 1225 break; 1226 } 1227 1228 // go backward 1229 for (; i >= 0; i--) 1230 pCondition->getChild(i)->parseNodeToPredicateStr( 1231 aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) ); 1232 } 1233 else 1234 return sal_False; 1235 1236 aItem.Name = getColumnName(pCondition->getChild(nPos),_rIterator); 1237 aItem.Value <<= aValue; 1238 rFilter.push_back(aItem); 1239 } 1240 else if (SQL_ISRULE(pCondition->getChild(0), set_fct_spec ) || 1241 SQL_ISRULE(pCondition->getChild(0), general_set_fct)) 1242 { 1243 PropertyValue aItem; 1244 ::rtl::OUString aValue; 1245 ::rtl::OUString aColumnName; 1246 1247 pCondition->getChild(2)->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) ); 1248 pCondition->getChild(0)->parseNodeToPredicateStr( aColumnName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep .toChar() ) ); 1249 1250 aItem.Name = getColumnName(pCondition->getChild(0),_rIterator); 1251 aItem.Value <<= aValue; 1252 aItem.Handle = getPredicateType(pCondition->getChild(1)); 1253 rFilter.push_back(aItem); 1254 } 1255 else // kann sich nur um einen Expr. Ausdruck handeln 1256 { 1257 PropertyValue aItem; 1258 ::rtl::OUString aName, aValue; 1259 1260 OSQLParseNode *pLhs = pCondition->getChild(0); 1261 OSQLParseNode *pRhs = pCondition->getChild(2); 1262 1263 // Feldnamen 1264 sal_uInt16 i; 1265 for (i=0;i< pLhs->count();i++) 1266 pLhs->getChild(i)->parseNodeToPredicateStr( aName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) ); 1267 1268 // Kriterium 1269 aItem.Handle = getPredicateType(pCondition->getChild(1)); 1270 aValue = pCondition->getChild(1)->getTokenValue(); 1271 for(i=0;i< pRhs->count();i++) 1272 pRhs->getChild(i)->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) ); 1273 1274 aItem.Name = aName; 1275 aItem.Value <<= aValue; 1276 rFilter.push_back(aItem); 1277 } 1278 return sal_True; 1279 } 1280 // functions for analysing SQL 1281 //-------------------------------------------------------------------------------------------------- 1282 ::rtl::OUString OSingleSelectQueryComposer::getColumnName( ::connectivity::OSQLParseNode* pColumnRef, OSQLParseTreeIterator& _rIterator ) const 1283 { 1284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getColumnName" ); 1285 ::rtl::OUString aTableRange, aColumnName; 1286 _rIterator.getColumnRange(pColumnRef,aColumnName,aTableRange); 1287 return aColumnName; 1288 } 1289 //------------------------------------------------------------------------------ 1290 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getFilter( ) throw(RuntimeException) 1291 { 1292 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getFilter" ); 1293 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1294 ::osl::MutexGuard aGuard( m_aMutex ); 1295 return getSQLPart(Where,m_aAdditiveIterator,sal_False); 1296 } 1297 // ------------------------------------------------------------------------- 1298 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getOrder( ) throw(RuntimeException) 1299 { 1300 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getOrder" ); 1301 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1302 ::osl::MutexGuard aGuard( m_aMutex ); 1303 return getSQLPart(Order,m_aAdditiveIterator,sal_False); 1304 } 1305 // ------------------------------------------------------------------------- 1306 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getGroup( ) throw (RuntimeException) 1307 { 1308 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getGroup" ); 1309 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1310 ::osl::MutexGuard aGuard( m_aMutex ); 1311 return getSQLPart(Group,m_aAdditiveIterator,sal_False); 1312 } 1313 // ----------------------------------------------------------------------------- 1314 ::rtl::OUString OSingleSelectQueryComposer::getHavingClause() throw (RuntimeException) 1315 { 1316 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getHavingClause" ); 1317 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1318 ::osl::MutexGuard aGuard( m_aMutex ); 1319 return getSQLPart(Having,m_aAdditiveIterator,sal_False); 1320 } 1321 // ----------------------------------------------------------------------------- 1322 ::rtl::OUString OSingleSelectQueryComposer::getTableAlias(const Reference< XPropertySet >& column) const 1323 { 1324 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getTableAlias" ); 1325 ::rtl::OUString sReturn; 1326 if(m_pTables && m_pTables->getCount() > 1) 1327 { 1328 ::rtl::OUString aCatalog,aSchema,aTable,aComposedName,aColumnName; 1329 column->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog; 1330 column->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema; 1331 column->getPropertyValue(PROPERTY_TABLENAME) >>= aTable; 1332 column->getPropertyValue(PROPERTY_NAME) >>= aColumnName; 1333 1334 Sequence< ::rtl::OUString> aNames(m_pTables->getElementNames()); 1335 const ::rtl::OUString* pBegin = aNames.getConstArray(); 1336 const ::rtl::OUString* pEnd = pBegin + aNames.getLength(); 1337 1338 if(!aTable.getLength()) 1339 { // we don't found a table name, now we must search every table for this column 1340 for(;pBegin != pEnd;++pBegin) 1341 { 1342 Reference<XColumnsSupplier> xColumnsSupp; 1343 m_pTables->getByName(*pBegin) >>= xColumnsSupp; 1344 1345 if(xColumnsSupp.is() && xColumnsSupp->getColumns()->hasByName(aColumnName)) 1346 { 1347 // Reference<XPropertySet> xTableProp(xColumnsSupp,UNO_QUERY); 1348 // xTableProp->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog; 1349 // xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema; 1350 // xTableProp->getPropertyValue(PROPERTY_NAME) >>= aTable; 1351 aTable = *pBegin; 1352 break; 1353 } 1354 } 1355 } 1356 else 1357 { 1358 aComposedName = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, sal_False, ::dbtools::eInDataManipulation ); 1359 1360 // first check if this is the table we want to or has it a tablealias 1361 1362 if(!m_pTables->hasByName(aComposedName)) 1363 { 1364 ::comphelper::UStringMixLess aTmp(m_aAdditiveIterator.getTables().key_comp()); 1365 ::comphelper::UStringMixEqual aComp(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive()); 1366 for(;pBegin != pEnd;++pBegin) 1367 { 1368 Reference<XPropertySet> xTableProp; 1369 m_pTables->getByName(*pBegin) >>= xTableProp; 1370 OSL_ENSURE(xTableProp.is(),"Table isn't a propertyset!"); 1371 if(xTableProp.is()) 1372 { 1373 ::rtl::OUString aCatalog2,aSchema2,aTable2; 1374 xTableProp->getPropertyValue(PROPERTY_CATALOGNAME) >>= aCatalog2; 1375 xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= aSchema2; 1376 xTableProp->getPropertyValue(PROPERTY_NAME) >>= aTable2; 1377 if(aComp(aCatalog,aCatalog2) && aComp(aSchema,aSchema2) && aComp(aTable,aTable2)) 1378 { 1379 aCatalog = aCatalog2; 1380 aSchema = aSchema2; 1381 aTable = aTable2; 1382 break; 1383 } 1384 } 1385 } 1386 } 1387 } 1388 if(pBegin != pEnd) 1389 { 1390 sReturn = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation ); 1391 sReturn += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".")); 1392 } 1393 } 1394 return sReturn; 1395 } 1396 // ----------------------------------------------------------------------------- 1397 Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getParameters( ) throw(RuntimeException) 1398 { 1399 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getParameters" ); 1400 // now set the Parameters 1401 if ( !m_aCurrentColumns[ParameterColumns] ) 1402 { 1403 ::vos::ORef< OSQLColumns> aCols = m_aSqlIterator.getParameters(); 1404 ::std::vector< ::rtl::OUString> aNames; 1405 OSQLColumns::Vector::const_iterator aEnd = aCols->get().end(); 1406 for(OSQLColumns::Vector::const_iterator aIter = aCols->get().begin(); aIter != aEnd;++aIter) 1407 aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME))); 1408 m_aCurrentColumns[ParameterColumns] = new OPrivateColumns(aCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True); 1409 } 1410 1411 return m_aCurrentColumns[ParameterColumns]; 1412 } 1413 // ----------------------------------------------------------------------------- 1414 void OSingleSelectQueryComposer::clearColumns( const EColumnType _eType ) 1415 { 1416 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearColumns" ); 1417 OPrivateColumns* pColumns = m_aCurrentColumns[ _eType ]; 1418 if ( pColumns != NULL ) 1419 { 1420 pColumns->disposing(); 1421 m_aColumnsCollection.push_back( pColumns ); 1422 m_aCurrentColumns[ _eType ] = NULL; 1423 } 1424 } 1425 // ----------------------------------------------------------------------------- 1426 void OSingleSelectQueryComposer::clearCurrentCollections() 1427 { 1428 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearCurrentCollections" ); 1429 ::std::vector<OPrivateColumns*>::iterator aIter = m_aCurrentColumns.begin(); 1430 ::std::vector<OPrivateColumns*>::iterator aEnd = m_aCurrentColumns.end(); 1431 for (;aIter != aEnd;++aIter) 1432 { 1433 if ( *aIter ) 1434 { 1435 (*aIter)->disposing(); 1436 m_aColumnsCollection.push_back(*aIter); 1437 *aIter = NULL; 1438 } 1439 } 1440 1441 if(m_pTables) 1442 { 1443 m_pTables->disposing(); 1444 m_aTablesCollection.push_back(m_pTables); 1445 m_pTables = NULL; 1446 } 1447 } 1448 // ----------------------------------------------------------------------------- 1449 Reference< XIndexAccess > OSingleSelectQueryComposer::setCurrentColumns( EColumnType _eType, 1450 const ::vos::ORef< OSQLColumns >& _rCols ) 1451 { 1452 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setCurrentColumns" ); 1453 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1454 1455 ::osl::MutexGuard aGuard( m_aMutex ); 1456 // now set the group columns 1457 if ( !m_aCurrentColumns[_eType] ) 1458 { 1459 ::std::vector< ::rtl::OUString> aNames; 1460 OSQLColumns::Vector::const_iterator aEnd = _rCols->get().end(); 1461 for(OSQLColumns::Vector::const_iterator aIter = _rCols->get().begin(); aIter != aEnd;++aIter) 1462 aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME))); 1463 m_aCurrentColumns[_eType] = new OPrivateColumns(_rCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True); 1464 } 1465 1466 return m_aCurrentColumns[_eType]; 1467 } 1468 // ----------------------------------------------------------------------------- 1469 Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getGroupColumns( ) throw(RuntimeException) 1470 { 1471 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getGroupColumns" ); 1472 return setCurrentColumns( GroupByColumns, m_aAdditiveIterator.getGroupColumns() ); 1473 } 1474 // ------------------------------------------------------------------------- 1475 Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getOrderColumns( ) throw(RuntimeException) 1476 { 1477 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getOrderColumns" ); 1478 return setCurrentColumns( OrderColumns, m_aAdditiveIterator.getOrderColumns() ); 1479 } 1480 // ----------------------------------------------------------------------------- 1481 ::rtl::OUString SAL_CALL OSingleSelectQueryComposer::getQueryWithSubstitution( ) throw (SQLException, RuntimeException) 1482 { 1483 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getQueryWithSubstitution" ); 1484 ::osl::MutexGuard aGuard( m_aMutex ); 1485 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1486 1487 ::rtl::OUString sSqlStatement( getQuery() ); 1488 1489 const OSQLParseNode* pStatementNode = m_aSqlIterator.getParseTree(); 1490 if ( pStatementNode ) 1491 { 1492 SQLException aError; 1493 if ( !pStatementNode->parseNodeToExecutableStatement( sSqlStatement, m_xConnection, m_aSqlParser, &aError ) ) 1494 throw SQLException( aError ); 1495 } 1496 1497 return sSqlStatement; 1498 } 1499 // ----------------------------------------------------------------------------- 1500 ::rtl::OUString OSingleSelectQueryComposer::getStatementPart( TGetParseNode& _aGetFunctor, OSQLParseTreeIterator& _rIterator ) 1501 { 1502 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStatementPart" ); 1503 ::rtl::OUString sResult; 1504 1505 const OSQLParseNode* pNode = _aGetFunctor( &_rIterator ); 1506 if ( pNode ) 1507 pNode->parseNodeToStr( sResult, m_xConnection ); 1508 1509 return sResult; 1510 } 1511 // ----------------------------------------------------------------------------- 1512 namespace 1513 { 1514 ::rtl::OUString lcl_getCondition(const Sequence< Sequence< PropertyValue > >& filter,const OPredicateInputController& i_aPredicateInputController,const Reference< XNameAccess >& i_xSelectColumns) 1515 { 1516 ::rtl::OUStringBuffer sRet; 1517 const Sequence< PropertyValue >* pOrIter = filter.getConstArray(); 1518 const Sequence< PropertyValue >* pOrEnd = pOrIter + filter.getLength(); 1519 while ( pOrIter != pOrEnd ) 1520 { 1521 if ( pOrIter->getLength() ) 1522 { 1523 sRet.append(L_BRACKET); 1524 const PropertyValue* pAndIter = pOrIter->getConstArray(); 1525 const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength(); 1526 while ( pAndIter != pAndEnd ) 1527 { 1528 sRet.append(pAndIter->Name); 1529 ::rtl::OUString sValue; 1530 pAndIter->Value >>= sValue; 1531 if ( i_xSelectColumns.is() && i_xSelectColumns->hasByName(pAndIter->Name) ) 1532 { 1533 Reference<XPropertySet> xColumn(i_xSelectColumns->getByName(pAndIter->Name),UNO_QUERY); 1534 sValue = i_aPredicateInputController.getPredicateValue(sValue,xColumn,sal_True); 1535 } 1536 else 1537 { 1538 sValue = i_aPredicateInputController.getPredicateValue(pAndIter->Name,sValue,sal_True); 1539 } 1540 lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet); 1541 ++pAndIter; 1542 if ( pAndIter != pAndEnd ) 1543 sRet.append(STR_AND); 1544 } 1545 sRet.append(R_BRACKET); 1546 } 1547 ++pOrIter; 1548 if ( pOrIter != pOrEnd && sRet.getLength() ) 1549 sRet.append(STR_OR); 1550 } 1551 return sRet.makeStringAndClear(); 1552 } 1553 } 1554 // ----------------------------------------------------------------------------- 1555 void SAL_CALL OSingleSelectQueryComposer::setStructuredFilter( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, ::com::sun::star::lang::IllegalArgumentException, RuntimeException) 1556 { 1557 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredFilter" ); 1558 OPredicateInputController aPredicateInput(m_aContext.getLegacyServiceFactory(),m_xConnection); 1559 setFilter(lcl_getCondition(filter,aPredicateInput,getColumns())); 1560 } 1561 // ----------------------------------------------------------------------------- 1562 void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, RuntimeException) 1563 { 1564 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredHavingClause" ); 1565 OPredicateInputController aPredicateInput(m_aContext.getLegacyServiceFactory(),m_xConnection); 1566 setHavingClause(lcl_getCondition(filter,aPredicateInput,getColumns())); 1567 } 1568 // ----------------------------------------------------------------------------- 1569 void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor,sal_Int32 filterOperator) 1570 { 1571 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setConditionByColumn" ); 1572 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1573 1574 if ( !column.is() 1575 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE) 1576 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) 1577 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE)) 1578 throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() ); 1579 1580 sal_Int32 nType = 0; 1581 column->getPropertyValue(PROPERTY_TYPE) >>= nType; 1582 sal_Int32 nSearchable = dbtools::getSearchColumnFlag(m_xConnection,nType); 1583 if(nSearchable == ColumnSearch::NONE) 1584 throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_SEARCHABLE),*this,SQLSTATE_GENERAL,1000,Any() ); 1585 1586 ::osl::MutexGuard aGuard( m_aMutex ); 1587 1588 ::rtl::OUString aName; 1589 column->getPropertyValue(PROPERTY_NAME) >>= aName; 1590 1591 Any aValue; 1592 column->getPropertyValue(PROPERTY_VALUE) >>= aValue; 1593 1594 ::rtl::OUStringBuffer aSQL; 1595 const ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString(); 1596 getColumns(); 1597 1598 if ( m_aCurrentColumns[SelectColumns] && m_aCurrentColumns[SelectColumns]->hasByName(aName) ) 1599 { 1600 Reference<XPropertySet> xColumn; 1601 m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn; 1602 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!"); 1603 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!"); 1604 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"))),"Property AggregateFunctionnot available!"); 1605 1606 ::rtl::OUString sRealName,sTableName; 1607 xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName; 1608 xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName; 1609 if(sTableName.indexOf('.',0) != -1) 1610 { 1611 ::rtl::OUString aCatlog,aSchema,aTable; 1612 ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation); 1613 sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation ); 1614 } 1615 else 1616 sTableName = ::dbtools::quoteName(aQuote,sTableName); 1617 1618 if ( !::comphelper::getBOOL(xColumn->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function")))) ) 1619 { 1620 aSQL = sTableName; 1621 aSQL.appendAscii( "." ); 1622 aSQL.append( ::dbtools::quoteName( aQuote, sRealName ) ); 1623 } 1624 else 1625 aSQL = sRealName; 1626 1627 } 1628 else 1629 { 1630 aSQL = getTableAlias( column ); 1631 aSQL.append( ::dbtools::quoteName( aQuote, aName ) ); 1632 } 1633 1634 1635 if ( aValue.hasValue() ) 1636 { 1637 if( !m_xTypeConverter.is() ) 1638 m_aContext.createComponent( "com.sun.star.script.Converter", m_xTypeConverter ); 1639 OSL_ENSURE(m_xTypeConverter.is(),"NO typeconverter!"); 1640 1641 if ( nType != DataType::BOOLEAN && DataType::BIT != nType ) 1642 { 1643 ::rtl::OUString sEmpty; 1644 lcl_addFilterCriteria_throw(filterOperator,sEmpty,aSQL); 1645 } 1646 1647 switch(nType) 1648 { 1649 case DataType::VARCHAR: 1650 case DataType::CHAR: 1651 case DataType::LONGVARCHAR: 1652 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); 1653 break; 1654 case DataType::CLOB: 1655 { 1656 Reference< XClob > xClob(aValue,UNO_QUERY); 1657 if ( xClob.is() ) 1658 { 1659 const ::sal_Int64 nLength = xClob->length(); 1660 if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) ) 1661 { 1662 aSQL.appendAscii("'"); 1663 aSQL.append( xClob->getSubString(1,(sal_Int32)nLength) ); 1664 aSQL.appendAscii("'"); 1665 } 1666 } 1667 else 1668 { 1669 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); 1670 } 1671 } 1672 break; 1673 case DataType::VARBINARY: 1674 case DataType::BINARY: 1675 case DataType::LONGVARBINARY: 1676 { 1677 Sequence<sal_Int8> aSeq; 1678 if(aValue >>= aSeq) 1679 { 1680 if(nSearchable == ColumnSearch::CHAR) 1681 { 1682 aSQL.appendAscii( "\'" ); 1683 } 1684 aSQL.appendAscii( "0x" ); 1685 const sal_Int8* pBegin = aSeq.getConstArray(); 1686 const sal_Int8* pEnd = pBegin + aSeq.getLength(); 1687 for(;pBegin != pEnd;++pBegin) 1688 { 1689 aSQL.append( (sal_Int32)*pBegin, 16 ).getStr(); 1690 } 1691 if(nSearchable == ColumnSearch::CHAR) 1692 aSQL.appendAscii( "\'" ); 1693 } 1694 else 1695 throw SQLException(DBACORE_RESSTRING(RID_STR_NOT_SEQUENCE_INT8),*this,SQLSTATE_GENERAL,1000,Any() ); 1696 } 1697 break; 1698 case DataType::BIT: 1699 case DataType::BOOLEAN: 1700 { 1701 sal_Bool bValue = sal_False; 1702 m_xTypeConverter->convertToSimpleType(aValue, TypeClass_BOOLEAN) >>= bValue; 1703 1704 ::rtl::OUString sColumnExp = aSQL.makeStringAndClear(); 1705 getBoleanComparisonPredicate( sColumnExp, bValue, m_nBoolCompareMode, aSQL ); 1706 } 1707 break; 1708 default: 1709 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) ); 1710 break; 1711 } 1712 } 1713 else 1714 { 1715 sal_Int32 nFilterOp = filterOperator; 1716 if ( filterOperator != SQLFilterOperator::SQLNULL && filterOperator != SQLFilterOperator::NOT_SQLNULL ) 1717 nFilterOp = SQLFilterOperator::SQLNULL; 1718 ::rtl::OUString sEmpty; 1719 lcl_addFilterCriteria_throw(nFilterOp,sEmpty,aSQL); 1720 } 1721 1722 // filter anhaengen 1723 // select ohne where und order by aufbauen 1724 ::rtl::OUString sFilter = getFilter(); 1725 1726 if ( sFilter.getLength() && aSQL.getLength() ) 1727 { 1728 ::rtl::OUString sTemp(L_BRACKET); 1729 sTemp += sFilter; 1730 sTemp += R_BRACKET; 1731 sTemp += andCriteria ? STR_AND : STR_OR; 1732 sFilter = sTemp; 1733 } 1734 sFilter += aSQL.makeStringAndClear(); 1735 1736 // add the filter and the sort order 1737 _aSetFunctor(this,sFilter); 1738 } 1739 // ----------------------------------------------------------------------------- 1740 Sequence< Sequence< PropertyValue > > OSingleSelectQueryComposer::getStructuredCondition( TGetParseNode& _aGetFunctor ) 1741 { 1742 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredCondition" ); 1743 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); 1744 1745 MutexGuard aGuard(m_aMutex); 1746 1747 Sequence< Sequence< PropertyValue > > aFilterSeq; 1748 ::rtl::OUString sFilter = getStatementPart( _aGetFunctor, m_aAdditiveIterator ); 1749 1750 if ( sFilter.getLength() != 0 ) 1751 { 1752 ::rtl::OUString aSql(m_aPureSelectSQL); 1753 // build a temporary parse node 1754 const OSQLParseNode* pTempNode = m_aAdditiveIterator.getParseTree(); 1755 1756 aSql += STR_WHERE; 1757 aSql += sFilter; 1758 1759 ::rtl::OUString aErrorMsg; 1760 ::std::auto_ptr<OSQLParseNode> pSqlParseNode( m_aSqlParser.parseTree(aErrorMsg,aSql)); 1761 if ( pSqlParseNode.get() ) 1762 { 1763 m_aAdditiveIterator.setParseTree(pSqlParseNode.get()); 1764 // normalize the filter 1765 OSQLParseNode* pWhereNode = const_cast<OSQLParseNode*>(m_aAdditiveIterator.getWhereTree()); 1766 1767 OSQLParseNode* pCondition = pWhereNode->getChild(1); 1768 #if OSL_DEBUG_LEVEL > 0 1769 ::rtl::OUString sCondition; 1770 pCondition->parseNodeToStr( sCondition, m_xConnection ); 1771 #endif 1772 OSQLParseNode::negateSearchCondition(pCondition); 1773 1774 pCondition = pWhereNode->getChild(1); 1775 #if OSL_DEBUG_LEVEL > 0 1776 sCondition = ::rtl::OUString(); 1777 pCondition->parseNodeToStr( sCondition, m_xConnection ); 1778 #endif 1779 OSQLParseNode::disjunctiveNormalForm(pCondition); 1780 1781 pCondition = pWhereNode->getChild(1); 1782 #if OSL_DEBUG_LEVEL > 0 1783 sCondition = ::rtl::OUString(); 1784 pCondition->parseNodeToStr( sCondition, m_xConnection ); 1785 #endif 1786 OSQLParseNode::absorptions(pCondition); 1787 1788 pCondition = pWhereNode->getChild(1); 1789 #if OSL_DEBUG_LEVEL > 0 1790 sCondition = ::rtl::OUString(); 1791 pCondition->parseNodeToStr( sCondition, m_xConnection ); 1792 #endif 1793 if ( pCondition ) 1794 { 1795 ::std::vector< ::std::vector < PropertyValue > > aFilters; 1796 Reference< XNumberFormatter > xFormatter; 1797 m_aContext.createComponent( "com.sun.star.util.NumberFormatter", xFormatter ); 1798 xFormatter->attachNumberFormatsSupplier( m_xNumberFormatsSupplier ); 1799 1800 if (setORCriteria(pCondition, m_aAdditiveIterator, aFilters, xFormatter)) 1801 { 1802 aFilterSeq.realloc(aFilters.size()); 1803 Sequence<PropertyValue>* pFilters = aFilterSeq.getArray(); 1804 ::std::vector< ::std::vector < PropertyValue > >::const_iterator aEnd = aFilters.end(); 1805 ::std::vector< ::std::vector < PropertyValue > >::const_iterator i = aFilters.begin(); 1806 for ( ; i != aEnd ; ++i) 1807 { 1808 const ::std::vector < PropertyValue >& rProperties = *i; 1809 pFilters->realloc(rProperties.size()); 1810 PropertyValue* pFilter = pFilters->getArray(); 1811 ::std::vector < PropertyValue >::const_iterator j = rProperties.begin(); 1812 ::std::vector < PropertyValue >::const_iterator aEnd2 = rProperties.end(); 1813 for ( ; j != aEnd2 ; ++j) 1814 { 1815 *pFilter = *j; 1816 ++pFilter; 1817 } 1818 ++pFilters; 1819 } 1820 } 1821 } 1822 // restore 1823 m_aAdditiveIterator.setParseTree(pTempNode); 1824 } 1825 } 1826 return aFilterSeq; 1827 } 1828 // ----------------------------------------------------------------------------- 1829 ::rtl::OUString OSingleSelectQueryComposer::getKeyword( SQLPart _ePart ) const 1830 { 1831 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getKeyword" ); 1832 ::rtl::OUString sKeyword; 1833 switch(_ePart) 1834 { 1835 default: 1836 OSL_ENSURE( 0, "OSingleSelectQueryComposer::getKeyWord: Invalid enum value!" ); 1837 // no break, fallback to WHERE 1838 case Where: 1839 sKeyword = STR_WHERE; 1840 break; 1841 case Group: 1842 sKeyword = STR_GROUP_BY; 1843 break; 1844 case Having: 1845 sKeyword = STR_HAVING; 1846 break; 1847 case Order: 1848 sKeyword = STR_ORDER_BY; 1849 break; 1850 } 1851 return sKeyword; 1852 } 1853 1854 // ----------------------------------------------------------------------------- 1855 ::rtl::OUString OSingleSelectQueryComposer::getSQLPart( SQLPart _ePart, OSQLParseTreeIterator& _rIterator, sal_Bool _bWithKeyword ) 1856 { 1857 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getSQLPart" ); 1858 TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree); 1859 ::rtl::OUString sKeyword( getKeyword( _ePart ) ); 1860 switch(_ePart) 1861 { 1862 case Where: 1863 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleWhereTree); 1864 break; 1865 case Group: 1866 F_tmp = TGetParseNode (&OSQLParseTreeIterator::getSimpleGroupByTree); 1867 break; 1868 case Having: 1869 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleHavingTree); 1870 break; 1871 case Order: 1872 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleOrderTree); 1873 break; 1874 default: 1875 OSL_ENSURE(0,"Invalid enum value!"); 1876 } 1877 1878 ::rtl::OUString sRet = getStatementPart( F_tmp, _rIterator ); 1879 if ( _bWithKeyword && sRet.getLength() ) 1880 sRet = sKeyword + sRet; 1881 return sRet; 1882 } 1883 // ----------------------------------------------------------------------------- 1884