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 * $RCSfile: statementcomposer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include <connectivity/statementcomposer.hxx>
35 #include <connectivity/dbtools.hxx>
37 /** === begin UNO includes === **/
38 #include <com/sun/star/sdb/CommandType.hpp>
39 #include <com/sun/star/lang/NullPointerException.hpp>
40 #include <com/sun/star/lang/XComponent.hpp>
41 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 /** === end UNO includes === **/
45 #include <unotools/sharedunocomponent.hxx>
46 #include <tools/diagnose_ex.h>
47 #include <comphelper/property.hxx>
49 //........................................................................
52 //........................................................................
54 /** === begin UNO using === **/
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::sdbc::XConnection
;
57 using ::com::sun::star::sdb::XSingleSelectQueryComposer
;
58 using ::com::sun::star::lang::NullPointerException
;
59 using ::com::sun::star::uno::Exception
;
60 using ::com::sun::star::lang::XComponent
;
61 using ::com::sun::star::uno::UNO_QUERY_THROW
;
62 using ::com::sun::star::sdb::XQueriesSupplier
;
63 using ::com::sun::star::container::XNameAccess
;
64 using ::com::sun::star::uno::UNO_QUERY
;
65 using ::com::sun::star::beans::XPropertySet
;
66 using ::com::sun::star::lang::XMultiServiceFactory
;
67 using ::com::sun::star::sdbc::SQLException
;
68 /** === end UNO using === **/
69 namespace CommandType
= ::com::sun::star::sdb::CommandType
;
71 //====================================================================
72 //= StatementComposer_Data
73 //====================================================================
74 struct StatementComposer_Data
76 const Reference
< XConnection
> xConnection
;
77 Reference
< XSingleSelectQueryComposer
> xComposer
;
78 ::rtl::OUString sCommand
;
79 ::rtl::OUString sFilter
;
80 ::rtl::OUString sOrder
;
81 sal_Int32 nCommandType
;
82 sal_Bool bEscapeProcessing
;
84 bool bDisposeComposer
;
86 StatementComposer_Data( const Reference
< XConnection
>& _rxConnection
)
87 :xConnection( _rxConnection
)
91 ,nCommandType( CommandType::COMMAND
)
92 ,bEscapeProcessing( sal_True
)
93 ,bComposerDirty( true )
94 ,bDisposeComposer( true )
96 if ( !_rxConnection
.is() )
97 throw NullPointerException();
101 //--------------------------------------------------------------------
104 //----------------------------------------------------------------
105 void lcl_resetComposer( StatementComposer_Data
& _rData
)
107 if ( _rData
.bDisposeComposer
&& _rData
.xComposer
.is() )
111 Reference
< XComponent
> xComposerComponent( _rData
.xComposer
, UNO_QUERY_THROW
);
112 xComposerComponent
->dispose();
114 catch( const Exception
& )
116 DBG_UNHANDLED_EXCEPTION();
119 _rData
.xComposer
.clear();
122 //----------------------------------------------------------------
123 bool lcl_ensureUpToDateComposer_nothrow( StatementComposer_Data
& _rData
)
125 if ( !_rData
.bComposerDirty
)
126 return _rData
.xComposer
.is();
127 lcl_resetComposer( _rData
);
131 ::rtl::OUString sStatement
;
132 switch ( _rData
.nCommandType
)
134 case CommandType::COMMAND
:
135 if ( _rData
.bEscapeProcessing
)
136 sStatement
= _rData
.sCommand
;
137 // (in case of no escape processing we assume a not parseable statement)
140 case CommandType::TABLE
:
142 if ( !_rData
.sCommand
.getLength() )
145 sStatement
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SELECT * FROM " ) );
147 ::rtl::OUString sCatalog
, sSchema
, sTable
;
148 qualifiedNameComponents( _rData
.xConnection
->getMetaData(), _rData
.sCommand
, sCatalog
, sSchema
, sTable
, eInDataManipulation
);
150 sStatement
+= composeTableNameForSelect( _rData
.xConnection
, sCatalog
, sSchema
, sTable
);
154 case CommandType::QUERY
:
156 // ask the connection for the query
157 Reference
< XQueriesSupplier
> xSupplyQueries( _rData
.xConnection
, UNO_QUERY_THROW
);
158 Reference
< XNameAccess
> xQueries( xSupplyQueries
->getQueries(), UNO_QUERY_THROW
);
160 if ( !xQueries
->hasByName( _rData
.sCommand
) )
163 Reference
< XPropertySet
> xQuery( xQueries
->getByName( _rData
.sCommand
), UNO_QUERY_THROW
);
166 sal_Bool bQueryEscapeProcessing
= sal_False
;
167 xQuery
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EscapeProcessing" ) ) ) >>= bQueryEscapeProcessing
;
168 if ( !bQueryEscapeProcessing
)
171 // the command used by the query
172 xQuery
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Command" ) ) ) >>= sStatement
;
173 if ( !sStatement
.getLength() )
176 // use a composer to build a statement from the query filter/order props
177 Reference
< XMultiServiceFactory
> xFactory( _rData
.xConnection
, UNO_QUERY_THROW
);
178 ::utl::SharedUNOComponent
< XSingleSelectQueryComposer
> xComposer
;
180 xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
184 // the "basic" statement
185 xComposer
->setElementaryQuery( sStatement
);
188 const ::rtl::OUString
sPropOrder( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Order" ) ) );
189 if ( ::comphelper::hasProperty( sPropOrder
, xQuery
) )
191 ::rtl::OUString sOrder
;
192 OSL_VERIFY( xQuery
->getPropertyValue( sPropOrder
) >>= sOrder
);
193 xComposer
->setOrder( sOrder
);
197 sal_Bool bApplyFilter
= sal_True
;
198 const ::rtl::OUString sPropApply
= ::rtl::OUString::createFromAscii( "ApplyFilter" );
199 if ( ::comphelper::hasProperty( sPropApply
, xQuery
) )
201 OSL_VERIFY( xQuery
->getPropertyValue( sPropApply
) >>= bApplyFilter
);
206 ::rtl::OUString sFilter
;
207 OSL_VERIFY( xQuery
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Filter" ) ) ) >>= sFilter
);
208 xComposer
->setFilter( sFilter
);
211 // the composed statement
212 sStatement
= xComposer
->getQuery();
217 OSL_ENSURE(sal_False
, "lcl_ensureUpToDateComposer_nothrow: no table, no query, no statement - what else ?!");
221 if ( sStatement
.getLength() )
223 // create an composer
224 Reference
< XMultiServiceFactory
> xFactory( _rData
.xConnection
, UNO_QUERY_THROW
);
225 Reference
< XSingleSelectQueryComposer
> xComposer( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ),
227 xComposer
->setElementaryQuery( sStatement
);
229 // append sort/filter
230 xComposer
->setOrder( _rData
.sOrder
);
231 xComposer
->setFilter( _rData
.sFilter
);
233 sStatement
= xComposer
->getQuery();
235 _rData
.xComposer
= xComposer
;
236 _rData
.bComposerDirty
= false;
239 catch( const SQLException
& )
241 // allowed to leave here
243 catch( const Exception
& )
245 DBG_UNHANDLED_EXCEPTION();
248 return _rData
.xComposer
.is();
252 //====================================================================
253 //= StatementComposer
254 //====================================================================
255 //--------------------------------------------------------------------
256 StatementComposer::StatementComposer( const Reference
< XConnection
>& _rxConnection
,
257 const ::rtl::OUString
& _rCommand
, const sal_Int32 _nCommandType
, const sal_Bool _bEscapeProcessing
)
258 :m_pData( new StatementComposer_Data( _rxConnection
) )
260 OSL_PRECOND( _rxConnection
.is(), "StatementComposer::StatementComposer: illegal connection!" );
261 m_pData
->sCommand
= _rCommand
;
262 m_pData
->nCommandType
= _nCommandType
;
263 m_pData
->bEscapeProcessing
= _bEscapeProcessing
;
266 //--------------------------------------------------------------------
267 StatementComposer::~StatementComposer()
269 lcl_resetComposer( *m_pData
);
272 //--------------------------------------------------------------------
273 void StatementComposer::setDisposeComposer( bool _bDoDispose
)
275 m_pData
->bDisposeComposer
= _bDoDispose
;
278 //--------------------------------------------------------------------
279 bool StatementComposer::getDisposeComposer() const
281 return m_pData
->bDisposeComposer
;
284 //--------------------------------------------------------------------
285 void StatementComposer::setFilter( const ::rtl::OUString
& _rFilter
)
287 m_pData
->sFilter
= _rFilter
;
288 m_pData
->bComposerDirty
= true;
291 //--------------------------------------------------------------------
292 void StatementComposer::setOrder( const ::rtl::OUString
& _rOrder
)
294 m_pData
->sOrder
= _rOrder
;
295 m_pData
->bComposerDirty
= true;
298 //--------------------------------------------------------------------
299 Reference
< XSingleSelectQueryComposer
> StatementComposer::getComposer()
301 lcl_ensureUpToDateComposer_nothrow( *m_pData
);
302 return m_pData
->xComposer
;
305 //--------------------------------------------------------------------
306 ::rtl::OUString
StatementComposer::getQuery()
308 if ( lcl_ensureUpToDateComposer_nothrow( *m_pData
) )
310 return m_pData
->xComposer
->getQuery();
313 return ::rtl::OUString();
316 //........................................................................
317 } // namespace dbtools
318 //........................................................................