git.iko.soy/typeable/postgresql-simple
on master help sign in
Merge pull request #56 from stackbuilders/all_copy_data
227fcb3Oleg Grenrus
src/Database/PostgreSQL/Simple/Copy.hs+25
@@ -32,6 +32,7 @@ module Database.PostgreSQL.Simple.Copy
32 ( copy
32 ( copy
33 , copy_
33 , copy_
34 , CopyOutResult(..)
34 , CopyOutResult(..)
35+ , foldCopyData
35 , getCopyData
36 , getCopyData
36 , putCopyData
37 , putCopyData
37 , putCopyEnd
38 , putCopyEnd
@@ -104,6 +105,30 @@ data CopyOutResult
104 deriving (Eq, Typeable, Show)
105 deriving (Eq, Typeable, Show)
105
106
106
107
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+
107-- | Retrieve some data from a @COPY TO STDOUT@ query. A connection
132-- | Retrieve some data from a @COPY TO STDOUT@ query. A connection
108-- must be in the @CopyOut@ state in order to call this function. If this
133-- must be in the @CopyOut@ state in order to call this function. If this
109-- returns a 'CopyOutRow', the connection remains in the @CopyOut@ state,
134-- returns a 'CopyOutRow', the connection remains in the @CopyOut@ state,
test/Main.hs+8
@@ -442,6 +442,14 @@ testCopy TestEnv{..} = do
442 -- so that we can issue more queries:
442 -- so that we can issue more queries:
443 [Only (x::Int)] <- query_ conn "SELECT 2 + 2"
443 [Only (x::Int)] <- query_ conn "SELECT 2 + 2"
444 x @?= 4
444 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
445 where
453 where
446 copyRows = ["1,foo\n"
454 copyRows = ["1,foo\n"
447 ,"2,bar\n"]
455 ,"2,bar\n"]