1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
32 #include <osl/diagnose.h>
33 #include <osl/thread.h>
34 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
35 #include <com/sun/star/sdbc/ResultSetType.hpp>
36 #include <com/sun/star/sdbc/FetchDirection.hpp>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include <cppuhelper/typeprovider.hxx>
39 #include "propertyids.hxx"
40 #include "NStatement.hxx"
41 #include "NConnection.hxx"
42 #include "NDatabaseMetaData.hxx"
43 #include "NResultSet.hxx"
45 #include "resource/evoab2_res.hrc"
46 #include <resource/common_res.hrc>
47 #include <connectivity/dbexception.hxx>
48 #include <tools/diagnose_ex.h>
50 namespace connectivity
{ namespace evoab
{
52 //------------------------------------------------------------------------------
53 using namespace com::sun::star::uno
;
54 using namespace com::sun::star::lang
;
55 using namespace com::sun::star::beans
;
56 using namespace com::sun::star::sdbc
;
57 using namespace com::sun::star::sdbcx
;
58 using namespace com::sun::star::container
;
59 using namespace com::sun::star::io
;
60 using namespace com::sun::star::util
;
61 //------------------------------------------------------------------------------
62 OCommonStatement::OCommonStatement(OEvoabConnection
* _pConnection
)
63 : OCommonStatement_IBase(m_aMutex
)
64 , ::comphelper::OPropertyContainer(OCommonStatement_IBase::rBHelper
)
65 , OStatement_CBase( (::cppu::OWeakObject
*)_pConnection
, this )
68 , m_pConnection(_pConnection
)
69 , m_aParser(_pConnection
->getDriver().getMSFactory())
70 , m_aSQLIterator( _pConnection
, _pConnection
->createCatalog()->getTables(), m_aParser
, NULL
)
76 , m_nResultSetType(ResultSetType::FORWARD_ONLY
)
77 , m_nFetchDirection(FetchDirection::FORWARD
)
78 , m_nResultSetConcurrency(ResultSetConcurrency::UPDATABLE
)
79 , m_bEscapeProcessing(sal_True
)
80 , rBHelper(OCommonStatement_IBase::rBHelper
)
82 m_pConnection
->acquire();
84 #define REGISTER_PROP( id, member ) \
86 OMetaConnection::getPropMap().getNameByIndex( id ), \
90 ::getCppuType( &member ) \
93 REGISTER_PROP( PROPERTY_ID_CURSORNAME
, m_aCursorName
);
94 REGISTER_PROP( PROPERTY_ID_MAXFIELDSIZE
, m_nMaxFieldSize
);
95 REGISTER_PROP( PROPERTY_ID_MAXROWS
, m_nMaxRows
);
96 REGISTER_PROP( PROPERTY_ID_QUERYTIMEOUT
, m_nQueryTimeOut
);
97 REGISTER_PROP( PROPERTY_ID_FETCHSIZE
, m_nFetchSize
);
98 REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE
, m_nResultSetType
);
99 REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION
, m_nFetchDirection
);
100 REGISTER_PROP( PROPERTY_ID_ESCAPEPROCESSING
, m_bEscapeProcessing
);
101 REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY
, m_nResultSetConcurrency
);
103 // -----------------------------------------------------------------------------
104 OCommonStatement::~OCommonStatement()
107 //------------------------------------------------------------------------------
108 void OCommonStatement::disposeResultSet()
110 // free the cursor if alive
111 Reference
< XComponent
> xComp(m_xResultSet
.get(), UNO_QUERY
);
114 m_xResultSet
= Reference
< XResultSet
>();
116 //------------------------------------------------------------------------------
117 void OCommonStatement::disposing()
119 ::osl::MutexGuard
aGuard(m_aMutex
);
124 m_pConnection
->release();
125 m_pConnection
= NULL
;
128 OCommonStatement_IBase::disposing();
130 //-----------------------------------------------------------------------------
131 Any SAL_CALL
OCommonStatement::queryInterface( const Type
& rType
) throw(RuntimeException
)
133 Any aRet
= OCommonStatement_IBase::queryInterface(rType
);
135 aRet
= ::comphelper::OPropertyContainer::queryInterface(rType
);
138 // -------------------------------------------------------------------------
139 Sequence
< Type
> SAL_CALL
OCommonStatement::getTypes( ) throw(RuntimeException
)
141 ::cppu::OTypeCollection
aTypes( ::getCppuType( (const Reference
< XMultiPropertySet
> *)0 ),
142 ::getCppuType( (const Reference
< XFastPropertySet
> *)0 ),
143 ::getCppuType( (const Reference
< XPropertySet
> *)0 ));
145 return ::comphelper::concatSequences(aTypes
.getTypes(),OCommonStatement_IBase::getTypes());
147 // -------------------------------------------------------------------------
149 //void SAL_CALL OCommonStatement::cancel( ) throw(RuntimeException)
151 //::osl::MutexGuard aGuard( m_aMutex );
152 //checkDisposed(OCommonStatement_IBase::rBHelper.bDisposed);
153 //// cancel the current sql statement
156 // -------------------------------------------------------------------------
157 void SAL_CALL
OCommonStatement::close( ) throw(SQLException
, RuntimeException
)
160 ::osl::MutexGuard
aGuard( m_aMutex
);
161 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
166 // -------------------------------------------------------------------------
168 void OCommonStatement::reset() throw (SQLException
)
170 ::osl::MutexGuard
aGuard( m_aMutex
);
171 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
176 if (m_xResultSet
.get().is())
180 void OCommonStatement::clearMyResultSet () throw (SQLException
)
182 ::osl::MutexGuard
aGuard( m_aMutex
);
183 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
187 Reference
<XCloseable
> xCloseable
;
188 if ( ::comphelper::query_interface( m_xResultSet
.get(), xCloseable
) )
191 catch( const DisposedException
& ) { }
193 m_xResultSet
= Reference
< XResultSet
>();
197 OCommonStatement::createTrue()
198 { // Not the world's most efficient unconditional true but ...
199 return e_book_query_from_string("(exists \"full_name\")");
203 OCommonStatement::createTest( const ::rtl::OUString
&aColumnName
,
204 EBookQueryTest eTest
,
205 const ::rtl::OUString
&aMatch
)
207 ::rtl::OString sMatch
= rtl::OUStringToOString( aMatch
, RTL_TEXTENCODING_UTF8
);
208 ::rtl::OString sColumnName
= rtl::OUStringToOString( aColumnName
, RTL_TEXTENCODING_UTF8
);
210 return e_book_query_field_test( e_contact_field_id( sColumnName
),
214 // -------------------------------------------------------------------------
216 ::rtl::OUString
OCommonStatement::impl_getColumnRefColumnName_throw( const OSQLParseNode
& _rColumnRef
)
218 ENSURE_OR_THROW( SQL_ISRULE( &_rColumnRef
, column_ref
), "internal error: only column_refs supported as LHS" );
220 ::rtl::OUString sColumnName
;
221 switch ( _rColumnRef
.count() )
223 case 3: // SQL_TOKEN_NAME '.' column_val
225 const OSQLParseNode
* pPunct
= _rColumnRef
.getChild( 1 );
226 const OSQLParseNode
* pColVal
= _rColumnRef
.getChild( 2 );
227 if ( SQL_ISPUNCTUATION( pPunct
, "." )
228 && ( pColVal
->count() == 1 )
231 sColumnName
= pColVal
->getChild( 0 )->getTokenValue();
238 sColumnName
= _rColumnRef
.getChild( 0 )->getTokenValue();
243 if ( !sColumnName
.getLength() )
244 m_pConnection
->throwGenericSQLException( STR_QUERY_TOO_COMPLEX
, *this );
249 // -------------------------------------------------------------------------
250 void OCommonStatement::orderByAnalysis( const OSQLParseNode
* _pOrderByClause
, SortDescriptor
& _out_rSort
)
252 ENSURE_OR_THROW( _pOrderByClause
, "NULL node" );
253 ENSURE_OR_THROW( SQL_ISRULE( _pOrderByClause
, opt_order_by_clause
), "wrong node type" );
257 const OSQLParseNode
* pOrderList
= _pOrderByClause
->getByRule( OSQLParseNode::ordering_spec_commalist
);
258 ENSURE_OR_THROW( pOrderList
, "unexpected parse tree structure" );
260 for ( sal_uInt32 i
=0; i
<pOrderList
->count(); ++i
)
262 const OSQLParseNode
* pOrderBy
= pOrderList
->getChild(i
);
263 if ( !pOrderBy
|| !SQL_ISRULE( pOrderBy
, ordering_spec
) )
265 const OSQLParseNode
* pColumnRef
= pOrderBy
->count() == 2 ? pOrderBy
->getChild(0) : NULL
;
266 const OSQLParseNode
* pAscDesc
= pOrderBy
->count() == 2 ? pOrderBy
->getChild(1) : NULL
;
268 ( pColumnRef
!= NULL
)
269 && ( pAscDesc
!= NULL
)
270 && SQL_ISRULE( pAscDesc
, opt_asc_desc
)
271 && ( pAscDesc
->count() < 2 ),
272 "ordering_spec structure error" );
274 // column name -> column field
275 if ( !SQL_ISRULE( pColumnRef
, column_ref
) )
276 m_pConnection
->throwGenericSQLException( STR_SORT_BY_COL_ONLY
, *this );
277 const ::rtl::OUString
sColumnName( impl_getColumnRefColumnName_throw( *pColumnRef
) );
278 guint nField
= evoab::findEvoabField( sColumnName
);
279 // ascending/descending?
280 bool bAscending
= true;
281 if ( ( pAscDesc
->count() == 1 )
282 && SQL_ISTOKEN( pAscDesc
->getChild( 0 ), DESC
)
286 _out_rSort
.push_back( FieldSort( nField
, bAscending
) );
290 // -------------------------------------------------------------------------
291 EBookQuery
*OCommonStatement::whereAnalysis( const OSQLParseNode
* parseTree
)
293 EBookQuery
*pResult
= NULL
;
295 ENSURE_OR_THROW( parseTree
, "invalid parse tree" );
298 if( parseTree
->count() == 3 &&
299 SQL_ISPUNCTUATION( parseTree
->getChild( 0 ), "(" ) &&
300 SQL_ISPUNCTUATION( parseTree
->getChild( 2 ), ")" ) )
302 pResult
= whereAnalysis( parseTree
->getChild( 1 ) );
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
);
321 pResult
= e_book_query_and( 2, pArgs
, TRUE
);
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() != SQL_NODE_INTNUM
)
336 || ( ( pRHS
->getNodeType() != SQL_NODE_STRING
) // on the RHS, certain literals are acceptable
337 && ( pRHS
->getNodeType() != SQL_NODE_INTNUM
)
338 && ( pRHS
->getNodeType() != SQL_NODE_APPROXNUM
)
339 && !( SQL_ISTOKEN( pRHS
, TRUE
) )
340 && !( SQL_ISTOKEN( pRHS
, FALSE
) )
342 || ( ( pLHS
->getNodeType() == SQL_NODE_INTNUM
) // an int on LHS requires an int on RHS
343 && ( pRHS
->getNodeType() != SQL_NODE_INTNUM
)
347 m_pConnection
->throwGenericSQLException( STR_QUERY_TOO_COMPLEX
, *this );
350 if ( ( pPrec
->getNodeType() != SQL_NODE_EQUAL
)
351 && ( pPrec
->getNodeType() != SQL_NODE_NOTEQUAL
)
354 m_pConnection
->throwGenericSQLException( STR_OPERATOR_TOO_COMPLEX
, *this );
357 // recognize the special "0 = 1" condition
358 if ( ( pLHS
->getNodeType() == SQL_NODE_INTNUM
)
359 && ( pRHS
->getNodeType() == SQL_NODE_INTNUM
)
360 && ( pPrec
->getNodeType() == SQL_NODE_EQUAL
)
363 const sal_Int32 nLHS
= pLHS
->getTokenValue().toInt64();
364 const sal_Int32 nRHS
= pRHS
->getTokenValue().toInt64();
365 return ( nLHS
== nRHS
) ? createTrue() : NULL
;
368 ::rtl::OUString
aColumnName( impl_getColumnRefColumnName_throw( *pLHS
) );
370 ::rtl::OUString aMatchString
;
371 if ( pRHS
->isToken() )
372 aMatchString
= pRHS
->getTokenValue();
374 aMatchString
= pRHS
->getChild( 0 )->getTokenValue();
376 pResult
= createTest( aColumnName
, E_BOOK_QUERY_IS
, aMatchString
);
378 if ( pResult
&& ( pPrec
->getNodeType() == SQL_NODE_NOTEQUAL
) )
379 pResult
= e_book_query_not( pResult
, TRUE
);
382 else if( SQL_ISRULE( parseTree
, like_predicate
) )
384 ENSURE_OR_THROW( parseTree
->count() >= 4, "unexpected like_predicate structure" );
386 if( ! SQL_ISRULE( parseTree
->getChild( 0 ), column_ref
) )
387 m_pConnection
->throwGenericSQLException(STR_QUERY_INVALID_LIKE_COLUMN
,*this);
389 ::rtl::OUString
aColumnName( impl_getColumnRefColumnName_throw( *parseTree
->getChild( 0 ) ) );
391 OSQLParseNode
*pAtom
= parseTree
->getChild( parseTree
->count() - 2 ); // Match String
392 bool bNotLike
= parseTree
->count() == 5;
394 if( !( pAtom
->getNodeType() == SQL_NODE_STRING
||
395 pAtom
->getNodeType() == SQL_NODE_NAME
||
396 SQL_ISRULE( pAtom
,parameter
) ||
397 ( pAtom
->getChild( 0 ) && pAtom
->getChild( 0 )->getNodeType() == SQL_NODE_NAME
) ||
398 ( pAtom
->getChild( 0 ) && pAtom
->getChild( 0 )->getNodeType() == SQL_NODE_STRING
) ) )
400 OSL_TRACE( "analyseSQL : pAtom->count() = %d\n", pAtom
->count() );
401 m_pConnection
->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,*this);
404 const sal_Unicode WILDCARD
= '%';
406 rtl::OUString aMatchString
;
407 aMatchString
= pAtom
->getTokenValue();
409 // Determine where '%' character is...
410 if( aMatchString
.equals( ::rtl::OUString::valueOf( WILDCARD
) ) )
412 // String containing only a '%' and nothing else matches everything
413 pResult
= createTest( aColumnName
, E_BOOK_QUERY_CONTAINS
,
414 rtl::OUString::createFromAscii( "" ) );
416 else if( aMatchString
.indexOf( WILDCARD
) == -1 )
417 { // Simple string , eg. "to match" "contains in evo"
418 EVO_TRACE_STRING( "Plain contains '%s'", aMatchString
);
419 pResult
= createTest( aColumnName
, E_BOOK_QUERY_CONTAINS
, aMatchString
);
420 if( pResult
&& bNotLike
)
421 pResult
= e_book_query_not( pResult
, TRUE
);
425 // We currently can't handle a 'NOT LIKE' when there are '%'
426 m_pConnection
->throwGenericSQLException(STR_QUERY_NOT_LIKE_TOO_COMPLEX
,*this);
428 else if( (aMatchString
.indexOf ( WILDCARD
) == aMatchString
.lastIndexOf ( WILDCARD
) ) )
429 { // One occurance of '%' matches...
430 if ( aMatchString
.indexOf ( WILDCARD
) == 0 )
431 pResult
= createTest( aColumnName
, E_BOOK_QUERY_ENDS_WITH
, aMatchString
.copy( 1 ) );
432 else if ( aMatchString
.indexOf ( WILDCARD
) == aMatchString
.getLength() - 1 )
433 pResult
= createTest( aColumnName
, E_BOOK_QUERY_BEGINS_WITH
, aMatchString
.copy( 0, aMatchString
.getLength() - 1 ) );
435 m_pConnection
->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD
,*this);
437 if( pResult
&& bNotLike
)
438 pResult
= e_book_query_not( pResult
, TRUE
);
440 else if( aMatchString
.getLength() >= 3 &&
441 aMatchString
.indexOf ( WILDCARD
) == 0 &&
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
.copy (1, aMatchString
.getLength() - 2) );
447 m_pConnection
->throwGenericSQLException(STR_QUERY_LIKE_WILDCARD_MANY
,*this);
453 rtl::OUString
OCommonStatement::getTableName()
455 ::rtl::OUString aTableName
;
457 if( m_pParseTree
&& m_aSQLIterator
.getStatementType() == SQL_STATEMENT_SELECT
)
460 ::rtl::OUString aSchema
, aComposedName
;
461 const OSQLParseNode
*pSelectStmnt
= m_aSQLIterator
.getParseTree();
462 const OSQLParseNode
*pAllTableNames
= pSelectStmnt
->getChild( 3 )->getChild( 0 )->getChild( 1 );
464 if( m_aSQLIterator
.isTableNode( pAllTableNames
->getChild( 0 ) ) )
465 OSQLParseNode::getTableComponents( pAllTableNames
->getChild( 0 ),
466 aCatalog
,aSchema
, aTableName
,NULL
);
468 else if( SQL_ISRULE( pAllTableNames
->getChild( 0 ), table_ref
) )
470 OSQLParseNode
*pNodeForTableName
= pAllTableNames
->getChild( 0 )->getChild( 0 );
471 if( m_aSQLIterator
.isTableNode( pNodeForTableName
) )
473 aTableName
= OSQLParseNode::getTableRange(pAllTableNames
->getChild( 0 ));
474 if( !aTableName
.getLength() )
475 OSQLParseNode::getTableComponents( pNodeForTableName
, aCatalog
, aSchema
, aTableName
,NULL
);
478 OSL_ENSURE( false, "odd table layout" );
481 OSL_ENSURE( false, "unusual table layout" );
486 void OCommonStatement::parseSql( const rtl::OUString
& sql
, QueryData
& _out_rQueryData
)
488 EVO_TRACE_STRING( "parsing %s", sql
);
490 _out_rQueryData
.eFilterType
= eFilterOther
;
492 ::rtl::OUString aErr
;
493 m_pParseTree
= m_aParser
.parseTree( aErr
, sql
);
494 m_aSQLIterator
.setParseTree( m_pParseTree
);
495 m_aSQLIterator
.traverseAll();
497 _out_rQueryData
.sTable
= getTableName();
500 const OSQLParseNode
* pOrderByClause
= m_aSQLIterator
.getOrderTree();
501 if ( pOrderByClause
)
503 #if OSL_DEBUG_LEVEL > 0
504 ::rtl::OUString sTreeDebug
;
505 pOrderByClause
->showParseTree( sTreeDebug
);
506 EVO_TRACE_STRING( "found order-by tree:\n%s", sTreeDebug
);
508 orderByAnalysis( pOrderByClause
, _out_rQueryData
.aSortOrder
);
511 const OSQLParseNode
* pWhereClause
= m_aSQLIterator
.getWhereTree();
512 if ( pWhereClause
&& SQL_ISRULE( pWhereClause
, where_clause
) )
514 #if OSL_DEBUG_LEVEL > 0
515 ::rtl::OUString sTreeDebug
;
516 pWhereClause
->showParseTree( sTreeDebug
);
517 EVO_TRACE_STRING( "found where tree:\n%s", sTreeDebug
);
519 EBookQuery
* pQuery
= whereAnalysis( pWhereClause
->getChild( 1 ) );
522 _out_rQueryData
.eFilterType
= eFilterAlwaysFalse
;
523 pQuery
= createTrue();
525 _out_rQueryData
.setQuery( pQuery
);
529 _out_rQueryData
.eFilterType
= eFilterNone
;
530 _out_rQueryData
.setQuery( createTrue() );
534 // -------------------------------------------------------------------------
536 Reference
< XConnection
> SAL_CALL
OStatement::getConnection( ) throw(SQLException
, RuntimeException
)
538 ::osl::MutexGuard
aGuard( m_aMutex
);
539 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
541 // just return our connection here
542 return impl_getConnection();
545 // -------------------------------------------------------------------------
546 Any SAL_CALL
OCommonStatement::getWarnings( ) throw(SQLException
, RuntimeException
)
548 ::osl::MutexGuard
aGuard( m_aMutex
);
549 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
552 return makeAny(SQLWarning());
555 // -------------------------------------------------------------------------
556 void SAL_CALL
OCommonStatement::clearWarnings( ) throw(SQLException
, RuntimeException
)
558 ::osl::MutexGuard
aGuard( m_aMutex
);
559 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
562 // -------------------------------------------------------------------------
563 ::cppu::IPropertyArrayHelper
* OCommonStatement::createArrayHelper( ) const
565 Sequence
< Property
> aProps
;
566 describeProperties( aProps
);
567 return new ::cppu::OPropertyArrayHelper( aProps
);
569 // -------------------------------------------------------------------------
570 ::cppu::IPropertyArrayHelper
& OCommonStatement::getInfoHelper()
572 return *const_cast< OCommonStatement
* >( this )->getArrayHelper();
575 // -----------------------------------------------------------------------------
576 void SAL_CALL
OCommonStatement::acquire() throw()
578 OCommonStatement_IBase::acquire();
580 // -----------------------------------------------------------------------------
581 void SAL_CALL
OCommonStatement::release() throw()
586 // -------------------------------------------------------------------------
587 QueryData
OCommonStatement::impl_getEBookQuery_throw( const ::rtl::OUString
& _rSql
)
590 parseSql( _rSql
, aData
);
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
);
598 if ( !aData
.getQuery() )
599 m_pConnection
->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
.isValid() )
604 m_pConnection
->throwGenericSQLException( STR_QUERY_TOO_COMPLEX
, *this );
609 // -------------------------------------------------------------------------
610 Reference
< XResultSet
> OCommonStatement::impl_executeQuery_throw( const QueryData
& _rQueryData
)
613 OEvoabResultSet
* pResult
= new OEvoabResultSet( this, m_pConnection
);
614 Reference
< XResultSet
> xRS
= pResult
;
615 pResult
->construct( _rQueryData
);
622 // -------------------------------------------------------------------------
623 Reference
< XResultSet
> OCommonStatement::impl_executeQuery_throw( const ::rtl::OUString
& _rSql
)
625 EVO_TRACE_STRING( "OCommonStatement::impl_executeQuery_throw(%s)\n", _rSql
);
628 g_message( "Parse SQL '%s'\n",
629 (const sal_Char
*)OUStringToOString( _rSql
, RTL_TEXTENCODING_UTF8
) );
632 return impl_executeQuery_throw( impl_getEBookQuery_throw( _rSql
) );
635 // -----------------------------------------------------------------------------
636 Reference
< XPropertySetInfo
> SAL_CALL
OCommonStatement::getPropertySetInfo( ) throw(RuntimeException
)
638 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
641 // =============================================================================
643 // =============================================================================
644 // -----------------------------------------------------------------------------
645 IMPLEMENT_SERVICE_INFO( OStatement
, "com.sun.star.comp.sdbcx.evoab.OStatement", "com.sun.star.sdbc.Statement" );
647 // -----------------------------------------------------------------------------
648 IMPLEMENT_FORWARD_XINTERFACE2( OStatement
, OCommonStatement
, OStatement_IBase
)
650 // -----------------------------------------------------------------------------
651 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OStatement
, OCommonStatement
, OStatement_IBase
)
653 // -------------------------------------------------------------------------
654 sal_Bool SAL_CALL
OStatement::execute( const ::rtl::OUString
& _sql
) throw(SQLException
, RuntimeException
)
656 ::osl::MutexGuard
aGuard( m_aMutex
);
657 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
659 Reference
< XResultSet
> xRS
= impl_executeQuery_throw( _sql
);
663 // -------------------------------------------------------------------------
664 Reference
< XResultSet
> SAL_CALL
OStatement::executeQuery( const ::rtl::OUString
& _sql
) throw(SQLException
, RuntimeException
)
666 ::osl::MutexGuard
aGuard( m_aMutex
);
667 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
669 return impl_executeQuery_throw( _sql
);
672 // -----------------------------------------------------------------------------
673 sal_Int32 SAL_CALL
OStatement::executeUpdate( const ::rtl::OUString
& /*sql*/ ) throw(SQLException
, RuntimeException
)
675 ::osl::MutexGuard
aGuard( m_aMutex
);
676 checkDisposed(OCommonStatement_IBase::rBHelper
.bDisposed
);
677 ::dbtools::throwFeatureNotImplementedException( "XStatement::executeUpdate", *this );
681 } } // namespace ::connectivity::evoab