LibreOffice Module connectivity (master) 1
fanalyzer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <file/fanalyzer.hxx>
22#include <tools/debug.hxx>
24#include <file/FConnection.hxx>
25#include <strings.hrc>
26
27using namespace ::connectivity;
28using namespace ::connectivity::file;
29using namespace ::com::sun::star::uno;
30using namespace ::com::sun::star::beans;
31using namespace ::com::sun::star::sdbc;
32using namespace ::com::sun::star::container;
33
34OSQLAnalyzer::OSQLAnalyzer(OConnection* _pConnection)
35 :m_pConnection(_pConnection)
36 ,m_bHasSelectionCode(false)
37 ,m_bSelectionFirstTime(true)
38{
41}
42
43
45{
46}
47
48
49void OSQLAnalyzer::start(OSQLParseNode const * pSQLParseNode)
50{
51 if (SQL_ISRULE(pSQLParseNode,select_statement))
52 {
53 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Error in Parse Tree");
54
55 // check that we don't use anything other than count(*) as function
56 OSQLParseNode* pSelection = pSQLParseNode->getChild(2);
57 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) )
58 {
59 for (size_t i = 0; i < pSelection->count(); i++)
60 {
61 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
62 if ( ( SQL_ISRULE(pColumnRef,set_fct_spec) && pColumnRef->count() == 4 )
63 || SQL_ISRULE(pColumnRef,char_value_fct)
64 || SQL_ISRULE(pColumnRef,char_substring_fct)
65 || SQL_ISRULE(pColumnRef,position_exp)
66 || SQL_ISRULE(pColumnRef,fold)
67 || SQL_ISRULE(pColumnRef,length_exp)
68 || SQL_ISRULE(pColumnRef,num_value_exp)
69 || SQL_ISRULE(pColumnRef,term)
70 || SQL_ISRULE(pColumnRef,factor)
71 || SQL_ISRULE(pColumnRef,set_fct_spec) )
72 {
74 pCompiler->setOrigColumns(m_aCompiler->getOrigColumns());
76 pCompiler->execute( pColumnRef );
77 m_aSelectionEvaluations.push_back( TPredicates(pCompiler,pInterpreter) );
78 }
79 else if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 )
80 {
81 m_pConnection->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,nullptr);
82 }
83 else
84 {
85 if ( SQL_ISPUNCTUATION( pColumnRef, "*" )
86 || ( SQL_ISRULE( pColumnRef, column_ref )
87 && ( pColumnRef->count() == 3 )
88 && ( pColumnRef->getChild(0)->getNodeType() == SQLNodeType::Name )
89 && SQL_ISPUNCTUATION( pColumnRef->getChild(1), "." )
90 && SQL_ISRULE( pColumnRef->getChild(2), column_val )
91 && SQL_ISPUNCTUATION( pColumnRef->getChild(2)->getChild(0), "*" )
92 )
93 )
94 {
95 // push one element for each column of our table
96 const Reference< XNameAccess > xColumnNames( m_aCompiler->getOrigColumns() );
97 const Sequence< OUString > aColumnNames( xColumnNames->getElementNames() );
98 for ( sal_Int32 j=0; j<aColumnNames.getLength(); ++j )
100 }
101 else
103 }
104 }
105 }
106 }
107
108 m_aCompiler->start(pSQLParseNode);
109}
110
111
112void OSQLAnalyzer::bindRow(OCodeList& rCodeList,const OValueRefRow& _pRow)
113{
114 for (auto const& code : rCodeList)
115 {
116 OOperandAttr* pAttr = dynamic_cast<OOperandAttr*>(code.get());
117 if (pAttr)
118 {
119 pAttr->bindValue(_pRow);
120 }
121 }
122}
123
125{
126 // first the select part
127 for (auto const& selectionEval : m_aSelectionEvaluations)
128 {
129 if ( selectionEval.first.is() )
130 bindRow(selectionEval.first->m_aCodeList,_pRow);
131 }
132}
133
135{
136 bindRow(m_aCompiler->m_aCodeList,_pRow);
137}
138
140 const Reference< XPropertySet>& _xCol)
141{
142 return new OOperandAttr(static_cast<sal_uInt16>(_nPos),_xCol);
143}
144
146{
147 return m_aCompiler->hasCode();
148}
149
151{
153 {
154 m_bSelectionFirstTime = false;
155 for (auto const& selectionEval : m_aSelectionEvaluations)
156 {
157 if ( selectionEval.first.is() )
158 {
159 m_bHasSelectionCode = selectionEval.first->hasCode();
161 break;
162 }
163 }
164 }
165 return m_bHasSelectionCode;
166}
167
168void OSQLAnalyzer::setSelectionEvaluationResult(OValueRefRow const & _pRow,const std::vector<sal_Int32>& _rColumnMapping)
169{
170 sal_Int32 nPos = 1;
171 for (auto const& selectionEval : m_aSelectionEvaluations)
172 {
173 if ( selectionEval.second.is() )
174 {
175 // the first column (index 0) is for convenience only. The first real select column is no 1.
176 sal_Int32 map = nPos;
177 if ( nPos < static_cast< sal_Int32 >( _rColumnMapping.size() ) )
178 map = _rColumnMapping[nPos];
179 if ( map > 0 )
180 selectionEval.second->startSelection( (*_pRow)[map] );
181 }
182 ++nPos;
183 }
184}
185
187{
188 m_aCompiler->dispose();
189 for (auto const& selectionEval : m_aSelectionEvaluations)
190 {
191 if ( selectionEval.first.is() )
192 selectionEval.first->dispose();
193 }
194}
195
196void OSQLAnalyzer::setOrigColumns(const css::uno::Reference< css::container::XNameAccess>& rCols)
197{
198 m_aCompiler->setOrigColumns(rCols);
199 for (auto const& selectionEval : m_aSelectionEvaluations)
200 {
201 if ( selectionEval.first.is() )
202 selectionEval.first->setOrigColumns(rCols);
203 }
204}
205
206
207/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void throwGenericSQLException(TranslateId pErrorResourceId, const css::uno::Reference< css::uno::XInterface > &_xContext)
Definition: TConnection.cxx:74
OSQLParseNode * getChild(sal_uInt32 nPos) const
Definition: sqlnode.hxx:433
SQLNodeType getNodeType() const
Definition: sqlnode.hxx:339
void bindValue(const OValueRefRow &_pRow)
Definition: fcode.cxx:40
::rtl::Reference< OPredicateCompiler > m_aCompiler
Definition: fanalyzer.hxx:32
void setSelectionEvaluationResult(OValueRefRow const &_pRow, const std::vector< sal_Int32 > &_rColumnMapping)
Definition: fanalyzer.cxx:168
std::vector< TPredicates > m_aSelectionEvaluations
Definition: fanalyzer.hxx:31
void bindSelectRow(const OValueRefRow &_pRow)
bind the select columns if they contain a function which needs a row value
Definition: fanalyzer.cxx:124
::rtl::Reference< OPredicateInterpreter > m_aInterpreter
Definition: fanalyzer.hxx:33
std::pair< ::rtl::Reference< OPredicateCompiler >,::rtl::Reference< OPredicateInterpreter > > TPredicates
Definition: fanalyzer.hxx:29
static void bindRow(OCodeList &rCodeList, const OValueRefRow &_pRow)
Definition: fanalyzer.cxx:112
static OOperandAttr * createOperandAttr(sal_Int32 _nPos, const css::uno::Reference< css::beans::XPropertySet > &_xCol)
Definition: fanalyzer.cxx:139
void setOrigColumns(const css::uno::Reference< css::container::XNameAccess > &rCols)
Definition: fanalyzer.cxx:196
void start(OSQLParseNode const *pSQLParseNode)
Definition: fanalyzer.cxx:49
void bindEvaluationRow(OValueRefRow const &_pRow)
Definition: fanalyzer.cxx:134
#define DBG_ASSERT(sCon, aError)
sal_uInt16 nPos
std::vector< std::unique_ptr< OCode > > OCodeList
Definition: fcomp.hxx:31
int i
sal_Unicode code
std::map< OUString, rtl::Reference< Entity > > map
#define SQL_ISRULE(pParseNode, eRule)
Definition: sqlnode.hxx:439
#define SQL_ISPUNCTUATION(pParseNode, aString)
Definition: sqlnode.hxx:450
sal_Int32 _nPos