2018-06-27 16:11:32 +03:00
|
|
|
module Hasura.GraphQL.Resolve.Context
|
2019-11-20 09:47:06 +03:00
|
|
|
( FunctionArgItem(..)
|
2018-10-26 14:57:33 +03:00
|
|
|
, OrdByItem(..)
|
2019-02-23 13:36:42 +03:00
|
|
|
, UpdPermForIns(..)
|
2018-10-05 18:13:51 +03:00
|
|
|
, InsCtx(..)
|
2018-06-27 16:11:32 +03:00
|
|
|
, RespTx
|
2018-12-13 10:26:15 +03:00
|
|
|
, LazyRespTx
|
2019-03-20 09:31:49 +03:00
|
|
|
, AnnPGVal(..)
|
2019-04-17 12:48:41 +03:00
|
|
|
, UnresolvedVal(..)
|
|
|
|
, resolveValTxt
|
2018-08-17 17:44:43 +03:00
|
|
|
, InsertTxConflictCtx(..)
|
2018-06-27 16:11:32 +03:00
|
|
|
, getFldInfo
|
|
|
|
, getPGColInfo
|
|
|
|
, getArg
|
|
|
|
, withArg
|
|
|
|
, withArgM
|
2018-08-06 15:15:08 +03:00
|
|
|
, nameAsPath
|
2019-04-17 12:48:41 +03:00
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
, PrepArgs
|
|
|
|
, prepare
|
2019-03-20 09:31:49 +03:00
|
|
|
, prepareColVal
|
2019-04-17 12:48:41 +03:00
|
|
|
, withPrepArgs
|
|
|
|
|
2019-03-07 13:24:07 +03:00
|
|
|
, txtConverter
|
2019-04-17 12:48:41 +03:00
|
|
|
|
|
|
|
, withSelSet
|
|
|
|
, fieldAsPath
|
2019-09-19 07:47:36 +03:00
|
|
|
, resolvePGCol
|
2018-06-27 16:11:32 +03:00
|
|
|
, module Hasura.GraphQL.Utils
|
2019-08-09 12:19:17 +03:00
|
|
|
, module Hasura.GraphQL.Resolve.Types
|
2018-06-27 16:11:32 +03:00
|
|
|
) where
|
|
|
|
|
|
|
|
import Data.Has
|
|
|
|
import Hasura.Prelude
|
|
|
|
|
2019-08-09 12:19:17 +03:00
|
|
|
import qualified Data.HashMap.Strict as Map
|
|
|
|
import qualified Data.Sequence as Seq
|
|
|
|
import qualified Database.PG.Query as Q
|
|
|
|
import qualified Language.GraphQL.Draft.Syntax as G
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2019-08-09 12:19:17 +03:00
|
|
|
import Hasura.GraphQL.Resolve.Types
|
2018-06-27 16:11:32 +03:00
|
|
|
import Hasura.GraphQL.Utils
|
|
|
|
import Hasura.GraphQL.Validate.Field
|
|
|
|
import Hasura.GraphQL.Validate.Types
|
2019-12-13 00:46:33 +03:00
|
|
|
import Hasura.RQL.DML.Internal (currentSession, sessVarFromCurrentSetting)
|
2018-06-27 16:11:32 +03:00
|
|
|
import Hasura.RQL.Types
|
|
|
|
import Hasura.SQL.Types
|
|
|
|
import Hasura.SQL.Value
|
|
|
|
|
2019-08-09 12:19:17 +03:00
|
|
|
import qualified Hasura.SQL.DML as S
|
2019-04-17 12:48:41 +03:00
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
getFldInfo
|
|
|
|
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
|
2018-11-16 15:40:23 +03:00
|
|
|
=> G.NamedType -> G.Name
|
2019-10-18 11:29:47 +03:00
|
|
|
-> m ResolveField
|
2018-06-27 16:11:32 +03:00
|
|
|
getFldInfo nt n = do
|
|
|
|
fldMap <- asks getter
|
|
|
|
onNothing (Map.lookup (nt,n) fldMap) $
|
|
|
|
throw500 $ "could not lookup " <> showName n <> " in " <>
|
|
|
|
showNamedTy nt
|
|
|
|
|
|
|
|
getPGColInfo
|
|
|
|
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
|
2019-08-11 18:34:38 +03:00
|
|
|
=> G.NamedType -> G.Name -> m PGColumnInfo
|
2018-06-27 16:11:32 +03:00
|
|
|
getPGColInfo nt n = do
|
|
|
|
fldInfo <- getFldInfo nt n
|
|
|
|
case fldInfo of
|
2019-10-18 11:29:47 +03:00
|
|
|
RFPGColumn pgColInfo -> return pgColInfo
|
|
|
|
RFRelationship _ -> throw500 $ mkErrMsg "relation"
|
|
|
|
RFComputedField _ -> throw500 $ mkErrMsg "computed field"
|
|
|
|
where
|
|
|
|
mkErrMsg ty =
|
|
|
|
"found " <> ty <> " when expecting pgcolinfo for "
|
2018-06-27 16:11:32 +03:00
|
|
|
<> showNamedTy nt <> ":" <> showName n
|
|
|
|
|
|
|
|
getArg
|
|
|
|
:: (MonadError QErr m)
|
|
|
|
=> ArgsMap
|
|
|
|
-> G.Name
|
2019-03-20 09:31:49 +03:00
|
|
|
-> m AnnInpVal
|
2018-06-27 16:11:32 +03:00
|
|
|
getArg args arg =
|
|
|
|
onNothing (Map.lookup arg args) $
|
|
|
|
throw500 $ "missing argument: " <> showName arg
|
|
|
|
|
2018-08-06 15:15:08 +03:00
|
|
|
prependArgsInPath
|
|
|
|
:: (MonadError QErr m)
|
|
|
|
=> m a -> m a
|
|
|
|
prependArgsInPath = withPathK "args"
|
|
|
|
|
|
|
|
nameAsPath
|
|
|
|
:: (MonadError QErr m)
|
|
|
|
=> G.Name -> m a -> m a
|
|
|
|
nameAsPath name = withPathK (G.unName name)
|
|
|
|
|
2018-06-27 16:11:32 +03:00
|
|
|
withArg
|
|
|
|
:: (MonadError QErr m)
|
|
|
|
=> ArgsMap
|
|
|
|
-> G.Name
|
2019-03-20 09:31:49 +03:00
|
|
|
-> (AnnInpVal -> m a)
|
2018-06-27 16:11:32 +03:00
|
|
|
-> m a
|
2018-08-06 15:15:08 +03:00
|
|
|
withArg args arg f = prependArgsInPath $ nameAsPath arg $
|
2018-06-27 16:11:32 +03:00
|
|
|
getArg args arg >>= f
|
|
|
|
|
|
|
|
withArgM
|
2019-10-16 17:33:34 +03:00
|
|
|
:: (MonadReusability m, MonadError QErr m)
|
2018-06-27 16:11:32 +03:00
|
|
|
=> ArgsMap
|
|
|
|
-> G.Name
|
2019-03-20 09:31:49 +03:00
|
|
|
-> (AnnInpVal -> m a)
|
2018-06-27 16:11:32 +03:00
|
|
|
-> m (Maybe a)
|
2019-09-14 09:01:06 +03:00
|
|
|
withArgM args argName f = do
|
|
|
|
wrappedArg <- for (Map.lookup argName args) $ \arg -> do
|
|
|
|
when (isJust (_aivVariable arg) && G.isNullable (_aivType arg)) markNotReusable
|
|
|
|
pure . bool (Just arg) Nothing $ hasNullVal (_aivValue arg)
|
|
|
|
prependArgsInPath . nameAsPath argName $ traverse f (join wrappedArg)
|
2018-06-27 16:11:32 +03:00
|
|
|
|
|
|
|
type PrepArgs = Seq.Seq Q.PrepArg
|
|
|
|
|
2019-07-22 15:47:13 +03:00
|
|
|
prepare :: (MonadState PrepArgs m) => AnnPGVal -> m S.SQLExp
|
2019-09-14 09:01:06 +03:00
|
|
|
prepare (AnnPGVal _ _ scalarValue) = prepareColVal scalarValue
|
2019-03-20 09:31:49 +03:00
|
|
|
|
2019-04-17 12:48:41 +03:00
|
|
|
resolveValTxt :: (Applicative f) => UnresolvedVal -> f S.SQLExp
|
|
|
|
resolveValTxt = \case
|
|
|
|
UVPG annPGVal -> txtConverter annPGVal
|
|
|
|
UVSessVar colTy sessVar -> sessVarFromCurrentSetting colTy sessVar
|
|
|
|
UVSQL sqlExp -> pure sqlExp
|
2019-11-20 09:47:06 +03:00
|
|
|
UVSession -> pure currentSession
|
2019-04-17 12:48:41 +03:00
|
|
|
|
|
|
|
withPrepArgs :: StateT PrepArgs m a -> m (a, PrepArgs)
|
|
|
|
withPrepArgs m = runStateT m Seq.empty
|
|
|
|
|
2019-03-20 09:31:49 +03:00
|
|
|
prepareColVal
|
|
|
|
:: (MonadState PrepArgs m)
|
2019-08-11 18:34:38 +03:00
|
|
|
=> WithScalarType PGScalarValue -> m S.SQLExp
|
|
|
|
prepareColVal (WithScalarType scalarType colVal) = do
|
2018-06-27 16:11:32 +03:00
|
|
|
preparedArgs <- get
|
|
|
|
put (preparedArgs Seq.|> binEncoder colVal)
|
2019-07-22 15:47:13 +03:00
|
|
|
return $ toPrepParam (Seq.length preparedArgs + 1) scalarType
|
2018-06-27 16:11:32 +03:00
|
|
|
|
2019-04-17 12:48:41 +03:00
|
|
|
txtConverter :: Applicative f => AnnPGVal -> f S.SQLExp
|
2019-09-14 09:01:06 +03:00
|
|
|
txtConverter (AnnPGVal _ _ scalarValue) = pure $ toTxtValue scalarValue
|
2019-03-07 13:24:07 +03:00
|
|
|
|
2019-04-17 12:48:41 +03:00
|
|
|
withSelSet :: (Monad m) => SelSet -> (Field -> m a) -> m [(Text, a)]
|
|
|
|
withSelSet selSet f =
|
|
|
|
forM (toList selSet) $ \fld -> do
|
|
|
|
res <- f fld
|
|
|
|
return (G.unName $ G.unAlias $ _fAlias fld, res)
|
2019-03-25 21:25:25 +03:00
|
|
|
|
2019-04-17 12:48:41 +03:00
|
|
|
fieldAsPath :: (MonadError QErr m) => Field -> m a -> m a
|
|
|
|
fieldAsPath = nameAsPath . _fName
|
2019-09-19 07:47:36 +03:00
|
|
|
|
|
|
|
resolvePGCol :: (MonadError QErr m)
|
|
|
|
=> PGColGNameMap -> G.Name -> m PGColumnInfo
|
|
|
|
resolvePGCol colFldMap fldName =
|
|
|
|
onNothing (Map.lookup fldName colFldMap) $ throw500 $
|
|
|
|
"no column associated with name " <> G.unName fldName
|