    {-| Management of handles and exception handling.
    -}
    module DB.HSQL.Core where
    import Prelude hiding(catch)
    import Control.Monad(when,unless)
    import Control.Exception(Exception,throw,catch,handle)
    import Control.Concurrent.MVar(MVar,withMVar,modifyMVar_)
    import Data.Dynamic(cast)

    import DB.HSQL.Error(SqlError(SqlClosedHandle))

    -- | if closed, no action.
    closeHandle :: MVar Bool -- ^ closing state ref
                -> IO () -- ^ DB action to do if not closed
                -> IO ()
    closeHandle ref action =
    	modifyMVar_ ref (\closed -> unless closed action
                             >> return True)

    -- | if closed, throws `SqlClosedHandle' exception.
    checkHandle :: MVar Bool -- ^ closing state ref
                -> IO a -- ^ DB action to do if not closed
                -> IO a
    checkHandle ref action =
    	withMVar ref (\closed -> when closed (throw SqlClosedHandle)
                          >> action)

    ------------------------------------------------------------------------------
    -- routines for exception handling
    ------------------------------------------------------------------------------
    -- | Casts, if possible, an `Exception' to an `SqlError'.
    sqlExceptions :: Exception x
                  => x -- ^ the exception thinc to be cast
                  -> Maybe SqlError
    sqlExceptions = cast

    -- | Deprecated: Use `Control.Exception.catch' instead.
    {-# DEPRECATED catchSql "Use Control.Exception.catch instead." #-}
    catchSql :: IO a -> (SqlError -> IO a) -> IO a
    catchSql = catch

    -- | Deprecated: Use `Control.Exception.handle' instead.
    {-# DEPRECATED handleSql "Use Control.Exception.handle instead." #-}
    handleSql :: (SqlError -> IO a) -> IO a -> IO a
    handleSql = handle