LCOV - code coverage report
Current view: top level - connectivity/source/commontools - dbexception.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 30 215 14.0 %
Date: 2014-04-11 Functions: 7 35 20.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/dbexception.hxx>
      21             : #include <comphelper/types.hxx>
      22             : #include <cppuhelper/exc_hlp.hxx>
      23             : #include <osl/diagnose.h>
      24             : #include <com/sun/star/sdb/SQLContext.hpp>
      25             : #include <com/sun/star/sdbc/SQLWarning.hpp>
      26             : #include <com/sun/star/sdb/SQLErrorEvent.hpp>
      27             : #include "TConnection.hxx"
      28             : #include "resource/common_res.hrc"
      29             : #include "resource/sharedresources.hxx"
      30             : 
      31             : 
      32             : namespace dbtools
      33             : {
      34             : 
      35             : 
      36             :     using namespace ::com::sun::star::uno;
      37             :     using namespace ::com::sun::star::sdb;
      38             :     using namespace ::com::sun::star::sdbc;
      39             :     using namespace ::comphelper;
      40             :     using namespace ::connectivity;
      41             : 
      42             : 
      43             : //= SQLExceptionInfo - encapsulating the type info of an SQLException-derived class
      44             : 
      45             : 
      46           5 : SQLExceptionInfo::SQLExceptionInfo()
      47           5 :     :m_eType(UNDEFINED)
      48             : {
      49           5 : }
      50             : 
      51             : 
      52           0 : SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLException& _rError)
      53             : {
      54           0 :     m_aContent <<= _rError;
      55           0 :     implDetermineType();
      56           0 : }
      57             : 
      58             : 
      59           0 : SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLWarning& _rError)
      60             : {
      61           0 :     m_aContent <<= _rError;
      62           0 :     implDetermineType();
      63           0 : }
      64             : 
      65             : 
      66           0 : SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdb::SQLContext& _rError)
      67             : {
      68           0 :     m_aContent <<= _rError;
      69           0 :     implDetermineType();
      70           0 : }
      71             : 
      72             : 
      73           0 : SQLExceptionInfo::SQLExceptionInfo( const OUString& _rSimpleErrorMessage )
      74             : {
      75           0 :     SQLException aError;
      76           0 :     aError.Message = _rSimpleErrorMessage;
      77           0 :     m_aContent <<= aError;
      78           0 :     implDetermineType();
      79           0 : }
      80             : 
      81             : 
      82           0 : SQLExceptionInfo::SQLExceptionInfo(const SQLExceptionInfo& _rCopySource)
      83             :     :m_aContent(_rCopySource.m_aContent)
      84           0 :     ,m_eType(_rCopySource.m_eType)
      85             : {
      86           0 : }
      87             : 
      88             : 
      89           0 : const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLException& _rError)
      90             : {
      91           0 :     m_aContent <<= _rError;
      92           0 :     implDetermineType();
      93           0 :     return *this;
      94             : }
      95             : 
      96             : 
      97           0 : const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLWarning& _rError)
      98             : {
      99           0 :     m_aContent <<= _rError;
     100           0 :     implDetermineType();
     101           0 :     return *this;
     102             : }
     103             : 
     104             : 
     105           0 : const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLContext& _rError)
     106             : {
     107           0 :     m_aContent <<= _rError;
     108           0 :     implDetermineType();
     109           0 :     return *this;
     110             : }
     111             : 
     112             : 
     113           0 : const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLErrorEvent& _rErrorEvent)
     114             : {
     115           0 :     m_aContent = _rErrorEvent.Reason;
     116           0 :     implDetermineType();
     117           0 :     return *this;
     118             : }
     119             : 
     120             : 
     121           0 : const SQLExceptionInfo& SQLExceptionInfo::operator=(const ::com::sun::star::uno::Any& _rCaughtSQLException)
     122             : {
     123           0 :     m_aContent = _rCaughtSQLException;
     124           0 :     implDetermineType();
     125           0 :     return *this;
     126             : }
     127             : 
     128             : 
     129           3 : SQLExceptionInfo::SQLExceptionInfo(const staruno::Any& _rError)
     130             : {
     131           3 :     const staruno::Type& aSQLExceptionType = ::getCppuType(static_cast< ::com::sun::star::sdbc::SQLException*>(0));
     132           3 :     sal_Bool bValid = isAssignableFrom(aSQLExceptionType, _rError.getValueType());
     133           3 :     if (bValid)
     134           0 :         m_aContent = _rError;
     135             :     // no assertion here : if used with the NextException member of an SQLException bValid==sal_False is allowed.
     136             : 
     137           3 :     implDetermineType();
     138           3 : }
     139             : 
     140             : 
     141           3 : void SQLExceptionInfo::implDetermineType()
     142             : {
     143           3 :     const Type& aSQLExceptionType = ::getCppuType( static_cast< SQLException* >( 0 ) );
     144           3 :     const Type& aSQLWarningType = ::getCppuType( static_cast< SQLWarning* >( 0 ) );
     145           3 :     const Type& aSQLContextType  = ::getCppuType( static_cast< SQLContext* >( 0 ) );
     146             : 
     147           3 :     if ( isAssignableFrom( aSQLContextType, m_aContent.getValueType() ) )
     148           0 :         m_eType = SQL_CONTEXT;
     149           3 :     else if ( isAssignableFrom( aSQLWarningType, m_aContent.getValueType() ) )
     150           0 :         m_eType = SQL_WARNING;
     151           3 :     else if ( isAssignableFrom( aSQLExceptionType, m_aContent.getValueType() ) )
     152           0 :         m_eType = SQL_EXCEPTION;
     153             :     else
     154             :     {
     155           3 :         m_eType = UNDEFINED;
     156           3 :         m_aContent.clear();
     157             :     }
     158           3 : }
     159             : 
     160             : 
     161           0 : bool SQLExceptionInfo::isKindOf(TYPE _eType) const
     162             : {
     163           0 :     switch (_eType)
     164             :     {
     165             :         case SQL_CONTEXT:
     166           0 :             return (m_eType == SQL_CONTEXT);
     167             :         case SQL_WARNING:
     168           0 :             return (m_eType == SQL_CONTEXT) || (m_eType == SQL_WARNING);
     169             :         case SQL_EXCEPTION:
     170           0 :             return (m_eType == SQL_CONTEXT) || (m_eType == SQL_WARNING) || (m_eType == SQL_EXCEPTION);
     171             :         case UNDEFINED:
     172           0 :             return (m_eType == UNDEFINED);
     173             :     }
     174           0 :     return false;
     175             : }
     176             : 
     177             : 
     178           0 : SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLException*() const
     179             : {
     180             :     OSL_ENSURE(isKindOf(SQL_EXCEPTION), "SQLExceptionInfo::operator SQLException* : invalid call !");
     181           0 :     return reinterpret_cast<const ::com::sun::star::sdbc::SQLException*>(m_aContent.getValue());
     182             : }
     183             : 
     184             : 
     185           0 : SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLWarning*() const
     186             : {
     187             :     OSL_ENSURE(isKindOf(SQL_WARNING), "SQLExceptionInfo::operator SQLException* : invalid call !");
     188           0 :     return reinterpret_cast<const ::com::sun::star::sdbc::SQLWarning*>(m_aContent.getValue());
     189             : }
     190             : 
     191             : 
     192           0 : SQLExceptionInfo::operator const ::com::sun::star::sdb::SQLContext*() const
     193             : {
     194             :     OSL_ENSURE(isKindOf(SQL_CONTEXT), "SQLExceptionInfo::operator SQLException* : invalid call !");
     195           0 :     return reinterpret_cast<const ::com::sun::star::sdb::SQLContext*>(m_aContent.getValue());
     196             : }
     197             : 
     198             : 
     199           0 : void SQLExceptionInfo::prepend( const OUString& _rErrorMessage, const OUString& _rSQLState, const sal_Int32 _nErrorCode )
     200             : {
     201           0 :     SQLException aException;
     202           0 :     aException.Message = _rErrorMessage;
     203           0 :     aException.ErrorCode = _nErrorCode;
     204           0 :     aException.SQLState = !_rSQLState.isEmpty() ? _rSQLState : "S1000";
     205           0 :     aException.NextException = m_aContent;
     206           0 :     m_aContent <<= aException;
     207             : 
     208           0 :     m_eType = SQL_EXCEPTION;
     209           0 : }
     210             : 
     211             : 
     212           0 : void SQLExceptionInfo::append( TYPE _eType, const OUString& _rErrorMessage, const OUString& _rSQLState, const sal_Int32 _nErrorCode )
     213             : {
     214             :     // create the to-be-appended exception
     215           0 :     Any aAppend;
     216           0 :     switch ( _eType )
     217             :     {
     218           0 :     case SQL_EXCEPTION: aAppend <<= SQLException(); break;
     219           0 :     case SQL_WARNING:   aAppend <<= SQLWarning();   break;
     220           0 :     case SQL_CONTEXT:   aAppend <<= SQLContext();   break;
     221             :     default:
     222             :         OSL_FAIL( "SQLExceptionInfo::append: invalid exception type: this will crash!" );
     223           0 :         break;
     224             :     }
     225             : 
     226           0 :     SQLException* pAppendException( static_cast< SQLException* >( const_cast< void* >( aAppend.getValue() ) ) );
     227           0 :     pAppendException->Message = _rErrorMessage;
     228           0 :     pAppendException->SQLState = _rSQLState;
     229           0 :     pAppendException->ErrorCode = _nErrorCode;
     230             : 
     231             :     // find the end of the current chain
     232           0 :     Any* pChainIterator = &m_aContent;
     233           0 :     SQLException* pLastException = NULL;
     234           0 :     const Type& aSQLExceptionType( ::getCppuType< SQLException >() );
     235           0 :     while ( pChainIterator )
     236             :     {
     237           0 :         if ( !pChainIterator->hasValue() )
     238           0 :             break;
     239             : 
     240           0 :         if ( !isAssignableFrom( aSQLExceptionType, pChainIterator->getValueType() ) )
     241           0 :             break;
     242             : 
     243           0 :         pLastException = static_cast< SQLException* >( const_cast< void* >( pChainIterator->getValue() ) );
     244           0 :         pChainIterator = &pLastException->NextException;
     245             :     }
     246             : 
     247             :     // append
     248           0 :     if ( pLastException )
     249           0 :         pLastException->NextException = aAppend;
     250             :     else
     251             :     {
     252           0 :         m_aContent = aAppend;
     253           0 :         m_eType = _eType;
     254           0 :     }
     255           0 : }
     256             : 
     257             : 
     258           0 : void SQLExceptionInfo::doThrow()
     259             : {
     260           0 :     if ( m_aContent.getValueTypeClass() == TypeClass_EXCEPTION )
     261           0 :         ::cppu::throwException( m_aContent );
     262           0 :     throw RuntimeException();
     263             : }
     264             : 
     265             : 
     266             : //= SQLExceptionIteratorHelper
     267             : 
     268             : 
     269             : 
     270           0 : SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const SQLExceptionInfo& _rChainStart )
     271             :     :m_pCurrent( NULL )
     272           0 :     ,m_eCurrentType( SQLExceptionInfo::UNDEFINED )
     273             : {
     274           0 :     if ( _rChainStart.isValid() )
     275             :     {
     276           0 :         m_pCurrent = (const SQLException*)_rChainStart;
     277           0 :         m_eCurrentType = _rChainStart.getType();
     278             :     }
     279           0 : }
     280             : 
     281             : 
     282           0 : SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const ::com::sun::star::sdbc::SQLException& _rChainStart )
     283             :     :m_pCurrent( &_rChainStart )
     284           0 :     ,m_eCurrentType( SQLExceptionInfo::SQL_EXCEPTION )
     285             : {
     286           0 : }
     287             : 
     288             : 
     289           0 : void SQLExceptionIteratorHelper::current( SQLExceptionInfo& _out_rInfo ) const
     290             : {
     291           0 :     switch ( m_eCurrentType )
     292             :     {
     293             :     case SQLExceptionInfo::SQL_EXCEPTION:
     294           0 :         _out_rInfo = *m_pCurrent;
     295           0 :         break;
     296             : 
     297             :     case SQLExceptionInfo::SQL_WARNING:
     298           0 :         _out_rInfo = *static_cast< const SQLWarning* >( m_pCurrent );
     299           0 :         break;
     300             : 
     301             :     case SQLExceptionInfo::SQL_CONTEXT:
     302           0 :         _out_rInfo = *static_cast< const SQLContext* >( m_pCurrent );
     303           0 :         break;
     304             : 
     305             :     default:
     306           0 :         _out_rInfo = Any();
     307           0 :         break;
     308             :     }
     309           0 : }
     310             : 
     311             : 
     312           0 : const ::com::sun::star::sdbc::SQLException* SQLExceptionIteratorHelper::next()
     313             : {
     314             :     OSL_ENSURE( hasMoreElements(), "SQLExceptionIteratorHelper::next : invalid call (please use hasMoreElements)!" );
     315             : 
     316           0 :     const ::com::sun::star::sdbc::SQLException* pReturn = current();
     317           0 :     if ( !m_pCurrent )
     318           0 :         return pReturn;
     319             : 
     320             :     // check for the next element within the chain
     321           0 :     const Type aTypeException( ::cppu::UnoType< SQLException >::get() );
     322             : 
     323           0 :     Type aNextElementType = m_pCurrent->NextException.getValueType();
     324           0 :     if ( !isAssignableFrom( aTypeException, aNextElementType ) )
     325             :     {
     326             :         // no SQLException at all in the next chain element
     327           0 :         m_pCurrent = NULL;
     328           0 :         m_eCurrentType = SQLExceptionInfo::UNDEFINED;
     329           0 :         return pReturn;
     330             :     }
     331             : 
     332           0 :     m_pCurrent = static_cast< const SQLException* >( m_pCurrent->NextException.getValue() );
     333             : 
     334             :     // no finally determine the proper type of the exception
     335           0 :     const Type aTypeContext( ::cppu::UnoType< SQLContext >::get() );
     336           0 :     if ( isAssignableFrom( aTypeContext, aNextElementType ) )
     337             :     {
     338           0 :         m_eCurrentType = SQLExceptionInfo::SQL_CONTEXT;
     339           0 :         return pReturn;
     340             :     }
     341             : 
     342           0 :     const Type aTypeWarning( ::cppu::UnoType< SQLWarning >::get() );
     343           0 :     if ( isAssignableFrom( aTypeWarning, aNextElementType ) )
     344             :     {
     345           0 :         m_eCurrentType = SQLExceptionInfo::SQL_WARNING;
     346           0 :         return pReturn;
     347             :     }
     348             : 
     349             :     // a simple SQLException
     350           0 :     m_eCurrentType = SQLExceptionInfo::SQL_EXCEPTION;
     351           0 :     return pReturn;
     352             : }
     353             : 
     354             : 
     355           0 : void SQLExceptionIteratorHelper::next( SQLExceptionInfo& _out_rInfo )
     356             : {
     357           0 :     current( _out_rInfo );
     358           0 :     next();
     359           0 : }
     360             : 
     361             : 
     362           1 : void throwFunctionSequenceException(const Reference< XInterface >& _Context, const Any& _Next)  throw ( ::com::sun::star::sdbc::SQLException )
     363             : {
     364           1 :     ::connectivity::SharedResources aResources;
     365             :     throw SQLException(
     366             :         aResources.getResourceString(STR_ERRORMSG_SEQUENCE),
     367             :         _Context,
     368             :         getStandardSQLState( SQL_FUNCTION_SEQUENCE_ERROR ),
     369             :         0,
     370             :         _Next
     371           1 :     );
     372             : }
     373             : 
     374           0 : void throwInvalidIndexException(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _Context,
     375             :         const ::com::sun::star::uno::Any& _Next)  throw ( ::com::sun::star::sdbc::SQLException )
     376             : {
     377           0 :     ::connectivity::SharedResources aResources;
     378             :     throw SQLException(
     379             :         aResources.getResourceString(STR_INVALID_INDEX),
     380             :         _Context,
     381             :         getStandardSQLState( SQL_INVALID_DESCRIPTOR_INDEX ),
     382             :         0,
     383             :         _Next
     384           0 :     );
     385             : }
     386             : 
     387           0 : void throwFunctionNotSupportedException( const OUString& _rFunctionName, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContext,
     388             :         const ::com::sun::star::uno::Any& _rNextException ) throw ( ::com::sun::star::sdbc::SQLException )
     389             : {
     390           0 :     ::connectivity::SharedResources aResources;
     391             :     const OUString sError( aResources.getResourceStringWithSubstitution(
     392             :             STR_UNSUPPORTED_FUNCTION,
     393             :             "$functionname$", _rFunctionName
     394           0 :          ) );
     395             :     throw SQLException(
     396             :         sError,
     397             :         _rxContext,
     398             :         getStandardSQLState( SQL_FUNCTION_NOT_SUPPORTED ),
     399             :         0,
     400             :         _rNextException
     401           0 :     );
     402             : }
     403             : 
     404          33 : void throwGenericSQLException(const OUString& _rMsg, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxSource)
     405             :     throw (::com::sun::star::sdbc::SQLException)
     406             : {
     407          66 :     throwGenericSQLException(_rMsg, _rxSource, Any());
     408           0 : }
     409             : 
     410             : 
     411          33 : void throwGenericSQLException(const OUString& _rMsg, const Reference< XInterface >& _rxSource, const Any& _rNextException)
     412             :     throw (SQLException)
     413             : {
     414          33 :     throw SQLException( _rMsg, _rxSource, getStandardSQLState( SQL_GENERAL_ERROR ), 0, _rNextException);
     415             : }
     416             : 
     417             : 
     418           0 : void throwFeatureNotImplementedException( const OUString& _rFeatureName, const Reference< XInterface >& _rxContext, const Any* _pNextException )
     419             :     throw (SQLException)
     420             : {
     421           0 :     ::connectivity::SharedResources aResources;
     422             :     const OUString sError( aResources.getResourceStringWithSubstitution(
     423             :             STR_UNSUPPORTED_FEATURE,
     424             :             "$featurename$", _rFeatureName
     425           0 :          ) );
     426             : 
     427             :     throw SQLException(
     428             :         sError,
     429             :         _rxContext,
     430             :         getStandardSQLState( SQL_FEATURE_NOT_IMPLEMENTED ),
     431             :         0,
     432             :         _pNextException ? *_pNextException : Any()
     433           0 :     );
     434             : }
     435             : 
     436           0 : void throwInvalidColumnException( const OUString& _rColumnName, const Reference< XInterface >& _rxContext)
     437             :     throw (SQLException)
     438             : {
     439           0 :     ::connectivity::SharedResources aResources;
     440             :     OUString sErrorMessage( aResources.getResourceStringWithSubstitution(
     441             :                                 STR_INVALID_COLUMNNAME,
     442           0 :                                 "$columnname$",_rColumnName) );
     443           0 :     throwSQLException( sErrorMessage, SQL_COLUMN_NOT_FOUND, _rxContext );
     444           0 : }
     445             : 
     446           0 : void throwSQLException( const OUString& _rMessage, const OUString& _rSQLState,
     447             :         const Reference< XInterface >& _rxContext, const sal_Int32 _nErrorCode, const Any* _pNextException ) throw (SQLException)
     448             : {
     449             :     throw SQLException(
     450             :         _rMessage,
     451             :         _rxContext,
     452             :         _rSQLState,
     453             :         _nErrorCode,
     454             :         _pNextException ? *_pNextException : Any()
     455           0 :     );
     456             : }
     457             : 
     458             : 
     459           0 : void throwSQLException( const OUString& _rMessage, StandardSQLState _eSQLState,
     460             :         const Reference< XInterface >& _rxContext, const sal_Int32 _nErrorCode,
     461             :         const Any* _pNextException ) throw (SQLException)
     462             : {
     463           0 :     throwSQLException( _rMessage, getStandardSQLState( _eSQLState ), _rxContext, _nErrorCode, _pNextException );
     464           0 : }
     465             : 
     466             : 
     467          79 : OUString getStandardSQLState( StandardSQLState _eState )
     468             : {
     469          79 :     switch ( _eState )
     470             :     {
     471           0 :     case SQL_WRONG_PARAMETER_NUMBER:    return OUString("07001");
     472           0 :     case SQL_INVALID_DESCRIPTOR_INDEX:  return OUString("07009");
     473           0 :     case SQL_UNABLE_TO_CONNECT:         return OUString("08001");
     474           0 :     case SQL_NUMERIC_OUT_OF_RANGE:      return OUString("22003");
     475           0 :     case SQL_INVALID_DATE_TIME:         return OUString("22007");
     476           0 :     case SQL_INVALID_CURSOR_STATE:      return OUString("24000");
     477           0 :     case SQL_TABLE_OR_VIEW_EXISTS:      return OUString("42S01");
     478           0 :     case SQL_TABLE_OR_VIEW_NOT_FOUND:   return OUString("42S02");
     479           0 :     case SQL_INDEX_ESISTS:              return OUString("42S11");
     480           0 :     case SQL_INDEX_NOT_FOUND:           return OUString("42S12");
     481           0 :     case SQL_COLUMN_EXISTS:             return OUString("42S21");
     482           0 :     case SQL_COLUMN_NOT_FOUND:          return OUString("42S22");
     483          78 :     case SQL_GENERAL_ERROR:             return OUString("HY000");
     484           0 :     case SQL_INVALID_SQL_DATA_TYPE:     return OUString("HY004");
     485           0 :     case SQL_OPERATION_CANCELED:        return OUString("HY008");
     486           1 :     case SQL_FUNCTION_SEQUENCE_ERROR:   return OUString("HY010");
     487           0 :     case SQL_INVALID_CURSOR_POSITION:   return OUString("HY109");
     488           0 :     case SQL_INVALID_BOOKMARK_VALUE:    return OUString("HY111");
     489           0 :     case SQL_FEATURE_NOT_IMPLEMENTED:   return OUString("HYC00");
     490           0 :     case SQL_FUNCTION_NOT_SUPPORTED:    return OUString("IM001");
     491           0 :     case SQL_CONNECTION_DOES_NOT_EXIST: return OUString("08003");
     492           0 :     default:                            return OUString("HY001"); // General Error
     493             :     }
     494             : }
     495             : 
     496             : 
     497             : 
     498             : }   // namespace dbtools
     499             : 
     500             : 
     501             : 
     502             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10