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 */
parseStatement_throwError(OSQLParser & _rParser,const::rtl::OUString & _rStatement,const Reference<XInterface> & _rxContext)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 */
checkForSingleSelect_throwError(const OSQLParseNode * pStatementNode,OSQLParseTreeIterator & _rIterator,const Reference<XInterface> & _rxContext,const::rtl::OUString & _rOriginatingCommand)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 */
parseAndCheck_throwError(OSQLParser & _rParser,const::rtl::OUString & _rStatement,OSQLParseTreeIterator & _rIterator,const Reference<XInterface> & _rxContext)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 */
getPureSelectStatement(const OSQLParseNode * _pRootNode,Reference<XConnection> _rxConnection)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 */
resetIterator(OSQLParseTreeIterator & _rIterator,bool _bDispose)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 }
lcl_addFilterCriteria_throw(sal_Int32 i_nFilterOperator,const::rtl::OUString & i_sValue,::rtl::OUStringBuffer & o_sRet)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
DBG_NAME(OSingleSelectQueryComposer)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 // -------------------------------------------------------------------------
~OSingleSelectQueryComposer()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
disposing(void)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 }
IMPLEMENT_FORWARD_XINTERFACE3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer)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
getQuery()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 // -------------------------------------------------------------------------
setQuery(const::rtl::OUString & command)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 // -------------------------------------------------------------------------
setCommand(const::rtl::OUString & Command,sal_Int32 _nCommandType)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 // -----------------------------------------------------------------------------
setQuery_Impl(const::rtl::OUString & command)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 // -----------------------------------------------------------------------------
getStructuredHavingClause()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 // -------------------------------------------------------------------------
getStructuredFilter()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 // -----------------------------------------------------------------------------
appendHavingClauseByColumn(const Reference<XPropertySet> & column,sal_Bool andCriteria,sal_Int32 filterOperator)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 // -----------------------------------------------------------------------------
appendFilterByColumn(const Reference<XPropertySet> & column,sal_Bool andCriteria,sal_Int32 filterOperator)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 // -----------------------------------------------------------------------------
impl_getColumnName_throw(const Reference<XPropertySet> & column)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 // -------------------------------------------------------------------------
appendOrderByColumn(const Reference<XPropertySet> & column,sal_Bool ascending)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 // -------------------------------------------------------------------------
appendGroupByColumn(const Reference<XPropertySet> & column)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 // -------------------------------------------------------------------------
composeStatementFromParts(const::std::vector<::rtl::OUString> & _rParts)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 // -------------------------------------------------------------------------
getElementaryQuery()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 // -------------------------------------------------------------------------
setElementaryQuery(const::rtl::OUString & _rElementary)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 {
getComposedClause(const::rtl::OUString _rElementaryClause,const::rtl::OUString _rAdditionalClause,TokenComposer & _rComposer,const::rtl::OUString _rKeyword)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 // -------------------------------------------------------------------------
setSingleAdditiveClause(SQLPart _ePart,const::rtl::OUString & _rClause)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 // -------------------------------------------------------------------------
setFilter(const::rtl::OUString & filter)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 // -------------------------------------------------------------------------
setOrder(const::rtl::OUString & order)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 // -----------------------------------------------------------------------------
setGroup(const::rtl::OUString & group)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 // -------------------------------------------------------------------------
setHavingClause(const::rtl::OUString & filter)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
getTables()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
getColumns()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 // -------------------------------------------------------------------------
setORCriteria(OSQLParseNode * pCondition,OSQLParseTreeIterator & _rIterator,::std::vector<::std::vector<PropertyValue>> & rFilters,const Reference<::com::sun::star::util::XNumberFormatter> & xFormatter) const994 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 //--------------------------------------------------------------------------------------------------
setANDCriteria(OSQLParseNode * pCondition,OSQLParseTreeIterator & _rIterator,::std::vector<PropertyValue> & rFilter,const Reference<XNumberFormatter> & xFormatter) const1033 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 // -----------------------------------------------------------------------------
getPredicateType(OSQLParseNode * _pPredicate) const1124 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 //------------------------------------------------------------------------------
setComparsionPredicate(OSQLParseNode * pCondition,OSQLParseTreeIterator & _rIterator,::std::vector<PropertyValue> & rFilter,const Reference<::com::sun::star::util::XNumberFormatter> & xFormatter) const1154 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 //--------------------------------------------------------------------------------------------------
getColumnName(::connectivity::OSQLParseNode * pColumnRef,OSQLParseTreeIterator & _rIterator) const1278 ::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 //------------------------------------------------------------------------------
getFilter()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 // -------------------------------------------------------------------------
getOrder()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 // -------------------------------------------------------------------------
getGroup()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 // -----------------------------------------------------------------------------
getHavingClause()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 // -----------------------------------------------------------------------------
getTableAlias(const Reference<XPropertySet> & column) const1318 ::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 // -----------------------------------------------------------------------------
getParameters()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 // -----------------------------------------------------------------------------
clearColumns(const EColumnType _eType)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 // -----------------------------------------------------------------------------
clearCurrentCollections()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 // -----------------------------------------------------------------------------
setCurrentColumns(EColumnType _eType,const::vos::ORef<OSQLColumns> & _rCols)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 // -----------------------------------------------------------------------------
getGroupColumns()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 // -------------------------------------------------------------------------
getOrderColumns()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 // -----------------------------------------------------------------------------
getQueryWithSubstitution()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 // -----------------------------------------------------------------------------
getStatementPart(TGetParseNode & _aGetFunctor,OSQLParseTreeIterator & _rIterator)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 {
lcl_getDecomposedColumnName(const::rtl::OUString & rComposedName,const::rtl::OUString & rQuoteString)1510 ::rtl::OUString lcl_getDecomposedColumnName( const ::rtl::OUString& rComposedName, const ::rtl::OUString& rQuoteString )
1511 {
1512 const sal_Int32 nQuoteLength = rQuoteString.getLength();
1513 ::rtl::OUString sName = rComposedName.trim();
1514 ::rtl::OUString sColumnName;
1515 sal_Int32 nPos, nRPos = 0;
1516
1517 for (;;)
1518 {
1519 nPos = sName.indexOf( rQuoteString, nRPos );
1520 if ( nPos >= 0 )
1521 {
1522 nRPos = sName.indexOf( rQuoteString, nPos + nQuoteLength );
1523 if ( nRPos > nPos )
1524 {
1525 if ( nRPos + nQuoteLength < sName.getLength() )
1526 {
1527 nRPos += nQuoteLength; // -1 + 1 skip dot
1528 }
1529 else
1530 {
1531 sColumnName = sName.copy( nPos + nQuoteLength, nRPos - nPos - nQuoteLength );
1532 break;
1533 }
1534 }
1535 else
1536 break;
1537 }
1538 else
1539 break;
1540 }
1541 return sColumnName.isEmpty() ? rComposedName : sColumnName;
1542 }
1543
lcl_getCondition(const Sequence<Sequence<PropertyValue>> & filter,const OPredicateInputController & i_aPredicateInputController,const Reference<XNameAccess> & i_xSelectColumns,const::rtl::OUString & rQuoteString)1544 ::rtl::OUString lcl_getCondition(const Sequence< Sequence< PropertyValue > >& filter,
1545 const OPredicateInputController& i_aPredicateInputController,
1546 const Reference< XNameAccess >& i_xSelectColumns,
1547 const ::rtl::OUString& rQuoteString )
1548 {
1549 ::rtl::OUStringBuffer sRet;
1550 const Sequence< PropertyValue >* pOrIter = filter.getConstArray();
1551 const Sequence< PropertyValue >* pOrEnd = pOrIter + filter.getLength();
1552 while ( pOrIter != pOrEnd )
1553 {
1554 if ( pOrIter->getLength() )
1555 {
1556 sRet.append(L_BRACKET);
1557 const PropertyValue* pAndIter = pOrIter->getConstArray();
1558 const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength();
1559 while ( pAndIter != pAndEnd )
1560 {
1561 sRet.append(pAndIter->Name);
1562 ::rtl::OUString sValue;
1563 pAndIter->Value >>= sValue;
1564 const ::rtl::OUString sColumnName = lcl_getDecomposedColumnName( pAndIter->Name, rQuoteString );
1565 if ( i_xSelectColumns.is() && i_xSelectColumns->hasByName(sColumnName) )
1566 {
1567 Reference<XPropertySet> xColumn(i_xSelectColumns->getByName(sColumnName),UNO_QUERY);
1568 sValue = i_aPredicateInputController.getPredicateValue(sValue,xColumn,sal_True);
1569 }
1570 else
1571 {
1572 sValue = i_aPredicateInputController.getPredicateValue(pAndIter->Name,sValue,sal_True);
1573 }
1574 lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet);
1575 ++pAndIter;
1576 if ( pAndIter != pAndEnd )
1577 sRet.append(STR_AND);
1578 }
1579 sRet.append(R_BRACKET);
1580 }
1581 ++pOrIter;
1582 if ( pOrIter != pOrEnd && sRet.getLength() )
1583 sRet.append(STR_OR);
1584 }
1585 return sRet.makeStringAndClear();
1586 }
1587 }
1588 // -----------------------------------------------------------------------------
setStructuredFilter(const Sequence<Sequence<PropertyValue>> & filter)1589 void SAL_CALL OSingleSelectQueryComposer::setStructuredFilter( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, ::com::sun::star::lang::IllegalArgumentException, RuntimeException)
1590 {
1591 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredFilter" );
1592 OPredicateInputController aPredicateInput(m_aContext.getLegacyServiceFactory(),m_xConnection);
1593 setFilter(lcl_getCondition(filter,aPredicateInput,getColumns(), m_xMetaData->getIdentifierQuoteString()));
1594 }
1595 // -----------------------------------------------------------------------------
setStructuredHavingClause(const Sequence<Sequence<PropertyValue>> & filter)1596 void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, RuntimeException)
1597 {
1598 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setStructuredHavingClause" );
1599 OPredicateInputController aPredicateInput(m_aContext.getLegacyServiceFactory(),m_xConnection);
1600 setHavingClause(lcl_getCondition(filter,aPredicateInput,getColumns(), m_xMetaData->getIdentifierQuoteString()));
1601 }
1602 // -----------------------------------------------------------------------------
setConditionByColumn(const Reference<XPropertySet> & column,sal_Bool andCriteria,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString> & _aSetFunctor,sal_Int32 filterOperator)1603 void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor,sal_Int32 filterOperator)
1604 {
1605 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::setConditionByColumn" );
1606 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
1607
1608 if ( !column.is()
1609 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE)
1610 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
1611 || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE))
1612 throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() );
1613
1614 sal_Int32 nType = 0;
1615 column->getPropertyValue(PROPERTY_TYPE) >>= nType;
1616 sal_Int32 nSearchable = dbtools::getSearchColumnFlag(m_xConnection,nType);
1617 if(nSearchable == ColumnSearch::NONE)
1618 throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_SEARCHABLE),*this,SQLSTATE_GENERAL,1000,Any() );
1619
1620 ::osl::MutexGuard aGuard( m_aMutex );
1621
1622 ::rtl::OUString aName;
1623 column->getPropertyValue(PROPERTY_NAME) >>= aName;
1624
1625 Any aValue;
1626 column->getPropertyValue(PROPERTY_VALUE) >>= aValue;
1627
1628 ::rtl::OUStringBuffer aSQL;
1629 const ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString();
1630 getColumns();
1631
1632 if ( m_aCurrentColumns[SelectColumns] && m_aCurrentColumns[SelectColumns]->hasByName(aName) )
1633 {
1634 Reference<XPropertySet> xColumn;
1635 m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn;
1636 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
1637 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
1638 OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction"))),"Property AggregateFunctionnot available!");
1639
1640 ::rtl::OUString sRealName,sTableName;
1641 xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
1642 xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
1643 if(sTableName.indexOf('.',0) != -1)
1644 {
1645 ::rtl::OUString aCatlog,aSchema,aTable;
1646 ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation);
1647 sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, sal_True, ::dbtools::eInDataManipulation );
1648 }
1649 else
1650 sTableName = ::dbtools::quoteName(aQuote,sTableName);
1651
1652 if ( !::comphelper::getBOOL(xColumn->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Function")))) )
1653 {
1654 aSQL = sTableName;
1655 aSQL.appendAscii( "." );
1656 aSQL.append( ::dbtools::quoteName( aQuote, sRealName ) );
1657 }
1658 else
1659 aSQL = sRealName;
1660
1661 }
1662 else
1663 {
1664 aSQL = getTableAlias( column );
1665 aSQL.append( ::dbtools::quoteName( aQuote, aName ) );
1666 }
1667
1668
1669 if ( aValue.hasValue() )
1670 {
1671 if( !m_xTypeConverter.is() )
1672 m_aContext.createComponent( "com.sun.star.script.Converter", m_xTypeConverter );
1673 OSL_ENSURE(m_xTypeConverter.is(),"NO typeconverter!");
1674
1675 if ( nType != DataType::BOOLEAN && DataType::BIT != nType )
1676 {
1677 ::rtl::OUString sEmpty;
1678 lcl_addFilterCriteria_throw(filterOperator,sEmpty,aSQL);
1679 }
1680
1681 switch(nType)
1682 {
1683 case DataType::VARCHAR:
1684 case DataType::CHAR:
1685 case DataType::LONGVARCHAR:
1686 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
1687 break;
1688 case DataType::CLOB:
1689 {
1690 Reference< XClob > xClob(aValue,UNO_QUERY);
1691 if ( xClob.is() )
1692 {
1693 const ::sal_Int64 nLength = xClob->length();
1694 if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) )
1695 {
1696 aSQL.appendAscii("'");
1697 aSQL.append( xClob->getSubString(1,(sal_Int32)nLength) );
1698 aSQL.appendAscii("'");
1699 }
1700 }
1701 else
1702 {
1703 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
1704 }
1705 }
1706 break;
1707 case DataType::VARBINARY:
1708 case DataType::BINARY:
1709 case DataType::LONGVARBINARY:
1710 {
1711 Sequence<sal_Int8> aSeq;
1712 if(aValue >>= aSeq)
1713 {
1714 if(nSearchable == ColumnSearch::CHAR)
1715 {
1716 aSQL.appendAscii( "\'" );
1717 }
1718 aSQL.appendAscii( "0x" );
1719 const sal_Int8* pBegin = aSeq.getConstArray();
1720 const sal_Int8* pEnd = pBegin + aSeq.getLength();
1721 for(;pBegin != pEnd;++pBegin)
1722 {
1723 aSQL.append( (sal_Int32)*pBegin, 16 ).getStr();
1724 }
1725 if(nSearchable == ColumnSearch::CHAR)
1726 aSQL.appendAscii( "\'" );
1727 }
1728 else
1729 throw SQLException(DBACORE_RESSTRING(RID_STR_NOT_SEQUENCE_INT8),*this,SQLSTATE_GENERAL,1000,Any() );
1730 }
1731 break;
1732 case DataType::BIT:
1733 case DataType::BOOLEAN:
1734 {
1735 sal_Bool bValue = sal_False;
1736 m_xTypeConverter->convertToSimpleType(aValue, TypeClass_BOOLEAN) >>= bValue;
1737
1738 ::rtl::OUString sColumnExp = aSQL.makeStringAndClear();
1739 getBoleanComparisonPredicate( sColumnExp, bValue, m_nBoolCompareMode, aSQL );
1740 }
1741 break;
1742 default:
1743 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, sal_True, m_xTypeConverter ) );
1744 break;
1745 }
1746 }
1747 else
1748 {
1749 sal_Int32 nFilterOp = filterOperator;
1750 if ( filterOperator != SQLFilterOperator::SQLNULL && filterOperator != SQLFilterOperator::NOT_SQLNULL )
1751 nFilterOp = SQLFilterOperator::SQLNULL;
1752 ::rtl::OUString sEmpty;
1753 lcl_addFilterCriteria_throw(nFilterOp,sEmpty,aSQL);
1754 }
1755
1756 // filter anhaengen
1757 // select ohne where und order by aufbauen
1758 ::rtl::OUString sFilter = getFilter();
1759
1760 if ( sFilter.getLength() && aSQL.getLength() )
1761 {
1762 ::rtl::OUString sTemp(L_BRACKET);
1763 sTemp += sFilter;
1764 sTemp += R_BRACKET;
1765 sTemp += andCriteria ? STR_AND : STR_OR;
1766 sFilter = sTemp;
1767 }
1768 sFilter += aSQL.makeStringAndClear();
1769
1770 // add the filter and the sort order
1771 _aSetFunctor(this,sFilter);
1772 }
1773 // -----------------------------------------------------------------------------
getStructuredCondition(TGetParseNode & _aGetFunctor)1774 Sequence< Sequence< PropertyValue > > OSingleSelectQueryComposer::getStructuredCondition( TGetParseNode& _aGetFunctor )
1775 {
1776 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getStructuredCondition" );
1777 ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
1778
1779 MutexGuard aGuard(m_aMutex);
1780
1781 Sequence< Sequence< PropertyValue > > aFilterSeq;
1782 ::rtl::OUString sFilter = getStatementPart( _aGetFunctor, m_aAdditiveIterator );
1783
1784 if ( sFilter.getLength() != 0 )
1785 {
1786 ::rtl::OUString aSql(m_aPureSelectSQL);
1787 // build a temporary parse node
1788 const OSQLParseNode* pTempNode = m_aAdditiveIterator.getParseTree();
1789
1790 aSql += STR_WHERE;
1791 aSql += sFilter;
1792
1793 ::rtl::OUString aErrorMsg;
1794 ::std::auto_ptr<OSQLParseNode> pSqlParseNode( m_aSqlParser.parseTree(aErrorMsg,aSql));
1795 if ( pSqlParseNode.get() )
1796 {
1797 m_aAdditiveIterator.setParseTree(pSqlParseNode.get());
1798 // normalize the filter
1799 OSQLParseNode* pWhereNode = const_cast<OSQLParseNode*>(m_aAdditiveIterator.getWhereTree());
1800
1801 OSQLParseNode* pCondition = pWhereNode->getChild(1);
1802 #if OSL_DEBUG_LEVEL > 0
1803 ::rtl::OUString sCondition;
1804 pCondition->parseNodeToStr( sCondition, m_xConnection );
1805 #endif
1806 OSQLParseNode::negateSearchCondition(pCondition);
1807
1808 pCondition = pWhereNode->getChild(1);
1809 #if OSL_DEBUG_LEVEL > 0
1810 sCondition = ::rtl::OUString();
1811 pCondition->parseNodeToStr( sCondition, m_xConnection );
1812 #endif
1813 OSQLParseNode::disjunctiveNormalForm(pCondition);
1814
1815 pCondition = pWhereNode->getChild(1);
1816 #if OSL_DEBUG_LEVEL > 0
1817 sCondition = ::rtl::OUString();
1818 pCondition->parseNodeToStr( sCondition, m_xConnection );
1819 #endif
1820 OSQLParseNode::absorptions(pCondition);
1821
1822 pCondition = pWhereNode->getChild(1);
1823 #if OSL_DEBUG_LEVEL > 0
1824 sCondition = ::rtl::OUString();
1825 pCondition->parseNodeToStr( sCondition, m_xConnection );
1826 #endif
1827 if ( pCondition )
1828 {
1829 ::std::vector< ::std::vector < PropertyValue > > aFilters;
1830 Reference< XNumberFormatter > xFormatter;
1831 m_aContext.createComponent( "com.sun.star.util.NumberFormatter", xFormatter );
1832 xFormatter->attachNumberFormatsSupplier( m_xNumberFormatsSupplier );
1833
1834 if (setORCriteria(pCondition, m_aAdditiveIterator, aFilters, xFormatter))
1835 {
1836 aFilterSeq.realloc(aFilters.size());
1837 Sequence<PropertyValue>* pFilters = aFilterSeq.getArray();
1838 ::std::vector< ::std::vector < PropertyValue > >::const_iterator aEnd = aFilters.end();
1839 ::std::vector< ::std::vector < PropertyValue > >::const_iterator i = aFilters.begin();
1840 for ( ; i != aEnd ; ++i)
1841 {
1842 const ::std::vector < PropertyValue >& rProperties = *i;
1843 pFilters->realloc(rProperties.size());
1844 PropertyValue* pFilter = pFilters->getArray();
1845 ::std::vector < PropertyValue >::const_iterator j = rProperties.begin();
1846 ::std::vector < PropertyValue >::const_iterator aEnd2 = rProperties.end();
1847 for ( ; j != aEnd2 ; ++j)
1848 {
1849 *pFilter = *j;
1850 ++pFilter;
1851 }
1852 ++pFilters;
1853 }
1854 }
1855 }
1856 // restore
1857 m_aAdditiveIterator.setParseTree(pTempNode);
1858 }
1859 }
1860 return aFilterSeq;
1861 }
1862 // -----------------------------------------------------------------------------
getKeyword(SQLPart _ePart) const1863 ::rtl::OUString OSingleSelectQueryComposer::getKeyword( SQLPart _ePart ) const
1864 {
1865 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getKeyword" );
1866 ::rtl::OUString sKeyword;
1867 switch(_ePart)
1868 {
1869 default:
1870 OSL_ENSURE( 0, "OSingleSelectQueryComposer::getKeyWord: Invalid enum value!" );
1871 // no break, fallback to WHERE
1872 case Where:
1873 sKeyword = STR_WHERE;
1874 break;
1875 case Group:
1876 sKeyword = STR_GROUP_BY;
1877 break;
1878 case Having:
1879 sKeyword = STR_HAVING;
1880 break;
1881 case Order:
1882 sKeyword = STR_ORDER_BY;
1883 break;
1884 }
1885 return sKeyword;
1886 }
1887
1888 // -----------------------------------------------------------------------------
getSQLPart(SQLPart _ePart,OSQLParseTreeIterator & _rIterator,sal_Bool _bWithKeyword)1889 ::rtl::OUString OSingleSelectQueryComposer::getSQLPart( SQLPart _ePart, OSQLParseTreeIterator& _rIterator, sal_Bool _bWithKeyword )
1890 {
1891 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::getSQLPart" );
1892 TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree);
1893 ::rtl::OUString sKeyword( getKeyword( _ePart ) );
1894 switch(_ePart)
1895 {
1896 case Where:
1897 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleWhereTree);
1898 break;
1899 case Group:
1900 F_tmp = TGetParseNode (&OSQLParseTreeIterator::getSimpleGroupByTree);
1901 break;
1902 case Having:
1903 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleHavingTree);
1904 break;
1905 case Order:
1906 F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleOrderTree);
1907 break;
1908 default:
1909 OSL_ENSURE(0,"Invalid enum value!");
1910 }
1911
1912 ::rtl::OUString sRet = getStatementPart( F_tmp, _rIterator );
1913 if ( _bWithKeyword && sRet.getLength() )
1914 sRet = sKeyword + sRet;
1915 return sRet;
1916 }
1917 // -----------------------------------------------------------------------------
1918