{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE TemplateHaskellQuotes #-}

-- | Generate the GraphQL schema types related to streaming subscriptions.
module Hasura.GraphQL.Schema.SubscriptionStream
  ( selectStreamTable,
  )
where

import Control.Lens ((^?), _1)
import Control.Monad.Memoize
import Data.Has
import Data.List.NonEmpty qualified as NE
import Data.Text.Casing (GQLNameIdentifier)
import Data.Text.Extended ((<>>))
import Hasura.GraphQL.Parser.Class
import Hasura.GraphQL.Schema.Backend
import Hasura.GraphQL.Schema.BoolExp (AggregationPredicatesSchema)
import Hasura.GraphQL.Schema.Common
import Hasura.GraphQL.Schema.Parser
  ( InputFieldsParser,
    Kind (..),
    Parser,
  )
import Hasura.GraphQL.Schema.Parser qualified as P
import Hasura.GraphQL.Schema.Select (tablePermissionsInfo, tableSelectionList, tableWhereArg)
import Hasura.GraphQL.Schema.Table (getTableGQLName, getTableIdentifierName, tableSelectColumns, tableSelectPermissions)
import Hasura.GraphQL.Schema.Typename
import Hasura.Name qualified as Name
import Hasura.Prelude
import Hasura.RQL.IR.Select qualified as IR
import Hasura.RQL.IR.Value qualified as IR
import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Metadata.Object
import Hasura.RQL.Types.NamingCase
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.RQL.Types.SchemaCache
import Hasura.RQL.Types.Source
import Hasura.RQL.Types.SourceCustomization
import Hasura.RQL.Types.Subscription
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Table.Cache
import Language.GraphQL.Draft.Syntax qualified as G

-- | Argument to limit the maximum number of results returned in a single batch.
cursorBatchSizeArg ::
  forall n.
  (MonadParse n) =>
  NamingCase ->
  InputFieldsParser n Int
cursorBatchSizeArg :: forall (n :: * -> *).
MonadParse n =>
NamingCase -> InputFieldsParser n Int
cursorBatchSizeArg NamingCase
tCase =
  Int32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    (Int32 -> Int)
-> InputFieldsParser MetadataObjId n Int32
-> InputFieldsParser MetadataObjId n Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name
-> Maybe Description
-> Parser MetadataObjId 'Both n Int32
-> InputFieldsParser MetadataObjId n Int32
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m a
P.field Name
batchSizeName Maybe Description
batchSizeDesc Parser MetadataObjId 'Both n Int32
forall (m :: * -> *) origin.
MonadParse m =>
Parser origin 'Both m Int32
P.nonNegativeInt
  where
    batchSizeName :: Name
batchSizeName = NamingCase -> Name -> Name
applyFieldNameCaseCust NamingCase
tCase Name
Name._batch_size
    batchSizeDesc :: Maybe Description
batchSizeDesc = Description -> Maybe Description
forall a. a -> Maybe a
Just (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description Text
"maximum number of rows returned in a single batch"

-- | Cursor ordering enum fields
--
-- > enum cursor_ordering {
-- >   ASC
-- >   DESC
-- > }
cursorOrderingArgParser ::
  forall b r m n.
  (MonadBuildSourceSchema b r m n) =>
  SchemaT r m (Parser 'Both n CursorOrdering)
cursorOrderingArgParser :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSourceSchema b r m n =>
SchemaT r m (Parser 'Both n CursorOrdering)
cursorOrderingArgParser = do
  SourceInfo b
sourceInfo :: SourceInfo b <- (r -> SourceInfo b) -> SchemaT r m (SourceInfo b)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> SourceInfo b
forall a t. Has a t => t -> a
getter
  let customization :: ResolvedSourceCustomization
customization = SourceInfo b -> ResolvedSourceCustomization
forall (b :: BackendType).
SourceInfo b -> ResolvedSourceCustomization
_siCustomization SourceInfo b
sourceInfo
      tCase :: NamingCase
tCase = ResolvedSourceCustomization -> NamingCase
_rscNamingConvention ResolvedSourceCustomization
customization
      enumName :: Name
enumName = MkTypename -> Name -> Name
runMkTypename (ResolvedSourceCustomization -> MkTypename
_rscTypeNames ResolvedSourceCustomization
customization) (Name -> Name) -> Name -> Name
forall a b. (a -> b) -> a -> b
$ NamingCase -> Name -> Name
applyTypeNameCaseCust NamingCase
tCase Name
Name._cursor_ordering
  let description :: Maybe Description
description =
        Description -> Maybe Description
forall a. a -> Maybe a
Just
          (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description
          (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"ordering argument of a cursor"
  Parser 'Both n CursorOrdering
-> SchemaT r m (Parser 'Both n CursorOrdering)
forall a. a -> SchemaT r m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    (Parser 'Both n CursorOrdering
 -> SchemaT r m (Parser 'Both n CursorOrdering))
-> Parser 'Both n CursorOrdering
-> SchemaT r m (Parser 'Both n CursorOrdering)
forall a b. (a -> b) -> a -> b
$ Name
-> Maybe Description
-> NonEmpty
     (Definition MetadataObjId EnumValueInfo, CursorOrdering)
-> Parser 'Both n CursorOrdering
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> NonEmpty (Definition origin EnumValueInfo, a)
-> Parser origin 'Both m a
P.enum Name
enumName Maybe Description
description
    (NonEmpty (Definition MetadataObjId EnumValueInfo, CursorOrdering)
 -> Parser 'Both n CursorOrdering)
-> NonEmpty
     (Definition MetadataObjId EnumValueInfo, CursorOrdering)
-> Parser 'Both n CursorOrdering
forall a b. (a -> b) -> a -> b
$ [(Definition MetadataObjId EnumValueInfo, CursorOrdering)]
-> NonEmpty
     (Definition MetadataObjId EnumValueInfo, CursorOrdering)
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList -- It's fine to use fromList here because we know the list is never empty.
      [ ( (Name, CursorOrdering) -> Definition MetadataObjId EnumValueInfo
forall {origin}.
(Name, CursorOrdering) -> Definition origin EnumValueInfo
define (Name, CursorOrdering)
enumNameVal,
          (Name, CursorOrdering) -> CursorOrdering
forall a b. (a, b) -> b
snd (Name, CursorOrdering)
enumNameVal
        )
        | (Name, CursorOrdering)
enumNameVal <- [(Name
Name._ASC, CursorOrdering
COAscending), (Name
Name._DESC, CursorOrdering
CODescending)]
      ]
  where
    define :: (Name, CursorOrdering) -> Definition origin EnumValueInfo
define (Name
name, CursorOrdering
val) =
      let orderingTypeDesc :: Text
orderingTypeDesc = Text -> Text -> Bool -> Text
forall a. a -> a -> Bool -> a
bool Text
"descending" Text
"ascending" (Bool -> Text) -> Bool -> Text
forall a b. (a -> b) -> a -> b
$ CursorOrdering
val CursorOrdering -> CursorOrdering -> Bool
forall a. Eq a => a -> a -> Bool
== CursorOrdering
COAscending
       in Name
-> Maybe Description
-> Maybe origin
-> [Directive Void]
-> EnumValueInfo
-> Definition origin EnumValueInfo
forall origin a.
Name
-> Maybe Description
-> Maybe origin
-> [Directive Void]
-> a
-> Definition origin a
P.Definition Name
name (Description -> Maybe Description
forall a. a -> Maybe a
Just (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
orderingTypeDesc Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" ordering of the cursor") Maybe origin
forall a. Maybe a
Nothing [] EnumValueInfo
P.EnumValueInfo

-- | Argument to specify the ordering of the cursor.
-- > ordering: cursor_ordering
cursorOrderingArg ::
  forall b r m n.
  (MonadBuildSourceSchema b r m n) =>
  SchemaT r m (InputFieldsParser n (Maybe CursorOrdering))
cursorOrderingArg :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSourceSchema b r m n =>
SchemaT r m (InputFieldsParser n (Maybe CursorOrdering))
cursorOrderingArg = do
  Parser 'Both n CursorOrdering
cursorOrderingParser' <- forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSourceSchema b r m n =>
SchemaT r m (Parser 'Both n CursorOrdering)
cursorOrderingArgParser @b
  pure $ Name
-> Maybe Description
-> Parser 'Both n CursorOrdering
-> InputFieldsParser n (Maybe CursorOrdering)
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m (Maybe a)
P.fieldOptional Name
Name._ordering (Description -> Maybe Description
forall a. a -> Maybe a
Just (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description Text
"cursor ordering") Parser 'Both n CursorOrdering
cursorOrderingParser'

-- | Input fields parser to parse the value of a table's column
-- > column_name: column_type
streamColumnParserArg ::
  forall b n m r.
  (MonadBuildSchema b r m n) =>
  ColumnInfo b ->
  SchemaT r m (InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b)))
streamColumnParserArg :: forall (b :: BackendType) (n :: * -> *) (m :: * -> *) r.
MonadBuildSchema b r m n =>
ColumnInfo b
-> SchemaT
     r m (InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b)))
streamColumnParserArg ColumnInfo b
colInfo = do
  Parser MetadataObjId 'Both n (ColumnValue b)
fieldParser <- ColumnInfo b
-> SchemaT r m (Parser MetadataObjId 'Both n (ColumnValue b))
forall {b :: BackendType} {m :: * -> *} {n :: * -> *} {r}.
(BackendSchema b, MonadError QErr m, MonadMemoize m, MonadParse n,
 Has (SourceInfo b) r, Has SchemaContext r, Has SchemaOptions r) =>
ColumnInfo b
-> SchemaT r m (Parser MetadataObjId 'Both n (ColumnValue b))
typedParser ColumnInfo b
colInfo
  let fieldName :: Name
fieldName = ColumnInfo b -> Name
forall (b :: BackendType). ColumnInfo b -> Name
ciName ColumnInfo b
colInfo
      fieldDesc :: Maybe Description
fieldDesc = ColumnInfo b -> Maybe Description
forall (b :: BackendType). ColumnInfo b -> Maybe Description
ciDescription ColumnInfo b
colInfo
  InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b))
-> SchemaT
     r m (InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b)))
forall a. a -> SchemaT r m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure do
    Name
-> Maybe Description
-> Parser MetadataObjId 'Both n (ColumnValue b)
-> InputFieldsParser MetadataObjId n (Maybe (ColumnValue b))
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m (Maybe a)
P.fieldOptional Name
fieldName Maybe Description
fieldDesc Parser MetadataObjId 'Both n (ColumnValue b)
fieldParser InputFieldsParser MetadataObjId n (Maybe (ColumnValue b))
-> (Maybe (ColumnValue b) -> Maybe (ColumnInfo b, ColumnValue b))
-> InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (ColumnValue b -> (ColumnInfo b, ColumnValue b))
-> Maybe (ColumnValue b) -> Maybe (ColumnInfo b, ColumnValue b)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ColumnInfo b
colInfo,)
  where
    typedParser :: ColumnInfo b
-> SchemaT r m (Parser MetadataObjId 'Both n (ColumnValue b))
typedParser ColumnInfo b
columnInfo = do
      (ValueWithOrigin (ColumnValue b) -> ColumnValue b)
-> Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
-> Parser MetadataObjId 'Both n (ColumnValue b)
forall a b.
(a -> b)
-> Parser MetadataObjId 'Both n a -> Parser MetadataObjId 'Both n b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ValueWithOrigin (ColumnValue b) -> ColumnValue b
forall a. ValueWithOrigin a -> a
IR.openValueOrigin (Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
 -> Parser MetadataObjId 'Both n (ColumnValue b))
-> SchemaT
     r
     m
     (Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
-> SchemaT r m (Parser MetadataObjId 'Both n (ColumnValue b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ColumnType b
-> Nullability
-> SchemaT
     r
     m
     (Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
forall r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
ColumnType b
-> Nullability
-> SchemaT r m (Parser 'Both n (ValueWithOrigin (ColumnValue b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(BackendSchema b, MonadBuildSchema b r m n) =>
ColumnType b
-> Nullability
-> SchemaT r m (Parser 'Both n (ValueWithOrigin (ColumnValue b)))
columnParser (ColumnInfo b -> ColumnType b
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType ColumnInfo b
columnInfo) (Bool -> Nullability
G.Nullability (Bool -> Nullability) -> Bool -> Nullability
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Bool
forall (b :: BackendType). ColumnInfo b -> Bool
ciIsNullable ColumnInfo b
columnInfo)

-- | Input object parser whose keys are the column names and the values are the
--   initial values of those columns from where the streaming should start.
-- > input table_stream_cursor_value_input {
-- >   col1: col1_type
-- >   col2: col2_type
--     ...
-- > }
streamColumnValueParser ::
  forall b r m n.
  (MonadBuildSchema b r m n) =>
  GQLNameIdentifier ->
  NE.NonEmpty (ColumnInfo b) ->
  SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParser :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParser GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
colInfos = do
  SourceInfo b
sourceInfo :: SourceInfo b <- (r -> SourceInfo b) -> SchemaT r m (SourceInfo b)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> SourceInfo b
forall a t. Has a t => t -> a
getter
  let sourceName :: SourceName
sourceName = SourceInfo b -> SourceName
forall (b :: BackendType). SourceInfo b -> SourceName
_siName SourceInfo b
sourceInfo
      customization :: ResolvedSourceCustomization
customization = SourceInfo b -> ResolvedSourceCustomization
forall (b :: BackendType).
SourceInfo b -> ResolvedSourceCustomization
_siCustomization SourceInfo b
sourceInfo
      tCase :: NamingCase
tCase = ResolvedSourceCustomization -> NamingCase
_rscNamingConvention ResolvedSourceCustomization
customization
      mkTypename :: Name -> Name
mkTypename = MkTypename -> Name -> Name
runMkTypename (MkTypename -> Name -> Name) -> MkTypename -> Name -> Name
forall a b. (a -> b) -> a -> b
$ ResolvedSourceCustomization -> MkTypename
_rscTypeNames ResolvedSourceCustomization
customization
      objName :: Name
objName = Name -> Name
mkTypename (Name -> Name) -> Name -> Name
forall a b. (a -> b) -> a -> b
$ NamingCase -> GQLNameIdentifier -> Name
applyTypeNameCaseIdentifier NamingCase
tCase (GQLNameIdentifier -> Name) -> GQLNameIdentifier -> Name
forall a b. (a -> b) -> a -> b
$ GQLNameIdentifier -> GQLNameIdentifier
mkStreamCursorValueInputTypeName GQLNameIdentifier
tableGQLIdentifier
      description :: Description
description = Text -> Description
G.Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"Initial value of the column from where the streaming should start"
  Name
-> (SourceName, GQLNameIdentifier)
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
forall a p.
(Ord a, Typeable a, Typeable p) =>
Name -> a -> SchemaT r m p -> SchemaT r m p
forall (m :: * -> *) a p.
(MonadMemoize m, Ord a, Typeable a, Typeable p) =>
Name -> a -> m p -> m p
memoizeOn 'streamColumnValueParser (SourceName
sourceName, GQLNameIdentifier
tableGQLIdentifier) (SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
 -> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)]))
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
forall a b. (a -> b) -> a -> b
$ do
    InputFieldsParser
  MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
columnVals <- NonEmpty
  (InputFieldsParser
     MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b)))
-> InputFieldsParser
     MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a.
Applicative f =>
NonEmpty (f a) -> f (NonEmpty a)
sequenceA (NonEmpty
   (InputFieldsParser
      MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b)))
 -> InputFieldsParser
      MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b))))
-> SchemaT
     r
     m
     (NonEmpty
        (InputFieldsParser
           MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b))))
-> SchemaT
     r
     m
     (InputFieldsParser
        MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b))))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ColumnInfo b
 -> SchemaT
      r
      m
      (InputFieldsParser
         MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b))))
