1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/sdb/XParametersSupplier.hpp>
22 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
23 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
24 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
25 #include <com/sun/star/lang/XServiceInfo.hpp>
26 #include <com/sun/star/script/XTypeConverter.hpp>
27 #include <cppuhelper/implbase5.hxx>
28 #include <connectivity/sqliterator.hxx>
29 #include <connectivity/sqlparse.hxx>
30 #include <apitools.hxx>
31 #include <comphelper/broadcasthelper.hxx>
32 #include <comphelper/uno3.hxx>
33 #include <comphelper/proparrhlp.hxx>
34 #include <comphelper/propertycontainer.hxx>
35 #include <svx/ParseContext.hxx>
37 namespace com::sun::star::util
{
38 class XNumberFormatsSupplier
;
39 class XNumberFormatter
;
44 typedef ::cppu::ImplHelper5
< css::sdb::XSingleSelectQueryComposer
,
45 css::sdb::XParametersSupplier
,
46 css::sdbcx::XColumnsSupplier
,
47 css::sdbcx::XTablesSupplier
,
48 css::lang::XServiceInfo
> OSingleSelectQueryComposer_BASE
;
50 class OPrivateColumns
;
53 class OSingleSelectQueryComposer
: public ::comphelper::OMutexAndBroadcastHelper
55 ,public ::comphelper::OPropertyContainer
56 ,public ::comphelper::OPropertyArrayUsageHelper
< OSingleSelectQueryComposer
>
57 ,public OSingleSelectQueryComposer_BASE
61 Where
= 0, // the 0 is important, as it will be used as index into arrays
68 static void incSQLPart( SQLPart
& e
) { e
= static_cast<SQLPart
>(1 + static_cast<size_t>(e
)); }
76 typedef std::function
<const ::connectivity::OSQLParseNode
*(::connectivity::OSQLParseTreeIterator
*)>
78 ::svxform::OSystemParseContext m_aParseContext
;
79 ::connectivity::OSQLParser m_aSqlParser
;
80 ::connectivity::OSQLParseTreeIterator m_aSqlIterator
; // the iterator for the complete statement
81 ::connectivity::OSQLParseTreeIterator m_aAdditiveIterator
; // the iterator for the "additive statement" (means without the clauses of the elementary statement)
82 std::vector
<std::unique_ptr
<OPrivateColumns
>>
83 m_aColumnsCollection
; // used for columns and parameters of old queries
84 std::vector
<std::unique_ptr
<OPrivateTables
>>
87 std::vector
< OUString
> m_aElementaryParts
; // the filter/groupby/having/order of the elementary statement
89 css::uno::Reference
< css::sdbc::XConnection
> m_xConnection
;
90 css::uno::Reference
< css::sdbc::XDatabaseMetaData
> m_xMetaData
;
91 css::uno::Reference
< css::container::XNameAccess
> m_xConnectionTables
;
92 css::uno::Reference
< css::container::XNameAccess
> m_xConnectionQueries
;
93 css::uno::Reference
< css::util::XNumberFormatsSupplier
> m_xNumberFormatsSupplier
;
94 css::uno::Reference
< css::uno::XComponentContext
> m_aContext
;
95 css::uno::Reference
< css::script::XTypeConverter
> m_xTypeConverter
;
97 std::vector
<std::unique_ptr
<OPrivateColumns
>> m_aCurrentColumns
;
98 std::unique_ptr
<OPrivateTables
> m_pTables
; // currently used tables
100 OUString m_aPureSelectSQL
; // the pure select statement, without filter/order/groupby/having
101 OUString m_sDecimalSep
;
103 css::lang::Locale m_aLocale
;
104 sal_Int32 m_nBoolCompareMode
; // how to compare bool values
105 sal_Int32 m_nCommandType
;
108 OUString m_sOriginal
;
112 bool setORCriteria(::connectivity::OSQLParseNode
const * pCondition
, ::connectivity::OSQLParseTreeIterator
& _rIterator
,
113 std::vector
< std::vector
< css::beans::PropertyValue
> >& rFilters
, const css::uno::Reference
< css::util::XNumberFormatter
> & xFormatter
) const;
114 bool setANDCriteria(::connectivity::OSQLParseNode
const * pCondition
, ::connectivity::OSQLParseTreeIterator
& _rIterator
,
115 std::vector
< css::beans::PropertyValue
> & rFilters
, const css::uno::Reference
< css::util::XNumberFormatter
> & xFormatter
) const;
116 bool setLikePredicate(::connectivity::OSQLParseNode
const * pCondition
, ::connectivity::OSQLParseTreeIterator
const & _rIterator
,
117 std::vector
< css::beans::PropertyValue
> & rFilters
, const css::uno::Reference
< css::util::XNumberFormatter
> & xFormatter
) const;
118 bool setComparisonPredicate(::connectivity::OSQLParseNode
const * pCondition
, ::connectivity::OSQLParseTreeIterator
const & _rIterator
,
119 std::vector
< css::beans::PropertyValue
> & rFilters
, const css::uno::Reference
< css::util::XNumberFormatter
> & xFormatter
) const;
121 static OUString
getColumnName(::connectivity::OSQLParseNode
const * pColumnRef
, ::connectivity::OSQLParseTreeIterator
const & _rIterator
);
122 OUString
getTableAlias(const css::uno::Reference
< css::beans::XPropertySet
>& column
) const;
123 static sal_Int32
getPredicateType(::connectivity::OSQLParseNode
const * _pPredicate
);
124 // clears all Columns,Parameters and tables and insert it to their vectors
125 void clearCurrentCollections();
126 // clears the columns collection given by EColumnType
127 void clearColumns( const EColumnType _eType
);
129 /** retrieves a particular part of a statement
133 OUString
getStatementPart( TGetParseNode
const & _aGetFunctor
, ::connectivity::OSQLParseTreeIterator
& _rIterator
);
134 void setQuery_Impl( const OUString
& command
);
136 void setConditionByColumn( const css::uno::Reference
< css::beans::XPropertySet
>& column
138 , std::function
<bool(OSingleSelectQueryComposer
*, const OUString
&)> const & _aSetFunctor
139 ,sal_Int32 filterOperator
);
141 /** getStructuredCondition returns the structured condition for the where or having clause
143 A member function to get the correct parse node.
146 The structured filter
148 css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> >
149 getStructuredCondition( TGetParseNode
const & _aGetFunctor
);
151 css::uno::Reference
< css::container::XIndexAccess
>
152 setCurrentColumns( EColumnType _eType
, const ::rtl::Reference
< ::connectivity::OSQLColumns
>& _rCols
);
154 //helper methods for mem_fun_t
155 bool implSetFilter(const OUString
& _sFilter
) { setFilter(_sFilter
); return true;}
156 bool implSetHavingClause(const OUString
& _sFilter
) { setHavingClause(_sFilter
); return true;}
158 /** returns the part of the select statement
160 Which part should be returned.
162 If <TRUE/> the keyword will be added too. Otherwise not.
167 The part of the select statement.
169 OUString
getSQLPart( SQLPart _ePart
, ::connectivity::OSQLParseTreeIterator
& _rIterator
, bool _bWithKeyword
);
171 /** retrieves the keyword for the given SQLPart
173 static OUString
getKeyword( SQLPart _ePart
);
175 /** sets a single "additive" clause, means a filter/groupby/having/order clause
177 void setSingleAdditiveClause( SQLPart _ePart
, const OUString
& _rClause
);
179 /** composes a statement from m_aPureSelectSQL and the 4 usual clauses
181 OUString
composeStatementFromParts( const std::vector
< OUString
>& _rParts
);
183 /** return the name of the column in the *source* *table*.
185 That is, for (SELECT a AS b FROM t), it returns A or "t"."A", as appropriate.
187 Use e.g. for WHERE, GROUP BY and HAVING clauses.
189 @param bGroupBy: for GROUP BY clause? In that case, throw exception if trying to use an unrelated column and the database does not support that.
191 OUString
impl_getColumnRealName_throw(const css::uno::Reference
< css::beans::XPropertySet
>& column
, bool bGroupBy
);
193 /** return the name of the column in the *query* for ORDER BY clause.
195 That is, for (SELECT a AS b FROM t), it returns "b"
197 Throws exception if trying to use an unrelated column and the database does not support that.
199 OUString
impl_getColumnNameOrderBy_throw(const css::uno::Reference
< css::beans::XPropertySet
>& column
);
202 virtual ~OSingleSelectQueryComposer() override
;
205 OSingleSelectQueryComposer( const css::uno::Reference
< css::container::XNameAccess
>& _xTableSupplier
,
206 const css::uno::Reference
< css::sdbc::XConnection
>& _xConnection
,
207 const css::uno::Reference
< css::uno::XComponentContext
>& _rContext
);
210 void SAL_CALL
disposing() override
;
212 virtual css::uno::Sequence
<css::uno::Type
> SAL_CALL
getTypes() override
;
213 virtual css::uno::Sequence
<sal_Int8
> SAL_CALL
getImplementationId() override
;
215 // css::uno::XInterface
216 DECLARE_XINTERFACE( )
219 DECLARE_SERVICE_INFO();
221 DECLARE_PROPERTYCONTAINER_DEFAULTS();
223 // css::sdb::XSingleSelectQueryComposer
224 virtual OUString SAL_CALL
getElementaryQuery() override
;
225 virtual void SAL_CALL
setElementaryQuery( const OUString
& _rElementary
) override
;
226 virtual void SAL_CALL
setFilter( const OUString
& filter
) override
;
227 virtual void SAL_CALL
setStructuredFilter( const css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> >& filter
) override
;
228 virtual void SAL_CALL
appendFilterByColumn( const css::uno::Reference
< css::beans::XPropertySet
>& column
, sal_Bool andCriteria
,sal_Int32 filterOperator
) override
;
229 virtual void SAL_CALL
appendGroupByColumn( const css::uno::Reference
< css::beans::XPropertySet
>& column
) override
;
230 virtual void SAL_CALL
setGroup( const OUString
& group
) override
;
231 virtual void SAL_CALL
setHavingClause( const OUString
& filter
) override
;
232 virtual void SAL_CALL
setStructuredHavingClause( const css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> >& filter
) override
;
233 virtual void SAL_CALL
appendHavingClauseByColumn( const css::uno::Reference
< css::beans::XPropertySet
>& column
, sal_Bool andCriteria
,sal_Int32 filterOperator
) override
;
234 virtual void SAL_CALL
appendOrderByColumn( const css::uno::Reference
< css::beans::XPropertySet
>& column
, sal_Bool ascending
) override
;
235 virtual void SAL_CALL
setOrder( const OUString
& order
) override
;
237 // XSingleSelectQueryAnalyzer
238 virtual OUString SAL_CALL
getQuery( ) override
;
239 virtual void SAL_CALL
setQuery( const OUString
& command
) override
;
240 virtual void SAL_CALL
setCommand( const OUString
& command
,sal_Int32 CommandType
) override
;
241 virtual OUString SAL_CALL
getFilter( ) override
;
242 virtual css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > SAL_CALL
getStructuredFilter( ) override
;
243 virtual OUString SAL_CALL
getGroup( ) override
;
244 virtual css::uno::Reference
< css::container::XIndexAccess
> SAL_CALL
getGroupColumns( ) override
;
245 virtual OUString SAL_CALL
getHavingClause( ) override
;
246 virtual css::uno::Sequence
< css::uno::Sequence
< css::beans::PropertyValue
> > SAL_CALL
getStructuredHavingClause( ) override
;
247 virtual OUString SAL_CALL
getOrder( ) override
;
248 virtual css::uno::Reference
< css::container::XIndexAccess
> SAL_CALL
getOrderColumns( ) override
;
249 virtual OUString SAL_CALL
getQueryWithSubstitution( ) override
;
252 virtual css::uno::Reference
< css::container::XNameAccess
> SAL_CALL
getColumns( ) override
;
254 virtual css::uno::Reference
< css::container::XNameAccess
> SAL_CALL
getTables( ) override
;
255 // XParametersSupplier
256 virtual css::uno::Reference
< css::container::XIndexAccess
> SAL_CALL
getParameters( ) override
;
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */