module Hasql.CursorQuery.Private.CursorTransactions where import Hasql.CursorQuery.Private.Prelude import qualified Hasql.CursorQuery.Private.CursorQuery as B import qualified Hasql.CursorQuery.Private.Decoders as I import qualified Hasql.Decoders as E import qualified Hasql.Encoders as F import qualified Hasql.CursorTransaction as G import qualified Control.Foldl as D -- | -- Fetch and fold the data from cursor until it dries out. fetchAndFoldCursor :: G.Cursor s -> G.BatchSize -> E.Row row -> D.Fold row result -> G.CursorTransaction s result fetchAndFoldCursor cursor batchSize rowDecoder (D.Fold progress enter exit) = fmap exit $ fetchAndFoldMore enter where fetchAndFoldMore batch = do (null, fetchedBatch) <- fetchBatch if null then return batch else fetchAndFoldMore fetchedBatch where fetchBatch = fetchAndFoldCursorBatch cursor batchSize rowDecoder fold where fold = (,) <$> D.null <*> D.Fold progress batch id fetchAndFoldCursorBatch :: G.Cursor s -> G.BatchSize -> E.Row row -> D.Fold row result -> G.CursorTransaction s result fetchAndFoldCursorBatch cursor batchSize rowDecoder rowsFold = G.fetchBatch cursor batchSize (I.fold rowsFold rowDecoder) -- | -- Executes CursorQuery in CursorTransaction provided the parameters. cursorQuery :: params -> B.CursorQuery params result -> G.CursorTransaction s result cursorQuery params (B.CursorQuery template encoder (B.ReducingDecoder rowDecoder rowsFold) batchSize) = do cursor <- G.declareCursor template (G.encodedParams encoder params) fetchAndFoldCursor cursor batchSize rowDecoder rowsFold