-> NonEmpty (ColumnInfo b)
-> SchemaT
     r
     m
     (NonEmpty
        (InputFieldsParser
           MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b))))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse ColumnInfo b
-> SchemaT
     r
     m
     (InputFieldsParser
        MetadataObjId n (Maybe (ColumnInfo b, ColumnValue b)))
forall (b :: BackendType) (n :: * -> *) (m :: * -> *) r.
MonadBuildSchema b r m n =>
ColumnInfo b
-> SchemaT
     r m (InputFieldsParser n (Maybe (ColumnInfo b, ColumnValue b)))
streamColumnParserArg NonEmpty (ColumnInfo b)
colInfos
    pure $ Name
-> Maybe Description
-> InputFieldsParser
     MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
-> Parser
     MetadataObjId
     'Input
     n
     (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Input m a
P.object Name
objName (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
description) InputFieldsParser
  MetadataObjId n (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
columnVals Parser
  MetadataObjId
  'Input
  n
  (NonEmpty (Maybe (ColumnInfo b, ColumnValue b)))
-> (NonEmpty (Maybe (ColumnInfo b, ColumnValue b))
    -> [(ColumnInfo b, ColumnValue b)])
-> Parser 'Input n [(ColumnInfo b, ColumnValue b)]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> ([Maybe (ColumnInfo b, ColumnValue b)]
-> [(ColumnInfo b, ColumnValue b)]
forall a. [Maybe a] -> [a]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes ([Maybe (ColumnInfo b, ColumnValue b)]
 -> [(ColumnInfo b, ColumnValue b)])
-> (NonEmpty (Maybe (ColumnInfo b, ColumnValue b))
    -> [Maybe (ColumnInfo b, ColumnValue b)])
-> NonEmpty (Maybe (ColumnInfo b, ColumnValue b))
-> [(ColumnInfo b, ColumnValue b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Maybe (ColumnInfo b, ColumnValue b))
-> [Maybe (ColumnInfo b, ColumnValue b)]
forall a. NonEmpty a -> [a]
NE.toList)

-- | Argument to accept the initial value from where the streaming should start.
-- > initial_value: table_stream_cursor_value_input!
streamColumnValueParserArg ::
  forall b r m n.
  (MonadBuildSchema b r m n) =>
  GQLNameIdentifier ->
  NE.NonEmpty (ColumnInfo b) ->
  SchemaT r m (InputFieldsParser n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParserArg :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT
     r m (InputFieldsParser n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParserArg GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
nonEmptyColInfos = do
  NamingCase
tCase <- (SourceInfo b -> NamingCase) -> SchemaT r m NamingCase
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve ((SourceInfo b -> NamingCase) -> SchemaT r m NamingCase)
-> (SourceInfo b -> NamingCase) -> SchemaT r m NamingCase
forall a b. (a -> b) -> a -> b
$ ResolvedSourceCustomization -> NamingCase
_rscNamingConvention (ResolvedSourceCustomization -> NamingCase)
-> (SourceInfo b -> ResolvedSourceCustomization)
-> SourceInfo b
-> NamingCase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (b :: BackendType).
SourceInfo b -> ResolvedSourceCustomization
_siCustomization @b
  Parser 'Input n [(ColumnInfo b, ColumnValue b)]
columnValueParser <- GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (Parser 'Input n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParser GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
nonEmptyColInfos
  pure do
    Name
-> Maybe Description
-> Parser 'Input n [(ColumnInfo b, ColumnValue b)]
-> InputFieldsParser n [(ColumnInfo b, ColumnValue b)]
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m a
P.field (NamingCase -> Name -> Name
applyFieldNameCaseCust NamingCase
tCase Name
Name._initial_value) (Description -> Maybe Description
forall a. a -> Maybe a
Just (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description Text
"Stream column input with initial value") Parser 'Input n [(ColumnInfo b, ColumnValue b)]
columnValueParser

-- | Argument to accept the cursor data. At the time of writing this, only a single
--   column cursor is supported and if multiple column cursors are provided,
--   then a parse error is thrown.
-- >
tableStreamColumnArg ::
  forall b r m n.
  (MonadBuildSchema b r m n) =>
  GQLNameIdentifier ->
  NE.NonEmpty (ColumnInfo b) ->
  SchemaT r m (InputFieldsParser n [IR.StreamCursorItem b])
tableStreamColumnArg :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (InputFieldsParser n [StreamCursorItem b])
tableStreamColumnArg GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
colInfos = do
  InputFieldsParser n (Maybe CursorOrdering)
cursorOrderingParser <- forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSourceSchema b r m n =>
SchemaT r m (InputFieldsParser n (Maybe CursorOrdering))
cursorOrderingArg @b
  InputFieldsParser n [(ColumnInfo b, ColumnValue b)]
streamColumnParser <- GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT
     r m (InputFieldsParser n [(ColumnInfo b, ColumnValue b)])
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT
     r m (InputFieldsParser n [(ColumnInfo b, ColumnValue b)])
streamColumnValueParserArg GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
colInfos
  pure $ do
    Maybe CursorOrdering
orderingArg <- InputFieldsParser n (Maybe CursorOrdering)
cursorOrderingParser
    [(ColumnInfo b, ColumnValue b)]
columnArg <- InputFieldsParser n [(ColumnInfo b, ColumnValue b)]
streamColumnParser
    pure $ ((ColumnInfo b -> ColumnValue b -> StreamCursorItem b)
-> (ColumnInfo b, ColumnValue b) -> StreamCursorItem b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (CursorOrdering
-> ColumnInfo b -> ColumnValue b -> StreamCursorItem b
forall (b :: BackendType).
CursorOrdering
-> ColumnInfo b -> ColumnValue b -> StreamCursorItem b
IR.StreamCursorItem (CursorOrdering -> Maybe CursorOrdering -> CursorOrdering
forall a. a -> Maybe a -> a
fromMaybe CursorOrdering
COAscending Maybe CursorOrdering
orderingArg))) ((ColumnInfo b, ColumnValue b) -> StreamCursorItem b)
-> [(ColumnInfo b, ColumnValue b)] -> [StreamCursorItem b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(ColumnInfo b, ColumnValue b)]
columnArg

-- | Input object that contains the initial value of a column
--   along with how it needs to be ordered.
-- > input table_stream_cursor_input {
-- >   initial_value: table_stream_cursor_value_input!
-- >   ordering: cursor_ordering
-- > }
tableStreamCursorExp ::
  forall m n r b.
  (MonadBuildSchema b r m n) =>
  TableInfo b ->
  SchemaT r m (Maybe (Parser 'Input n [(IR.StreamCursorItem b)]))
tableStreamCursorExp :: forall (m :: * -> *) (n :: * -> *) r (b :: BackendType).
MonadBuildSchema b r m n =>
TableInfo b
-> SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
tableStreamCursorExp TableInfo b
tableInfo = MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b])
-> SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT do
  SourceInfo b
sourceInfo :: SourceInfo b <- (r -> SourceInfo b) -> MaybeT (SchemaT r m) (SourceInfo b)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> SourceInfo b
forall a t. Has a t => t -> a
getter
  let sourceName :: SourceName
sourceName = SourceInfo b -> SourceName
forall (b :: BackendType). SourceInfo b -> SourceName
_siName SourceInfo b
sourceInfo
      tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
      customization :: ResolvedSourceCustomization
customization = SourceInfo b -> ResolvedSourceCustomization
forall (b :: BackendType).
SourceInfo b -> ResolvedSourceCustomization
_siCustomization SourceInfo b
sourceInfo
      tCase :: NamingCase
tCase = ResolvedSourceCustomization -> NamingCase
_rscNamingConvention ResolvedSourceCustomization
customization
      mkTypename :: Name -> Name
mkTypename = MkTypename -> Name -> Name
runMkTypename (MkTypename -> Name -> Name) -> MkTypename -> Name -> Name
forall a b. (a -> b) -> a -> b
$ ResolvedSourceCustomization -> MkTypename
_rscTypeNames ResolvedSourceCustomization
customization
  Name
tableGQLName <- TableInfo b -> MaybeT (SchemaT r m) Name
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m Name
getTableGQLName TableInfo b
tableInfo
  GQLNameIdentifier
tableGQLIdentifier <- TableInfo b -> MaybeT (SchemaT r m) GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo b
tableInfo
  -- TODO(redactionExp): Do we need to deal with redaction expressions here too?
  [ColumnInfo b]
columnInfos <- ((StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
 -> Maybe (ColumnInfo b))
-> [(StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)]
-> [ColumnInfo b]
forall a b. (a -> Maybe b) -> [a] -> [b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe ((StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
-> Getting
     (First (ColumnInfo b))
     (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
     (ColumnInfo b)
-> Maybe (ColumnInfo b)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (StructuredColumnInfo b
 -> Const (First (ColumnInfo b)) (StructuredColumnInfo b))
-> (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
-> Const
     (First (ColumnInfo b))
     (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
forall s t a b. Field1 s t a b => Lens s t a b
Lens
  (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
  (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
  (StructuredColumnInfo b)
  (StructuredColumnInfo b)
_1 ((StructuredColumnInfo b
  -> Const (First (ColumnInfo b)) (StructuredColumnInfo b))
 -> (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
 -> Const
      (First (ColumnInfo b))
      (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b))
-> ((ColumnInfo b -> Const (First (ColumnInfo b)) (ColumnInfo b))
    -> StructuredColumnInfo b
    -> Const (First (ColumnInfo b)) (StructuredColumnInfo b))
-> Getting
     (First (ColumnInfo b))
     (StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)
     (ColumnInfo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ColumnInfo b -> Const (First (ColumnInfo b)) (ColumnInfo b))
-> StructuredColumnInfo b
-> Const (First (ColumnInfo b)) (StructuredColumnInfo b)
forall (b :: BackendType) (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (ColumnInfo b) (f (ColumnInfo b))
-> p (StructuredColumnInfo b) (f (StructuredColumnInfo b))
_SCIScalarColumn) ([(StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)]
 -> [ColumnInfo b])
-> MaybeT
     (SchemaT r m)
     [(StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)]
-> MaybeT (SchemaT r m) [ColumnInfo b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TableInfo b
-> MaybeT
     (SchemaT r m)
     [(StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)]
forall (b :: BackendType) r (m :: * -> *).
(Backend b, MonadError QErr m, MonadReader r m,
 Has SchemaContext r, Has (SourceInfo b) r) =>
TableInfo b
-> m [(StructuredColumnInfo b, AnnRedactionExpUnpreparedValue b)]
tableSelectColumns TableInfo b
tableInfo
  NonEmpty (ColumnInfo b)
columnInfosNE <- Maybe (NonEmpty (ColumnInfo b))
-> MaybeT (SchemaT r m) (NonEmpty (ColumnInfo b))
forall (m :: * -> *) b. Applicative m => Maybe b -> MaybeT m b
hoistMaybe (Maybe (NonEmpty (ColumnInfo b))
 -> MaybeT (SchemaT r m) (NonEmpty (ColumnInfo b)))
-> Maybe (NonEmpty (ColumnInfo b))
-> MaybeT (SchemaT r m) (NonEmpty (ColumnInfo b))
forall a b. (a -> b) -> a -> b
$ [ColumnInfo b] -> Maybe (NonEmpty (ColumnInfo b))
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [ColumnInfo b]
columnInfos
  SchemaT r m (Parser 'Input n [StreamCursorItem b])
-> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b])
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SchemaT r m (Parser 'Input n [StreamCursorItem b])
 -> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b]))
-> SchemaT r m (Parser 'Input n [StreamCursorItem b])
-> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b])
forall a b. (a -> b) -> a -> b
$ Name
-> (SourceName, TableName b)
-> SchemaT r m (Parser 'Input n [StreamCursorItem b])
-> SchemaT r m (Parser 'Input n [StreamCursorItem b])
forall a p.
(Ord a, Typeable a, Typeable p) =>
Name -> a -> SchemaT r m p -> SchemaT r m p
forall (m :: * -> *) a p.
(MonadMemoize m, Ord a, Typeable a, Typeable p) =>
Name -> a -> m p -> m p
memoizeOn 'tableStreamCursorExp (SourceName
sourceName, TableName b
tableName) do
    InputFieldsParser n [StreamCursorItem b]
columnParsers <- GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (InputFieldsParser n [StreamCursorItem b])
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
GQLNameIdentifier
-> NonEmpty (ColumnInfo b)
-> SchemaT r m (InputFieldsParser n [StreamCursorItem b])
tableStreamColumnArg GQLNameIdentifier
tableGQLIdentifier NonEmpty (ColumnInfo b)
columnInfosNE
    let objName :: Name
objName = Name -> Name
mkTypename (Name -> Name) -> Name -> Name
forall a b. (a -> b) -> a -> b
$ NamingCase -> GQLNameIdentifier -> Name
applyTypeNameCaseIdentifier NamingCase
tCase (GQLNameIdentifier -> Name) -> GQLNameIdentifier -> Name
forall a b. (a -> b) -> a -> b
$ GQLNameIdentifier -> GQLNameIdentifier
mkStreamCursorInputTypeName GQLNameIdentifier
tableGQLIdentifier
        description :: Description
description = Text -> Description
G.Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"Streaming cursor of the table " Text -> Name -> Text
forall t. ToTxt t => Text -> t -> Text
<>> Name
tableGQLName
    Parser 'Input n [StreamCursorItem b]
-> SchemaT r m (Parser 'Input n [StreamCursorItem b])
forall a. a -> SchemaT r m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Parser 'Input n [StreamCursorItem b]
 -> SchemaT r m (Parser 'Input n [StreamCursorItem b]))
-> Parser 'Input n [StreamCursorItem b]
-> SchemaT r m (Parser 'Input n [StreamCursorItem b])
forall a b. (a -> b) -> a -> b
$ Name
-> Maybe Description
-> InputFieldsParser n [StreamCursorItem b]
-> Parser 'Input n [StreamCursorItem b]
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Input m a
P.object Name
objName (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
description) InputFieldsParser n [StreamCursorItem b]
columnParsers

-- | Argument to accept the cursor input object.
-- > cursor: [table_stream_cursor_input]!
tableStreamCursorArg ::
  forall b r m n.
  (MonadBuildSchema b r m n) =>
  TableInfo b ->
  SchemaT r m (Maybe (InputFieldsParser n [IR.StreamCursorItem b]))
tableStreamCursorArg :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
tableStreamCursorArg TableInfo b
tableInfo = MaybeT (SchemaT r m) (InputFieldsParser n [StreamCursorItem b])
-> SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT do
  Parser 'Input n [StreamCursorItem b]
cursorParser <- SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
-> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b])
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
 -> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b]))
-> SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
-> MaybeT (SchemaT r m) (Parser 'Input n [StreamCursorItem b])
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
forall (m :: * -> *) (n :: * -> *) r (b :: BackendType).
MonadBuildSchema b r m n =>
TableInfo b
-> SchemaT r m (Maybe (Parser 'Input n [StreamCursorItem b]))
tableStreamCursorExp TableInfo b
tableInfo
  pure $ do
    [Maybe [StreamCursorItem b]]
cursorArgs <-
      Name
-> Maybe Description
-> Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]]
-> InputFieldsParser MetadataObjId n [Maybe [StreamCursorItem b]]
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m a
P.field Name
cursorName Maybe Description
cursorDesc (Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]]
 -> InputFieldsParser MetadataObjId n [Maybe [StreamCursorItem b]])
-> Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]]
-> InputFieldsParser MetadataObjId n [Maybe [StreamCursorItem b]]
forall a b. (a -> b) -> a -> b
$ Parser MetadataObjId 'Input n (Maybe [StreamCursorItem b])
-> Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]]
forall origin (k :: Kind) (m :: * -> *) a.
(MonadParse m, 'Input <: k) =>
Parser origin k m a -> Parser origin k m [a]
P.list (Parser MetadataObjId 'Input n (Maybe [StreamCursorItem b])
 -> Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]])
-> Parser MetadataObjId 'Input n (Maybe [StreamCursorItem b])
-> Parser MetadataObjId 'Input n [Maybe [StreamCursorItem b]]
forall a b. (a -> b) -> a -> b
$ Parser 'Input n [StreamCursorItem b]
-> Parser MetadataObjId 'Input n (Maybe [StreamCursorItem b])
forall origin (k :: Kind) (m :: * -> *) a.
(MonadParse m, 'Input <: k) =>
Parser origin k m a -> Parser origin k m (Maybe a)
P.nullable Parser 'Input n [StreamCursorItem b]
cursorParser
    pure $ [[StreamCursorItem b]] -> [StreamCursorItem b]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[StreamCursorItem b]] -> [StreamCursorItem b])
-> [[StreamCursorItem b]] -> [StreamCursorItem b]
forall a b. (a -> b) -> a -> b
$ [Maybe [StreamCursorItem b]] -> [[StreamCursorItem b]]
forall a. [Maybe a] -> [a]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes [Maybe [StreamCursorItem b]]
cursorArgs
  where
    cursorName :: Name
cursorName = Name
Name._cursor
    cursorDesc :: Maybe Description
cursorDesc = Description -> Maybe Description
forall a. a -> Maybe a
Just (Description -> Maybe Description)
-> Description -> Maybe Description
forall a b. (a -> b) -> a -> b
$ Text -> Description
G.Description Text
"cursor to stream the results returned by the query"

-- | Arguments to the streaming subscription field.
-- > table_stream (cursor: [table_stream_cursor_input]!, batch_size: Int!, where: table_bool_exp)
tableStreamArguments ::
  forall b r m n.
  ( AggregationPredicatesSchema b,
    MonadBuildSchema b r m n
  ) =>
  TableInfo b ->
  SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
tableStreamArguments :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(AggregationPredicatesSchema b, MonadBuildSchema b r m n) =>
TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
tableStreamArguments TableInfo b
tableInfo = MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b))
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b))
 -> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b))))
-> MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b))
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
forall a b. (a -> b) -> a -> b
$ do
  NamingCase
tCase <- (SourceInfo b -> NamingCase) -> MaybeT (SchemaT r m) NamingCase
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve ((SourceInfo b -> NamingCase) -> MaybeT (SchemaT r m) NamingCase)
-> (SourceInfo b -> NamingCase) -> MaybeT (SchemaT r m) NamingCase
forall a b. (a -> b) -> a -> b
$ ResolvedSourceCustomization -> NamingCase
_rscNamingConvention (ResolvedSourceCustomization -> NamingCase)
-> (SourceInfo b -> ResolvedSourceCustomization)
-> SourceInfo b
-> NamingCase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (b :: BackendType).
SourceInfo b -> ResolvedSourceCustomization
_siCustomization @b
  InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b)))
whereParser <- SchemaT
  r
  m
  (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
-> MaybeT
     (SchemaT r m)
     (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (SchemaT
   r
   m
   (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
 -> MaybeT
      (SchemaT r m)
      (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b)))))
-> SchemaT
     r
     m
     (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
-> MaybeT
     (SchemaT r m)
     (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> SchemaT
     r
     m
     (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(AggregationPredicatesSchema b, MonadBuildSchema b r m n) =>
TableInfo b
-> SchemaT
     r
     m
     (InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b))))
