{-# LANGUAGE OverloadedLists #-}

-- | Types for stored procedures.
module Hasura.StoredProcedure.Types
  ( NullableScalarType (..),
    nullableScalarTypeMapCodec,
    StoredProcedureConfig (..),
    StoredProcedureExposedAs (..),
  )
where

import Autodocodec (HasCodec (codec))
import Autodocodec qualified as AC
import Autodocodec.Extended (graphQLFieldNameCodec)
import Data.Aeson
import Data.Char (toLower)
import Hasura.LogicalModel.NullableScalarType
import Hasura.Prelude hiding (first)
import Language.GraphQL.Draft.Syntax qualified as G

-- | Tracked stored procedure configuration, and payload of the 'pg_track_stored procedure'.
data StoredProcedureConfig = StoredProcedureConfig
  { -- | In which top-level field should we expose this stored procedure?
    StoredProcedureConfig -> StoredProcedureExposedAs
_spcExposedAs :: StoredProcedureExposedAs,
    StoredProcedureConfig -> Maybe Name
_spcCustomName :: Maybe G.Name
  }
  deriving (Int -> StoredProcedureConfig -> ShowS
[StoredProcedureConfig] -> ShowS
StoredProcedureConfig -> String
(Int -> StoredProcedureConfig -> ShowS)
-> (StoredProcedureConfig -> String)
-> ([StoredProcedureConfig] -> ShowS)
-> Show StoredProcedureConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StoredProcedureConfig -> ShowS
showsPrec :: Int -> StoredProcedureConfig -> ShowS
$cshow :: StoredProcedureConfig -> String
show :: StoredProcedureConfig -> String
$cshowList :: [StoredProcedureConfig] -> ShowS
showList :: [StoredProcedureConfig] -> ShowS
Show, StoredProcedureConfig -> StoredProcedureConfig -> Bool
(StoredProcedureConfig -> StoredProcedureConfig -> Bool)
-> (StoredProcedureConfig -> StoredProcedureConfig -> Bool)
-> Eq StoredProcedureConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StoredProcedureConfig -> StoredProcedureConfig -> Bool
== :: StoredProcedureConfig -> StoredProcedureConfig -> Bool
$c/= :: StoredProcedureConfig -> StoredProcedureConfig -> Bool
/= :: StoredProcedureConfig -> StoredProcedureConfig -> Bool
Eq, (forall x. StoredProcedureConfig -> Rep StoredProcedureConfig x)
-> (forall x. Rep StoredProcedureConfig x -> StoredProcedureConfig)
-> Generic StoredProcedureConfig
forall x. Rep StoredProcedureConfig x -> StoredProcedureConfig
forall x. StoredProcedureConfig -> Rep StoredProcedureConfig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StoredProcedureConfig -> Rep StoredProcedureConfig x
from :: forall x. StoredProcedureConfig -> Rep StoredProcedureConfig x
$cto :: forall x. Rep StoredProcedureConfig x -> StoredProcedureConfig
to :: forall x. Rep StoredProcedureConfig x -> StoredProcedureConfig
Generic)

instance NFData StoredProcedureConfig

instance HasCodec StoredProcedureConfig where
  codec :: JSONCodec StoredProcedureConfig
codec =
    Text
-> ObjectCodec StoredProcedureConfig StoredProcedureConfig
-> JSONCodec StoredProcedureConfig
forall input output.
Text -> ObjectCodec input output -> ValueCodec input output
AC.object Text
"StoredProcedureConfig"
      (ObjectCodec StoredProcedureConfig StoredProcedureConfig
 -> JSONCodec StoredProcedureConfig)
-> ObjectCodec StoredProcedureConfig StoredProcedureConfig
-> JSONCodec StoredProcedureConfig
forall a b. (a -> b) -> a -> b
$ StoredProcedureExposedAs -> Maybe Name -> StoredProcedureConfig
StoredProcedureConfig
      (StoredProcedureExposedAs -> Maybe Name -> StoredProcedureConfig)
-> Codec Object StoredProcedureConfig StoredProcedureExposedAs
-> Codec
     Object StoredProcedureConfig (Maybe Name -> StoredProcedureConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> ObjectCodec StoredProcedureExposedAs StoredProcedureExposedAs
forall output. HasCodec output => Text -> ObjectCodec output output
AC.requiredField' Text
"exposed_as"
      ObjectCodec StoredProcedureExposedAs StoredProcedureExposedAs
-> (StoredProcedureConfig -> StoredProcedureExposedAs)
-> Codec Object StoredProcedureConfig StoredProcedureExposedAs
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= StoredProcedureConfig -> StoredProcedureExposedAs
_spcExposedAs
        Codec
  Object StoredProcedureConfig (Maybe Name -> StoredProcedureConfig)
-> Codec Object StoredProcedureConfig (Maybe Name)
-> ObjectCodec StoredProcedureConfig StoredProcedureConfig
forall a b.
Codec Object StoredProcedureConfig (a -> b)
-> Codec Object StoredProcedureConfig a
-> Codec Object StoredProcedureConfig b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text
-> ValueCodec Name Name -> ObjectCodec (Maybe Name) (Maybe Name)
forall input output.
Text
-> ValueCodec input output
-> ObjectCodec (Maybe input) (Maybe output)
AC.optionalFieldWith' Text
"custom_name" ValueCodec Name Name
graphQLFieldNameCodec
      ObjectCodec (Maybe Name) (Maybe Name)
-> (StoredProcedureConfig -> Maybe Name)
-> Codec Object StoredProcedureConfig (Maybe Name)
forall oldInput output newInput.
ObjectCodec oldInput output
-> (newInput -> oldInput) -> ObjectCodec newInput output
AC..= StoredProcedureConfig -> Maybe Name
_spcCustomName

instance FromJSON StoredProcedureConfig where
  parseJSON :: Value -> Parser StoredProcedureConfig
parseJSON = String
-> (Object -> Parser StoredProcedureConfig)
-> Value
-> Parser StoredProcedureConfig
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"StoredProcedureConfig" ((Object -> Parser StoredProcedureConfig)
 -> Value -> Parser StoredProcedureConfig)
-> (Object -> Parser StoredProcedureConfig)
-> Value
-> Parser StoredProcedureConfig
forall a b. (a -> b) -> a -> b
$ \Object
obj ->
    StoredProcedureExposedAs -> Maybe Name -> StoredProcedureConfig
StoredProcedureConfig
      (StoredProcedureExposedAs -> Maybe Name -> StoredProcedureConfig)
-> Parser StoredProcedureExposedAs
-> Parser (Maybe Name -> StoredProcedureConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj
      Object -> Key -> Parser StoredProcedureExposedAs
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"exposed_as"
      Parser (Maybe Name -> StoredProcedureConfig)
-> Parser (Maybe Name) -> Parser StoredProcedureConfig
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
obj
      Object -> Key -> Parser (Maybe Name)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"custom_name"

instance ToJSON StoredProcedureConfig where
  toJSON :: StoredProcedureConfig -> Value
toJSON = Options -> StoredProcedureConfig -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
hasuraJSON {omitNothingFields :: Bool
omitNothingFields = Bool
True}
  toEncoding :: StoredProcedureConfig -> Encoding
toEncoding = Options -> StoredProcedureConfig -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
hasuraJSON {omitNothingFields :: Bool
omitNothingFields = Bool
True}

-- | Indicates whether the user requested the corresponding stored procedure to be
-- tracked as a mutation or a query, in @track_stored_procedure@.
-- currently only query is supported.
data StoredProcedureExposedAs = SPEAQuery
  deriving (Int -> StoredProcedureExposedAs -> ShowS
[StoredProcedureExposedAs] -> ShowS
StoredProcedureExposedAs -> String
(Int -> StoredProcedureExposedAs -> ShowS)
-> (StoredProcedureExposedAs -> String)
-> ([StoredProcedureExposedAs] -> ShowS)
-> Show StoredProcedureExposedAs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StoredProcedureExposedAs -> ShowS
showsPrec :: Int -> StoredProcedureExposedAs -> ShowS
$cshow :: StoredProcedureExposedAs -> String
show :: StoredProcedureExposedAs -> String
$cshowList :: [StoredProcedureExposedAs] -> ShowS
showList :: [StoredProcedureExposedAs] -> ShowS
Show, StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool
(StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool)
-> (StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool)
-> Eq StoredProcedureExposedAs
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool
== :: StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool
$c/= :: StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool
/= :: StoredProcedureExposedAs -> StoredProcedureExposedAs -> Bool
Eq, (forall x.
 StoredProcedureExposedAs -> Rep StoredProcedureExposedAs x)
-> (forall x.
    Rep StoredProcedureExposedAs x -> StoredProcedureExposedAs)
-> Generic StoredProcedureExposedAs
forall x.
Rep StoredProcedureExposedAs x -> StoredProcedureExposedAs
forall x.
StoredProcedureExposedAs -> Rep StoredProcedureExposedAs x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x.
StoredProcedureExposedAs -> Rep StoredProcedureExposedAs x
from :: forall x.
StoredProcedureExposedAs -> Rep StoredProcedureExposedAs x
$cto :: forall x.
Rep StoredProcedureExposedAs x -> StoredProcedureExposedAs
to :: forall x.
Rep StoredProcedureExposedAs x -> StoredProcedureExposedAs
Generic)

instance NFData StoredProcedureExposedAs

instance HasCodec StoredProcedureExposedAs where
  codec :: JSONCodec StoredProcedureExposedAs
codec = NonEmpty (StoredProcedureExposedAs, Text)
-> JSONCodec StoredProcedureExposedAs
forall constant.
Eq constant =>
NonEmpty (constant, Text) -> JSONCodec constant
AC.stringConstCodec [(StoredProcedureExposedAs
SPEAQuery, Text
"query")]

instance FromJSON StoredProcedureExposedAs where
  parseJSON :: Value -> Parser StoredProcedureExposedAs
parseJSON = Options -> Value -> Parser StoredProcedureExposedAs
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions {sumEncoding :: SumEncoding
sumEncoding = SumEncoding
UntaggedValue, constructorTagModifier :: ShowS
constructorTagModifier = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4}

instance ToJSON StoredProcedureExposedAs where
  toJSON :: StoredProcedureExposedAs -> Value
toJSON = Options -> StoredProcedureExposedAs -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions {sumEncoding :: SumEncoding
sumEncoding = SumEncoding
UntaggedValue, constructorTagModifier :: ShowS
constructorTagModifier = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4}
  toEncoding :: StoredProcedureExposedAs -> Encoding
toEncoding = Options -> StoredProcedureExposedAs -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
genericToEncoding Options
defaultOptions {sumEncoding :: SumEncoding
sumEncoding = SumEncoding
UntaggedValue, constructorTagModifier :: ShowS
constructorTagModifier = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4}