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

Generated by: LCOV version 1.11