{-# LANGUAGE TemplateHaskell #-}

module Hasura.RQL.Types.Relationships.Local
  ( ArrRelDef,
    ArrRelUsing,
    ArrRelUsingFKeyOn (..),
    Nullable (..),
    ObjRelDef,
    ObjRelUsing,
    ObjRelUsingChoice (..),
    RelDef (..),
    RelInfo (..),
    RelManualConfig (..),
    RelUsing (..),
    WithTable (..),
    boolToNullable,
    fromRel,
    rdComment,
    rdName,
    rdUsing,
  )
where

import Control.Lens (makeLenses)
import Data.Aeson.KeyMap qualified as KM
import Data.Aeson.TH
import Data.Aeson.Types
import Data.Text qualified as T
import Hasura.Incremental (Cacheable)
import Hasura.Prelude
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Common
import Hasura.SQL.Backend

data RelDef a = RelDef
  { RelDef a -> RelName
_rdName :: RelName,
    RelDef a -> a
_rdUsing :: a,
    RelDef a -> Maybe Text
_rdComment :: Maybe T.Text
  }
  deriving (Int -> RelDef a -> ShowS
[RelDef a] -> ShowS
RelDef a -> String
(Int -> RelDef a -> ShowS)
-> (RelDef a -> String) -> ([RelDef a] -> ShowS) -> Show (RelDef a)
forall a. Show a => Int -> RelDef a -> ShowS
forall a. Show a => [RelDef a] -> ShowS
forall a. Show a => RelDef a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RelDef a] -> ShowS
$cshowList :: forall a. Show a => [RelDef a] -> ShowS
show :: RelDef a -> String
$cshow :: forall a. Show a => RelDef a -> String
showsPrec :: Int -> RelDef a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> RelDef a -> ShowS
Show, RelDef a -> RelDef a -> Bool
(RelDef a -> RelDef a -> Bool)
-> (RelDef a -> RelDef a -> Bool) -> Eq (RelDef a)
forall a. Eq a => RelDef a -> RelDef a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RelDef a -> RelDef a -> Bool
$c/= :: forall a. Eq a => RelDef a -> RelDef a -> Bool
== :: RelDef a -> RelDef a -> Bool
$c== :: forall a. Eq a => RelDef a -> RelDef a -> Bool
Eq, (forall x. RelDef a -> Rep (RelDef a) x)
-> (forall x. Rep (RelDef a) x -> RelDef a) -> Generic (RelDef a)
forall x. Rep (RelDef a) x -> RelDef a
forall x. RelDef a -> Rep (RelDef a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (RelDef a) x -> RelDef a
forall a x. RelDef a -> Rep (RelDef a) x
$cto :: forall a x. Rep (RelDef a) x -> RelDef a
$cfrom :: forall a x. RelDef a -> Rep (RelDef a) x
Generic)

instance (Cacheable a) => Cacheable (RelDef a)

$(deriveFromJSON hasuraJSON {omitNothingFields = True} ''RelDef)
$(makeLenses ''RelDef)

instance (ToJSON a) => ToJSON (RelDef a) where
  toJSON :: RelDef a -> Value
toJSON = [Pair] -> Value
object ([Pair] -> Value) -> (RelDef a -> [Pair]) -> RelDef a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RelDef a -> [Pair]
forall a v. (ToAesonPairs a, KeyValue v) => a -> [v]
toAesonPairs

instance (ToJSON a) => ToAesonPairs (RelDef a) where
  toAesonPairs :: RelDef a -> [v]
toAesonPairs (RelDef RelName
rn a
ru Maybe Text
rc) =
    [ Key
"name" Key -> RelName -> v
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= RelName
rn,
      Key
"using" Key -> a -> v
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= a
ru,
      Key
"comment" Key -> Maybe Text -> v
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe Text
rc
    ]

data RelManualConfig (b :: BackendType) = RelManualConfig
  { RelManualConfig b -> TableName b
rmTable :: TableName b,
    RelManualConfig b -> HashMap (Column b) (Column b)
rmColumns :: HashMap (Column b) (Column b),
    RelManualConfig b -> Maybe InsertOrder
rmInsertOrder :: Maybe InsertOrder
  }
  deriving ((forall x. RelManualConfig b -> Rep (RelManualConfig b) x)
-> (forall x. Rep (RelManualConfig b) x -> RelManualConfig b)
-> Generic (RelManualConfig b)
forall x. Rep (RelManualConfig b) x -> RelManualConfig b
forall x. RelManualConfig b -> Rep (RelManualConfig b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (RelManualConfig b) x -> RelManualConfig b
forall (b :: BackendType) x.
RelManualConfig b -> Rep (RelManualConfig b) x
$cto :: forall (b :: BackendType) x.
Rep (RelManualConfig b) x -> RelManualConfig b
$cfrom :: forall (b :: BackendType) x.
RelManualConfig b -> Rep (RelManualConfig b) x
Generic)

deriving instance Backend b => Eq (RelManualConfig b)

deriving instance Backend b => Show (RelManualConfig b)

instance (Backend b) => Cacheable (RelManualConfig b)

instance (Backend b) => FromJSON (RelManualConfig b) where
  parseJSON :: Value -> Parser (RelManualConfig b)
parseJSON (Object Object
v) =
    TableName b
-> HashMap (Column b) (Column b)
-> Maybe InsertOrder
-> RelManualConfig b
forall (b :: BackendType).
TableName b
-> HashMap (Column b) (Column b)
-> Maybe InsertOrder
-> RelManualConfig b
RelManualConfig
      (TableName b
 -> HashMap (Column b) (Column b)
 -> Maybe InsertOrder
 -> RelManualConfig b)
-> Parser (TableName b)
-> Parser
     (HashMap (Column b) (Column b)
      -> Maybe InsertOrder -> RelManualConfig b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser (TableName b)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"remote_table"
      Parser
  (HashMap (Column b) (Column b)
   -> Maybe InsertOrder -> RelManualConfig b)
-> Parser (HashMap (Column b) (Column b))
-> Parser (Maybe InsertOrder -> RelManualConfig b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (HashMap (Column b) (Column b))
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"column_mapping"
      Parser (Maybe InsertOrder -> RelManualConfig b)
-> Parser (Maybe InsertOrder) -> Parser (RelManualConfig b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe InsertOrder)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"insertion_order"
  parseJSON Value
_ =
    String -> Parser (RelManualConfig b)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"manual_configuration should be an object"

instance (Backend b) => ToJSON (RelManualConfig b) where
  toJSON :: RelManualConfig b -> Value
toJSON (RelManualConfig TableName b
qt HashMap (Column b) (Column b)
cm Maybe InsertOrder
io) =
    [Pair] -> Value
object
      [ Key
"remote_table" Key -> TableName b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= TableName b
qt,
        Key
"column_mapping" Key -> HashMap (Column b) (Column b) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= HashMap (Column b) (Column b)
cm,
        Key
"insertion_order" Key -> Maybe InsertOrder -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Maybe InsertOrder
io
      ]

data RelUsing (b :: BackendType) a
  = RUFKeyOn a
  | RUManual (RelManualConfig b)
  deriving (Int -> RelUsing b a -> ShowS
[RelUsing b a] -> ShowS
RelUsing b a -> String
(Int -> RelUsing b a -> ShowS)
-> (RelUsing b a -> String)
-> ([RelUsing b a] -> ShowS)
-> Show (RelUsing b a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (b :: BackendType) a.
(Backend b, Show a) =>
Int -> RelUsing b a -> ShowS
forall (b :: BackendType) a.
(Backend b, Show a) =>
[RelUsing b a] -> ShowS
forall (b :: BackendType) a.
(Backend b, Show a) =>
RelUsing b a -> String
showList :: [RelUsing b a] -> ShowS
$cshowList :: forall (b :: BackendType) a.
(Backend b, Show a) =>
[RelUsing b a] -> ShowS
show :: RelUsing b a -> String
$cshow :: forall (b :: BackendType) a.
(Backend b, Show a) =>
RelUsing b a -> String
showsPrec :: Int -> RelUsing b a -> ShowS
$cshowsPrec :: forall (b :: BackendType) a.
(Backend b, Show a) =>
Int -> RelUsing b a -> ShowS
Show, RelUsing b a -> RelUsing b a -> Bool
(RelUsing b a -> RelUsing b a -> Bool)
-> (RelUsing b a -> RelUsing b a -> Bool) -> Eq (RelUsing b a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (b :: BackendType) a.
(Backend b, Eq a) =>
RelUsing b a -> RelUsing b a -> Bool
/= :: RelUsing b a -> RelUsing b a -> Bool
$c/= :: forall (b :: BackendType) a.
(Backend b, Eq a) =>
RelUsing b a -> RelUsing b a -> Bool
== :: RelUsing b a -> RelUsing b a -> Bool
$c== :: forall (b :: BackendType) a.
(Backend b, Eq a) =>
RelUsing b a -> RelUsing b a -> Bool
Eq, (forall x. RelUsing b a -> Rep (RelUsing b a) x)
-> (forall x. Rep (RelUsing b a) x -> RelUsing b a)
-> Generic (RelUsing b a)
forall x. Rep (RelUsing b a) x -> RelUsing b a
forall x. RelUsing b a -> Rep (RelUsing b a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) a x. Rep (RelUsing b a) x -> RelUsing b a
forall (b :: BackendType) a x. RelUsing b a -> Rep (RelUsing b a) x
$cto :: forall (b :: BackendType) a x. Rep (RelUsing b a) x -> RelUsing b a
$cfrom :: forall (b :: BackendType) a x. RelUsing b a -> Rep (RelUsing b a) x
Generic)

instance (Backend b, Cacheable a) => Cacheable (RelUsing b a)

instance (Backend b, ToJSON a) => ToJSON (RelUsing b a) where
  toJSON :: RelUsing b a -> Value
toJSON (RUFKeyOn a
fkey) =
    [Pair] -> Value
object [Key
"foreign_key_constraint_on" Key -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= a
fkey]
  toJSON (RUManual RelManualConfig b
manual) =
    [Pair] -> Value
object [Key
"manual_configuration" Key -> RelManualConfig b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= RelManualConfig b
manual]

instance (FromJSON a, Backend b) => FromJSON (RelUsing b a) where
  parseJSON :: Value -> Parser (RelUsing b a)
parseJSON (Object Object
o) = do
    let fkeyOnM :: Maybe Value
fkeyOnM = Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"foreign_key_constraint_on" Object
o
        manualM :: Maybe Value
manualM = Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"manual_configuration" Object
o
        msgFrag :: String
msgFrag = String
"one of foreign_key_constraint_on/manual_configuration should be present"
    case (Maybe Value
fkeyOnM, Maybe Value
manualM) of
      (Maybe Value
Nothing, Maybe Value
Nothing) -> String -> Parser (RelUsing b a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser (RelUsing b a))
-> String -> Parser (RelUsing b a)
forall a b. (a -> b) -> a -> b
$ String
"atleast " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
msgFrag
      (Just Value
a, Maybe Value
Nothing) -> a -> RelUsing b a
forall (b :: BackendType) a. a -> RelUsing b a
RUFKeyOn (a -> RelUsing b a) -> Parser a -> Parser (RelUsing b a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
forall a. FromJSON a => Value -> Parser a
parseJSON Value
a
      (Maybe Value
Nothing, Just Value
b) -> RelManualConfig b -> RelUsing b a
forall (b :: BackendType) a. RelManualConfig b -> RelUsing b a
RUManual (RelManualConfig b -> RelUsing b a)
-> Parser (RelManualConfig b) -> Parser (RelUsing b a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (RelManualConfig b)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
b
      (Maybe Value, Maybe Value)
_ -> String -> Parser (RelUsing b a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser (RelUsing b a))
-> String -> Parser (RelUsing b a)
forall a b. (a -> b) -> a -> b
$ String
"only " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
msgFrag
  parseJSON Value
_ =
    String -> Parser (RelUsing b a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"using should be an object"

data ArrRelUsingFKeyOn (b :: BackendType) = ArrRelUsingFKeyOn
  { ArrRelUsingFKeyOn b -> TableName b
arufTable :: TableName b,
    ArrRelUsingFKeyOn b -> NonEmpty (Column b)
arufColumns :: NonEmpty (Column b)
  }
  deriving ((forall x. ArrRelUsingFKeyOn b -> Rep (ArrRelUsingFKeyOn b) x)
-> (forall x. Rep (ArrRelUsingFKeyOn b) x -> ArrRelUsingFKeyOn b)
-> Generic (ArrRelUsingFKeyOn b)
forall x. Rep (ArrRelUsingFKeyOn b) x -> ArrRelUsingFKeyOn b
forall x. ArrRelUsingFKeyOn b -> Rep (ArrRelUsingFKeyOn b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (ArrRelUsingFKeyOn b) x -> ArrRelUsingFKeyOn b
forall (b :: BackendType) x.
ArrRelUsingFKeyOn b -> Rep (ArrRelUsingFKeyOn b) x
$cto :: forall (b :: BackendType) x.
Rep (ArrRelUsingFKeyOn b) x -> ArrRelUsingFKeyOn b
$cfrom :: forall (b :: BackendType) x.
ArrRelUsingFKeyOn b -> Rep (ArrRelUsingFKeyOn b) x
Generic)

deriving instance Backend b => Eq (ArrRelUsingFKeyOn b)

deriving instance Backend b => Show (ArrRelUsingFKeyOn b)

instance Backend b => Cacheable (ArrRelUsingFKeyOn b)

-- TODO: This has to move to a common module
data WithTable b a = WithTable
  { WithTable b a -> SourceName
wtSource :: SourceName,
    WithTable b a -> TableName b
wtName :: TableName b,
    WithTable b a -> a
wtInfo :: a
  }

deriving instance (Backend b, Show a) => Show (WithTable b a)

deriving instance (Backend b, Eq a) => Eq (WithTable b a)

instance (FromJSON a, Backend b) => FromJSON (WithTable b a) where
  parseJSON :: Value -> Parser (WithTable b a)
parseJSON v :: Value
v@(Object Object
o) =
    SourceName -> TableName b -> a -> WithTable b a
forall (b :: BackendType) a.
SourceName -> TableName b -> a -> WithTable b a
WithTable
      (SourceName -> TableName b -> a -> WithTable b a)
-> Parser SourceName -> Parser (TableName b -> a -> WithTable b a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser (Maybe SourceName)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"source" Parser (Maybe SourceName) -> SourceName -> Parser SourceName
forall a. Parser (Maybe a) -> a -> Parser a
.!= SourceName
defaultSource
      Parser (TableName b -> a -> WithTable b a)
-> Parser (TableName b) -> Parser (a -> WithTable b a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (TableName b)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"table"
      Parser (a -> WithTable b a) -> Parser a -> Parser (WithTable b a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Value -> Parser a
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
  parseJSON Value
_ =
    String -> Parser (WithTable b a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expecting an Object with key 'table'"

instance (ToAesonPairs a, Backend b) => ToJSON (WithTable b a) where
  toJSON :: WithTable b a -> Value
toJSON (WithTable SourceName
sourceName TableName b
tn a
rel) =
    [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ (Key
"source" Key -> SourceName -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= SourceName
sourceName) Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
: (Key
"table" Key -> TableName b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= TableName b
tn) Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
: a -> [Pair]
forall a v. (ToAesonPairs a, KeyValue v) => a -> [v]
toAesonPairs a
rel

data ObjRelUsingChoice b
  = SameTable (NonEmpty (Column b))
  | RemoteTable (TableName b) (NonEmpty (Column b))
  deriving ((forall x. ObjRelUsingChoice b -> Rep (ObjRelUsingChoice b) x)
-> (forall x. Rep (ObjRelUsingChoice b) x -> ObjRelUsingChoice b)
-> Generic (ObjRelUsingChoice b)
forall x. Rep (ObjRelUsingChoice b) x -> ObjRelUsingChoice b
forall x. ObjRelUsingChoice b -> Rep (ObjRelUsingChoice b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x.
Rep (ObjRelUsingChoice b) x -> ObjRelUsingChoice b
forall (b :: BackendType) x.
ObjRelUsingChoice b -> Rep (ObjRelUsingChoice b) x
$cto :: forall (b :: BackendType) x.
Rep (ObjRelUsingChoice b) x -> ObjRelUsingChoice b
$cfrom :: forall (b :: BackendType) x.
ObjRelUsingChoice b -> Rep (ObjRelUsingChoice b) x
Generic)

deriving instance Backend b => Eq (ObjRelUsingChoice b)

deriving instance Backend b => Show (ObjRelUsingChoice b)

instance (Backend b) => Cacheable (ObjRelUsingChoice b)

instance (Backend b) => ToJSON (ObjRelUsingChoice b) where
  toJSON :: ObjRelUsingChoice b -> Value
toJSON = \case
    SameTable (Column b
col :| []) -> Column b -> Value
forall a. ToJSON a => a -> Value
toJSON Column b
col
    SameTable NonEmpty (Column b)
cols -> NonEmpty (Column b) -> Value
forall a. ToJSON a => a -> Value
toJSON NonEmpty (Column b)
cols
    RemoteTable TableName b
qt (Column b
lcol :| []) ->
      [Pair] -> Value
object
        [ Key
"table" Key -> TableName b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= TableName b
qt,
          Key
"column" Key -> Column b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Column b
lcol
        ]
    RemoteTable TableName b
qt NonEmpty (Column b)
lcols ->
      [Pair] -> Value
object
        [ Key
"table" Key -> TableName b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= TableName b
qt,
          Key
"columns" Key -> NonEmpty (Column b) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= NonEmpty (Column b)
lcols
        ]

instance (Backend b) => FromJSON (ObjRelUsingChoice b) where
  parseJSON :: Value -> Parser (ObjRelUsingChoice b)
parseJSON = \case
    Object Object
o -> do
      TableName b
table <- Object
o Object -> Key -> Parser (TableName b)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"table"
      Maybe Value
column <- Object
o Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"column"
      Maybe Value
columns <- Object
o Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"columns"
      NonEmpty (Column b)
cols <- case (Maybe Value
column, Maybe Value
columns) of
        (Just Value
col, Maybe Value
Nothing) -> Value -> Parser (NonEmpty (Column b))
parseColumns Value
col
        (Maybe Value
Nothing, Just Value
cols) -> Value -> Parser (NonEmpty (Column b))
parseColumns Value
cols
        (Maybe Value, Maybe Value)
_ -> String -> Parser (NonEmpty (Column b))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected exactly one of 'column' or 'columns'"
      ObjRelUsingChoice b -> Parser (ObjRelUsingChoice b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ObjRelUsingChoice b -> Parser (ObjRelUsingChoice b))
-> ObjRelUsingChoice b -> Parser (ObjRelUsingChoice b)
forall a b. (a -> b) -> a -> b
$ TableName b -> NonEmpty (Column b) -> ObjRelUsingChoice b
forall (b :: BackendType).
TableName b -> NonEmpty (Column b) -> ObjRelUsingChoice b
RemoteTable TableName b
table NonEmpty (Column b)
cols
    Value
val -> NonEmpty (Column b) -> ObjRelUsingChoice b
forall (b :: BackendType).
NonEmpty (Column b) -> ObjRelUsingChoice b
SameTable (NonEmpty (Column b) -> ObjRelUsingChoice b)
-> Parser (NonEmpty (Column b)) -> Parser (ObjRelUsingChoice b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (NonEmpty (Column b))
parseColumns Value
val
    where
      parseColumns :: Value -> Parser (NonEmpty (Column b))
      parseColumns :: Value -> Parser (NonEmpty (Column b))
parseColumns = \case
        v :: Value
v@(String Text
_) -> Column b -> NonEmpty (Column b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Column b -> NonEmpty (Column b))
-> Parser (Column b) -> Parser (NonEmpty (Column b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Column b)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
        v :: Value
v@(Array Array
_) -> Value -> Parser (NonEmpty (Column b))
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
        Value
_ -> String -> Parser (NonEmpty (Column b))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected string or array"

instance (Backend b) => ToJSON (ArrRelUsingFKeyOn b) where
  toJSON :: ArrRelUsingFKeyOn b -> Value
toJSON ArrRelUsingFKeyOn {arufTable :: forall (b :: BackendType). ArrRelUsingFKeyOn b -> TableName b
arufTable = TableName b
_arufTable, arufColumns :: forall (b :: BackendType).
ArrRelUsingFKeyOn b -> NonEmpty (Column b)
arufColumns = NonEmpty (Column b)
_arufColumns} =
    [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
      (Key
"table" Key -> TableName b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= TableName b
_arufTable) Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
:
      case NonEmpty (Column b)
_arufColumns of
        Column b
col :| [] -> [Key
"column" Key -> Column b -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= Column b
col]
        NonEmpty (Column b)
cols -> [Key
"columns" Key -> NonEmpty (Column b) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= NonEmpty (Column b)
cols]

instance (Backend b) => FromJSON (ArrRelUsingFKeyOn b) where
  parseJSON :: Value -> Parser (ArrRelUsingFKeyOn b)
parseJSON = \case
    Object Object
o -> do
      TableName b
table <- Object
o Object -> Key -> Parser (TableName b)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"table"
      Maybe Value
column <- Object
o Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"column"
      Maybe Value
columns <- Object
o Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"columns"
      NonEmpty (Column b)
cols <- case (Maybe Value
column, Maybe Value
columns) of
        (Just Value
col, Maybe Value
Nothing) -> Value -> Parser (NonEmpty (Column b))
parseColumns Value
col
        (Maybe Value
Nothing, Just Value
cols) -> Value -> Parser (NonEmpty (Column b))
parseColumns Value
cols
        (Maybe Value, Maybe Value)
_ -> String -> Parser (NonEmpty (Column b))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected exactly one of 'column' or 'columns'"
      ArrRelUsingFKeyOn b -> Parser (ArrRelUsingFKeyOn b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ArrRelUsingFKeyOn b -> Parser (ArrRelUsingFKeyOn b))
-> ArrRelUsingFKeyOn b -> Parser (ArrRelUsingFKeyOn b)
forall a b. (a -> b) -> a -> b
$ TableName b -> NonEmpty (Column b) -> ArrRelUsingFKeyOn b
forall (b :: BackendType).
TableName b -> NonEmpty (Column b) -> ArrRelUsingFKeyOn b
ArrRelUsingFKeyOn TableName b
table NonEmpty (Column b)
cols
    Value
_ -> String -> Parser (ArrRelUsingFKeyOn b)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expecting object { table, columns }."
    where
      parseColumns :: Value -> Parser (NonEmpty (Column b))
      parseColumns :: Value -> Parser (NonEmpty (Column b))
parseColumns = \case
        v :: Value
v@(String Text
_) -> Column b -> NonEmpty (Column b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Column b -> NonEmpty (Column b))
-> Parser (Column b) -> Parser (NonEmpty (Column b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Column b)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
        v :: Value
v@(Array Array
_) -> Value -> Parser (NonEmpty (Column b))
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v
        Value
_ -> String -> Parser (NonEmpty (Column b))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected string or array"

type ArrRelUsing b = RelUsing b (ArrRelUsingFKeyOn b)

type ArrRelDef b = RelDef (ArrRelUsing b)

type ObjRelUsing b = RelUsing b (ObjRelUsingChoice b)

type ObjRelDef b = RelDef (ObjRelUsing b)

data RelInfo (b :: BackendType) = RelInfo
  { RelInfo b -> RelName
riName :: RelName,
    RelInfo b -> RelType
riType :: RelType,
    RelInfo b -> HashMap (Column b) (Column b)
riMapping :: HashMap (Column b) (Column b),
    RelInfo b -> TableName b
riRTable :: TableName b,
    RelInfo b -> Bool
riIsManual :: Bool,
    RelInfo b -> InsertOrder
riInsertOrder :: InsertOrder
  }
  deriving ((forall x. RelInfo b -> Rep (RelInfo b) x)
-> (forall x. Rep (RelInfo b) x -> RelInfo b)
-> Generic (RelInfo b)
forall x. Rep (RelInfo b) x -> RelInfo b
forall x. RelInfo b -> Rep (RelInfo b) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (b :: BackendType) x. Rep (RelInfo b) x -> RelInfo b
forall (b :: BackendType) x. RelInfo b -> Rep (RelInfo b) x
$cto :: forall (b :: BackendType) x. Rep (RelInfo b) x -> RelInfo b
$cfrom :: forall (b :: BackendType) x. RelInfo b -> Rep (RelInfo b) x
Generic)

deriving instance Backend b => Show (RelInfo b)

deriving instance Backend b => Eq (RelInfo b)

instance Backend b => NFData (RelInfo b)

instance Backend b => Cacheable (RelInfo b)

instance Backend b => Hashable (RelInfo b)

instance (Backend b) => FromJSON (RelInfo b) where
  parseJSON :: Value -> Parser (RelInfo b)
parseJSON = Options -> Value -> Parser (RelInfo b)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
hasuraJSON

instance (Backend b) => ToJSON (RelInfo b) where
  toJSON :: RelInfo b -> Value
toJSON = Options -> RelInfo b -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
hasuraJSON

data Nullable = Nullable | NotNullable
  deriving (Nullable -> Nullable -> Bool
(Nullable -> Nullable -> Bool)
-> (Nullable -> Nullable -> Bool) -> Eq Nullable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Nullable -> Nullable -> Bool
$c/= :: Nullable -> Nullable -> Bool
== :: Nullable -> Nullable -> Bool
$c== :: Nullable -> Nullable -> Bool
Eq, Int -> Nullable -> ShowS
[Nullable] -> ShowS
Nullable -> String
(Int -> Nullable -> ShowS)
-> (Nullable -> String) -> ([Nullable] -> ShowS) -> Show Nullable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Nullable] -> ShowS
$cshowList :: [Nullable] -> ShowS
show :: Nullable -> String
$cshow :: Nullable -> String
showsPrec :: Int -> Nullable -> ShowS
$cshowsPrec :: Int -> Nullable -> ShowS
Show, (forall x. Nullable -> Rep Nullable x)
-> (forall x. Rep Nullable x -> Nullable) -> Generic Nullable
forall x. Rep Nullable x -> Nullable
forall x. Nullable -> Rep Nullable x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Nullable x -> Nullable
$cfrom :: forall x. Nullable -> Rep Nullable x
Generic)

instance NFData Nullable

instance Cacheable Nullable

instance Hashable Nullable

boolToNullable :: Bool -> Nullable
boolToNullable :: Bool -> Nullable
boolToNullable Bool
True = Nullable
Nullable
boolToNullable Bool
False = Nullable
NotNullable

instance FromJSON Nullable where
  parseJSON :: Value -> Parser Nullable
parseJSON = (Bool -> Nullable) -> Parser Bool -> Parser Nullable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> Nullable
boolToNullable (Parser Bool -> Parser Nullable)
-> (Value -> Parser Bool) -> Value -> Parser Nullable
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Bool
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToJSON Nullable where
  toJSON :: Nullable -> Value
toJSON =
    Bool -> Value
forall a. ToJSON a => a -> Value
toJSON (Bool -> Value) -> (Nullable -> Bool) -> Nullable -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
      Nullable
Nullable -> Bool
True
      Nullable
NotNullable -> Bool
False

fromRel :: RelName -> FieldName
fromRel :: RelName -> FieldName
fromRel = Text -> FieldName
FieldName (Text -> FieldName) -> (RelName -> Text) -> RelName -> FieldName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RelName -> Text
relNameToTxt