@@ -8,7 +8,23 @@
8-- Maintainer: Leon P Smith <leon@melding-monads.com>
8-- Maintainer: Leon P Smith <leon@melding-monads.com>
9-- Stability: experimental
9-- Stability: experimental
11−-- mid-level support for COPY IN and COPY OUT.
11+-- mid-level support for COPY IN and COPY OUT. See
12+-- <http://www.postgresql.org/docs/9.2/static/sql-copy.html> for
15+-- To use this binding, first call 'copy' with a @COPY FROM STDIN@
16+-- or @COPY TO STDOUT@ query as documented in the link above. Then
17+-- call @getCopyData@ repeatedly until it returns 'CopyOutDone' in
18+-- the former case, or in the latter case call @putCopyData@ repeatedly
19+-- and then finally call either @putCopyEnd@ to proceed or @putCopyError@
22+-- You cannot issue another query on the same connection while a copy
23+-- is ongoing; this will result in an exception. It is harmless to
24+-- concurrently call @getNotification@ on a connection while it is in
25+-- a copy in or copy out state, however be aware that current versions
26+-- of the PostgreSQL backend will not deliver notifications to a client
27+-- while a transaction is ongoing.
13------------------------------------------------------------------------------
29------------------------------------------------------------------------------
@@ -22,7 +38,7 @@ module Database.PostgreSQL.Simple.Copy
24import Control.Applicative
40import Control.Applicative
25−import Control.Concurrent ( threadWaitRead, threadWaitWrite )
41+import Control.Concurrent
26import Control.Exception ( throwIO )
42import Control.Exception ( throwIO )
27import qualified Data.Attoparsec.ByteString.Char8 as P
43import qualified Data.Attoparsec.ByteString.Char8 as P
28import Data.Int(Int64)
44import Data.Int(Int64)
@@ -57,7 +73,6 @@ doCopy funcName conn template q = do
57 PQ.BadResponse -> throwResultError funcName result status
73 PQ.BadResponse -> throwResultError funcName result status
58 PQ.NonfatalError -> throwResultError funcName result status
74 PQ.NonfatalError -> throwResultError funcName result status
59 PQ.FatalError -> throwResultError funcName result status
75 PQ.FatalError -> throwResultError funcName result status
62data CopyOutResult
77data CopyOutResult
63 = CopyOutRow !B.ByteString -- ^ Data representing exactly one row
78 = CopyOutRow !B.ByteString -- ^ Data representing exactly one row
@@ -77,13 +92,12 @@ getCopyData conn = withConnection conn loop
78 case row of
93 case row of
79 PQ.CopyOutRow rowdata -> return $! CopyOutRow rowdata
94 PQ.CopyOutRow rowdata -> return $! CopyOutRow rowdata
81− CopyOutDone <$> getCopyCommandTag funcName pqconn
95+ PQ.CopyOutDone -> CopyOutDone <$> getCopyCommandTag funcName pqconn
82#if defined(mingw32_HOST_OS)
96#if defined(mingw32_HOST_OS)
83 PQ.CopyOutWouldBlock -> do
97 PQ.CopyOutWouldBlock -> do
84 fail (B.unpack funcName ++ ": the impossible happened")
98 fail (B.unpack funcName ++ ": the impossible happened")
86− PQ.CopyOutWouldBlock -> do
100+ PQ.CopyOutWouldBlock -> do
87 mfd <- PQ.socket pqconn
101 mfd <- PQ.socket pqconn
88 case mfd of
102 case mfd of
89 Nothing -> throwIO (fdError funcName)
103 Nothing -> throwIO (fdError funcName)
@@ -92,7 +106,7 @@ getCopyData conn = withConnection conn loop
92 _ <- PQ.consumeInput pqconn
106 _ <- PQ.consumeInput pqconn
93 loop pqconn
107 loop pqconn
95− PQ.CopyOutError -> do
109+ PQ.CopyOutError -> do
96 mmsg <- PQ.errorMessage pqconn
110 mmsg <- PQ.errorMessage pqconn
97 throwIO SqlError {
111 throwIO SqlError {
98 sqlState = "",
112 sqlState = "",