summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--graphql.cabal1
-rw-r--r--src/Language/GraphQL/Executor.hs82
2 files changed, 83 insertions, 0 deletions
diff --git a/graphql.cabal b/graphql.cabal
index b67f4ae..98f4365 100644
--- a/graphql.cabal
+++ b/graphql.cabal
@@ -38,6 +38,7 @@ library
Language.GraphQL.Error
Language.GraphQL.Execute
Language.GraphQL.Execute.Coerce
+ Language.GraphQL.Executor
Language.GraphQL.Execute.OrderedMap
Language.GraphQL.Type
Language.GraphQL.Type.In
diff --git a/src/Language/GraphQL/Executor.hs b/src/Language/GraphQL/Executor.hs
new file mode 100644
index 0000000..97447f5
--- /dev/null
+++ b/src/Language/GraphQL/Executor.hs
@@ -0,0 +1,82 @@
+{- This Source Code Form is subject to the terms of the Mozilla Public License,
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ obtain one at https://mozilla.org/MPL/2.0/. -}
+
+{-# LANGUAGE LambdaCase #-}
+
+module Language.GraphQL.Executor
+ ( Error(..)
+ , Operation(..)
+ , QueryError(..)
+ , Response(..)
+ , Segment(..)
+ , executeRequest
+ ) where
+
+import qualified Language.GraphQL.AST.Document as Full
+import qualified Data.Aeson as Aeson
+import Data.Foldable (find)
+import qualified Data.Text as Text
+import qualified Language.GraphQL.Type.Internal as Type.Internal
+
+data Segment = Segment String | Index Int
+
+data Error = Error
+ { message :: String
+ , locations :: [Full.Location]
+ , path :: [Segment]
+ }
+
+data Response = Response
+ { data' :: Aeson.Object
+ , errors :: [Error]
+ }
+
+data QueryError
+ = OperationNameRequired
+ | OperationNotFound
+
+-- operationName selectionSet location
+data Operation = Operation
+ Full.OperationType
+ (Maybe String)
+ [Full.VariableDefinition]
+ Full.SelectionSet
+ Full.Location
+
+document :: Full.Document -> [Operation]
+document = foldr filterOperation []
+ where
+ filterOperation (Full.ExecutableDefinition executableDefinition) accumulator
+ | Full.DefinitionOperation operationDefinition' <- executableDefinition =
+ operationDefinition operationDefinition' : accumulator
+ filterOperation _ accumulator = accumulator -- Fragment.
+
+operationDefinition :: Full.OperationDefinition -> Operation
+operationDefinition = \case
+ Full.OperationDefinition operationType operationName variables _ selectionSet operationLocation ->
+ let maybeOperationName = Text.unpack <$> operationName
+ in Operation operationType maybeOperationName variables selectionSet operationLocation
+ Full.SelectionSet selectionSet operationLocation ->
+ Operation Full.Query Nothing [] selectionSet operationLocation
+
+executeRequest :: Type.Internal.Schema IO
+ -> Full.Document
+ -> Maybe String
+ -> Aeson.Object
+ -> Aeson.Object
+ -> IO Response
+executeRequest _schema sourceDocument operationName _variableValues _initialValue =
+ let transformedDocument = document sourceDocument
+ _operation = getOperation transformedDocument operationName
+ in pure $ Response mempty mempty
+
+getOperation :: [Operation] -> Maybe String -> Either QueryError Operation
+getOperation [operation] Nothing = Right operation
+getOperation operations (Just givenOperationName) =
+ maybe (Left OperationNotFound) Right $ find findOperationByName operations
+ where
+ findOperationByName (Operation _ (Just operationName) _ _ _) =
+ givenOperationName == operationName
+ findOperationByName _ = False
+getOperation _ _ = Left OperationNameRequired