Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / connectivity / source / commontools / statementcomposer.cxx
blob9838787f4fcda82e8d95b61737ace5a2712b83cb
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 <connectivity/statementcomposer.hxx>
22 #include <connectivity/dbtools.hxx>
24 #include <com/sun/star/sdb/CommandType.hpp>
25 #include <com/sun/star/lang/NullPointerException.hpp>
26 #include <com/sun/star/lang/XComponent.hpp>
27 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <unotools/sharedunocomponent.hxx>
31 #include <tools/diagnose_ex.h>
32 #include <comphelper/property.hxx>
35 namespace dbtools
39 using ::com::sun::star::uno::Reference;
40 using ::com::sun::star::sdbc::XConnection;
41 using ::com::sun::star::sdb::XSingleSelectQueryComposer;
42 using ::com::sun::star::lang::NullPointerException;
43 using ::com::sun::star::uno::Exception;
44 using ::com::sun::star::lang::XComponent;
45 using ::com::sun::star::uno::UNO_QUERY_THROW;
46 using ::com::sun::star::sdb::XQueriesSupplier;
47 using ::com::sun::star::container::XNameAccess;
48 using ::com::sun::star::uno::UNO_QUERY;
49 using ::com::sun::star::beans::XPropertySet;
50 using ::com::sun::star::lang::XMultiServiceFactory;
51 using ::com::sun::star::sdbc::SQLException;
53 namespace CommandType = ::com::sun::star::sdb::CommandType;
56 //= StatementComposer_Data
58 struct StatementComposer_Data
60 const Reference< XConnection > xConnection;
61 Reference< XSingleSelectQueryComposer > xComposer;
62 OUString sCommand;
63 OUString sFilter;
64 OUString sOrder;
65 sal_Int32 nCommandType;
66 bool bEscapeProcessing;
67 bool bComposerDirty;
68 bool bDisposeComposer;
70 StatementComposer_Data( const Reference< XConnection >& _rxConnection )
71 :xConnection( _rxConnection )
72 ,sCommand()
73 ,sFilter()
74 ,sOrder()
75 ,nCommandType( CommandType::COMMAND )
76 ,bEscapeProcessing( true )
77 ,bComposerDirty( true )
78 ,bDisposeComposer( true )
80 if ( !_rxConnection.is() )
81 throw NullPointerException();
86 namespace
89 void lcl_resetComposer( StatementComposer_Data& _rData )
91 if ( _rData.bDisposeComposer && _rData.xComposer.is() )
93 try
95 Reference< XComponent > xComposerComponent( _rData.xComposer, UNO_QUERY_THROW );
96 xComposerComponent->dispose();
98 catch( const Exception& )
100 DBG_UNHANDLED_EXCEPTION();
103 _rData.xComposer.clear();
107 bool lcl_ensureUpToDateComposer_nothrow( StatementComposer_Data& _rData )
109 if ( !_rData.bComposerDirty )
110 return _rData.xComposer.is();
111 lcl_resetComposer( _rData );
115 OUString sStatement;
116 switch ( _rData.nCommandType )
118 case CommandType::COMMAND:
119 if ( _rData.bEscapeProcessing )
120 sStatement = _rData.sCommand;
121 // (in case of no escape processing we assume a not parseable statement)
122 break;
124 case CommandType::TABLE:
126 if ( _rData.sCommand.isEmpty() )
127 break;
129 sStatement = "SELECT * FROM ";
131 OUString sCatalog, sSchema, sTable;
132 qualifiedNameComponents( _rData.xConnection->getMetaData(), _rData.sCommand, sCatalog, sSchema, sTable, eInDataManipulation );
134 sStatement += composeTableNameForSelect( _rData.xConnection, sCatalog, sSchema, sTable );
136 break;
138 case CommandType::QUERY:
140 // ask the connection for the query
141 Reference< XQueriesSupplier > xSupplyQueries( _rData.xConnection, UNO_QUERY_THROW );
142 Reference< XNameAccess > xQueries( xSupplyQueries->getQueries(), UNO_QUERY_THROW );
144 if ( !xQueries->hasByName( _rData.sCommand ) )
145 break;
147 Reference< XPropertySet > xQuery( xQueries->getByName( _rData.sCommand ), UNO_QUERY_THROW );
149 // a native query ?
150 bool bQueryEscapeProcessing = false;
151 xQuery->getPropertyValue("EscapeProcessing") >>= bQueryEscapeProcessing;
152 if ( !bQueryEscapeProcessing )
153 break;
155 // the command used by the query
156 xQuery->getPropertyValue("Command") >>= sStatement;
157 if ( sStatement.isEmpty() )
158 break;
160 // use a composer to build a statement from the query filter/order props
161 Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
162 ::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer;
163 xComposer.set(
164 xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"),
165 UNO_QUERY_THROW
168 // the "basic" statement
169 xComposer->setElementaryQuery( sStatement );
171 // the sort order
172 const OUString sPropOrder( "Order" );
173 if ( ::comphelper::hasProperty( sPropOrder, xQuery ) )
175 OUString sOrder;
176 OSL_VERIFY( xQuery->getPropertyValue( sPropOrder ) >>= sOrder );
177 xComposer->setOrder( sOrder );
180 // the filter
181 bool bApplyFilter = true;
182 const OUString sPropApply( "ApplyFilter" );
183 if ( ::comphelper::hasProperty( sPropApply, xQuery ) )
185 OSL_VERIFY( xQuery->getPropertyValue( sPropApply ) >>= bApplyFilter );
188 if ( bApplyFilter )
190 OUString sFilter;
191 OSL_VERIFY( xQuery->getPropertyValue("Filter") >>= sFilter );
192 xComposer->setFilter( sFilter );
195 // the composed statement
196 sStatement = xComposer->getQuery();
198 break;
200 default:
201 OSL_FAIL("lcl_ensureUpToDateComposer_nothrow: no table, no query, no statement - what else ?!");
202 break;
205 if ( !sStatement.isEmpty() )
207 // create an composer
208 Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
209 Reference< XSingleSelectQueryComposer > xComposer( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"),
210 UNO_QUERY_THROW );
211 xComposer->setElementaryQuery( sStatement );
213 // append sort/filter
214 xComposer->setOrder( _rData.sOrder );
215 xComposer->setFilter( _rData.sFilter );
217 sStatement = xComposer->getQuery();
219 _rData.xComposer = xComposer;
220 _rData.bComposerDirty = false;
223 catch( const SQLException& )
225 // allowed to leave here
227 catch( const Exception& )
229 DBG_UNHANDLED_EXCEPTION();
232 return _rData.xComposer.is();
237 //= StatementComposer
240 StatementComposer::StatementComposer( const Reference< XConnection >& _rxConnection,
241 const OUString& _rCommand, const sal_Int32 _nCommandType, const bool _bEscapeProcessing )
242 :m_pData( new StatementComposer_Data( _rxConnection ) )
244 OSL_PRECOND( _rxConnection.is(), "StatementComposer::StatementComposer: illegal connection!" );
245 m_pData->sCommand = _rCommand;
246 m_pData->nCommandType = _nCommandType;
247 m_pData->bEscapeProcessing = _bEscapeProcessing;
251 StatementComposer::~StatementComposer()
253 lcl_resetComposer( *m_pData );
257 void StatementComposer::setDisposeComposer( bool _bDoDispose )
259 m_pData->bDisposeComposer = _bDoDispose;
263 void StatementComposer::setFilter( const OUString& _rFilter )
265 m_pData->sFilter = _rFilter;
266 m_pData->bComposerDirty = true;
270 void StatementComposer::setOrder( const OUString& _rOrder )
272 m_pData->sOrder = _rOrder;
273 m_pData->bComposerDirty = true;
277 Reference< XSingleSelectQueryComposer > StatementComposer::getComposer()
279 lcl_ensureUpToDateComposer_nothrow( *m_pData );
280 return m_pData->xComposer;
284 OUString StatementComposer::getQuery()
286 if ( lcl_ensureUpToDateComposer_nothrow( *m_pData ) )
288 return m_pData->xComposer->getQuery();
291 return OUString();
295 } // namespace dbtools
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */