@@ -26,13 +26,12 @@ module Database.PostgreSQL.Simple.Result
2626 (
2727 Result(..)
2828 , ResultError(..)
29− , Status(..)
3029 ) where
3130
3231#include "MachDeps.h"
3332
3433import Control.Applicative (Applicative, (<$>), (<*>), (<*), pure)
35−import Control.Exception (Exception, throw)
34+import Control.Exception (SomeException(..), Exception, throw)
3635import Data.Attoparsec.Char8 hiding (Result)
3736import Data.Bits ((.&.), (.|.), shiftL)
3837import Data.ByteString (ByteString)
@@ -81,12 +80,17 @@ data ResultError = Incompatible { errSQLType :: String
8180
8281instance Exception ResultError
8382
83+left :: Exception a => a -> Either SomeException b
84+left = Left . SomeException
85+
8486-- | A type that may be converted from a SQL type.
8587class Result a where
86− convert :: Field -> Maybe ByteString -> Status ResultError a
88+ convert :: Field -> Maybe ByteString -> Either SomeException a
8789 -- ^ Convert a SQL value to a Haskell value.
8890 --
89− -- Throws a 'ResultError' if conversion fails.
91+ -- Returns an exception if the conversion fails. In the case of
92+ -- library instances, this will usually be a 'ResultError', but may
93+ -- be a 'UnicodeError'.
9094{--
9195instance (Result a) => Result (Maybe a) where
9296 convert _ Nothing = pure Nothing
@@ -155,7 +159,7 @@ instance Result LB.ByteString where
155159
156160
157161instance Result ST.Text where
158− convert f {- | isText f -} = doConvert f okText $ (Success . ST.decodeUtf8)
162+ convert f {- | isText f -} = doConvert f okText $ (Right . ST.decodeUtf8)
159163{- | otherwise = incompatible f (typeOf ST.empty)
160164 "attempt to mix binary and text" -}
161165 -- FIXME: return a "Fail someUnicodeError" instead of throwing it
@@ -170,7 +174,7 @@ instance Result [Char] where
170174instance Result UTCTime where
171175 convert f = doConvert f ok $ \bs ->
172176 case parseTime defaultTimeLocale "%F %T%Q%z" (B8.unpack bs ++ "00") of
173− Just t -> Success t
177+ Just t -> Right t
174178 Nothing -> conversionFailed f "UTCTime" "could not parse"
175179 where ok = mkCompats [TimestampWithTimeZone]
176180{--
@@ -224,29 +228,29 @@ okInt = ok64
224228#endif
225229--}
226230doConvert :: forall a . (Typeable a)
227− => Field -> Compat -> (ByteString -> Status ResultError a)
228− -> Maybe ByteString -> Status ResultError a
231+ => Field -> Compat -> (ByteString -> Either SomeException a)
232+ -> Maybe ByteString -> Either SomeException a
229233doConvert f types cvt (Just bs)
230234 | Just typ <- oid2builtin (typeOid f)
231235 , mkCompat typ `compat` types = cvt bs
232236 | otherwise = incompatible f (typeOf (undefined::a)) "types incompatible"
233−doConvert f _ cvt _ = Fail $ UnexpectedNull (B.unpack (typename f))
237+doConvert f _ cvt _ = left $ UnexpectedNull (B.unpack (typename f))
234238 (show (typeOf (undefined::a))) ""
235239
236−incompatible :: Field -> TypeRep -> String -> Status ResultError a
237−incompatible f r = Fail . Incompatible (B.unpack (typename f)) (show r)
240+incompatible :: Field -> TypeRep -> String -> Either SomeException a
241+incompatible f r = left . Incompatible (B.unpack (typename f)) (show r)
238242
239−conversionFailed :: Field -> String -> String -> Status ResultError a
240−conversionFailed f s = Fail . ConversionFailed (B.unpack (typename f)) s
243+conversionFailed :: Field -> String -> String -> Either SomeException a
244+conversionFailed f s = left . ConversionFailed (B.unpack (typename f)) s
241245
242−atto :: (Typeable a) => Compat -> Parser a -> Field -> Maybe ByteString -> Status ResultError a
246+atto :: (Typeable a) => Compat -> Parser a -> Field -> Maybe ByteString -> Either SomeException a
243247atto types p0 f dat = doConvert f types (go undefined p0) dat
244248 where
245− go :: (Typeable a) => a -> Parser a -> ByteString -> Status ResultError a
249+ go :: (Typeable a) => a -> Parser a -> ByteString -> Either SomeException a
246250 go dummy p s =
247251 case parseOnly p s of
248252 Left err -> conversionFailed f (show (typeOf dummy)) err
249− Right v -> Success v
253+ Right v -> Right v
250254
251255instance Result RawResult where
252− convert field rawData = Success (RawResult field rawData)
256+ convert field rawData = Right (RawResult field rawData)