tableWhereArg TableInfo b
tableInfo
  InputFieldsParser n [StreamCursorItem b]
cursorParser <- SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
-> MaybeT (SchemaT r m) (InputFieldsParser n [StreamCursorItem b])
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
 -> MaybeT (SchemaT r m) (InputFieldsParser n [StreamCursorItem b]))
-> SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
-> MaybeT (SchemaT r m) (InputFieldsParser n [StreamCursorItem b])
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n [StreamCursorItem b]))
tableStreamCursorArg TableInfo b
tableInfo
  pure $ do
    Maybe (AnnBoolExp b (UnpreparedValue b))
whereArg <- InputFieldsParser n (Maybe (AnnBoolExp b (UnpreparedValue b)))
whereParser
    StreamCursorItem b
cursorArg <-
      InputFieldsParser n [StreamCursorItem b]
cursorParser InputFieldsParser n [StreamCursorItem b]
-> ([StreamCursorItem b] -> n (StreamCursorItem b))
-> InputFieldsParser MetadataObjId n (StreamCursorItem b)
forall (m :: * -> *) origin a b.
Monad m =>
InputFieldsParser origin m a
-> (a -> m b) -> InputFieldsParser origin m b
`P.bindFields` \case
        [] -> ErrorMessage -> n (StreamCursorItem b)
