@@ -14,11 +14,14 @@
1414
1515module Database.PostgreSQL.Simple.Internal.PQResultUtils
1616 ( finishQueryWith
17+ , finishQueryWithV
18+ , finishQueryWithVU
1719 , getRowWith
1820 ) where
1921
2022import Control.Exception as E
2123import Data.ByteString (ByteString)
24+import Data.Foldable (for_)
2225import Database.PostgreSQL.Simple.FromField (ResultError(..))
2326import Database.PostgreSQL.Simple.Ok
2427import Database.PostgreSQL.Simple.Types (Query(..))
@@ -26,18 +29,49 @@ import Database.PostgreSQL.Simple.Internal as Base
2629import Database.PostgreSQL.Simple.TypeInfo
2730import qualified Database.PostgreSQL.LibPQ as PQ
2831import qualified Data.ByteString.Char8 as B
32+import qualified Data.Vector as V
33+import qualified Data.Vector.Mutable as MV
34+import qualified Data.Vector.Unboxed as VU
35+import qualified Data.Vector.Unboxed.Mutable as MVU
2936import Control.Monad.Trans.Reader
3037import Control.Monad.Trans.State.Strict
3138
3239finishQueryWith :: RowParser r -> Connection -> Query -> PQ.Result -> IO [r]
33−finishQueryWith parser conn q result = do
40+finishQueryWith parser conn q result = finishQueryWith' q result $ do
41+ nrows <- PQ.ntuples result
42+ ncols <- PQ.nfields result
43+ forM' 0 (nrows-1) $ \row ->
44+ getRowWith parser row ncols conn result
45+
46+finishQueryWithV :: RowParser r -> Connection -> Query -> PQ.Result -> IO (V.Vector r)
47+finishQueryWithV parser conn q result = finishQueryWith' q result $ do
48+ nrows <- PQ.ntuples result
49+ let PQ.Row nrows' = nrows
50+ ncols <- PQ.nfields result
51+ mv <- MV.unsafeNew (fromIntegral nrows')
52+ for_ [ 0 .. nrows-1 ] $ \row -> do
53+ let PQ.Row row' = row
54+ value <- getRowWith parser row ncols conn result
55+ MV.unsafeWrite mv (fromIntegral row') value
56+ V.unsafeFreeze mv
57+
58+finishQueryWithVU :: VU.Unbox r => RowParser r -> Connection -> Query -> PQ.Result -> IO (VU.Vector r)
59+finishQueryWithVU parser conn q result = finishQueryWith' q result $ do
60+ nrows <- PQ.ntuples result
61+ let PQ.Row nrows' = nrows
62+ ncols <- PQ.nfields result
63+ mv <- MVU.unsafeNew (fromIntegral nrows')
64+ for_ [ 0 .. nrows-1 ] $ \row -> do
65+ let PQ.Row row' = row
66+ value <- getRowWith parser row ncols conn result
67+ MVU.unsafeWrite mv (fromIntegral row') value
68+ VU.unsafeFreeze mv
69+
70+finishQueryWith' :: Query -> PQ.Result -> IO a -> IO a
71+finishQueryWith' q result k = do
3472 status <- PQ.resultStatus result
3573 case status of
36− PQ.TuplesOk -> do
37− nrows <- PQ.ntuples result
38− ncols <- PQ.nfields result
39− forM' 0 (nrows-1) $ \row ->
40− getRowWith parser row ncols conn result
74+ PQ.TuplesOk -> k
4175 PQ.EmptyQuery -> queryErr "query: Empty query"
4276 PQ.CommandOk -> queryErr "query resulted in a command response"
4377 PQ.CopyOut -> queryErr "query: COPY TO is not supported"