LCOV - code coverage report
Current view: top level - connectivity/source/drivers/firebird - StatementCommonBase.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 103 158 65.2 %
Date: 2014-04-11 Functions: 17 28 60.7 %
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 "Driver.hxx"
      21             : #include "ResultSet.hxx"
      22             : #include "StatementCommonBase.hxx"
      23             : #include "Util.hxx"
      24             : 
      25             : #include <comphelper/sequence.hxx>
      26             : #include <cppuhelper/typeprovider.hxx>
      27             : #include <propertyids.hxx>
      28             : #include <TConnection.hxx>
      29             : 
      30             : using namespace ::connectivity::firebird;
      31             : 
      32             : using namespace ::com::sun::star;
      33             : using namespace ::com::sun::star::uno;
      34             : using namespace ::com::sun::star::lang;
      35             : using namespace ::com::sun::star::beans;
      36             : using namespace ::com::sun::star::sdbc;
      37             : using namespace ::com::sun::star::sdbcx;
      38             : using namespace ::com::sun::star::container;
      39             : using namespace ::com::sun::star::io;
      40             : using namespace ::com::sun::star::util;
      41             : 
      42             : using namespace ::comphelper;
      43             : using namespace ::osl;
      44             : using namespace ::rtl;
      45             : using namespace ::std;
      46             : 
      47          11 : OStatementCommonBase::OStatementCommonBase(Connection* _pConnection)
      48             :     : OStatementCommonBase_Base(m_aMutex),
      49             :       OPropertySetHelper(OStatementCommonBase_Base::rBHelper),
      50             :       m_pConnection(_pConnection),
      51             :       m_aStatementHandle( 0 ),
      52          11 :       rBHelper(OStatementCommonBase_Base::rBHelper)
      53             : {
      54          11 :     m_pConnection->acquire();
      55          11 : }
      56             : 
      57          11 : OStatementCommonBase::~OStatementCommonBase()
      58             : {
      59          11 : }
      60             : 
      61          32 : void OStatementCommonBase::disposeResultSet()
      62             : {
      63          32 :     uno::Reference< XComponent > xComp(m_xResultSet.get(), UNO_QUERY);
      64          32 :     if (xComp.is())
      65           9 :         xComp->dispose();
      66          32 :     m_xResultSet = uno::Reference< XResultSet>();
      67          32 : }
      68             : 
      69          21 : void OStatementCommonBase::freeStatementHandle()
      70             :     throw (SQLException)
      71             : {
      72          21 :     if (m_aStatementHandle)
      73             :     {
      74             :         isc_dsql_free_statement(m_statusVector,
      75             :                                 &m_aStatementHandle,
      76           9 :                                 DSQL_drop);
      77             :         evaluateStatusVector(m_statusVector,
      78             :                              "isc_dsql_free_statement",
      79           9 :                              *this);
      80             :     }
      81          21 : }
      82             : 
      83             : 
      84          35 : Any SAL_CALL OStatementCommonBase::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
      85             : {
      86          35 :     Any aRet = OStatementCommonBase_Base::queryInterface(rType);
      87          35 :     if(!aRet.hasValue())
      88           2 :         aRet = OPropertySetHelper::queryInterface(rType);
      89          35 :     return aRet;
      90             : }
      91             : 
      92           0 : Sequence< Type > SAL_CALL OStatementCommonBase::getTypes(  ) throw(RuntimeException, std::exception)
      93             : {
      94             :     ::cppu::OTypeCollection aTypes(
      95           0 :         ::cppu::UnoType< uno::Reference< XMultiPropertySet > >::get(),
      96           0 :         ::cppu::UnoType< uno::Reference< XFastPropertySet > >::get(),
      97           0 :         ::cppu::UnoType< uno::Reference< XPropertySet > >::get());
      98             : 
      99           0 :     return concatSequences(aTypes.getTypes(),OStatementCommonBase_Base::getTypes());
     100             : }
     101             : 
     102             : 
     103           0 : void SAL_CALL OStatementCommonBase::cancel(  ) throw(RuntimeException, std::exception)
     104             : {
     105           0 :     MutexGuard aGuard(m_aMutex);
     106           0 :     checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
     107             :     // cancel the current sql statement
     108           0 : }
     109             : 
     110          12 : void SAL_CALL OStatementCommonBase::close()
     111             :     throw(SQLException, RuntimeException, std::exception)
     112             : {
     113             :     SAL_INFO("connectivity.firebird", "close");
     114             : 
     115             :     {
     116          12 :         MutexGuard aGuard(m_aMutex);
     117          12 :         checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
     118          12 :         disposeResultSet();
     119          12 :         freeStatementHandle();
     120             :     }
     121             : 
     122          12 :     dispose();
     123          12 : }
     124             : 
     125           9 : void OStatementCommonBase::prepareAndDescribeStatement(const OUString& sql,
     126             :                                                       XSQLDA*& pOutSqlda,
     127             :                                                       XSQLDA* pInSqlda)
     128             :     throw (SQLException)
     129             : {
     130           9 :     MutexGuard aGuard(m_aMutex);
     131             : 
     132           9 :     freeStatementHandle();
     133             : 
     134           9 :     if (!pOutSqlda)
     135             :     {
     136           9 :         pOutSqlda = (XSQLDA*) malloc(XSQLDA_LENGTH(10));
     137           9 :         pOutSqlda->version = SQLDA_VERSION1;
     138           9 :         pOutSqlda->sqln = 10;
     139             :     }
     140             : 
     141           9 :     ISC_STATUS aErr = 0;
     142             : 
     143             :     aErr = isc_dsql_allocate_statement(m_statusVector,
     144           9 :                                        &m_pConnection->getDBHandle(),
     145          18 :                                        &m_aStatementHandle);
     146             : 
     147           9 :     if (aErr)
     148             :     {
     149           0 :         free(pOutSqlda);
     150           0 :         pOutSqlda = 0;
     151             :         evaluateStatusVector(m_statusVector,
     152             :                              "isc_dsql_allocate_statement",
     153           0 :                              *this);
     154             :     }
     155             : 
     156             :     aErr = isc_dsql_prepare(m_statusVector,
     157           9 :                             &m_pConnection->getTransaction(),
     158             :                             &m_aStatementHandle,
     159             :                             0,
     160             :                             OUStringToOString(sql, RTL_TEXTENCODING_UTF8).getStr(),
     161             :                             FIREBIRD_SQL_DIALECT,
     162          18 :                             pInSqlda);
     163             : 
     164           9 :     if (aErr)
     165             :     {
     166             :         // TODO: free statement handle?
     167           0 :         free(pOutSqlda);
     168           0 :         pOutSqlda = 0;
     169             :         evaluateStatusVector(m_statusVector,
     170             :                              "isc_dsql_prepare",
     171           0 :                              *this);
     172             :     }
     173             : 
     174             :     aErr = isc_dsql_describe(m_statusVector,
     175             :                              &m_aStatementHandle,
     176             :                              1,
     177           9 :                              pOutSqlda);
     178             : 
     179             : 
     180           9 :     if (aErr)
     181             :     {
     182             :         // TODO: free statement handle, etc.?
     183           0 :         free(pOutSqlda);
     184           0 :         pOutSqlda = 0;
     185             :         evaluateStatusVector(m_statusVector,
     186             :                              "isc_dsql_describe",
     187           0 :                              *this);
     188             :     }
     189             : 
     190             :     // Ensure we have enough space in pOutSqlda
     191           9 :     if (pOutSqlda->sqld > pOutSqlda->sqln)
     192             :     {
     193           0 :         int n = pOutSqlda->sqld;
     194           0 :         free(pOutSqlda);
     195           0 :         pOutSqlda = (XSQLDA*) malloc(XSQLDA_LENGTH(n));
     196           0 :         pOutSqlda->version = SQLDA_VERSION1;
     197             :         aErr = isc_dsql_describe(m_statusVector,
     198             :                                  &m_aStatementHandle,
     199             :                                  1,
     200           0 :                                  pOutSqlda);
     201             :     }
     202             : 
     203             :     // Process each XSQLVAR parameter structure in the output XSQLDA
     204           9 :     if (aErr)
     205             :         evaluateStatusVector(m_statusVector,
     206             :                              "isc_dsql_describe",
     207           0 :                              *this);
     208             : 
     209           9 :     mallocSQLVAR(pOutSqlda);
     210           9 : }
     211             : 
     212             : // ---- XMultipleResults - UNSUPPORTED ----------------------------------------
     213           0 : uno::Reference< XResultSet > SAL_CALL OStatementCommonBase::getResultSet() throw(SQLException, RuntimeException, std::exception)
     214             : {
     215             :     // TODO: verify we really can't support this
     216             : //     return uno::Reference< XResultSet >();
     217           0 :     MutexGuard aGuard(m_aMutex);
     218           0 :     checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
     219             : 
     220           0 :     return m_xResultSet;
     221             : }
     222             : 
     223           0 : sal_Bool SAL_CALL OStatementCommonBase::getMoreResults() throw(SQLException, RuntimeException, std::exception)
     224             : {
     225             :     // TODO: verify we really can't support this
     226           0 :     return sal_False;
     227             : //     MutexGuard aGuard( m_aMutex );
     228             : //     checkDisposed(OStatementCommonBase_Base::rBHelper.bDisposed);
     229             : }
     230             : 
     231           0 : sal_Int32 SAL_CALL OStatementCommonBase::getUpdateCount() throw(SQLException, RuntimeException, std::exception)
     232             : {
     233             :     // TODO: verify we really can't support this
     234           0 :     return 0;
     235             : }
     236             : 
     237             : 
     238             : // ---- XWarningsSupplier - UNSUPPORTED ----------------------------------------
     239           0 : Any SAL_CALL OStatementCommonBase::getWarnings() throw(SQLException, RuntimeException, std::exception)
     240             : {
     241           0 :     return Any();
     242             : }
     243             : 
     244           0 : void SAL_CALL OStatementCommonBase::clearWarnings() throw(SQLException, RuntimeException, std::exception)
     245             : {
     246           0 : }
     247             : 
     248           1 : ::cppu::IPropertyArrayHelper* OStatementCommonBase::createArrayHelper( ) const
     249             : {
     250             :     // this properties are define by the service statement
     251             :     // they must in alphabetic order
     252           1 :     Sequence< Property > aProps(10);
     253           1 :     Property* pProperties = aProps.getArray();
     254           1 :     sal_Int32 nPos = 0;
     255           1 :     DECL_PROP0(CURSORNAME,  OUString);
     256           1 :     DECL_BOOL_PROP0(ESCAPEPROCESSING);
     257           1 :     DECL_PROP0(FETCHDIRECTION,sal_Int32);
     258           1 :     DECL_PROP0(FETCHSIZE,   sal_Int32);
     259           1 :     DECL_PROP0(MAXFIELDSIZE,sal_Int32);
     260           1 :     DECL_PROP0(MAXROWS,     sal_Int32);
     261           1 :     DECL_PROP0(QUERYTIMEOUT,sal_Int32);
     262           1 :     DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32);
     263           1 :     DECL_PROP0(RESULTSETTYPE,sal_Int32);
     264           1 :     DECL_BOOL_PROP0(USEBOOKMARKS);
     265             : 
     266           1 :     return new ::cppu::OPropertyArrayHelper(aProps);
     267             : }
     268             : 
     269             : 
     270           2 : ::cppu::IPropertyArrayHelper & OStatementCommonBase::getInfoHelper()
     271             : {
     272           2 :     return *const_cast<OStatementCommonBase*>(this)->getArrayHelper();
     273             : }
     274             : 
     275           1 : sal_Bool OStatementCommonBase::convertFastPropertyValue(
     276             :                             Any & rConvertedValue,
     277             :                             Any & rOldValue,
     278             :                             sal_Int32 nHandle,
     279             :                             const Any& rValue )
     280             :     throw (IllegalArgumentException)
     281             : {
     282             :     (void) rConvertedValue;
     283             :     (void) rOldValue;
     284             :     (void) nHandle;
     285             :     (void) rValue;
     286           1 :     sal_Bool bConverted = sal_False;
     287             :     // here we have to try to convert
     288           1 :     return bConverted;
     289             : }
     290             : 
     291           0 : void OStatementCommonBase::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception, std::exception)
     292             : {
     293             :     (void) rValue;
     294             :     // set the value to what ever is necessary
     295             :     switch(nHandle)
     296             :     {
     297             :         case PROPERTY_ID_QUERYTIMEOUT:
     298             :         case PROPERTY_ID_MAXFIELDSIZE:
     299             :         case PROPERTY_ID_MAXROWS:
     300             :         case PROPERTY_ID_CURSORNAME:
     301             :         case PROPERTY_ID_RESULTSETCONCURRENCY:
     302             :         case PROPERTY_ID_RESULTSETTYPE:
     303             :         case PROPERTY_ID_FETCHDIRECTION:
     304             :         case PROPERTY_ID_FETCHSIZE:
     305             :         case PROPERTY_ID_ESCAPEPROCESSING:
     306             :         case PROPERTY_ID_USEBOOKMARKS:
     307             :         default:
     308             :             ;
     309             :     }
     310           0 : }
     311             : 
     312           0 : void OStatementCommonBase::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
     313             : {
     314             :     (void) rValue;
     315             :     switch(nHandle)
     316             :     {
     317             :         case PROPERTY_ID_QUERYTIMEOUT:
     318             :         case PROPERTY_ID_MAXFIELDSIZE:
     319             :         case PROPERTY_ID_MAXROWS:
     320             :         case PROPERTY_ID_CURSORNAME:
     321             :         case PROPERTY_ID_RESULTSETCONCURRENCY:
     322             :         case PROPERTY_ID_RESULTSETTYPE:
     323             :         case PROPERTY_ID_FETCHDIRECTION:
     324             :         case PROPERTY_ID_FETCHSIZE:
     325             :         case PROPERTY_ID_ESCAPEPROCESSING:
     326             :         case PROPERTY_ID_USEBOOKMARKS:
     327             :         default:
     328             :             ;
     329             :     }
     330           0 : }
     331             : 
     332         173 : void SAL_CALL OStatementCommonBase::acquire() throw()
     333             : {
     334         173 :     OStatementCommonBase_Base::acquire();
     335         173 : }
     336             : 
     337         173 : void SAL_CALL OStatementCommonBase::release() throw()
     338             : {
     339         173 :     OStatementCommonBase_Base::release();
     340         173 : }
     341             : 
     342           0 : uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OStatementCommonBase::getPropertySetInfo(  ) throw(RuntimeException, std::exception)
     343             : {
     344           0 :     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
     345             : }
     346             : 
     347          18 : short OStatementCommonBase::getSqlInfoItem(char aInfoItem)
     348             :     throw (SQLException)
     349             : {
     350             :     ISC_STATUS_ARRAY aStatusVector;
     351             :     ISC_STATUS aErr;
     352             : 
     353          18 :     char aInfoItems[] = {aInfoItem};
     354             :     char aResultsBuffer[8];
     355             : 
     356             :     aErr = isc_dsql_sql_info(aStatusVector,
     357             :                              &m_aStatementHandle,
     358             :                              sizeof(aInfoItems),
     359             :                              aInfoItems,
     360             :                              sizeof(aResultsBuffer),
     361          18 :                              aResultsBuffer);
     362             : 
     363          18 :     if (!aErr && aResultsBuffer[0] == aInfoItem)
     364             :     {
     365          18 :         const short aBytes = (short) isc_vax_integer(aResultsBuffer+1, 2);
     366          18 :         return (short) isc_vax_integer(aResultsBuffer+3, aBytes);
     367             :     }
     368             : 
     369             :     evaluateStatusVector(aStatusVector,
     370             :                          "isc_dsq_sql_info",
     371           0 :                          *this);
     372           0 :     return 0;
     373             : }
     374             : 
     375           9 : bool OStatementCommonBase::isDDLStatement()
     376             :     throw (SQLException)
     377             : {
     378           9 :     if (getSqlInfoItem(isc_info_sql_stmt_type) == isc_info_sql_stmt_ddl)
     379           0 :         return true;
     380             :     else
     381           9 :         return false;
     382             : }
     383             : 
     384           9 : sal_Int32 OStatementCommonBase::getStatementChangeCount()
     385             :     throw (SQLException)
     386             : {
     387           9 :     const short aStatementType = getSqlInfoItem(isc_info_sql_stmt_type);
     388             : 
     389             : 
     390             : 
     391             :     ISC_STATUS_ARRAY aStatusVector;
     392             :     ISC_STATUS aErr;
     393             : 
     394             :     // This is somewhat undocumented so I'm just guessing and hoping for the best.
     395           9 :     char aInfoItems[] = {isc_info_sql_records};
     396             :     char aResultsBuffer[1024];
     397             : 
     398             :     aErr = isc_dsql_sql_info(aStatusVector,
     399             :                              &m_aStatementHandle,
     400             :                              sizeof(aInfoItems),
     401             :                              aInfoItems,
     402             :                              sizeof(aResultsBuffer),
     403           9 :                              aResultsBuffer);
     404             : 
     405           9 :     if (aErr)
     406             :     {
     407             :         evaluateStatusVector(aStatusVector,
     408             :                              "isc_dsq_sql_info",
     409           0 :                              *this);
     410           0 :         return 0;
     411             :     }
     412             : 
     413           9 :     short aDesiredInfoType = 0;
     414           9 :     switch (aStatementType)
     415             :     {
     416             :         case isc_info_sql_stmt_select:
     417           9 :             aDesiredInfoType = isc_info_req_select_count;
     418           9 :             break;
     419             :         case isc_info_sql_stmt_insert:
     420           0 :             aDesiredInfoType = isc_info_req_insert_count;
     421           0 :             break;
     422             :         case isc_info_sql_stmt_update:
     423           0 :             aDesiredInfoType = isc_info_req_update_count;
     424           0 :             break;
     425             :         case isc_info_sql_stmt_delete:
     426           0 :             aDesiredInfoType = isc_info_req_delete_count;
     427           0 :             break;
     428             :         default:
     429           0 :             throw SQLException(); // TODO: better error message?
     430             :     }
     431             : 
     432           9 :     char* pResults = aResultsBuffer;
     433           9 :     if (((short) *pResults++) == isc_info_sql_records)
     434             :     {
     435             : //         const short aTotalLength = (short) isc_vax_integer(pResults, 2);
     436           9 :         pResults += 2;
     437             : 
     438             :         // Seems to be of form TOKEN (1 byte), LENGTH (2 bytes), DATA (LENGTH bytes)
     439          36 :         while (*pResults != isc_info_rsb_end)
     440             :         {
     441          27 :             const char aToken = *pResults;
     442          27 :             const short aLength =  (short) isc_vax_integer(pResults+1, 2);
     443             : 
     444          27 :             if (aToken == aDesiredInfoType)
     445             :             {
     446           9 :                 return sal_Int32(isc_vax_integer(pResults + 3, aLength));
     447             :             }
     448             : 
     449          18 :             pResults += (3 + aLength);
     450             :         }
     451             :     }
     452             : 
     453           0 :     return 0;
     454           6 : }
     455             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10