git.iko.soy/typeable/postgresql-simple
on master help sign in
Move finishQueryWith and getRowWith to new module
commit498e956c6ef0a390bd8b490eddab03748e08d520 authorBardur Arantsson <bardur@scientician.net> dateThu 20 Apr 2017, 18:37 (9 years ago) parent0b0c80f
3 files changed+91−64
postgresql-simple.cabal+1 src/Database/PostgreSQL/Simple.hs+1−64 src/Database/PostgreSQL/Simple/Internal/PQResultUtils.hs+89
postgresql-simple.cabal+1
@@ -45,6 +45,7 @@ Library
4545 Database.PostgreSQL.Simple.Errors
4646-- Other-modules:
4747 Database.PostgreSQL.Simple.Internal
48+ Database.PostgreSQL.Simple.Internal.PQResultUtils
4849
4950 Other-modules:
5051 Database.PostgreSQL.Simple.Compat
src/Database/PostgreSQL/Simple.hs+1−64
@@ -130,18 +130,15 @@ import Data.Monoid (mconcat)
130130import Database.PostgreSQL.Simple.Compat ( (<>), toByteString )
131131import Database.PostgreSQL.Simple.FromField (ResultError(..))
132132import Database.PostgreSQL.Simple.FromRow (FromRow(..))
133−import Database.PostgreSQL.Simple.Ok
134133import Database.PostgreSQL.Simple.ToField (Action(..))
135134import Database.PostgreSQL.Simple.ToRow (ToRow(..))
136135import Database.PostgreSQL.Simple.Types
137136 ( Binary(..), In(..), Only(..), Query(..), (:.)(..) )
138137import Database.PostgreSQL.Simple.Internal as Base
138+import Database.PostgreSQL.Simple.Internal.PQResultUtils
139139import Database.PostgreSQL.Simple.Transaction
140−import Database.PostgreSQL.Simple.TypeInfo
141140import qualified Database.PostgreSQL.LibPQ as PQ
142141import qualified Data.ByteString.Char8 as B
143−import Control.Monad.Trans.Reader
144−import Control.Monad.Trans.State.Strict
145142
146143
147144-- | Format a query string.
@@ -644,16 +641,6 @@ forEachWith_ :: RowParser r
644641forEachWith_ parser conn template = foldWith_ parser conn template () . const
645642{-# INLINE forEachWith_ #-}
646643
647−forM' :: (Ord n, Num n) => n -> n -> (n -> IO a) -> IO [a]
648−forM' lo hi m = loop hi []
649− where
650− loop !n !as
651− | n < lo = return as
652− | otherwise = do
653− a <- m n
654− loop (n-1) (a:as)
655−{-# INLINE forM' #-}
656−
657644foldM' :: (Ord n, Num n) => (a -> n -> IO a) -> a -> n -> n -> IO a
658645foldM' f a lo hi = loop a lo
659646 where
@@ -664,56 +651,6 @@ foldM' f a lo hi = loop a lo
664651 loop a' (n+1)
665652{-# INLINE foldM' #-}
666653
667−finishQueryWith :: RowParser r -> Connection -> Query -> PQ.Result -> IO [r]
668−finishQueryWith parser conn q result = do
669− status <- PQ.resultStatus result
670− case status of
671− PQ.EmptyQuery ->
672− throwIO $ QueryError "query: Empty query" q
673− PQ.CommandOk ->
674− throwIO $ QueryError "query resulted in a command response" q
675− PQ.TuplesOk -> do
676− nrows <- PQ.ntuples result
677− ncols <- PQ.nfields result
678− forM' 0 (nrows-1) $ \row ->
679− getRowWith parser row ncols conn result
680− PQ.CopyOut ->
681− throwIO $ QueryError "query: COPY TO is not supported" q
682− PQ.CopyIn ->
683− throwIO $ QueryError "query: COPY FROM is not supported" q
684− PQ.BadResponse -> throwResultError "query" result status
685− PQ.NonfatalError -> throwResultError "query" result status
686− PQ.FatalError -> throwResultError "query" result status
687−
688−getRowWith :: RowParser r -> PQ.Row -> PQ.Column -> Connection -> PQ.Result -> IO r
689−getRowWith parser row ncols conn result = do
690− let rw = Row row result
691− let unCol (PQ.Col x) = fromIntegral x :: Int
692− okvc <- runConversion (runStateT (runReaderT (unRP parser) rw) 0) conn
693− case okvc of
694− Ok (val,col) | col == ncols -> return val
695− | otherwise -> do
696− vals <- forM' 0 (ncols-1) $ \c -> do
697− tinfo <- getTypeInfo conn =<< PQ.ftype result c
698− v <- PQ.getvalue result row c
699− return ( tinfo
700− , fmap ellipsis v )
701− throw (ConversionFailed
702− (show (unCol ncols) ++ " values: " ++ show vals)
703− Nothing
704− ""
705− (show (unCol col) ++ " slots in target type")
706− "mismatch between number of columns to \
707− \convert and number in target type")
708− Errors [] -> throwIO $ ConversionFailed "" Nothing "" "" "unknown error"
709− Errors [x] -> throwIO x
710− Errors xs -> throwIO $ ManyErrors xs
711−
712−ellipsis :: ByteString -> ByteString
713−ellipsis bs
714− | B.length bs > 15 = B.take 10 bs `B.append` "[...]"
715− | otherwise = bs
716−
717654
718655-- $use
719656--
src/Database/PostgreSQL/Simple/Internal/PQResultUtils.hsnew file+89
@@ -0,0 +1,89 @@
1+
2+------------------------------------------------------------------------------
3+-- |
4+-- Module: Database.PostgreSQL.Simple.Internal.PQResultUtils
5+-- Copyright: (c) 2011 MailRank, Inc.
6+-- (c) 2011-2012 Leon P Smith
7+-- License: BSD3
8+-- Maintainer: Leon P Smith <leon@melding-monads.com>
9+-- Stability: experimental
10+--
11+------------------------------------------------------------------------------
12+
13+
14+module Database.PostgreSQL.Simple.Internal.PQResultUtils
15+ ( finishQueryWith
16+ , getRowWith
17+ ) where
18+
19+import Control.Exception as E
20+import Data.ByteString (ByteString)
21+import Database.PostgreSQL.Simple.FromField (ResultError(..))
22+import Database.PostgreSQL.Simple.Ok
23+import Database.PostgreSQL.Simple.Types (Query(..))
24+import Database.PostgreSQL.Simple.Internal as Base
25+import Database.PostgreSQL.Simple.TypeInfo
26+import qualified Database.PostgreSQL.LibPQ as PQ
27+import qualified Data.ByteString.Char8 as B
28+import Control.Monad.Trans.Reader
29+import Control.Monad.Trans.State.Strict
30+
31+finishQueryWith :: RowParser r -> Connection -> Query -> PQ.Result -> IO [r]
32+finishQueryWith parser conn q result = do
33+ status <- PQ.resultStatus result
34+ case status of
35+ PQ.EmptyQuery ->
36+ throwIO $ QueryError "query: Empty query" q
37+ PQ.CommandOk ->
38+ throwIO $ QueryError "query resulted in a command response" q
39+ PQ.TuplesOk -> do
40+ nrows <- PQ.ntuples result
41+ ncols <- PQ.nfields result
42+ forM' 0 (nrows-1) $ \row ->
43+ getRowWith parser row ncols conn result
44+ PQ.CopyOut ->
45+ throwIO $ QueryError "query: COPY TO is not supported" q
46+ PQ.CopyIn ->
47+ throwIO $ QueryError "query: COPY FROM is not supported" q
48+ PQ.BadResponse -> throwResultError "query" result status
49+ PQ.NonfatalError -> throwResultError "query" result status
50+ PQ.FatalError -> throwResultError "query" result status
51+
52+getRowWith :: RowParser r -> PQ.Row -> PQ.Column -> Connection -> PQ.Result -> IO r
53+getRowWith parser row ncols conn result = do
54+ let rw = Row row result
55+ let unCol (PQ.Col x) = fromIntegral x :: Int
56+ okvc <- runConversion (runStateT (runReaderT (unRP parser) rw) 0) conn
57+ case okvc of
58+ Ok (val,col) | col == ncols -> return val
59+ | otherwise -> do
60+ vals <- forM' 0 (ncols-1) $ \c -> do
61+ tinfo <- getTypeInfo conn =<< PQ.ftype result c
62+ v <- PQ.getvalue result row c
63+ return ( tinfo
64+ , fmap ellipsis v )
65+ throw (ConversionFailed
66+ (show (unCol ncols) ++ " values: " ++ show vals)
67+ Nothing
68+ ""
69+ (show (unCol col) ++ " slots in target type")
70+ "mismatch between number of columns to \
71+ \convert and number in target type")
72+ Errors [] -> throwIO $ ConversionFailed "" Nothing "" "" "unknown error"
73+ Errors [x] -> throwIO x
74+ Errors xs -> throwIO $ ManyErrors xs
75+
76+ellipsis :: ByteString -> ByteString
77+ellipsis bs
78+ | B.length bs > 15 = B.take 10 bs `B.append` "[...]"
79+ | otherwise = bs
80+
81+forM' :: (Ord n, Num n) => n -> n -> (n -> IO a) -> IO [a]
82+forM' lo hi m = loop hi []
83+ where
84+ loop !n !as
85+ | n < lo = return as
86+ | otherwise = do
87+ a <- m n
88+ loop (n-1) (a:as)
89+{-# INLINE forM' #-}