content: -----------------------------------------------------------------------------
  -- |
  -- Module      :  Database.PostgreSQL.Simple.LargeObjects
  -- Copyright   :  (c) 2011-2012 Leon P Smith
  -- License     :  BSD3
  --
  -- Maintainer  :  leon@melding-monads.com
  --
  -- Support for PostgreSQL's Large Objects;  see
  -- <https://www.postgresql.org/docs/9.5/static/largeobjects.html> for more
  -- information.
  --
  -- Note that Large Object File Descriptors are only valid within a single
  -- database transaction,  so if you are interested in using anything beyond
  -- 'loCreat', 'loCreate', and 'loUnlink',  you will need to run the entire
  -- sequence of functions in a transaction.   As 'loImport' and 'loExport'
  -- are simply C functions that call 'loCreat', 'loOpen', 'loRead', and
  -- 'loWrite',  and do not perform any transaction handling themselves,
  -- they also need to be wrapped in an explicit transaction.
  --
  -----------------------------------------------------------------------------
  
  module Database.PostgreSQL.Simple.LargeObjects
       ( loCreat
       , loCreate
       , loImport
       , loImportWithOid
       , loExport
       , loOpen
       , loWrite
       , loRead
       , loSeek
       , loTell
       , loTruncate
       , loClose
       , loUnlink
       , Oid(..)
       , LoFd
       , IOMode(..)
       , SeekMode(..)
       ) where
  
  import           Control.Applicative ((<$>))
  import           Control.Exception (throwIO)
  import qualified Data.ByteString as B
  import           Database.PostgreSQL.LibPQ (Oid(..),LoFd(..))
  import qualified Database.PostgreSQL.LibPQ as PQ
  import           Database.PostgreSQL.Simple.Internal
  import           System.IO (IOMode(..),SeekMode(..))
  
  liftPQ :: B.ByteString -> Connection -> (PQ.Connection -> IO (Maybe a)) -> IO a
  liftPQ str conn m = withConnection conn $ \c -> do
      res <- m c
      case res of
        Nothing -> do
            msg <- maybe str id <$> PQ.errorMessage c
            throwIO $ fatalError msg
        Just  x -> return x
  
  loCreat :: Connection -> IO Oid
  loCreat conn = liftPQ "loCreat" conn (\c -> PQ.loCreat c)
  
  loCreate :: Connection -> Oid -> IO Oid
  loCreate conn oid = liftPQ "loCreate" conn (\c -> PQ.loCreate c oid)
  
  loImport :: Connection -> FilePath -> IO Oid
  loImport conn path = liftPQ "loImport" conn (\c -> PQ.loImport c path)
  
  loImportWithOid :: Connection -> FilePath -> Oid -> IO Oid
  loImportWithOid conn path oid = liftPQ "loImportWithOid" conn (\c -> PQ.loImportWithOid c path oid)
  
  loExport :: Connection -> Oid -> FilePath -> IO ()
  loExport conn oid path = liftPQ "loExport" conn (\c -> PQ.loExport c oid path)
  
  loOpen :: Connection -> Oid -> IOMode -> IO LoFd
  loOpen conn oid mode  = liftPQ "loOpen" conn (\c -> PQ.loOpen c oid mode )
  
  loWrite :: Connection -> LoFd -> B.ByteString -> IO Int
  loWrite conn fd dat = liftPQ "loWrite" conn (\c -> PQ.loWrite c fd dat)
  
  loRead :: Connection -> LoFd -> Int -> IO B.ByteString
  loRead conn fd maxlen = liftPQ "loRead" conn (\c -> PQ.loRead c fd maxlen)
  
  loSeek :: Connection -> LoFd -> SeekMode -> Int -> IO Int
  loSeek conn fd seekmode offset = liftPQ "loSeek" conn (\c -> PQ.loSeek c fd seekmode offset)
  
  loTell :: Connection -> LoFd -> IO Int
  loTell conn fd = liftPQ "loTell" conn (\c -> PQ.loTell c fd)
  
  loTruncate :: Connection -> LoFd -> Int -> IO ()
  loTruncate conn fd len = liftPQ "loTruncate" conn (\c -> PQ.loTruncate c fd len)
  
  loClose :: Connection -> LoFd -> IO ()
  loClose conn fd = liftPQ "loClose" conn (\c -> PQ.loClose c fd)
  
  loUnlink :: Connection -> Oid -> IO ()
  loUnlink conn oid = liftPQ "loUnlink" conn (\c -> PQ.loUnlink c oid)
  