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, nothing to do:
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, 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 cast to SQLError
              -> Maybe SqlError
sqlExceptions = cast

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

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