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