1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/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"
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
;
42 SQLExceptionInfo::SQLExceptionInfo()
48 SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLException
& _rError
)
50 m_aContent
<<= _rError
;
55 SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdbc::SQLWarning
& _rError
)
57 m_aContent
<<= _rError
;
62 SQLExceptionInfo::SQLExceptionInfo(const ::com::sun::star::sdb::SQLContext
& _rError
)
64 m_aContent
<<= _rError
;
69 SQLExceptionInfo::SQLExceptionInfo( const OUString
& _rSimpleErrorMessage
)
72 aError
.Message
= _rSimpleErrorMessage
;
73 m_aContent
<<= aError
;
78 SQLExceptionInfo::SQLExceptionInfo(const SQLExceptionInfo
& _rCopySource
)
79 :m_aContent(_rCopySource
.m_aContent
)
80 ,m_eType(_rCopySource
.m_eType
)
85 const SQLExceptionInfo
& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLException
& _rError
)
87 m_aContent
<<= _rError
;
93 const SQLExceptionInfo
& SQLExceptionInfo::operator=(const ::com::sun::star::sdbc::SQLWarning
& _rError
)
95 m_aContent
<<= _rError
;
101 const SQLExceptionInfo
& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLContext
& _rError
)
103 m_aContent
<<= _rError
;
109 const SQLExceptionInfo
& SQLExceptionInfo::operator=(const ::com::sun::star::sdb::SQLErrorEvent
& _rErrorEvent
)
111 m_aContent
= _rErrorEvent
.Reason
;
117 const SQLExceptionInfo
& SQLExceptionInfo::operator=(const ::com::sun::star::uno::Any
& _rCaughtSQLException
)
119 m_aContent
= _rCaughtSQLException
;
125 SQLExceptionInfo::SQLExceptionInfo(const css::uno::Any
& _rError
)
127 const css::uno::Type
& aSQLExceptionType
= cppu::UnoType
<com::sun::star::sdbc::SQLException
>::get();
128 bool bValid
= isAssignableFrom(aSQLExceptionType
, _rError
.getValueType());
130 m_aContent
= _rError
;
131 // no assertion here : if used with the NextException member of an SQLException bValid==sal_False is allowed.
137 void SQLExceptionInfo::implDetermineType()
139 const Type
& aSQLExceptionType
= ::cppu::UnoType
<SQLException
>::get();
140 const Type
& aSQLWarningType
= ::cppu::UnoType
<SQLWarning
>::get();
141 const Type
& aSQLContextType
= ::cppu::UnoType
<SQLContext
>::get();
143 if ( isAssignableFrom( aSQLContextType
, m_aContent
.getValueType() ) )
144 m_eType
= SQL_CONTEXT
;
145 else if ( isAssignableFrom( aSQLWarningType
, m_aContent
.getValueType() ) )
146 m_eType
= SQL_WARNING
;
147 else if ( isAssignableFrom( aSQLExceptionType
, m_aContent
.getValueType() ) )
148 m_eType
= SQL_EXCEPTION
;
157 bool SQLExceptionInfo::isKindOf(TYPE _eType
) const
162 return (m_eType
== SQL_CONTEXT
);
164 return (m_eType
== SQL_CONTEXT
) || (m_eType
== SQL_WARNING
);
166 return (m_eType
== SQL_CONTEXT
) || (m_eType
== SQL_WARNING
) || (m_eType
== SQL_EXCEPTION
);
168 return (m_eType
== UNDEFINED
);
174 SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLException
*() const
176 OSL_ENSURE(isKindOf(SQL_EXCEPTION
), "SQLExceptionInfo::operator SQLException* : invalid call !");
177 return static_cast<const ::com::sun::star::sdbc::SQLException
*>(m_aContent
.getValue());
181 SQLExceptionInfo::operator const ::com::sun::star::sdbc::SQLWarning
*() const
183 OSL_ENSURE(isKindOf(SQL_WARNING
), "SQLExceptionInfo::operator SQLException* : invalid call !");
184 return static_cast<const ::com::sun::star::sdbc::SQLWarning
*>(m_aContent
.getValue());
188 SQLExceptionInfo::operator const ::com::sun::star::sdb::SQLContext
*() const
190 OSL_ENSURE(isKindOf(SQL_CONTEXT
), "SQLExceptionInfo::operator SQLException* : invalid call !");
191 return static_cast<const ::com::sun::star::sdb::SQLContext
*>(m_aContent
.getValue());
195 void SQLExceptionInfo::prepend( const OUString
& _rErrorMessage
, const OUString
& _rSQLState
, const sal_Int32 _nErrorCode
)
197 SQLException aException
;
198 aException
.Message
= _rErrorMessage
;
199 aException
.ErrorCode
= _nErrorCode
;
200 aException
.SQLState
= !_rSQLState
.isEmpty() ? _rSQLState
: "S1000";
201 aException
.NextException
= m_aContent
;
202 m_aContent
<<= aException
;
204 m_eType
= SQL_EXCEPTION
;
208 void SQLExceptionInfo::append( TYPE _eType
, const OUString
& _rErrorMessage
, const OUString
& _rSQLState
, const sal_Int32 _nErrorCode
)
210 // create the to-be-appended exception
214 case SQL_EXCEPTION
: aAppend
<<= SQLException(); break;
215 case SQL_WARNING
: aAppend
<<= SQLWarning(); break;
216 case SQL_CONTEXT
: aAppend
<<= SQLContext(); break;
218 OSL_FAIL( "SQLExceptionInfo::append: invalid exception type: this will crash!" );
222 SQLException
* pAppendException( static_cast< SQLException
* >( const_cast< void* >( aAppend
.getValue() ) ) );
223 pAppendException
->Message
= _rErrorMessage
;
224 pAppendException
->SQLState
= _rSQLState
;
225 pAppendException
->ErrorCode
= _nErrorCode
;
227 // find the end of the current chain
228 Any
* pChainIterator
= &m_aContent
;
229 SQLException
* pLastException
= NULL
;
230 const Type
& aSQLExceptionType( cppu::UnoType
<SQLException
>::get() );
231 while ( pChainIterator
)
233 if ( !pChainIterator
->hasValue() )
236 if ( !isAssignableFrom( aSQLExceptionType
, pChainIterator
->getValueType() ) )
239 pLastException
= static_cast< SQLException
* >( const_cast< void* >( pChainIterator
->getValue() ) );
240 pChainIterator
= &pLastException
->NextException
;
244 if ( pLastException
)
245 pLastException
->NextException
= aAppend
;
248 m_aContent
= aAppend
;
254 void SQLExceptionInfo::doThrow()
256 if ( m_aContent
.getValueTypeClass() == TypeClass_EXCEPTION
)
257 ::cppu::throwException( m_aContent
);
258 throw RuntimeException();
261 SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const SQLExceptionInfo
& _rChainStart
)
263 ,m_eCurrentType( SQLExceptionInfo::UNDEFINED
)
265 if ( _rChainStart
.isValid() )
267 m_pCurrent
= (const SQLException
*)_rChainStart
;
268 m_eCurrentType
= _rChainStart
.getType();
273 SQLExceptionIteratorHelper::SQLExceptionIteratorHelper( const ::com::sun::star::sdbc::SQLException
& _rChainStart
)
274 :m_pCurrent( &_rChainStart
)
275 ,m_eCurrentType( SQLExceptionInfo::SQL_EXCEPTION
)
280 void SQLExceptionIteratorHelper::current( SQLExceptionInfo
& _out_rInfo
) const
282 switch ( m_eCurrentType
)
284 case SQLExceptionInfo::SQL_EXCEPTION
:
285 _out_rInfo
= *m_pCurrent
;
288 case SQLExceptionInfo::SQL_WARNING
:
289 _out_rInfo
= *static_cast< const SQLWarning
* >( m_pCurrent
);
292 case SQLExceptionInfo::SQL_CONTEXT
:
293 _out_rInfo
= *static_cast< const SQLContext
* >( m_pCurrent
);
303 const ::com::sun::star::sdbc::SQLException
* SQLExceptionIteratorHelper::next()
305 OSL_ENSURE( hasMoreElements(), "SQLExceptionIteratorHelper::next : invalid call (please use hasMoreElements)!" );
307 const ::com::sun::star::sdbc::SQLException
* pReturn
= current();
311 // check for the next element within the chain
312 const Type
aTypeException( ::cppu::UnoType
< SQLException
>::get() );
314 Type aNextElementType
= m_pCurrent
->NextException
.getValueType();
315 if ( !isAssignableFrom( aTypeException
, aNextElementType
) )
317 // no SQLException at all in the next chain element
319 m_eCurrentType
= SQLExceptionInfo::UNDEFINED
;
323 m_pCurrent
= static_cast< const SQLException
* >( m_pCurrent
->NextException
.getValue() );
325 // no finally determine the proper type of the exception
326 const Type
aTypeContext( ::cppu::UnoType
< SQLContext
>::get() );
327 if ( isAssignableFrom( aTypeContext
, aNextElementType
) )
329 m_eCurrentType
= SQLExceptionInfo::SQL_CONTEXT
;
333 const Type
aTypeWarning( ::cppu::UnoType
< SQLWarning
>::get() );
334 if ( isAssignableFrom( aTypeWarning
, aNextElementType
) )
336 m_eCurrentType
= SQLExceptionInfo::SQL_WARNING
;
340 // a simple SQLException
341 m_eCurrentType
= SQLExceptionInfo::SQL_EXCEPTION
;
346 void SQLExceptionIteratorHelper::next( SQLExceptionInfo
& _out_rInfo
)
348 current( _out_rInfo
);
353 void throwFunctionSequenceException(const Reference
< XInterface
>& _Context
, const Any
& _Next
) throw ( ::com::sun::star::sdbc::SQLException
)
355 ::connectivity::SharedResources aResources
;
357 aResources
.getResourceString(STR_ERRORMSG_SEQUENCE
),
359 getStandardSQLState( SQL_FUNCTION_SEQUENCE_ERROR
),
365 void throwInvalidIndexException(const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _Context
,
366 const ::com::sun::star::uno::Any
& _Next
) throw ( ::com::sun::star::sdbc::SQLException
)
368 ::connectivity::SharedResources aResources
;
370 aResources
.getResourceString(STR_INVALID_INDEX
),
372 getStandardSQLState( SQL_INVALID_DESCRIPTOR_INDEX
),
378 void throwFunctionNotSupportedSQLException(const OUString
& _rFunctionName
,
379 const css::uno::Reference
<css::uno::XInterface
>& _rxContext
,
380 const css::uno::Any
& _rNextException
) throw (css::sdbc::SQLException
)
382 ::connectivity::SharedResources aResources
;
383 const OUString
sError( aResources
.getResourceStringWithSubstitution(
384 STR_UNSUPPORTED_FUNCTION
,
385 "$functionname$", _rFunctionName
390 getStandardSQLState( SQL_FUNCTION_NOT_SUPPORTED
),
396 void throwFunctionNotSupportedRuntimeException(const OUString
& _rFunctionName
,
397 const css::uno::Reference
<css::uno::XInterface
>& _rxContext
) throw (css::uno::RuntimeException
)
399 ::connectivity::SharedResources aResources
;
400 const OUString
sError( aResources
.getResourceStringWithSubstitution(
401 STR_UNSUPPORTED_FUNCTION
,
402 "$functionname$", _rFunctionName
404 throw RuntimeException(
410 void throwGenericSQLException(const OUString
& _rMsg
, const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _rxSource
)
411 throw (::com::sun::star::sdbc::SQLException
)
413 throwGenericSQLException(_rMsg
, _rxSource
, Any());
417 void throwGenericSQLException(const OUString
& _rMsg
, const Reference
< XInterface
>& _rxSource
, const Any
& _rNextException
)
420 throw SQLException( _rMsg
, _rxSource
, getStandardSQLState( SQL_GENERAL_ERROR
), 0, _rNextException
);
423 void throwFeatureNotImplementedSQLException( const OUString
& _rFeatureName
, const Reference
< XInterface
>& _rxContext
, const Any
* _pNextException
)
426 ::connectivity::SharedResources aResources
;
427 const OUString
sError( aResources
.getResourceStringWithSubstitution(
428 STR_UNSUPPORTED_FEATURE
,
429 "$featurename$", _rFeatureName
435 getStandardSQLState( SQL_FEATURE_NOT_IMPLEMENTED
),
437 _pNextException
? *_pNextException
: Any()
441 void throwFeatureNotImplementedRuntimeException(const OUString
& _rFeatureName
, const Reference
< XInterface
>& _rxContext
)
442 throw (RuntimeException
)
444 ::connectivity::SharedResources aResources
;
445 const OUString
sError( aResources
.getResourceStringWithSubstitution(
446 STR_UNSUPPORTED_FEATURE
,
447 "$featurename$", _rFeatureName
450 throw RuntimeException(sError
, _rxContext
);
453 void throwInvalidColumnException( const OUString
& _rColumnName
, const Reference
< XInterface
>& _rxContext
)
456 ::connectivity::SharedResources aResources
;
457 OUString
sErrorMessage( aResources
.getResourceStringWithSubstitution(
458 STR_INVALID_COLUMNNAME
,
459 "$columnname$",_rColumnName
) );
460 throwSQLException( sErrorMessage
, SQL_COLUMN_NOT_FOUND
, _rxContext
);
463 void throwSQLException( const OUString
& _rMessage
, const OUString
& _rSQLState
,
464 const Reference
< XInterface
>& _rxContext
, const sal_Int32 _nErrorCode
, const Any
* _pNextException
) throw (SQLException
)
471 _pNextException
? *_pNextException
: Any()
476 void throwSQLException( const OUString
& _rMessage
, StandardSQLState _eSQLState
,
477 const Reference
< XInterface
>& _rxContext
, const sal_Int32 _nErrorCode
,
478 const Any
* _pNextException
) throw (SQLException
)
480 throwSQLException( _rMessage
, getStandardSQLState( _eSQLState
), _rxContext
, _nErrorCode
, _pNextException
);
484 OUString
getStandardSQLState( StandardSQLState _eState
)
488 case SQL_WRONG_PARAMETER_NUMBER
: return OUString("07001");
489 case SQL_INVALID_DESCRIPTOR_INDEX
: return OUString("07009");
490 case SQL_UNABLE_TO_CONNECT
: return OUString("08001");
491 case SQL_NUMERIC_OUT_OF_RANGE
: return OUString("22003");
492 case SQL_INVALID_DATE_TIME
: return OUString("22007");
493 case SQL_INVALID_CURSOR_STATE
: return OUString("24000");
494 case SQL_TABLE_OR_VIEW_EXISTS
: return OUString("42S01");
495 case SQL_TABLE_OR_VIEW_NOT_FOUND
: return OUString("42S02");
496 case SQL_INDEX_ESISTS
: return OUString("42S11");
497 case SQL_INDEX_NOT_FOUND
: return OUString("42S12");
498 case SQL_COLUMN_EXISTS
: return OUString("42S21");
499 case SQL_COLUMN_NOT_FOUND
: return OUString("42S22");
500 case SQL_GENERAL_ERROR
: return OUString("HY000");
501 case SQL_INVALID_SQL_DATA_TYPE
: return OUString("HY004");
502 case SQL_OPERATION_CANCELED
: return OUString("HY008");
503 case SQL_FUNCTION_SEQUENCE_ERROR
: return OUString("HY010");
504 case SQL_INVALID_CURSOR_POSITION
: return OUString("HY109");
505 case SQL_INVALID_BOOKMARK_VALUE
: return OUString("HY111");
506 case SQL_FEATURE_NOT_IMPLEMENTED
: return OUString("HYC00");
507 case SQL_FUNCTION_NOT_SUPPORTED
: return OUString("IM001");
508 case SQL_CONNECTION_DOES_NOT_EXIST
: return OUString("08003");
509 default: return OUString("HY001"); // General Error
515 } // namespace dbtools
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */