53 lines
1.2 KiB
Haskell
53 lines
1.2 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
|
|
module Database.PostgreSQL.Opium.FromField (FromField (..)) where
|
|
|
|
import Data.Attoparsec.Text
|
|
( Parser
|
|
, decimal
|
|
, parseOnly
|
|
, signed
|
|
)
|
|
import Data.Text (Text)
|
|
import Database.PostgreSQL.LibPQ (Oid)
|
|
|
|
import qualified Data.Text as Text
|
|
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
|
|
|
|
fromParser
|
|
:: (Oid -> Bool)
|
|
-> Parser a
|
|
-> Oid
|
|
-> Text
|
|
-> Maybe a
|
|
fromParser validOid parser oid value
|
|
| validOid oid = eitherToMaybe $ parseOnly parser value
|
|
| otherwise = Nothing
|
|
|
|
class FromField a where
|
|
fromField :: Oid -> Text -> Maybe a
|
|
|
|
instance FromField Int where
|
|
fromField = fromParser
|
|
(Oid.smallint \/ Oid.integer \/ Oid.bigint)
|
|
(signed decimal)
|
|
|
|
instance FromField Text where
|
|
fromField oid text =
|
|
if Oid.text oid || Oid.character oid || Oid.characterVarying oid then
|
|
Just text
|
|
else
|
|
Nothing
|
|
|
|
instance FromField String where
|
|
fromField oid text = Text.unpack <$> fromField oid text
|