forall (m :: * -> *) a. MonadParse m => ErrorMessage -> m a
parseError ErrorMessage
"one streaming column field is expected"
        [StreamCursorItem b
c] -> StreamCursorItem b -> n (StreamCursorItem b)
forall a. a -> n a
forall (f :: * -> *) a. Applicative f => a -> f a
pure StreamCursorItem b
c
        [StreamCursorItem b]
_ -> ErrorMessage -> n (StreamCursorItem b)
forall (m :: * -> *) a. MonadParse m => ErrorMessage -> m a
parseError ErrorMessage
"multiple column cursors are not supported yet"
    Int
batchSizeArg <- NamingCase -> InputFieldsParser n Int
forall (n :: * -> *).
MonadParse n =>
NamingCase -> InputFieldsParser n Int
cursorBatchSizeArg NamingCase
tCase
    pure
      $ Maybe (AnnBoolExp b (UnpreparedValue b))
-> Int -> StreamCursorItem b -> SelectStreamArgs b
forall (b :: BackendType) v.
Maybe (AnnBoolExp b v)
-> Int -> StreamCursorItem b -> SelectStreamArgsG b v
IR.SelectStreamArgsG Maybe (AnnBoolExp b (UnpreparedValue b))
whereArg Int
batchSizeArg StreamCursorItem b
cursorArg

