Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / connectivity / source / drivers / evoab2 / NStatement.cxx
blob2acfd427dbc6383ac603e0a507d7fa9ff3b4314a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <osl/diagnose.h>
25 #include <rtl/ref.hxx>
26 #include <rtl/ustring.hxx>
27 #include <sal/log.hxx>
28 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
29 #include <com/sun/star/sdbc/ResultSetType.hpp>
30 #include <com/sun/star/sdbc/FetchDirection.hpp>
31 #include <com/sun/star/lang/DisposedException.hpp>
32 #include <cppuhelper/typeprovider.hxx>
33 #include <propertyids.hxx>
34 #include "NStatement.hxx"
35 #include "NConnection.hxx"
36 #include "NDatabaseMetaData.hxx"
37 #include "NResultSet.hxx"
38 #include <sqlbison.hxx>
39 #include <strings.hrc>
40 #include <connectivity/dbexception.hxx>
41 #include <comphelper/diagnose_ex.hxx>
43 namespace connectivity::evoab {
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star::lang;
48 using namespace com::sun::star::beans;
49 using namespace com::sun::star::sdbc;
50 using namespace com::sun::star::sdbcx;
51 using namespace com::sun::star::container;
52 using namespace com::sun::star::io;
53 using namespace com::sun::star::util;
55 namespace {
57 EBookQuery * createTrue()
58 { // Not the world's most efficient unconditional true but ...
59 return e_book_query_from_string("(exists \"full_name\")");
62 EBookQuery * createTest( std::u16string_view aColumnName,
63 EBookQueryTest eTest,
64 std::u16string_view aMatch )
66 OString sMatch = OUStringToOString( aMatch, RTL_TEXTENCODING_UTF8 );
67 OString sColumnName = OUStringToOString( aColumnName, RTL_TEXTENCODING_UTF8 );
69 return e_book_query_field_test( e_contact_field_id( sColumnName.getStr() ),
70 eTest, sMatch.getStr() );
75 OCommonStatement::OCommonStatement(OEvoabConnection* _pConnection)
76 : OCommonStatement_IBase(m_aMutex)
77 , ::comphelper::OPropertyContainer(OCommonStatement_IBase::rBHelper)
78 , m_xResultSet(nullptr)
79 , m_xConnection(_pConnection)
80 , m_aParser(_pConnection->getDriver().getComponentContext())
81 , m_aSQLIterator( _pConnection, _pConnection->createCatalog()->getTables(), m_aParser )
82 , m_pParseTree(nullptr)
83 , m_nMaxFieldSize(0)
84 , m_nMaxRows(0)
85 , m_nQueryTimeOut(0)
86 , m_nFetchSize(0)
87 , m_nResultSetType(ResultSetType::FORWARD_ONLY)
88 , m_nFetchDirection(FetchDirection::FORWARD)
89 , m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE)
90 , m_bEscapeProcessing(true)
92 registerProperty(
93 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),
94 PROPERTY_ID_CURSORNAME,
96 &m_aCursorName,
97 cppu::UnoType<decltype(m_aCursorName)>::get()
99 registerProperty(
100 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXFIELDSIZE),
101 PROPERTY_ID_MAXFIELDSIZE,
103 &m_nMaxFieldSize,
104 cppu::UnoType<decltype(m_nMaxFieldSize)>::get()
106 registerProperty(
107 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MAXROWS),
108 PROPERTY_ID_MAXROWS,
110 &m_nMaxRows,
111 cppu::UnoType<decltype(m_nMaxRows)>::get()
113 registerProperty(
114 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_QUERYTIMEOUT),
115 PROPERTY_ID_QUERYTIMEOUT,
117 &m_nQueryTimeOut,
118 cppu::UnoType<decltype(m_nQueryTimeOut)>::get()
120 registerProperty(
121 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
122 PROPERTY_ID_FETCHSIZE,
124 &m_nFetchSize,
125 cppu::UnoType<decltype(m_nFetchSize)>::get()
127 registerProperty(
128 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
129 PROPERTY_ID_RESULTSETTYPE,
131 &m_nResultSetType,
132 cppu::UnoType<decltype(m_nResultSetType)>::get()
134 registerProperty(
135 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
136 PROPERTY_ID_FETCHDIRECTION,
138 &m_nFetchDirection,
139 cppu::UnoType<decltype(m_nFetchDirection)>::get()
141 registerProperty(
142 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ESCAPEPROCESSING),
143 PROPERTY_ID_ESCAPEPROCESSING,
145 &m_bEscapeProcessing,
146 cppu::UnoType<decltype(m_bEscapeProcessing)>::get()
148 registerProperty(
149 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
150 PROPERTY_ID_RESULTSETCONCURRENCY,
152 &m_nResultSetConcurrency,
153 cppu::UnoType<decltype(m_nResultSetConcurrency)>::get()
157 OCommonStatement::~OCommonStatement()
161 void OCommonStatement::disposeResultSet()
163 // free the cursor if alive
164 Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
165 if (xComp.is())
166 xComp->dispose();
167 m_xResultSet.clear();
170 void OCommonStatement::disposing()
172 ::osl::MutexGuard aGuard(m_aMutex);
174 disposeResultSet();
176 m_xConnection.clear();
178 OCommonStatement_IBase::disposing();
181 Any SAL_CALL OCommonStatement::queryInterface( const Type & rType )
183 Any aRet = OCommonStatement_IBase::queryInterface(rType);
184 if(!aRet.hasValue())
185 aRet = ::comphelper::OPropertyContainer::queryInterface(rType);
186 return aRet;
189 Sequence< Type > SAL_CALL OCommonStatement::getTypes( )
191 ::cppu::OTypeCollection aTypes( cppu::UnoType<XMultiPropertySet>::get(),
192 cppu::UnoType<XFastPropertySet>::get(),
193 cppu::UnoType<XPropertySet>::get());
195 return ::comphelper::concatSequences(aTypes.getTypes(),OCommonStatement_IBase::getTypes());
199 //void SAL_CALL OCommonStatement::cancel( ) throw(RuntimeException)
201 //::osl::MutexGuard aGuard( m_aMutex );
202 //checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
203 //// cancel the current sql statement
207 void SAL_CALL OCommonStatement::close( )
210 ::osl::MutexGuard aGuard( m_aMutex );
211 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
214 dispose();
217 OUString OCommonStatement::impl_getColumnRefColumnName_throw( const OSQLParseNode& _rColumnRef )
219 ENSURE_OR_THROW( SQL_ISRULE( &_rColumnRef, column_ref ), "internal error: only column_refs supported as LHS" );
221 OUString sColumnName;
222 switch ( _rColumnRef.count() )
224 case 3: // SQL_TOKEN_NAME '.' column_val
226 const OSQLParseNode* pPunct = _rColumnRef.getChild( 1 );
227 const OSQLParseNode* pColVal = _rColumnRef.getChild( 2 );
228 if ( SQL_ISPUNCTUATION( pPunct, "." )
229 && ( pColVal->count() == 1 )
232 sColumnName = pColVal->getChild( 0 )->getTokenValue();
235 break;
237 case 1: // column
239 sColumnName = _rColumnRef.getChild( 0 )->getTokenValue();
241 break;
244 if ( !sColumnName.getLength() )
245 m_xConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
247 return sColumnName;
251 void OCommonStatement::orderByAnalysis( const OSQLParseNode* _pOrderByClause, SortDescriptor& _out_rSort )
253 ENSURE_OR_THROW( _pOrderByClause, "NULL node" );
254 ENSURE_OR_THROW( SQL_ISRULE( _pOrderByClause, opt_order_by_clause ), "wrong node type" );
256 _out_rSort.clear();
258 const OSQLParseNode* pOrderList = _pOrderByClause->getByRule( OSQLParseNode::ordering_spec_commalist );
259 ENSURE_OR_THROW( pOrderList, "unexpected parse tree structure" );
261 for ( size_t i=0; i<pOrderList->count(); ++i )
263 const OSQLParseNode* pOrderBy = pOrderList->getChild(i);
264 if ( !pOrderBy || !SQL_ISRULE( pOrderBy, ordering_spec ) )
265 continue;
266 const OSQLParseNode* pColumnRef = pOrderBy->count() == 2 ? pOrderBy->getChild(0) : nullptr;
267 const OSQLParseNode* pAscDesc = pOrderBy->count() == 2 ? pOrderBy->getChild(1) : nullptr;
268 ENSURE_OR_THROW(
269 ( pColumnRef != nullptr )
270 && ( pAscDesc != nullptr )
271 && ( pAscDesc->isLeaf() )
272 && ( SQL_ISRULE( pAscDesc, opt_asc_desc )
273 || SQL_ISTOKEN(pAscDesc, ASC)
274 || SQL_ISTOKEN(pAscDesc, DESC)
276 "ordering_spec structure error" );
278 // column name -> column field
279 if ( !SQL_ISRULE( pColumnRef, column_ref ) )
280 m_xConnection->throwGenericSQLException( STR_SORT_BY_COL_ONLY, *this );
281 const OUString sColumnName( impl_getColumnRefColumnName_throw( *pColumnRef ) );
282 guint nField = evoab::findEvoabField( sColumnName );
283 // ascending/descending?
284 bool bAscending = !SQL_ISTOKEN(pAscDesc, DESC);
286 _out_rSort.push_back( FieldSort( nField, bAscending ) );
291 EBookQuery *OCommonStatement::whereAnalysis( const OSQLParseNode* parseTree )
293 EBookQuery *pResult = nullptr;
295 ENSURE_OR_THROW( parseTree, "invalid parse tree" );
297 // Nested brackets
298 if( parseTree->count() == 3 &&
299 SQL_ISPUNCTUATION( parseTree->getChild( 0 ), "(" ) &&
300 SQL_ISPUNCTUATION( parseTree->getChild( 2 ), ")" ) )
302 pResult = whereAnalysis( parseTree->getChild( 1 ) );
305 // SQL AND, OR
306 else if( ( SQL_ISRULE( parseTree, search_condition ) ||
307 SQL_ISRULE( parseTree, boolean_term ) ) &&
308 parseTree->count() == 3 )
310 ENSURE_OR_THROW( SQL_ISTOKEN( parseTree->getChild( 1 ), OR )
311 || SQL_ISTOKEN( parseTree->getChild( 1 ), AND ),
312 "unexpected search_condition structure" );
314 EBookQuery *pArgs[2];
315 pArgs[0] = whereAnalysis( parseTree->getChild( 0 ) );
316 pArgs[1] = whereAnalysis( parseTree->getChild( 2 ) );
318 if( SQL_ISTOKEN( parseTree->getChild( 1 ), OR ) )
319 pResult = e_book_query_or( 2, pArgs, true );
320 else
321 pResult = e_book_query_and( 2, pArgs, true );
323 // SQL =, !=
324 else if( SQL_ISRULE( parseTree, comparison_predicate ) )
326 OSQLParseNode *pPrec = parseTree->getChild( 1 );
328 ENSURE_OR_THROW( parseTree->count() == 3, "unexpected comparison_predicate structure" );
330 OSQLParseNode* pLHS = parseTree->getChild( 0 );
331 OSQLParseNode* pRHS = parseTree->getChild( 2 );
333 if ( ( ! SQL_ISRULE( pLHS, column_ref ) // on the LHS, we accept a column or a constant int value
334 && ( pLHS->getNodeType() != SQLNodeType::IntNum )
336 || ( ( pRHS->getNodeType() != SQLNodeType::String ) // on the RHS, certain literals are acceptable
337 && ( pRHS->getNodeType() != SQLNodeType::IntNum )
338 && ( pRHS->getNodeType() != SQLNodeType::ApproxNum )
339 && ! SQL_ISTOKEN( pRHS, TRUE )
340 && ! SQL_ISTOKEN( pRHS, FALSE )
342 || ( ( pLHS->getNodeType() == SQLNodeType::IntNum ) // an int on LHS requires an int on RHS
343 && ( pRHS->getNodeType() != SQLNodeType::IntNum )
347 m_xConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
350 if ( ( pPrec->getNodeType() != SQLNodeType::Equal )
351 && ( pPrec->getNodeType() != SQLNodeType::NotEqual )
354 m_xConnection->throwGenericSQLException( STR_OPERATOR_TOO_COMPLEX, *this );
357 // recognize the special "0 = 1" condition
358 if ( ( pLHS->getNodeType() == SQLNodeType::IntNum )
359 && ( pRHS->getNodeType() == SQLNodeType::IntNum )
360 && ( pPrec->getNodeType() == SQLNodeType::Equal )
363 const sal_Int32 nLHS = pLHS->getTokenValue().toInt64();
364 const sal_Int32 nRHS = pRHS->getTokenValue().toInt64();
365 return ( nLHS == nRHS ) ? createTrue() : nullptr;
368 OUString aColumnName( impl_getColumnRefColumnName_throw( *pLHS ) );
370 OUString aMatchString;
371 if ( pRHS->isToken() )
372 aMatchString = pRHS->getTokenValue();
373 else
374 aMatchString = pRHS->getChild( 0 )->getTokenValue();
376 pResult = createTest( aColumnName, E_BOOK_QUERY_IS, aMatchString );
378 if ( pResult && ( pPrec->getNodeType() == SQLNodeType::NotEqual ) )
379 pResult = e_book_query_not( pResult, true );
381 // SQL like
382 else if( SQL_ISRULE( parseTree, like_predicate ) )
384 ENSURE_OR_THROW( parseTree->count() == 2, "unexpected like_predicate structure" );
385 const OSQLParseNode* pPart2 = parseTree->getChild(1);
387 if( ! SQL_ISRULE( parseTree->getChild( 0 ), column_ref) )
388 m_xConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_COLUMN,*this);
390 OUString aColumnName( impl_getColumnRefColumnName_throw( *parseTree->getChild( 0 ) ) );
392 OSQLParseNode *pAtom = pPart2->getChild( pPart2->count() - 2 ); // Match String
393 bool bNotLike = pPart2->getChild(0)->isToken();
395 if( !( pAtom->getNodeType() == SQLNodeType::String ||
396 pAtom->getNodeType() == SQLNodeType::Name ||
397 SQL_ISRULE( pAtom,parameter ) ||
398 ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQLNodeType::Name ) ||
399 ( pAtom->getChild( 0 ) && pAtom->getChild( 0 )->getNodeType() == SQLNodeType::String ) ) )
401 SAL_INFO(
402 "connectivity.evoab2",
403 "analyseSQL : pAtom->count() = " << pAtom->count());
404 m_xConnection->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,*this);
407 const sal_Unicode WILDCARD = '%';
409 OUString aMatchString = pAtom->getTokenValue();
411 // Determine where '%' character is...
412 if( aMatchString == OUStringChar(WILDCARD) )
414 // String containing only a '%' and nothing else matches everything
415 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS,
416 u"" );
418 else if( aMatchString.indexOf( WILDCARD ) == -1 )
419 { // Simple string , eg. "to match" "contains in evo"
420 SAL_INFO( "connectivity.evoab2", "Plain contains '" << aMatchString << "'" );
421 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString );
422 if( pResult && bNotLike )
423 pResult = e_book_query_not( pResult, true );
425 else if( bNotLike )
427 // We currently can't handle a 'NOT LIKE' when there are '%'
428 m_xConnection->throwGenericSQLException(STR_QUERY_NOT_LIKE_TOO_COMPLEX,*this);
430 else if( aMatchString.indexOf ( WILDCARD ) == aMatchString.lastIndexOf ( WILDCARD ) )
431 { // One occurrence of '%' matches...
432 if ( aMatchString.startsWith(OUStringChar(WILDCARD)) )
433 pResult = createTest(
434 aColumnName, E_BOOK_QUERY_ENDS_WITH, aMatchString.subView( 1 ) );
435 else if ( aMatchString.indexOf ( WILDCARD ) == aMatchString.getLength() - 1 )
436 pResult = createTest( aColumnName, E_BOOK_QUERY_BEGINS_WITH, aMatchString.subView( 0, aMatchString.getLength() - 1 ) );
437 else
438 m_xConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD,*this);
440 else if( aMatchString.getLength() >= 3 &&
441 aMatchString.startsWith(OUStringChar(WILDCARD)) &&
442 aMatchString.indexOf ( WILDCARD, 1) == aMatchString.getLength() - 1 ) {
443 // one '%' at the start and another at the end
444 pResult = createTest( aColumnName, E_BOOK_QUERY_CONTAINS, aMatchString.subView (1, aMatchString.getLength() - 2) );
446 else
447 m_xConnection->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD_MANY,*this);
450 return pResult;
453 OUString OCommonStatement::getTableName() const
455 OUString aTableName;
457 if( m_pParseTree && m_aSQLIterator.getStatementType() == OSQLStatementType::Select )
459 Any aCatalog;
460 OUString aSchema;
461 const OSQLParseNode *pSelectStmnt = m_aSQLIterator.getParseTree();
462 const OSQLParseNode *pAllTableNames = pSelectStmnt->getChild( 3 )->getChild( 0 )->getChild( 1 );
464 if( OSQLParseTreeIterator::isTableNode( pAllTableNames->getChild( 0 ) ) )
465 OSQLParseNode::getTableComponents( pAllTableNames->getChild( 0 ),
466 aCatalog,aSchema, aTableName,nullptr );
468 else if( SQL_ISRULE( pAllTableNames->getChild( 0 ), table_ref ) )
470 OSQLParseNode *pNodeForTableName = pAllTableNames->getChild( 0 )->getChild( 0 );
471 if( OSQLParseTreeIterator::isTableNode( pNodeForTableName ) )
473 aTableName = OSQLParseNode::getTableRange(pAllTableNames->getChild( 0 ));
474 if( !aTableName.getLength() )
475 OSQLParseNode::getTableComponents( pNodeForTableName, aCatalog, aSchema, aTableName,nullptr);
477 else
478 OSL_FAIL( "odd table layout" );
480 else
481 OSL_FAIL( "unusual table layout" );
483 return aTableName;
486 void OCommonStatement::parseSql( const OUString& sql, QueryData& _out_rQueryData )
488 SAL_INFO( "connectivity.evoab2", "parsing " << sql );
490 _out_rQueryData.eFilterType = eFilterOther;
492 OUString aErr;
493 m_pParseTree = m_aParser.parseTree( aErr, sql ).release();
494 m_aSQLIterator.setParseTree( m_pParseTree );
495 m_aSQLIterator.traverseAll();
497 _out_rQueryData.sTable = getTableName();
499 // to be sorted?
500 const OSQLParseNode* pOrderByClause = m_aSQLIterator.getOrderTree();
501 if ( pOrderByClause )
503 #if OSL_DEBUG_LEVEL > 1
504 OUString sTreeDebug;
505 pOrderByClause->showParseTree( sTreeDebug );
506 SAL_INFO( "connectivity.evoab2", "found order-by tree:\n" << sTreeDebug );
507 #endif
509 orderByAnalysis( pOrderByClause, _out_rQueryData.aSortOrder );
512 const OSQLParseNode* pWhereClause = m_aSQLIterator.getWhereTree();
513 if ( pWhereClause && SQL_ISRULE( pWhereClause, where_clause ) )
515 #if OSL_DEBUG_LEVEL > 1
516 OUString sTreeDebug;
517 pWhereClause->showParseTree( sTreeDebug );
518 SAL_INFO( "connectivity.evoab2", "found where tree:\n" << sTreeDebug );
519 #endif
520 EBookQuery* pQuery = whereAnalysis( pWhereClause->getChild( 1 ) );
521 if ( !pQuery )
523 _out_rQueryData.eFilterType = eFilterAlwaysFalse;
524 pQuery = createTrue();
526 _out_rQueryData.setQuery( pQuery );
528 else
530 _out_rQueryData.eFilterType = eFilterNone;
531 _out_rQueryData.setQuery( createTrue() );
536 Reference< XConnection > SAL_CALL OStatement::getConnection( )
538 ::osl::MutexGuard aGuard( m_aMutex );
539 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
541 // just return our connection here
542 return impl_getConnection();
546 Any SAL_CALL OCommonStatement::getWarnings( )
548 ::osl::MutexGuard aGuard( m_aMutex );
549 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
552 return Any(SQLWarning());
556 void SAL_CALL OCommonStatement::clearWarnings( )
558 ::osl::MutexGuard aGuard( m_aMutex );
559 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
563 ::cppu::IPropertyArrayHelper* OCommonStatement::createArrayHelper( ) const
565 Sequence< Property > aProps;
566 describeProperties( aProps );
567 return new ::cppu::OPropertyArrayHelper( aProps );
570 ::cppu::IPropertyArrayHelper & OCommonStatement::getInfoHelper()
572 return *getArrayHelper();
576 void SAL_CALL OCommonStatement::acquire() noexcept
578 OCommonStatement_IBase::acquire();
581 void SAL_CALL OCommonStatement::release() noexcept
583 OCommonStatement_IBase::release();
587 QueryData OCommonStatement::impl_getEBookQuery_throw( const OUString& _rSql )
589 QueryData aData;
590 parseSql( _rSql, aData );
592 #if OSL_DEBUG_LEVEL > 1
593 char *pSexpr = aData.getQuery() ? e_book_query_to_string( aData.getQuery() ) : g_strdup( "<map failed>" );
594 g_message( "Parsed SQL to sexpr '%s'\n", pSexpr );
595 g_free( pSexpr );
596 #endif
598 if ( !aData.getQuery() )
599 m_xConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
601 // a postcondition of this method is that we properly determined the SELECT columns
602 aData.xSelectColumns = m_aSQLIterator.getSelectColumns();
603 if ( !aData.xSelectColumns.is() )
604 m_xConnection->throwGenericSQLException( STR_QUERY_TOO_COMPLEX, *this );
606 return aData;
610 Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const QueryData& _rQueryData )
612 // create result set
613 rtl::Reference<OEvoabResultSet> pResult = new OEvoabResultSet( this, m_xConnection.get() );
614 pResult->construct( _rQueryData );
616 // done
617 m_xResultSet = Reference<XWeak>(pResult);
618 return pResult;
622 Reference< XResultSet > OCommonStatement::impl_executeQuery_throw( const OUString& _rSql )
624 SAL_INFO( "connectivity.evoab2", "OCommonStatement::impl_executeQuery_throw " << _rSql );
626 #if OSL_DEBUG_LEVEL > 1
627 g_message( "Parse SQL '%s'\n",
628 OUStringToOString(_rSql, RTL_TEXTENCODING_UTF8).getStr() );
629 #endif
631 return impl_executeQuery_throw( impl_getEBookQuery_throw( _rSql ) );
635 Reference< XPropertySetInfo > SAL_CALL OCommonStatement::getPropertySetInfo( )
637 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
641 // = OStatement
644 IMPLEMENT_SERVICE_INFO( OStatement, "com.sun.star.comp.sdbcx.evoab.OStatement", "com.sun.star.sdbc.Statement" );
647 IMPLEMENT_FORWARD_XINTERFACE2( OStatement, OCommonStatement, OStatement_IBase )
650 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement, OCommonStatement, OStatement_IBase )
653 sal_Bool SAL_CALL OStatement::execute( const OUString& _sql )
655 ::osl::MutexGuard aGuard( m_aMutex );
656 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
658 Reference< XResultSet > xRS = impl_executeQuery_throw( _sql );
659 return xRS.is();
663 Reference< XResultSet > SAL_CALL OStatement::executeQuery( const OUString& _sql )
665 ::osl::MutexGuard aGuard( m_aMutex );
666 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
668 return impl_executeQuery_throw( _sql );
672 sal_Int32 SAL_CALL OStatement::executeUpdate( const OUString& /*sql*/ )
674 ::osl::MutexGuard aGuard( m_aMutex );
675 checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
676 ::dbtools::throwFeatureNotImplementedSQLException( "XStatement::executeUpdate", *this );
677 return 0;
680 } // namespace ::connectivity::evoab
682 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */