LCOV - code coverage report
Current view: top level - connectivity/source/commontools - statementcomposer.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 62 103 60.2 %
Date: 2014-04-11 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <connectivity/statementcomposer.hxx>
      21             : 
      22             : #include <connectivity/dbtools.hxx>
      23             : 
      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>
      29             : 
      30             : #include <unotools/sharedunocomponent.hxx>
      31             : #include <tools/diagnose_ex.h>
      32             : #include <comphelper/property.hxx>
      33             : 
      34             : 
      35             : namespace dbtools
      36             : {
      37             : 
      38             : 
      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;
      52             : 
      53             :     namespace CommandType = ::com::sun::star::sdb::CommandType;
      54             : 
      55             : 
      56             :     //= StatementComposer_Data
      57             : 
      58          17 :     struct StatementComposer_Data
      59             :     {
      60             :         const Reference< XConnection >          xConnection;
      61             :         Reference< XSingleSelectQueryComposer > xComposer;
      62             :         OUString                         sCommand;
      63             :         OUString                         sFilter;
      64             :         OUString                         sOrder;
      65             :         sal_Int32                               nCommandType;
      66             :         sal_Bool                                bEscapeProcessing;
      67             :         bool                                    bComposerDirty;
      68             :         bool                                    bDisposeComposer;
      69             : 
      70          17 :         StatementComposer_Data( const Reference< XConnection >& _rxConnection )
      71             :             :xConnection( _rxConnection )
      72             :             ,sCommand()
      73             :             ,sFilter()
      74             :             ,sOrder()
      75             :             ,nCommandType( CommandType::COMMAND )
      76             :             ,bEscapeProcessing( sal_True )
      77             :             ,bComposerDirty( true )
      78          17 :             ,bDisposeComposer( true )
      79             :         {
      80          17 :             if ( !_rxConnection.is() )
      81           0 :                 throw NullPointerException();
      82          17 :         }
      83             :     };
      84             : 
      85             : 
      86             :     namespace
      87             :     {
      88             : 
      89          34 :         void    lcl_resetComposer( StatementComposer_Data& _rData )
      90             :         {
      91          34 :             if ( _rData.bDisposeComposer && _rData.xComposer.is() )
      92             :             {
      93             :                 try
      94             :                 {
      95           0 :                     Reference< XComponent > xComposerComponent( _rData.xComposer, UNO_QUERY_THROW );
      96           0 :                     xComposerComponent->dispose();
      97             :                 }
      98           0 :                 catch( const Exception& )
      99             :                 {
     100             :                     DBG_UNHANDLED_EXCEPTION();
     101             :                 }
     102             :             }
     103          34 :             _rData.xComposer.clear();
     104          34 :         }
     105             : 
     106             : 
     107          34 :         bool    lcl_ensureUpToDateComposer_nothrow( StatementComposer_Data& _rData )
     108             :         {
     109          34 :             if ( !_rData.bComposerDirty )
     110          17 :                 return _rData.xComposer.is();
     111          17 :             lcl_resetComposer( _rData );
     112             : 
     113             :             try
     114             :             {
     115          17 :                 OUString sStatement;
     116          17 :                 switch ( _rData.nCommandType )
     117             :                 {
     118             :                     case CommandType::COMMAND:
     119           4 :                         if ( _rData.bEscapeProcessing )
     120           4 :                             sStatement = _rData.sCommand;
     121             :                         // (in case of no escape processing  we assume a not parseable statement)
     122           4 :                         break;
     123             : 
     124             :                     case CommandType::TABLE:
     125             :                     {
     126          13 :                         if ( _rData.sCommand.isEmpty() )
     127           0 :                             break;
     128             : 
     129          13 :                         sStatement = "SELECT * FROM ";
     130             : 
     131          26 :                         OUString sCatalog, sSchema, sTable;
     132          13 :                         qualifiedNameComponents( _rData.xConnection->getMetaData(), _rData.sCommand, sCatalog, sSchema, sTable, eInDataManipulation );
     133             : 
     134          26 :                         sStatement += composeTableNameForSelect( _rData.xConnection, sCatalog, sSchema, sTable );
     135             :                     }
     136          13 :                     break;
     137             : 
     138             :                     case CommandType::QUERY:
     139             :                     {
     140             :                         // ask the connection for the query
     141           0 :                         Reference< XQueriesSupplier > xSupplyQueries( _rData.xConnection, UNO_QUERY_THROW );
     142           0 :                         Reference< XNameAccess >      xQueries( xSupplyQueries->getQueries(), UNO_QUERY_THROW );
     143             : 
     144           0 :                         if ( !xQueries->hasByName( _rData.sCommand ) )
     145           0 :                             break;
     146             : 
     147           0 :                         Reference< XPropertySet > xQuery( xQueries->getByName( _rData.sCommand ), UNO_QUERY_THROW );
     148             : 
     149             :                         //  a native query ?
     150           0 :                         sal_Bool bQueryEscapeProcessing = sal_False;
     151           0 :                         xQuery->getPropertyValue("EscapeProcessing") >>= bQueryEscapeProcessing;
     152           0 :                         if ( !bQueryEscapeProcessing )
     153           0 :                             break;
     154             : 
     155             :                         // the command used by the query
     156           0 :                         xQuery->getPropertyValue("Command") >>= sStatement;
     157           0 :                         if ( sStatement.isEmpty() )
     158           0 :                             break;
     159             : 
     160             :                         // use a composer to build a statement from the query filter/order props
     161           0 :                         Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
     162           0 :                         ::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer;
     163             :                         xComposer.set(
     164           0 :                             xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"),
     165             :                             UNO_QUERY_THROW
     166           0 :                         );
     167             : 
     168             :                         // the "basic" statement
     169           0 :                         xComposer->setElementaryQuery( sStatement );
     170             : 
     171             :                         // the sort order
     172           0 :                         const OUString sPropOrder( "Order" );
     173           0 :                         if ( ::comphelper::hasProperty( sPropOrder, xQuery ) )
     174             :                         {
     175           0 :                             OUString sOrder;
     176           0 :                             OSL_VERIFY( xQuery->getPropertyValue( sPropOrder ) >>= sOrder );
     177           0 :                             xComposer->setOrder( sOrder );
     178             :                         }
     179             : 
     180             :                         // the filter
     181           0 :                         sal_Bool bApplyFilter = sal_True;
     182           0 :                         const OUString sPropApply( "ApplyFilter" );
     183           0 :                         if ( ::comphelper::hasProperty( sPropApply, xQuery ) )
     184             :                         {
     185           0 :                             OSL_VERIFY( xQuery->getPropertyValue( sPropApply ) >>= bApplyFilter );
     186             :                         }
     187             : 
     188           0 :                         if ( bApplyFilter )
     189             :                         {
     190           0 :                             OUString sFilter;
     191           0 :                             OSL_VERIFY( xQuery->getPropertyValue("Filter") >>= sFilter );
     192           0 :                             xComposer->setFilter( sFilter );
     193             :                         }
     194             : 
     195             :                         // the composed statement
     196           0 :                         sStatement = xComposer->getQuery();
     197             :                     }
     198           0 :                     break;
     199             : 
     200             :                     default:
     201             :                         OSL_FAIL("lcl_ensureUpToDateComposer_nothrow: no table, no query, no statement - what else ?!");
     202           0 :                         break;
     203             :                 }
     204             : 
     205          17 :                 if ( !sStatement.isEmpty() )
     206             :                 {
     207             :                     // create an composer
     208          17 :                     Reference< XMultiServiceFactory > xFactory( _rData.xConnection, UNO_QUERY_THROW );
     209          17 :                     Reference< XSingleSelectQueryComposer > xComposer( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"),
     210          34 :                         UNO_QUERY_THROW );
     211          17 :                     xComposer->setElementaryQuery( sStatement );
     212             : 
     213             :                     // append sort/filter
     214          17 :                     xComposer->setOrder( _rData.sOrder );
     215          17 :                     xComposer->setFilter( _rData.sFilter );
     216             : 
     217          17 :                     sStatement = xComposer->getQuery();
     218             : 
     219          17 :                     _rData.xComposer = xComposer;
     220          34 :                     _rData.bComposerDirty = false;
     221          17 :                 }
     222             :             }
     223           0 :             catch( const SQLException& )
     224             :             {
     225             :                 // allowed to leave here
     226             :             }
     227           0 :             catch( const Exception& )
     228             :             {
     229             :                 DBG_UNHANDLED_EXCEPTION();
     230             :             }
     231             : 
     232          17 :             return _rData.xComposer.is();
     233             :         }
     234             :     }
     235             : 
     236             : 
     237             :     //= StatementComposer
     238             : 
     239             : 
     240          17 :     StatementComposer::StatementComposer( const Reference< XConnection >& _rxConnection,
     241             :         const OUString&  _rCommand, const sal_Int32 _nCommandType, const bool _bEscapeProcessing )
     242          17 :         :m_pData( new StatementComposer_Data( _rxConnection ) )
     243             :     {
     244             :         OSL_PRECOND( _rxConnection.is(), "StatementComposer::StatementComposer: illegal connection!" );
     245          17 :         m_pData->sCommand = _rCommand;
     246          17 :         m_pData->nCommandType = _nCommandType;
     247          17 :         m_pData->bEscapeProcessing = _bEscapeProcessing;
     248          17 :     }
     249             : 
     250             : 
     251          34 :     StatementComposer::~StatementComposer()
     252             :     {
     253          17 :         lcl_resetComposer( *m_pData );
     254          17 :     }
     255             : 
     256             : 
     257          17 :     void StatementComposer::setDisposeComposer( bool _bDoDispose )
     258             :     {
     259          17 :         m_pData->bDisposeComposer = _bDoDispose;
     260          17 :     }
     261             : 
     262             : 
     263          11 :     void StatementComposer::setFilter( const OUString& _rFilter )
     264             :     {
     265          11 :         m_pData->sFilter = _rFilter;
     266          11 :         m_pData->bComposerDirty = true;
     267          11 :     }
     268             : 
     269             : 
     270          17 :     void StatementComposer::setOrder( const OUString& _rOrder )
     271             :     {
     272          17 :         m_pData->sOrder = _rOrder;
     273          17 :         m_pData->bComposerDirty = true;
     274          17 :     }
     275             : 
     276             : 
     277          17 :     Reference< XSingleSelectQueryComposer > StatementComposer::getComposer()
     278             :     {
     279          17 :         lcl_ensureUpToDateComposer_nothrow( *m_pData );
     280          17 :         return m_pData->xComposer;
     281             :     }
     282             : 
     283             : 
     284          17 :     OUString StatementComposer::getQuery()
     285             :     {
     286          17 :         if ( lcl_ensureUpToDateComposer_nothrow( *m_pData ) )
     287             :         {
     288          17 :             return m_pData->xComposer->getQuery();
     289             :         }
     290             : 
     291           0 :         return OUString();
     292             :     }
     293             : 
     294             : 
     295             : } // namespace dbtools
     296             : 
     297             : 
     298             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10