@@ -87,6 +87,8 @@ module Database.PostgreSQL.Simple.FromField
8787 , typeOid
8888 , PQ.Oid(..)
8989 , PQ.Format(..)
90+
91+ , fromJSONField
9092 ) where
9193
9294#include "MachDeps.h"
@@ -94,6 +96,7 @@ module Database.PostgreSQL.Simple.FromField
9496import Control.Applicative
9597 ( Applicative, (<|>), (<$>), pure )
9698import Control.Exception (Exception)
99+import qualified Data.Aeson as JSON
97100import Data.Attoparsec.Char8 hiding (Result)
98101import Data.ByteString (ByteString)
99102import qualified Data.ByteString.Char8 as B
@@ -441,6 +444,34 @@ fromArray typeInfo f = sequence . (parseIt <$>) <$> array delim
441444 where f' | Arrays.Array _ <- item = f
442445 | otherwise = fElem
443446
447+-- | json
448+instance FromField JSON.Value where
449+ fromField f Nothing = returnError UnexpectedNull f ""
450+ fromField f (Just bs)
451+ | typeOid f /= $(inlineTypoid TI.json) =
452+ returnError Incompatible f ""
453+ | otherwise =
454+ case JSON.eitherDecode' $ LB.fromStrict bs of
455+ Left err -> returnError ConversionFailed f err
456+ Right val -> pure val
457+
458+-- | Parse a field to a JSON 'JSON.Value' and convert that into a
459+-- Haskell value using 'JSON.fromJSON'.
460+--
461+-- This can be used as the default implementation for the 'fromField'
462+-- method for Haskell types that have a JSON representation in
463+-- PostgreSQL.
464+--
465+-- The 'Typeable' constraint is required to show more informative
466+-- error messages when parsing fails.
467+fromJSONField :: (JSON.FromJSON a, Typeable a) => FieldParser a
468+fromJSONField f mbBs = do
469+ value <- fromField f mbBs
470+ case JSON.fromJSON value of
471+ JSON.Error err -> returnError ConversionFailed f $
472+ "JSON decoding error: " ++ err
473+ JSON.Success x -> pure x
474+
444475type Compat = PQ.Oid -> Bool
445476
446477okText, okText', okBinary, ok16, ok32, ok64, okInt :: Compat