Add errors and optional fields
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
module Database.PostgreSQL.Opium.Error (Error (..)) where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Database.PostgreSQL.LibPQ (ExecStatus, Row)
|
||||
|
||||
import Database.PostgreSQL.Opium.FromField (FieldError)
|
||||
|
||||
data Error
|
||||
= ErrorDecode Row Text FieldError
|
||||
| ErrorNoResult
|
||||
| ErrorInvalidResult ExecStatus Text
|
||||
| ErrorMissingColumn Text
|
||||
| ErrorUnexpectedNull Row Text
|
||||
deriving (Eq, Show)
|
||||
@@ -1,13 +1,17 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
module Database.PostgreSQL.Opium.FromField (FromField (..)) where
|
||||
module Database.PostgreSQL.Opium.FromField
|
||||
( FieldError (..)
|
||||
, FromField (..)
|
||||
) where
|
||||
|
||||
import Data.Attoparsec.Text
|
||||
( Parser
|
||||
, decimal
|
||||
, parseOnly
|
||||
, signed
|
||||
, takeText
|
||||
)
|
||||
import Data.Text (Text)
|
||||
import Database.PostgreSQL.LibPQ (Oid)
|
||||
@@ -18,23 +22,30 @@ import qualified Database.PostgreSQL.Opium.Oid as Oid
|
||||
(\/) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
|
||||
p \/ q = \x -> p x || q x
|
||||
|
||||
eitherToMaybe :: Either b a -> Maybe a
|
||||
eitherToMaybe = \case
|
||||
Left _ -> Nothing
|
||||
Right x -> Just x
|
||||
data FieldError
|
||||
= FieldErrorUnexpectedNull
|
||||
| FieldErrorInvalidOid Oid
|
||||
| FieldErrorInvalidField Oid Text String
|
||||
deriving (Eq, Show)
|
||||
|
||||
mapLeft :: (b -> c) -> Either b a -> Either c a
|
||||
mapLeft f (Left l) = Left $ f l
|
||||
mapLeft _ (Right r) = Right r
|
||||
|
||||
fromParser
|
||||
:: (Oid -> Bool)
|
||||
-> Parser a
|
||||
-> Oid
|
||||
-> Text
|
||||
-> Maybe a
|
||||
fromParser validOid parser oid value
|
||||
| validOid oid = eitherToMaybe $ parseOnly parser value
|
||||
| otherwise = Nothing
|
||||
-> Either FieldError a
|
||||
fromParser validOid parser oid field
|
||||
| validOid oid =
|
||||
mapLeft (FieldErrorInvalidField oid field) $ parseOnly parser field
|
||||
| otherwise =
|
||||
Left $ FieldErrorInvalidOid oid
|
||||
|
||||
class FromField a where
|
||||
fromField :: Oid -> Text -> Maybe a
|
||||
fromField :: Oid -> Text -> Either FieldError a
|
||||
|
||||
instance FromField Int where
|
||||
fromField = fromParser
|
||||
@@ -42,11 +53,9 @@ instance FromField Int where
|
||||
(signed decimal)
|
||||
|
||||
instance FromField Text where
|
||||
fromField oid text =
|
||||
if Oid.text oid || Oid.character oid || Oid.characterVarying oid then
|
||||
Just text
|
||||
else
|
||||
Nothing
|
||||
fromField = fromParser
|
||||
(Oid.text \/ Oid.character \/ Oid.characterVarying)
|
||||
takeText
|
||||
|
||||
instance FromField String where
|
||||
fromField oid text = Text.unpack <$> fromField oid text
|
||||
|
||||
Reference in New Issue
Block a user