    {-# LANGUAGE CPP,DeriveDataTypeable #-}
    {-| `SqlError' type for a variety of DB specific error conditions,
    with appropriate `Show', `Typeable', and `Exception' instances.
    -}
    module DB.HSQL.Error(SqlError(..)) where

    import Control.Exception(Exception(..),SomeException(..))
    import Data.Dynamic(Typeable,TyCon,mkTyCon3,cast)
    import DB.HSQL.Type(SqlType)

    -- |
    data SqlError
        = SqlError
          { seState       :: String
          , seNativeError :: Int
          , seErrorMsg    :: String
          } -- ^ generic error condition, with further specification
        | SqlNoMoreData -- ^ no more data was available
        | SqlInvalidHandle -- ^ requested handle is invalid
        | SqlStillExecuting -- ^ connection is blocked by running transaction
        | SqlNeedMoreData -- ^ more data is needed, e.g. additional connection
                          -- specs
        | SqlBadTypeCast
          { seFieldName :: String
          , seFieldType :: SqlType
          } -- ^ requested field can't be converted to requested type
        | SqlFetchNull
          { seFieldName :: String } -- ^ requested field returns NULL
        | SqlUnknownField
          { seFieldName :: String } -- ^ requested field isn't known
        | SqlUnsupportedOperation -- ^ requested operation isn't supported
        | SqlClosedHandle -- ^ referenced handle is already closed
    #ifdef __GLASGOW_HASKELL__
       deriving (Eq,Ord,Typeable)
    #else
       deriving (Eq,Ord)

    instance Typeable SqlError where
    	typeOf _ = mkAppTy sqlErrorTc []
    #endif

    -- | The `TyCon' of `SqlError'.
    sqlErrorTc :: TyCon
    sqlErrorTc = mkTyCon3 "DB.HSQL" "Error" "SqlError"

    -- |
    instance Show SqlError where
        showsPrec _ (SqlError{seErrorMsg=msg}) = showString msg
        showsPrec _ SqlNoMoreData =
          showString "No more data was available"
        showsPrec _ SqlInvalidHandle           = showString "Invalid handle"
        showsPrec _ SqlStillExecuting          = showString "Still executing"
        showsPrec _ SqlNeedMoreData =
          showString "More data is needed, e.g. additional connection specs"
        showsPrec _ (SqlBadTypeCast name tp)   =
            showString ("The type of "++name++" field can't be converted to "
                        ++show tp++" type")
        showsPrec _ (SqlFetchNull name)        =
            showString ("The value of "++name++" field is null")
        showsPrec _ (SqlUnknownField name)     =
            showString ("Unknown field name: "++name)
        showsPrec _ SqlUnsupportedOperation    = showString "Unsupported operation"
        showsPrec _ SqlClosedHandle =
            showString "The referenced handle is already closed"

    -- |
    instance Exception SqlError where
        toException = SomeException
        fromException (SomeException exception) =
            cast exception