Skip to content

Commit 227fcb3

Browse files
authored
Merge pull request #56 from stackbuilders/all_copy_data
Add foldCopyData helper function
2 parents 5df8de3 + 6458cf9 commit 227fcb3

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/Database/PostgreSQL/Simple/Copy.hs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module Database.PostgreSQL.Simple.Copy
3232
( copy
3333
, copy_
3434
, CopyOutResult(..)
35+
, foldCopyData
3536
, getCopyData
3637
, putCopyData
3738
, putCopyEnd
@@ -104,6 +105,30 @@ data CopyOutResult
104105
deriving (Eq, Typeable, Show)
105106

106107

108+
-- | Fold over @COPY TO STDOUT@ query passing each copied row to an accumulator
109+
-- and calling a post-process at the end. A connection must be in the
110+
-- @CopyOut@ state in order to call this function.
111+
--
112+
-- __Example__
113+
--
114+
-- > (acc, count) <- foldCopyData conn
115+
-- > (\acc row -> return (row:acc))
116+
-- > (\acc count -> return (acc, count))
117+
-- > []
118+
119+
foldCopyData
120+
:: Connection -- ^ Database connection
121+
-> (a -> B.ByteString -> IO a) -- ^ Accumulate one row of the result
122+
-> (a -> Int64 -> IO b) -- ^ Post-process accumulator with a count of rows
123+
-> a -- ^ Initial accumulator
124+
-> IO b -- ^ Result
125+
foldCopyData conn f g !acc = do
126+
result <- getCopyData conn
127+
case result of
128+
CopyOutRow row -> f acc row >>= foldCopyData conn f g
129+
CopyOutDone count -> g acc count
130+
131+
107132
-- | Retrieve some data from a @COPY TO STDOUT@ query. A connection
108133
-- must be in the @CopyOut@ state in order to call this function. If this
109134
-- returns a 'CopyOutRow', the connection remains in the @CopyOut@ state,

test/Main.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ testCopy TestEnv{..} = do
442442
-- so that we can issue more queries:
443443
[Only (x::Int)] <- query_ conn "SELECT 2 + 2"
444444
x @?= 4
445+
-- foldCopyData
446+
copy_ conn "COPY copy_test TO STDOUT (FORMAT CSV)"
447+
(acc, count) <- foldCopyData conn
448+
(\acc row -> return (row:acc))
449+
(\acc count -> return (acc, count))
450+
[]
451+
sort acc @?= sort copyRows
452+
count @?= 2
445453
where
446454
copyRows = ["1,foo\n"
447455
,"2,bar\n"]

0 commit comments

Comments
 (0)