-- | Field parser for a streaming subscription for a table.
selectStreamTable ::
  forall b r m n.
  ( MonadBuildSchema b r m n,
    AggregationPredicatesSchema b,
    BackendTableSelectSchema b
  ) =>
  -- | table info
  TableInfo b ->
  -- | field display name
  G.Name ->
  -- | field description, if any
  Maybe G.Description ->
  SchemaT r m (Maybe (P.FieldParser n (StreamSelectExp b)))
selectStreamTable :: forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(MonadBuildSchema b r m n, AggregationPredicatesSchema b,
 BackendTableSelectSchema b) =>
TableInfo b
-> Name
-> Maybe Description
-> SchemaT r m (Maybe (FieldParser n (StreamSelectExp b)))
selectStreamTable TableInfo b
tableInfo Name
fieldName Maybe Description
description = MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b))
-> SchemaT r m (Maybe (FieldParser n (StreamSelectExp b)))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b))
 -> SchemaT r m (Maybe (FieldParser n (StreamSelectExp b))))
-> MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b))
-> SchemaT r m (Maybe (FieldParser n (StreamSelectExp b)))
forall a b. (a -> b) -> a -> b
$ do
  SourceInfo b
sourceInfo :: SourceInfo b <- (r -> SourceInfo b) -> MaybeT (SchemaT r m) (SourceInfo b)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> SourceInfo b
forall a t. Has a t => t -> a
getter
  let sourceName :: SourceName
