@@ -118,16 +118,15 @@ module Database.PostgreSQL.Simple
118 , formatQuery
118 , formatQuery
121−import Data.ByteString.Builder
121+import Data.ByteString.Builder (Builder, byteString, char8)
122− ( Builder, byteString, char8, intDec )
123import Control.Applicative ((<$>))
122import Control.Applicative ((<$>))
124import Control.Exception as E
123import Control.Exception as E
125−import Control.Monad (unless)
126import Data.ByteString (ByteString)
124import Data.ByteString (ByteString)
127import Data.Int (Int64)
125import Data.Int (Int64)
128import Data.List (intersperse)
126import Data.List (intersperse)
129import Data.Monoid (mconcat)
127import Data.Monoid (mconcat)
130−import Database.PostgreSQL.Simple.Compat ( (<>), toByteString )
128+import Database.PostgreSQL.Simple.Compat ((<>), toByteString)
129+import Database.PostgreSQL.Simple.Cursor
131import Database.PostgreSQL.Simple.FromField (ResultError(..))
130import Database.PostgreSQL.Simple.FromField (ResultError(..))
132import Database.PostgreSQL.Simple.FromRow (FromRow(..))
131import Database.PostgreSQL.Simple.FromRow (FromRow(..))
133import Database.PostgreSQL.Simple.ToField (Action(..))
132import Database.PostgreSQL.Simple.ToField (Action(..))
@@ -559,39 +558,17 @@ doFold FoldOptions{..} parser conn _template q a0 f = do
559 PQ.TransUnknown -> fail "foldWithOpts FIXME: PQ.TransUnknown"
558 PQ.TransUnknown -> fail "foldWithOpts FIXME: PQ.TransUnknown"
560 -- Not sure what this means.
559 -- Not sure what this means.
562− declare = do
561+ declare =
563− name <- newTempName conn
562+ declareCursor conn q
564− _ <- execute_ conn $ mconcat
563+ fetch cursor a =
565− [ "DECLARE ", name, " NO SCROLL CURSOR FOR ", q ]
564+ foldForwardWithParser cursor parser chunkSize f a
568− (execute_ conn ("CLOSE " <> name) >> return ()) `E.catch` \ex ->
569− -- Don't throw exception if CLOSE failed because the transaction is
570− -- aborted. Otherwise, it will throw away the original error.
571− unless (isFailedTransactionError ex) $ throwIO ex
573− go = bracket declare close $ \(Query name) ->
566+ go = bracket declare closeCursor $ \cursor ->
574− let q = toByteString (byteString "FETCH FORWARD "
567+ let loop a = fetch cursor a >>=
576− <> byteString " FROM "
580− result <- exec conn q
581− status <- PQ.resultStatus result
582− case status of
568+ \r -> case r of
583− PQ.TuplesOk -> do
569+ Left a -> return a
584− nrows <- PQ.ntuples result
570+ Right a -> loop a
585− ncols <- PQ.nfields result
588− let inner a row = do
589− x <- getRowWith parser row ncols conn result
591− foldM' inner a 0 (nrows - 1) >>= loop
593− _ -> throwResultError "fold" result status
594− in loop a0
571+ in loop a0
596-- FIXME: choose the Automatic chunkSize more intelligently
573-- FIXME: choose the Automatic chunkSize more intelligently
597-- One possibility is to use the type of the results, although this
574-- One possibility is to use the type of the results, although this
@@ -641,16 +618,6 @@ forEachWith_ :: RowParser r
641forEachWith_ parser conn template = foldWith_ parser conn template () . const
618forEachWith_ parser conn template = foldWith_ parser conn template () . const
642{-# INLINE forEachWith_ #-}
619{-# INLINE forEachWith_ #-}
644−foldM' :: (Ord n, Num n) => (a -> n -> IO a) -> a -> n -> n -> IO a
645−foldM' f a lo hi = loop a lo
652−{-# INLINE foldM' #-}