1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9b5730f6SAndrew Rist * distributed with this work for additional information
6*9b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at
10*9b5730f6SAndrew Rist *
11*9b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*9b5730f6SAndrew Rist *
13*9b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist * KIND, either express or implied. See the License for the
17*9b5730f6SAndrew Rist * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist * under the License.
19*9b5730f6SAndrew Rist *
20*9b5730f6SAndrew Rist *************************************************************/
21*9b5730f6SAndrew Rist
22*9b5730f6SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <stdio.h>
28cdf0e10cSrcweir #include <osl/diagnose.h>
29cdf0e10cSrcweir #include <osl/thread.h>
30cdf0e10cSrcweir #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
31cdf0e10cSrcweir #include <com/sun/star/sdbc/ResultSetType.hpp>
32cdf0e10cSrcweir #include <com/sun/star/sdbc/FetchDirection.hpp>
33cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
34cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
35cdf0e10cSrcweir #include "propertyids.hxx"
36cdf0e10cSrcweir #include "NStatement.hxx"
37cdf0e10cSrcweir #include "NConnection.hxx"
38cdf0e10cSrcweir #include "NDatabaseMetaData.hxx"
39cdf0e10cSrcweir #include "NResultSet.hxx"
40cdf0e10cSrcweir #include "NDebug.hxx"
41cdf0e10cSrcweir #include "resource/evoab2_res.hrc"
42cdf0e10cSrcweir #include <resource/common_res.hrc>
43cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
44cdf0e10cSrcweir #include <tools/diagnose_ex.h>
45cdf0e10cSrcweir
46cdf0e10cSrcweir namespace connectivity { namespace evoab {
47cdf0e10cSrcweir
48cdf0e10cSrcweir //------------------------------------------------------------------------------
49cdf0e10cSrcweir using namespace com::sun::star::uno;
50cdf0e10cSrcweir using namespace com::sun::star::lang;
51cdf0e10cSrcweir using namespace com::sun::star::beans;
52cdf0e10cSrcweir using namespace com::sun::star::sdbc;
53cdf0e10cSrcweir using namespace com::sun::star::sdbcx;
54cdf0e10cSrcweir using namespace com::sun::star::container;
55cdf0e10cSrcweir using namespace com::sun::star::io;
56cdf0e10cSrcweir using namespace com::sun::star::util;
57cdf0e10cSrcweir //------------------------------------------------------------------------------
OCommonStatement(OEvoabConnection * _pConnection)58cdf0e10cSrcweir OCommonStatement::OCommonStatement(OEvoabConnection* _pConnection)
59cdf0e10cSrcweir : OCommonStatement_IBase(m_aMutex)
60cdf0e10cSrcweir , ::comphelper::OPropertyContainer(OCommonStatement_IBase::rBHelper)
61cdf0e10cSrcweir , OStatement_CBase( (::cppu::OWeakObject*)_pConnection, this )
62cdf0e10cSrcweir , m_xResultSet(NULL)
63cdf0e10cSrcweir , m_pResultSet(NULL)
64cdf0e10cSrcweir , m_pConnection(_pConnection)
65cdf0e10cSrcweir , m_aParser(_pConnection->getDriver().getMSFactory())
66cdf0e10cSrcweir , m_aSQLIterator( _pConnection, _pConnection->createCatalog()->getTables(), m_aParser, NULL )
67cdf0e10cSrcweir , m_pParseTree(NULL)
68cdf0e10cSrcweir , m_nMaxFieldSize(0)
69cdf0e10cSrcweir , m_nMaxRows(0)
70cdf0e10cSrcweir , m_nQueryTimeOut(0)
71cdf0e10cSrcweir , m_nFetchSize(0)
72cdf0e10cSrcweir , m_nResultSetType(ResultSetType::FORWARD_ONLY)
73cdf0e10cSrcweir , m_nFetchDirection(FetchDirection::FORWARD)
74cdf0e10cSrcweir , m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
75cdf0e10cSrcweir , m_bEscapeProcessing(sal_True)
76cdf0e10cSrcweir , rBHelper(OCommonStatement_IBase::rBHelper)
77cdf0e10cSrcweir {
78cdf0e10cSrcweir m_pConnection->acquire();
79cdf0e10cSrcweir
80cdf0e10cSrcweir #define REGISTER_PROP( id, member ) \
81cdf0e10cSrcweir registerProperty( \
82cdf0e10cSrcweir OMetaConnection::getPropMap().getNameByIndex( id ), \
83cdf0e10cSrcweir id, \
84cdf0e10cSrcweir 0, \
85cdf0e10cSrcweir &member, \
86cdf0e10cSrcweir ::getCppuType( &member ) \
87cdf0e10cSrcweir );
88cdf0e10cSrcweir
89cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_CURSORNAME, m_aCursorName );
90cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_MAXFIELDSIZE, m_nMaxFieldSize );
91cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_MAXROWS, m_nMaxRows );
92cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_QUERYTIMEOUT, m_nQueryTimeOut );
93cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize );
94cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType );
95cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection );
96cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_ESCAPEPROCESSING, m_bEscapeProcessing );
97cdf0e10cSrcweir REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency );
98cdf0e10cSrcweir }
99cdf0e10cSrcweir // -----------------------------------------------------------------------------
~OCommonStatement()100cdf0e10cSrcweir OCommonStatement::~OCommonStatement()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir }
103cdf0e10cSrcweir //------------------------------------------------------------------------------
disposeResultSet()104cdf0e10cSrcweir void OCommonStatement::disposeResultSet()
105cdf0e10cSrcweir {
106cdf0e10cSrcweir // free the cursor if alive
107cdf0e10cSrcweir Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
108cdf0e10cSrcweir if (xComp.is())
109cdf0e10cSrcweir xComp->dispose();
110cdf0e10cSrcweir m_xResultSet = Reference< XResultSet>();
111cdf0e10cSrcweir }
112cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()113cdf0e10cSrcweir void OCommonStatement::disposing()
114cdf0e10cSrcweir {
115cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
116cdf0e10cSrcweir
117cdf0e10cSrcweir disposeResultSet();
118cdf0e10cSrcweir
119cdf0e10cSrcweir if (m_pConnection)
120cdf0e10cSrcweir m_pConnection->release();
121cdf0e10cSrcweir m_pConnection = NULL;
122cdf0e10cSrcweir
123cdf0e10cSrcweir dispose_ChildImpl();
124cdf0e10cSrcweir OCommonStatement_IBase::disposing();
125cdf0e10cSrcweir }
126cdf0e10cSrcweir //-----------------------------------------------------------------------------
queryInterface(const Type & rType)127cdf0e10cSrcweir Any SAL_CALL OCommonStatement::queryInterface( const Type & rType ) throw(RuntimeException)
128cdf0e10cSrcweir {
129cdf0e10cSrcweir Any aRet = OCommonStatement_IBase::queryInterface(rType);
130cdf0e10cSrcweir if(!aRet.hasValue())
131cdf0e10cSrcweir aRet = ::comphelper::OPropertyContainer::queryInterface(rType);
132cdf0e10cSrcweir return aRet;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir // -------------------------------------------------------------------------
getTypes()135cdf0e10cSrcweir Sequence< Type > SAL_CALL OCommonStatement::getTypes( ) throw(RuntimeException)
136cdf0e10cSrcweir {
137cdf0e10cSrcweir ::cppu::OTypeCollection aTypes( ::getCppuType( (const Reference< XMultiPropertySet > *)0 ),
138cdf0e10cSrcweir ::getCppuType( (const Reference< XFastPropertySet > *)0 ),
139cdf0e10cSrcweir ::getCppuType( (const Reference< XPropertySet > *)0 ));
140cdf0e10cSrcweir
141cdf0e10cSrcweir return ::comphelper::concatSequences(aTypes.getTypes(),OCommonStatement_IBase::getTypes());
142cdf0e10cSrcweir }
143cdf0e10cSrcweir // -------------------------------------------------------------------------
144cdf0e10cSrcweir
145cdf0e10cSrcweir //void SAL_CALL OCommonStatement::cancel( ) throw(RuntimeException)
146cdf0e10cSrcweir //{
147cdf0e10cSrcweir //::osl::MutexGuard aGuard( m_aMutex );
148cdf0e10cSrcweir //checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
149cdf0e10cSrcweir //// cancel the current sql statement
150cdf0e10cSrcweir //}
151cdf0e10cSrcweir
152cdf0e10cSrcweir // -------------------------------------------------------------------------
close()153cdf0e10cSrcweir void SAL_CALL OCommonStatement::close( ) throw(SQLException, RuntimeException)
154cdf0e10cSrcweir {
155cdf0e10cSrcweir {
156cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
157cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
158cdf0e10cSrcweir
159cdf0e10cSrcweir }
160cdf0e10cSrcweir dispose();
161cdf0e10cSrcweir }
162cdf0e10cSrcweir // -------------------------------------------------------------------------
163cdf0e10cSrcweir
reset()164cdf0e10cSrcweir void OCommonStatement::reset() throw (SQLException)
165cdf0e10cSrcweir {
166cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
167cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
168cdf0e10cSrcweir
169cdf0e10cSrcweir
170cdf0e10cSrcweir clearWarnings ();
171cdf0e10cSrcweir
172cdf0e10cSrcweir if (m_xResultSet.get().is())
173cdf0e10cSrcweir clearMyResultSet();
174cdf0e10cSrcweir }
175cdf0e10cSrcweir
clearMyResultSet()176cdf0e10cSrcweir void OCommonStatement::clearMyResultSet () throw (SQLException)
177cdf0e10cSrcweir {
178cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
179cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
180cdf0e10cSrcweir
181cdf0e10cSrcweir try
182cdf0e10cSrcweir {
183cdf0e10cSrcweir Reference<XCloseable> xCloseable;
184cdf0e10cSrcweir if ( ::comphelper::query_interface( m_xResultSet.get(), xCloseable ) )
185cdf0e10cSrcweir xCloseable->close();
186cdf0e10cSrcweir }
187cdf0e10cSrcweir catch( const DisposedException& ) { }
188cdf0e10cSrcweir
189cdf0e10cSrcweir m_xResultSet = Reference< XResultSet >();
190cdf0e10cSrcweir }
191cdf0e10cSrcweir
192cdf0e10cSrcweir EBookQuery *
createTrue()193cdf0e10cSrcweir OCommonStatement::createTrue()
194cdf0e10cSrcweir { // Not the world's most efficient unconditional true but ...
195cdf0e10cSrcweir return e_book_query_from_string("(exists \"full_name\")");
196cdf0e10cSrcweir }
197cdf0e10cSrcweir
198cdf0e10cSrcweir EBookQuery *
createTest(const::rtl::OUString & aColumnName,EBookQueryTest eTest,const::rtl::OUString & aMatch)199cdf0e10cSrcweir OCommonStatement::createTest( const ::rtl::OUString &aColumnName,
200cdf0e10cSrcweir EBookQueryTest eTest,
201cdf0e10cSrcweir const ::rtl::OUString &aMatch )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir ::rtl::OString sMatch = rtl::OUStringToOString( aMatch, RTL_TEXTENCODING_UTF8 );
204cdf0e10cSrcweir ::rtl::OString sColumnName = rtl::OUStringToOString( aColumnName, RTL_TEXTENCODING_UTF8 );
205cdf0e10cSrcweir
206cdf0e10cSrcweir return e_book_query_field_test( e_contact_field_id( sColumnName ),
207cdf0e10cSrcweir eTest, sMatch );
208cdf0e10cSrcweir }
209cdf0e10cSrcweir
210cdf0e10cSrcweir // -------------------------------------------------------------------------
211cdf0e10cSrcweir
impl_getColumnRefColumnName_throw(const OSQLParseNode & _rColumnRef)212cdf0e10cSrcweir ::rtl::OUString OCommonStatement::impl_getColumnRefColumnName_throw( const OSQLParseNode& _rColumnRef )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir ENSURE_OR_THROW( SQL_ISRULE( &_rColumnRef, column_ref ), "internal error: only column_refs supported as LHS" );
215cdf0e10cSrcweir
216cdf0e10cSrcweir ::rtl::OUString sColumnName;
217cdf0e10cSrcweir switch ( _rColumnRef.count() )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir case 3: // SQL_TOKEN_NAME '.' column_val
220cdf0e10cSrcweir {
221cdf0e10cSrcweir const OSQLParseNode* pPunct = _rColumnRef.getChild( 1 );
222cdf0e10cSrcweir const OSQLParseNode* pColVal = _rColumnRef.getChild( 2 );
223cdf0e10cSrcweir if ( SQL_ISPUNCTUATION( pPunct, "." )
224cdf0e10cSrcweir && ( pColVal->count() == 1 )
225cdf0e10cSrcweir )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir sColumnName = pColVal->getChild( 0 )->getTokenValue();
228cdf0e10cSrcweir }
229cdf0e10cSrcweir }
230cdf0e10cSrcweir break;
231cdf0e10cSrcweir
232cdf0e10cSrcweir case 1: // column
233cdf0e10cSrcweir {
234cdf0e10cSrcweir sColumnName = _rColumnRef.getChild( 0 )->getTokenValue();
235cdf0e10cSrcweir }
236cdf0e10cSrcweir break;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir
239cdf0e10cSrcweir if ( !sColumnName.getLength() )
240cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
241cdf0e10cSrcweir
242cdf0e10cSrcweir return sColumnName;
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir // -------------------------------------------------------------------------
orderByAnalysis(const OSQLParseNode * _pOrderByClause,SortDescriptor & _out_rSort)246cdf0e10cSrcweir void OCommonStatement::orderByAnalysis( const OSQLParseNode* _pOrderByClause, SortDescriptor& _out_rSort )
247cdf0e10cSrcweir {
248cdf0e10cSrcweir ENSURE_OR_THROW( _pOrderByClause, "NULL node" );
249cdf0e10cSrcweir ENSURE_OR_THROW( SQL_ISRULE( _pOrderByClause, opt_order_by_clause ), "wrong node type" );
250cdf0e10cSrcweir
251cdf0e10cSrcweir _out_rSort.clear();
252cdf0e10cSrcweir
253cdf0e10cSrcweir const OSQLParseNode* pOrderList = _pOrderByClause->getByRule( OSQLParseNode::ordering_spec_commalist );
254cdf0e10cSrcweir ENSURE_OR_THROW( pOrderList, "unexpected parse tree structure" );
255cdf0e10cSrcweir
256cdf0e10cSrcweir for ( sal_uInt32 i=0; i<pOrderList->count(); ++i )
257cdf0e10cSrcweir {
258cdf0e10cSrcweir const OSQLParseNode* pOrderBy = pOrderList->getChild(i);
259cdf0e10cSrcweir if ( !pOrderBy || !SQL_ISRULE( pOrderBy, ordering_spec ) )
260cdf0e10cSrcweir continue;
261cdf0e10cSrcweir const OSQLParseNode* pColumnRef = pOrderBy->count() == 2 ? pOrderBy->getChild(0) : NULL;
262cdf0e10cSrcweir const OSQLParseNode* pAscDesc = pOrderBy->count() == 2 ? pOrderBy->getChild(1) : NULL;
263cdf0e10cSrcweir ENSURE_OR_THROW(
264cdf0e10cSrcweir ( pColumnRef != NULL )
265cdf0e10cSrcweir && ( pAscDesc != NULL )
266cdf0e10cSrcweir && SQL_ISRULE( pAscDesc, opt_asc_desc )
267cdf0e10cSrcweir && ( pAscDesc->count() < 2 ),
268cdf0e10cSrcweir "ordering_spec structure error" );
269cdf0e10cSrcweir
270cdf0e10cSrcweir // column name -> column field
271cdf0e10cSrcweir if ( !SQL_ISRULE( pColumnRef, column_ref ) )
272cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_SORT_BY_COL_ONLY, *this );
273cdf0e10cSrcweir const ::rtl::OUString sColumnName( impl_getColumnRefColumnName_throw( *pColumnRef ) );
274cdf0e10cSrcweir guint nField = evoab::findEvoabField( sColumnName );
275cdf0e10cSrcweir // ascending/descending?
276cdf0e10cSrcweir bool bAscending = true;
277cdf0e10cSrcweir if ( ( pAscDesc->count() == 1 )
278cdf0e10cSrcweir && SQL_ISTOKEN( pAscDesc->getChild( 0 ), DESC )
279cdf0e10cSrcweir )
280cdf0e10cSrcweir bAscending = false;
281cdf0e10cSrcweir
282cdf0e10cSrcweir _out_rSort.push_back( FieldSort( nField, bAscending ) );
283cdf0e10cSrcweir }
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir // -------------------------------------------------------------------------
whereAnalysis(const OSQLParseNode * parseTree)287cdf0e10cSrcweir EBookQuery *OCommonStatement::whereAnalysis( const OSQLParseNode* parseTree )
288cdf0e10cSrcweir {
289cdf0e10cSrcweir EBookQuery *pResult = NULL;
290cdf0e10cSrcweir
291cdf0e10cSrcweir ENSURE_OR_THROW( parseTree, "invalid parse tree" );
292cdf0e10cSrcweir
293cdf0e10cSrcweir // Nested brackets
294cdf0e10cSrcweir if( parseTree->count() == 3 &&
295cdf0e10cSrcweir SQL_ISPUNCTUATION( parseTree->getChild( 0 ), "(" ) &&
296cdf0e10cSrcweir SQL_ISPUNCTUATION( parseTree->getChild( 2 ), ")" ) )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir pResult = whereAnalysis( parseTree->getChild( 1 ) );
299cdf0e10cSrcweir }
300cdf0e10cSrcweir
301cdf0e10cSrcweir // SQL AND, OR
302cdf0e10cSrcweir else if( ( SQL_ISRULE( parseTree, search_condition ) ||
303cdf0e10cSrcweir SQL_ISRULE( parseTree, boolean_term ) ) &&
304cdf0e10cSrcweir parseTree->count() == 3 )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir ENSURE_OR_THROW( SQL_ISTOKEN( parseTree->getChild( 1 ), OR )
307cdf0e10cSrcweir || SQL_ISTOKEN( parseTree->getChild( 1 ), AND ),
308cdf0e10cSrcweir "unexpected search_condition structure" );
309cdf0e10cSrcweir
310cdf0e10cSrcweir EBookQuery *pArgs[2];
311cdf0e10cSrcweir pArgs[0] = whereAnalysis( parseTree->getChild( 0 ) );
312cdf0e10cSrcweir pArgs[1] = whereAnalysis( parseTree->getChild( 2 ) );
313cdf0e10cSrcweir
314cdf0e10cSrcweir if( SQL_ISTOKEN( parseTree->getChild( 1 ), OR ) )
315cdf0e10cSrcweir pResult = e_book_query_or( 2, pArgs, TRUE );
316cdf0e10cSrcweir else
317cdf0e10cSrcweir pResult = e_book_query_and( 2, pArgs, TRUE );
318cdf0e10cSrcweir }
319cdf0e10cSrcweir // SQL =, !=
320cdf0e10cSrcweir else if( SQL_ISRULE( parseTree, comparison_predicate ) )
321cdf0e10cSrcweir {
322cdf0e10cSrcweir OSQLParseNode *pPrec = parseTree->getChild( 1 );
323cdf0e10cSrcweir
324cdf0e10cSrcweir ENSURE_OR_THROW( parseTree->count() == 3, "unexpected comparison_predicate structure" );
325cdf0e10cSrcweir
326cdf0e10cSrcweir OSQLParseNode* pLHS = parseTree->getChild( 0 );
327cdf0e10cSrcweir OSQLParseNode* pRHS = parseTree->getChild( 2 );
328cdf0e10cSrcweir
329cdf0e10cSrcweir if ( ( !( SQL_ISRULE( pLHS, column_ref ) ) // on the LHS, we accept a column or a constant int value
330cdf0e10cSrcweir && ( pLHS->getNodeType() != SQL_NODE_INTNUM )
331cdf0e10cSrcweir )
332cdf0e10cSrcweir || ( ( pRHS->getNodeType() != SQL_NODE_STRING ) // on the RHS, certain literals are acceptable
333cdf0e10cSrcweir && ( pRHS->getNodeType() != SQL_NODE_INTNUM )
334cdf0e10cSrcweir && ( pRHS->getNodeType() != SQL_NODE_APPROXNUM )
335cdf0e10cSrcweir && !( SQL_ISTOKEN( pRHS, TRUE ) )
336cdf0e10cSrcweir && !( SQL_ISTOKEN( pRHS, FALSE ) )
337cdf0e10cSrcweir )
338cdf0e10cSrcweir || ( ( pLHS->getNodeType() == SQL_NODE_INTNUM ) // an int on LHS requires an int on RHS
339cdf0e10cSrcweir && ( pRHS->getNodeType() != SQL_NODE_INTNUM )
340cdf0e10cSrcweir )
341cdf0e10cSrcweir )
342cdf0e10cSrcweir {
343cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
344cdf0e10cSrcweir }
345cdf0e10cSrcweir
346cdf0e10cSrcweir if ( ( pPrec->getNodeType() != SQL_NODE_EQUAL )
347cdf0e10cSrcweir && ( pPrec->getNodeType() != SQL_NODE_NOTEQUAL )
348cdf0e10cSrcweir )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_OPERATOR_TOO_COMPLEX, *this );
351cdf0e10cSrcweir }
352cdf0e10cSrcweir
353cdf0e10cSrcweir // recognize the special "0 = 1" condition
354cdf0e10cSrcweir if ( ( pLHS->getNodeType() == SQL_NODE_INTNUM )
355cdf0e10cSrcweir && ( pRHS->getNodeType() == SQL_NODE_INTNUM )
356cdf0e10cSrcweir && ( pPrec->getNodeType() == SQL_NODE_EQUAL )
357cdf0e10cSrcweir )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir const sal_Int32 nLHS = pLHS->getTokenValue().toInt64();
360cdf0e10cSrcweir const sal_Int32 nRHS = pRHS->getTokenValue().toInt64();
361cdf0e10cSrcweir return ( nLHS == nRHS ) ? createTrue() : NULL;
362cdf0e10cSrcweir }
363cdf0e10cSrcweir
364cdf0e10cSrcweir ::rtl::OUString aColumnName( impl_getColumnRefColumnName_throw( *pLHS ) );
365cdf0e10cSrcweir
366cdf0e10cSrcweir ::rtl::OUString aMatchString;
367cdf0e10cSrcweir if ( pRHS->isToken() )
368cdf0e10cSrcweir aMatchString = pRHS->getTokenValue();
369cdf0e10cSrcweir else
370cdf0e10cSrcweir aMatchString = pRHS->getChild( 0 )->getTokenValue();
371cdf0e10cSrcweir
372cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_IS, aMatchString );
373cdf0e10cSrcweir
374cdf0e10cSrcweir if ( pResult && ( pPrec->getNodeType() == SQL_NODE_NOTEQUAL ) )
375cdf0e10cSrcweir pResult = e_book_query_not( pResult, TRUE );
376cdf0e10cSrcweir }
377cdf0e10cSrcweir // SQL like
378cdf0e10cSrcweir else if( SQL_ISRULE( parseTree, like_predicate ) )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir ENSURE_OR_THROW( parseTree->count() == 2, "unexpected like_predicate structure" );
381cdf0e10cSrcweir const OSQLParseNode* pPart2 = parseTree->getChild(1);
382cdf0e10cSrcweir
383cdf0e10cSrcweir if( ! SQL_ISRULE( parseTree->getChild( 0 ), column_ref) )
384cdf0e10cSrcweir m_pConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_COLUMN,*this);
385cdf0e10cSrcweir
386cdf0e10cSrcweir ::rtl::OUString aColumnName( impl_getColumnRefColumnName_throw( *parseTree->getChild( 0 ) ) );
387cdf0e10cSrcweir
388cdf0e10cSrcweir OSQLParseNode *pAtom = pPart2->getChild( pPart2->count() - 2 ); // Match String
389cdf0e10cSrcweir bool bNotLike = pPart2->getChild(0)->isToken();
390cdf0e10cSrcweir
391cdf0e10cSrcweir if( !( pAtom->getNodeType() == SQL_NODE_STRING ||
392cdf0e10cSrcweir pAtom->getNodeType() == SQL_NODE_NAME ||
393cdf0e10cSrcweir SQL_ISRULE( pAtom,parameter ) ||
394cdf0e10cSrcweir ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQL_NODE_NAME ) ||
395cdf0e10cSrcweir ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQL_NODE_STRING ) ) )
396cdf0e10cSrcweir {
397cdf0e10cSrcweir OSL_TRACE( "analyseSQL : pAtom->count() = %d\n", pAtom->count() );
398cdf0e10cSrcweir m_pConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,*this);
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
401cdf0e10cSrcweir const sal_Unicode WILDCARD = '%';
402cdf0e10cSrcweir
403cdf0e10cSrcweir rtl::OUString aMatchString;
404cdf0e10cSrcweir aMatchString = pAtom->getTokenValue();
405cdf0e10cSrcweir
406cdf0e10cSrcweir // Determine where '%' character is...
407cdf0e10cSrcweir if( aMatchString.equals( ::rtl::OUString::valueOf( WILDCARD ) ) )
408cdf0e10cSrcweir {
409cdf0e10cSrcweir // String containing only a '%' and nothing else matches everything
410cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS,
411cdf0e10cSrcweir rtl::OUString::createFromAscii( "" ) );
412cdf0e10cSrcweir }
413cdf0e10cSrcweir else if( aMatchString.indexOf( WILDCARD ) == -1 )
414cdf0e10cSrcweir { // Simple string , eg. "to match" "contains in evo"
415cdf0e10cSrcweir EVO_TRACE_STRING( "Plain contains '%s'", aMatchString );
416cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString );
417cdf0e10cSrcweir if( pResult && bNotLike )
418cdf0e10cSrcweir pResult = e_book_query_not( pResult, TRUE );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir else if( bNotLike )
421cdf0e10cSrcweir {
422cdf0e10cSrcweir // We currently can't handle a 'NOT LIKE' when there are '%'
423cdf0e10cSrcweir m_pConnection->throwGenericSQLException(STR_QUERY_NOT_LIKE_TOO_COMPLEX,*this);
424cdf0e10cSrcweir }
425cdf0e10cSrcweir else if( (aMatchString.indexOf ( WILDCARD ) == aMatchString.lastIndexOf ( WILDCARD ) ) )
426cdf0e10cSrcweir { // One occurance of '%' matches...
427cdf0e10cSrcweir if ( aMatchString.indexOf ( WILDCARD ) == 0 )
428cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_ENDS_WITH, aMatchString.copy( 1 ) );
429cdf0e10cSrcweir else if ( aMatchString.indexOf ( WILDCARD ) == aMatchString.getLength() - 1 )
430cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_BEGINS_WITH, aMatchString.copy( 0, aMatchString.getLength() - 1 ) );
431cdf0e10cSrcweir else
432cdf0e10cSrcweir m_pConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD,*this);
433cdf0e10cSrcweir
434cdf0e10cSrcweir if( pResult && bNotLike )
435cdf0e10cSrcweir pResult = e_book_query_not( pResult, TRUE );
436cdf0e10cSrcweir }
437cdf0e10cSrcweir else if( aMatchString.getLength() >= 3 &&
438cdf0e10cSrcweir aMatchString.indexOf ( WILDCARD ) == 0 &&
439cdf0e10cSrcweir aMatchString.indexOf ( WILDCARD, 1) == aMatchString.getLength() - 1 ) {
440cdf0e10cSrcweir // one '%' at the start and another at the end
441cdf0e10cSrcweir pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString.copy (1, aMatchString.getLength() - 2) );
442cdf0e10cSrcweir }
443cdf0e10cSrcweir else
444cdf0e10cSrcweir m_pConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD_MANY,*this);
445cdf0e10cSrcweir }
446cdf0e10cSrcweir
447cdf0e10cSrcweir return pResult;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir
getTableName()450cdf0e10cSrcweir rtl::OUString OCommonStatement::getTableName()
451cdf0e10cSrcweir {
452cdf0e10cSrcweir ::rtl::OUString aTableName;
453cdf0e10cSrcweir
454cdf0e10cSrcweir if( m_pParseTree && m_aSQLIterator.getStatementType() == SQL_STATEMENT_SELECT )
455cdf0e10cSrcweir {
456cdf0e10cSrcweir Any aCatalog;
457cdf0e10cSrcweir ::rtl::OUString aSchema, aComposedName;
458cdf0e10cSrcweir const OSQLParseNode *pSelectStmnt = m_aSQLIterator.getParseTree();
459cdf0e10cSrcweir const OSQLParseNode *pAllTableNames = pSelectStmnt->getChild( 3 )->getChild( 0 )->getChild( 1 );
460cdf0e10cSrcweir
461cdf0e10cSrcweir if( m_aSQLIterator.isTableNode( pAllTableNames->getChild( 0 ) ) )
462cdf0e10cSrcweir OSQLParseNode::getTableComponents( pAllTableNames->getChild( 0 ),
463cdf0e10cSrcweir aCatalog,aSchema, aTableName,NULL );
464cdf0e10cSrcweir
465cdf0e10cSrcweir else if( SQL_ISRULE( pAllTableNames->getChild( 0 ), table_ref ) )
466cdf0e10cSrcweir {
467cdf0e10cSrcweir OSQLParseNode *pNodeForTableName = pAllTableNames->getChild( 0 )->getChild( 0 );
468cdf0e10cSrcweir if( m_aSQLIterator.isTableNode( pNodeForTableName ) )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir aTableName = OSQLParseNode::getTableRange(pAllTableNames->getChild( 0 ));
471cdf0e10cSrcweir if( !aTableName.getLength() )
472cdf0e10cSrcweir OSQLParseNode::getTableComponents( pNodeForTableName, aCatalog, aSchema, aTableName,NULL);
473cdf0e10cSrcweir }
474cdf0e10cSrcweir else
475cdf0e10cSrcweir OSL_ENSURE( false, "odd table layout" );
476cdf0e10cSrcweir }
477cdf0e10cSrcweir else
478cdf0e10cSrcweir OSL_ENSURE( false, "unusual table layout" );
479cdf0e10cSrcweir }
480cdf0e10cSrcweir return aTableName;
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
parseSql(const rtl::OUString & sql,QueryData & _out_rQueryData)483cdf0e10cSrcweir void OCommonStatement::parseSql( const rtl::OUString& sql, QueryData& _out_rQueryData )
484cdf0e10cSrcweir {
485cdf0e10cSrcweir EVO_TRACE_STRING( "parsing %s", sql );
486cdf0e10cSrcweir
487cdf0e10cSrcweir _out_rQueryData.eFilterType = eFilterOther;
488cdf0e10cSrcweir
489cdf0e10cSrcweir ::rtl::OUString aErr;
490cdf0e10cSrcweir m_pParseTree = m_aParser.parseTree( aErr, sql );
491cdf0e10cSrcweir m_aSQLIterator.setParseTree( m_pParseTree );
492cdf0e10cSrcweir m_aSQLIterator.traverseAll();
493cdf0e10cSrcweir
494cdf0e10cSrcweir _out_rQueryData.sTable = getTableName();
495cdf0e10cSrcweir
496cdf0e10cSrcweir // to be sorted?
497cdf0e10cSrcweir const OSQLParseNode* pOrderByClause = m_aSQLIterator.getOrderTree();
498cdf0e10cSrcweir if ( pOrderByClause )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
501cdf0e10cSrcweir ::rtl::OUString sTreeDebug;
502cdf0e10cSrcweir pOrderByClause->showParseTree( sTreeDebug );
503cdf0e10cSrcweir EVO_TRACE_STRING( "found order-by tree:\n%s", sTreeDebug );
504cdf0e10cSrcweir #endif
505cdf0e10cSrcweir orderByAnalysis( pOrderByClause, _out_rQueryData.aSortOrder );
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir const OSQLParseNode* pWhereClause = m_aSQLIterator.getWhereTree();
509cdf0e10cSrcweir if ( pWhereClause && SQL_ISRULE( pWhereClause, where_clause ) )
510cdf0e10cSrcweir {
511cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
512cdf0e10cSrcweir ::rtl::OUString sTreeDebug;
513cdf0e10cSrcweir pWhereClause->showParseTree( sTreeDebug );
514cdf0e10cSrcweir EVO_TRACE_STRING( "found where tree:\n%s", sTreeDebug );
515cdf0e10cSrcweir #endif
516cdf0e10cSrcweir EBookQuery* pQuery = whereAnalysis( pWhereClause->getChild( 1 ) );
517cdf0e10cSrcweir if ( !pQuery )
518cdf0e10cSrcweir {
519cdf0e10cSrcweir _out_rQueryData.eFilterType = eFilterAlwaysFalse;
520cdf0e10cSrcweir pQuery = createTrue();
521cdf0e10cSrcweir }
522cdf0e10cSrcweir _out_rQueryData.setQuery( pQuery );
523cdf0e10cSrcweir }
524cdf0e10cSrcweir else
525cdf0e10cSrcweir {
526cdf0e10cSrcweir _out_rQueryData.eFilterType = eFilterNone;
527cdf0e10cSrcweir _out_rQueryData.setQuery( createTrue() );
528cdf0e10cSrcweir }
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
531cdf0e10cSrcweir // -------------------------------------------------------------------------
532cdf0e10cSrcweir
getConnection()533cdf0e10cSrcweir Reference< XConnection > SAL_CALL OStatement::getConnection( ) throw(SQLException, RuntimeException)
534cdf0e10cSrcweir {
535cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
536cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
537cdf0e10cSrcweir
538cdf0e10cSrcweir // just return our connection here
539cdf0e10cSrcweir return impl_getConnection();
540cdf0e10cSrcweir }
541cdf0e10cSrcweir
542cdf0e10cSrcweir // -------------------------------------------------------------------------
getWarnings()543cdf0e10cSrcweir Any SAL_CALL OCommonStatement::getWarnings( ) throw(SQLException, RuntimeException)
544cdf0e10cSrcweir {
545cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
546cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
547cdf0e10cSrcweir
548cdf0e10cSrcweir
549cdf0e10cSrcweir return makeAny(SQLWarning());
550cdf0e10cSrcweir }
551cdf0e10cSrcweir
552cdf0e10cSrcweir // -------------------------------------------------------------------------
clearWarnings()553cdf0e10cSrcweir void SAL_CALL OCommonStatement::clearWarnings( ) throw(SQLException, RuntimeException)
554cdf0e10cSrcweir {
555cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
556cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
557cdf0e10cSrcweir
558cdf0e10cSrcweir }
559cdf0e10cSrcweir // -------------------------------------------------------------------------
createArrayHelper() const560cdf0e10cSrcweir ::cppu::IPropertyArrayHelper* OCommonStatement::createArrayHelper( ) const
561cdf0e10cSrcweir {
562cdf0e10cSrcweir Sequence< Property > aProps;
563cdf0e10cSrcweir describeProperties( aProps );
564cdf0e10cSrcweir return new ::cppu::OPropertyArrayHelper( aProps );
565cdf0e10cSrcweir }
566cdf0e10cSrcweir // -------------------------------------------------------------------------
getInfoHelper()567cdf0e10cSrcweir ::cppu::IPropertyArrayHelper & OCommonStatement::getInfoHelper()
568cdf0e10cSrcweir {
569cdf0e10cSrcweir return *const_cast< OCommonStatement* >( this )->getArrayHelper();
570cdf0e10cSrcweir }
571cdf0e10cSrcweir
572cdf0e10cSrcweir // -----------------------------------------------------------------------------
acquire()573cdf0e10cSrcweir void SAL_CALL OCommonStatement::acquire() throw()
574cdf0e10cSrcweir {
575cdf0e10cSrcweir OCommonStatement_IBase::acquire();
576cdf0e10cSrcweir }
577cdf0e10cSrcweir // -----------------------------------------------------------------------------
release()578cdf0e10cSrcweir void SAL_CALL OCommonStatement::release() throw()
579cdf0e10cSrcweir {
580cdf0e10cSrcweir relase_ChildImpl();
581cdf0e10cSrcweir }
582cdf0e10cSrcweir
583cdf0e10cSrcweir // -------------------------------------------------------------------------
impl_getEBookQuery_throw(const::rtl::OUString & _rSql)584cdf0e10cSrcweir QueryData OCommonStatement::impl_getEBookQuery_throw( const ::rtl::OUString& _rSql )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir QueryData aData;
587cdf0e10cSrcweir parseSql( _rSql, aData );
588cdf0e10cSrcweir
589cdf0e10cSrcweir #ifdef DEBUG
590cdf0e10cSrcweir char *pSexpr = aData.getQuery() ? e_book_query_to_string( aData.getQuery() ) : g_strdup( "<map failed>" );
591cdf0e10cSrcweir g_message( "Parsed SQL to sexpr '%s'\n", pSexpr );
592cdf0e10cSrcweir g_free( pSexpr );
593cdf0e10cSrcweir #endif
594cdf0e10cSrcweir
595cdf0e10cSrcweir if ( !aData.getQuery() )
596cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
597cdf0e10cSrcweir
598cdf0e10cSrcweir // a postcondition of this method is that we properly determined the SELECT columns
599cdf0e10cSrcweir aData.xSelectColumns = m_aSQLIterator.getSelectColumns();
600cdf0e10cSrcweir if ( !aData.xSelectColumns.isValid() )
601cdf0e10cSrcweir m_pConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
602cdf0e10cSrcweir
603cdf0e10cSrcweir return aData;
604cdf0e10cSrcweir }
605cdf0e10cSrcweir
606cdf0e10cSrcweir // -------------------------------------------------------------------------
impl_executeQuery_throw(const QueryData & _rQueryData)607cdf0e10cSrcweir Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const QueryData& _rQueryData )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir // create result set
610cdf0e10cSrcweir OEvoabResultSet* pResult = new OEvoabResultSet( this, m_pConnection );
611cdf0e10cSrcweir Reference< XResultSet > xRS = pResult;
612cdf0e10cSrcweir pResult->construct( _rQueryData );
613cdf0e10cSrcweir
614cdf0e10cSrcweir // done
615cdf0e10cSrcweir m_xResultSet = xRS;
616cdf0e10cSrcweir return xRS;
617cdf0e10cSrcweir }
618cdf0e10cSrcweir
619cdf0e10cSrcweir // -------------------------------------------------------------------------
impl_executeQuery_throw(const::rtl::OUString & _rSql)620cdf0e10cSrcweir Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const ::rtl::OUString& _rSql )
621cdf0e10cSrcweir {
622cdf0e10cSrcweir EVO_TRACE_STRING( "OCommonStatement::impl_executeQuery_throw(%s)\n", _rSql );
623cdf0e10cSrcweir
624cdf0e10cSrcweir #ifdef DEBUG
625cdf0e10cSrcweir g_message( "Parse SQL '%s'\n",
626cdf0e10cSrcweir (const sal_Char *)OUStringToOString( _rSql, RTL_TEXTENCODING_UTF8 ) );
627cdf0e10cSrcweir #endif
628cdf0e10cSrcweir
629cdf0e10cSrcweir return impl_executeQuery_throw( impl_getEBookQuery_throw( _rSql ) );
630cdf0e10cSrcweir }
631cdf0e10cSrcweir
632cdf0e10cSrcweir // -----------------------------------------------------------------------------
getPropertySetInfo()633cdf0e10cSrcweir Reference< XPropertySetInfo > SAL_CALL OCommonStatement::getPropertySetInfo( ) throw(RuntimeException)
634cdf0e10cSrcweir {
635cdf0e10cSrcweir return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
636cdf0e10cSrcweir }
637cdf0e10cSrcweir
638cdf0e10cSrcweir // =============================================================================
639cdf0e10cSrcweir // = OStatement
640cdf0e10cSrcweir // =============================================================================
641cdf0e10cSrcweir // -----------------------------------------------------------------------------
642cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO( OStatement, "com.sun.star.comp.sdbcx.evoab.OStatement", "com.sun.star.sdbc.Statement" );
643cdf0e10cSrcweir
644cdf0e10cSrcweir // -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OStatement,OCommonStatement,OStatement_IBase)645cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2( OStatement, OCommonStatement, OStatement_IBase )
646cdf0e10cSrcweir
647cdf0e10cSrcweir // -----------------------------------------------------------------------------
648cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement, OCommonStatement, OStatement_IBase )
649cdf0e10cSrcweir
650cdf0e10cSrcweir // -------------------------------------------------------------------------
651cdf0e10cSrcweir sal_Bool SAL_CALL OStatement::execute( const ::rtl::OUString& _sql ) throw(SQLException, RuntimeException)
652cdf0e10cSrcweir {
653cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
654cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
655cdf0e10cSrcweir
656cdf0e10cSrcweir Reference< XResultSet > xRS = impl_executeQuery_throw( _sql );
657cdf0e10cSrcweir return xRS.is();
658cdf0e10cSrcweir }
659cdf0e10cSrcweir
660cdf0e10cSrcweir // -------------------------------------------------------------------------
executeQuery(const::rtl::OUString & _sql)661cdf0e10cSrcweir Reference< XResultSet > SAL_CALL OStatement::executeQuery( const ::rtl::OUString& _sql ) throw(SQLException, RuntimeException)
662cdf0e10cSrcweir {
663cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
664cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
665cdf0e10cSrcweir
666cdf0e10cSrcweir return impl_executeQuery_throw( _sql );
667cdf0e10cSrcweir }
668cdf0e10cSrcweir
669cdf0e10cSrcweir // -----------------------------------------------------------------------------
executeUpdate(const::rtl::OUString &)670cdf0e10cSrcweir sal_Int32 SAL_CALL OStatement::executeUpdate( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
673cdf0e10cSrcweir checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
674cdf0e10cSrcweir ::dbtools::throwFeatureNotImplementedException( "XStatement::executeUpdate", *this );
675cdf0e10cSrcweir return 0;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir
678cdf0e10cSrcweir } } // namespace ::connectivity::evoab
679