sourceName = SourceInfo b -> SourceName
forall (b :: BackendType). SourceInfo b -> SourceName
_siName SourceInfo b
sourceInfo
      tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
  RoleName
roleName <- (SchemaContext -> RoleName) -> MaybeT (SchemaT r m) RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
  SelPermInfo b
selectPermissions <- Maybe (SelPermInfo b) -> MaybeT (SchemaT r m) (SelPermInfo b)
forall (m :: * -> *) b. Applicative m => Maybe b -> MaybeT m b
hoistMaybe (Maybe (SelPermInfo b) -> MaybeT (SchemaT r m) (SelPermInfo b))
-> Maybe (SelPermInfo b) -> MaybeT (SchemaT r m) (SelPermInfo b)
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> Maybe (SelPermInfo b)
forall (b :: BackendType).
RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions RoleName
roleName TableInfo b
tableInfo
  XStreamingSubscription b
xStreamSubscription <- Maybe (XStreamingSubscription b)
-> MaybeT (SchemaT r m) (XStreamingSubscription b)
forall (m :: * -> *) b. Applicative m => Maybe b -> MaybeT m b
hoistMaybe (Maybe (XStreamingSubscription b)
 -> MaybeT (SchemaT r m) (XStreamingSubscription b))
-> Maybe (XStreamingSubscription b)
-> MaybeT (SchemaT r m) (XStreamingSubscription b)
forall a b. (a -> b) -> a -> b
$ forall (b :: BackendType).
BackendSchema b =>
Maybe (XStreamingSubscription b)
streamSubscriptionExtension @b
  StringifyNumbers
stringifyNumbers <- (SchemaOptions -> StringifyNumbers)
-> MaybeT (SchemaT r m) StringifyNumbers
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaOptions -> StringifyNumbers
Options.soStringifyNumbers
  InputFieldsParser n (SelectStreamArgs b)
tableStreamArgsParser <- SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
-> MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b))
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
 -> MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b)))
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
-> MaybeT (SchemaT r m) (InputFieldsParser n (SelectStreamArgs b))
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(AggregationPredicatesSchema b, MonadBuildSchema b r m n) =>
TableInfo b
-> SchemaT r m (Maybe (InputFieldsParser n (SelectStreamArgs b)))
tableStreamArguments TableInfo b
tableInfo
  Parser 'Output n (AnnotatedFields b)
selectionSetParser <- SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
-> MaybeT (SchemaT r m) (Parser 'Output n (AnnotatedFields b))
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
 -> MaybeT (SchemaT r m) (Parser 'Output n (AnnotatedFields b)))
-> SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
-> MaybeT (SchemaT r m) (Parser 'Output n (AnnotatedFields b))
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(MonadBuildSchema b r m n, BackendTableSelectSchema b) =>
TableInfo b
-> SchemaT r m (Maybe (Parser 'Output n (AnnotatedFields b)))
tableSelectionList TableInfo b
tableInfo
  SchemaT r m (FieldParser n (StreamSelectExp b))
-> MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b))
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
    (SchemaT r m (FieldParser n (StreamSelectExp b))
 -> MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b)))
-> SchemaT r m (FieldParser n (StreamSelectExp b))
-> MaybeT (SchemaT r m) (FieldParser n (StreamSelectExp b))
forall a b. (a -> b) -> a -> b
$ Name
-> (SourceName, TableName b, Name)
-> SchemaT r m (FieldParser n (StreamSelectExp b))
-> SchemaT r m (FieldParser n (StreamSelectExp b))
forall a p.
(Ord a, Typeable a, Typeable p) =>
Name -> a -> SchemaT r m p -> SchemaT r m p
forall (m :: * -> *) a p.
(MonadMemoize m, Ord a, Typeable a, Typeable p) =>
Name -> a -> m p -> m p
memoizeOn 'selectStreamTable (SourceName
sourceName, TableName b
tableName, Name
fieldName)
    (SchemaT r m (FieldParser n (StreamSelectExp b))
 -> SchemaT r m (FieldParser n (StreamSelectExp b)))
-> SchemaT r m (FieldParser n (StreamSelectExp b))
-> SchemaT r m (FieldParser n (StreamSelectExp b))
forall a b. (a -> b) -> a -> b
$ do
      FieldParser n (StreamSelectExp b)
-> SchemaT r m (FieldParser n (StreamSelectExp b))
forall a. a -> SchemaT r m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (FieldParser n (StreamSelectExp b)
 -> SchemaT r m (FieldParser n (StreamSelectExp b)))
-> FieldParser n (StreamSelectExp b)
-> SchemaT r m (FieldParser n (StreamSelectExp b))
forall a b. (a -> b) -> a -> b
$ MetadataObjId
-> FieldParser n (StreamSelectExp b)
-> FieldParser n (StreamSelectExp b)
forall (m :: * -> *) origin a.
origin -> FieldParser origin m a -> FieldParser origin m a
P.setFieldParserOrigin (SourceName -> AnyBackend SourceMetadataObjId -> MetadataObjId
MOSourceObjId SourceName
sourceName (SourceMetadataObjId b -> AnyBackend SourceMetadataObjId
forall (b :: BackendType) (i :: BackendType -> *).
HasTag b =>
i b -> AnyBackend i
AB.mkAnyBackend (SourceMetadataObjId b -> AnyBackend SourceMetadataObjId)
-> SourceMetadataObjId b -> AnyBackend SourceMetadataObjId
forall a b. (a -> b) -> a -> b
$ forall (b :: BackendType). TableName b -> SourceMetadataObjId b
SMOTable @b TableName b
tableName))
        (FieldParser n (StreamSelectExp b)
 -> FieldParser n (StreamSelectExp b))
-> FieldParser n (StreamSelectExp b)
-> FieldParser n (StreamSelectExp b)
forall a b. (a -> b) -> a -> b
$ Name
-> Maybe Description
-> InputFieldsParser n (SelectStreamArgs b)
-> Parser 'Output n (AnnotatedFields b)
-> FieldParser
     MetadataObjId n (SelectStreamArgs b, AnnotatedFields b)
forall (m :: * -> *) origin a b.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Output m b
-> FieldParser origin m (a, b)
P.subselection Name
fieldName Maybe Description
description InputFieldsParser n (SelectStreamArgs b)
tableStreamArgsParser Parser 'Output n (AnnotatedFields b)
selectionSetParser
        FieldParser MetadataObjId n (SelectStreamArgs b, AnnotatedFields b)
-> ((SelectStreamArgs b, AnnotatedFields b) -> StreamSelectExp b)
-> FieldParser n (StreamSelectExp b)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(SelectStreamArgs b
args, AnnotatedFields b
fields) ->
          IR.AnnSelectStreamG
            { $sel:_assnXStreamingSubscription:AnnSelectStreamG :: XStreamingSubscription b
IR._assnXStreamingSubscription = XStreamingSubscription b
xStreamSubscription,
              $sel:_assnFields:AnnSelectStreamG :: AnnotatedFields b
IR._assnFields = AnnotatedFields b
fields,
              $sel:_assnFrom:AnnSelectStreamG :: SelectFromG b (UnpreparedValue b)
IR._assnFrom = TableName b -> SelectFromG b (UnpreparedValue b)
forall (b :: BackendType) v. TableName b -> SelectFromG b v
IR.FromTable TableName b
tableName,
              $sel:_assnPerm:AnnSelectStreamG :: TablePermG b (UnpreparedValue b)
IR._assnPerm = SelPermInfo b -> TablePermG b (UnpreparedValue b)
forall (b :: BackendType).
Backend b =>
SelPermInfo b -> TablePerms b
tablePermissionsInfo SelPermInfo b
selectPermissions,
              $sel:_assnArgs:AnnSelectStreamG :: SelectStreamArgs b
IR._assnArgs = SelectStreamArgs b
args,
              $sel:_assnStrfyNum:AnnSelectStreamG :: StringifyNumbers
IR._assnStrfyNum = StringifyNumbers
stringifyNumbers
            }