module Hasura.GraphQL.Schema.Table
( getTableGQLName,
tableSelectColumnsEnum,
tableSelectColumnsPredEnum,
tableUpdateColumnsEnum,
updateColumnsPlaceholderParser,
tableSelectPermissions,
tableSelectFields,
tableColumns,
tableSelectColumns,
tableUpdateColumns,
getTableIdentifierName,
)
where
import Data.Has
import Data.HashMap.Strict qualified as Map
import Data.HashSet qualified as Set
import Data.Text (pack)
import Data.Text.Casing qualified as C
import Data.Text.Extended
import Hasura.Base.Error (QErr)
import Hasura.GraphQL.Schema.Backend
import Hasura.GraphQL.Schema.Common
import Hasura.GraphQL.Schema.Parser (Kind (..), Parser)
import Hasura.GraphQL.Schema.Parser qualified as P
import Hasura.GraphQL.Schema.Typename (mkTypename)
import Hasura.Name qualified as Name
import Hasura.Prelude
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Column
import Hasura.RQL.Types.ComputedField
import Hasura.RQL.Types.Relationships.Local
import Hasura.RQL.Types.SchemaCache hiding (askTableInfo)
import Hasura.RQL.Types.Source
import Hasura.RQL.Types.SourceCustomization (applyTypeNameCaseIdentifier, mkTableSelectColumnTypeName, mkTableUpdateColumnTypeName)
import Hasura.RQL.Types.Table
import Hasura.Session (RoleName)
import Language.GraphQL.Draft.Syntax qualified as G
getTableGQLName ::
forall b m.
(Backend b, MonadError QErr m) =>
TableInfo b ->
m G.Name
getTableGQLName :: TableInfo b -> m Name
getTableGQLName TableInfo b
tableInfo = do
let coreInfo :: TableCoreInfo b
coreInfo = TableInfo b -> TableCoreInfo b
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo TableInfo b
tableInfo
tableName :: TableName b
tableName = TableCoreInfo b -> TableName b
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> TableName b
_tciName TableCoreInfo b
coreInfo
tableCustomName :: Maybe Name
tableCustomName = TableConfig b -> Maybe Name
forall (b :: BackendType). TableConfig b -> Maybe Name
_tcCustomName (TableConfig b -> Maybe Name) -> TableConfig b -> Maybe Name
forall a b. (a -> b) -> a -> b
$ TableCoreInfo b -> TableConfig b
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> TableConfig b
_tciCustomConfig TableCoreInfo b
coreInfo
Maybe Name
tableCustomName
Maybe Name -> Either QErr Name -> Either QErr Name
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` TableName b -> Either QErr Name
forall (b :: BackendType).
Backend b =>
TableName b -> Either QErr Name
tableGraphQLName @b TableName b
tableName
Either QErr Name -> (QErr -> m Name) -> m Name
forall (m :: * -> *) e a.
Applicative m =>
Either e a -> (e -> m a) -> m a
`onLeft` QErr -> m Name
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
getTableIdentifierName ::
forall b m.
(Backend b, MonadError QErr m) =>
TableInfo b ->
m (C.GQLNameIdentifier)
getTableIdentifierName :: TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo b
tableInfo =
let coreInfo :: TableCoreInfo b
coreInfo = TableInfo b -> TableCoreInfo b
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo TableInfo b
tableInfo
tableName :: TableName b
tableName = TableCoreInfo b -> TableName b
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> TableName b
_tciName TableCoreInfo b
coreInfo
tableCustomName :: Maybe GQLNameIdentifier
tableCustomName = (Name -> GQLNameIdentifier)
-> Maybe Name -> Maybe GQLNameIdentifier
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Name -> GQLNameIdentifier
C.fromCustomName (Maybe Name -> Maybe GQLNameIdentifier)
-> Maybe Name -> Maybe GQLNameIdentifier
forall a b. (a -> b) -> a -> b
$ TableConfig b -> Maybe Name
forall (b :: BackendType). TableConfig b -> Maybe Name
_tcCustomName (TableConfig b -> Maybe Name) -> TableConfig b -> Maybe Name
forall a b. (a -> b) -> a -> b
$ TableCoreInfo b -> TableConfig b
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> TableConfig b
_tciCustomConfig TableCoreInfo b
coreInfo
in Maybe GQLNameIdentifier
-> m GQLNameIdentifier -> m GQLNameIdentifier
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
onNothing
Maybe GQLNameIdentifier
tableCustomName
(Either QErr GQLNameIdentifier -> m GQLNameIdentifier
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither (Either QErr GQLNameIdentifier -> m GQLNameIdentifier)
-> Either QErr GQLNameIdentifier -> m GQLNameIdentifier
forall a b. (a -> b) -> a -> b
$ TableName b -> Either QErr GQLNameIdentifier
forall (b :: BackendType).
Backend b =>
TableName b -> Either QErr GQLNameIdentifier
getTableIdentifier @b TableName b
tableName)
tableSelectColumnsEnum ::
forall b r m n.
(Backend b, MonadBuildSchemaBase r m n) =>
SourceInfo b ->
TableInfo b ->
m (Maybe (Parser 'Both n (Column b)))
tableSelectColumnsEnum :: SourceInfo b
-> TableInfo b -> m (Maybe (Parser 'Both n (Column b)))
tableSelectColumnsEnum SourceInfo b
sourceInfo TableInfo b
tableInfo = do
NamingCase
tCase <- (r -> NamingCase) -> m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
GQLNameIdentifier
tableGQLName <- TableInfo b -> m GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName @b TableInfo b
tableInfo
[ColumnInfo b]
columns <- SourceInfo b -> TableInfo b -> m [ColumnInfo b]
forall (b :: BackendType) r (m :: * -> *).
(Backend b, MonadError QErr m, MonadReader r m,
Has SchemaContext r) =>
SourceInfo b -> TableInfo b -> m [ColumnInfo b]
tableSelectColumns SourceInfo b
sourceInfo TableInfo b
tableInfo
Name
enumName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m 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
mkTableSelectColumnTypeName GQLNameIdentifier
tableGQLName
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
"select columns of table " Text -> TableName b -> Text
forall t. ToTxt t => Text -> t -> Text
<>> TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b))))
-> Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall a b. (a -> b) -> a -> b
$
Name
-> Maybe Description
-> NonEmpty (Definition MetadataObjId EnumValueInfo, Column b)
-> Parser 'Both n (Column b)
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, Column b)
-> Parser 'Both n (Column b))
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
-> Maybe (Parser 'Both n (Column b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Definition MetadataObjId EnumValueInfo, Column b)]
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty
[ ( Name -> Definition MetadataObjId EnumValueInfo
forall origin. Name -> Definition origin EnumValueInfo
define (Name -> Definition MetadataObjId EnumValueInfo)
-> Name -> Definition MetadataObjId EnumValueInfo
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Name
forall (b :: BackendType). ColumnInfo b -> Name
ciName ColumnInfo b
column,
ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
column
)
| ColumnInfo b
column <- [ColumnInfo b]
columns
]
where
define :: Name -> Definition origin EnumValueInfo
define Name
name =
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
"column name") Maybe origin
forall a. Maybe a
Nothing [] EnumValueInfo
P.EnumValueInfo
tableSelectColumnsPredEnum ::
forall b r m n.
MonadBuildSchema b r m n =>
(ColumnType b -> Bool) ->
G.Name ->
SourceInfo b ->
TableInfo b ->
m (Maybe (Parser 'Both n (Column b)))
tableSelectColumnsPredEnum :: (ColumnType b -> Bool)
-> Name
-> SourceInfo b
-> TableInfo b
-> m (Maybe (Parser 'Both n (Column b)))
tableSelectColumnsPredEnum ColumnType b -> Bool
columnPredicate Name
predName SourceInfo b
sourceInfo TableInfo b
tableInfo = do
Name
tableGQLName <- TableInfo b -> m Name
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m Name
getTableGQLName @b TableInfo b
tableInfo
[ColumnInfo b]
columns <- (ColumnInfo b -> Bool) -> [ColumnInfo b] -> [ColumnInfo b]
forall a. (a -> Bool) -> [a] -> [a]
filter (ColumnType b -> Bool
columnPredicate (ColumnType b -> Bool)
-> (ColumnInfo b -> ColumnType b) -> ColumnInfo b -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColumnInfo b -> ColumnType b
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType) ([ColumnInfo b] -> [ColumnInfo b])
-> m [ColumnInfo b] -> m [ColumnInfo b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SourceInfo b -> TableInfo b -> m [ColumnInfo b]
forall (b :: BackendType) r (m :: * -> *).
(Backend b, MonadError QErr m, MonadReader r m,
Has SchemaContext r) =>
SourceInfo b -> TableInfo b -> m [ColumnInfo b]
tableSelectColumns SourceInfo b
sourceInfo TableInfo b
tableInfo
Name
enumName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m Name
forall a b. (a -> b) -> a -> b
$ Name
tableGQLName Name -> Name -> Name
forall a. Semigroup a => a -> a -> a
<> Name
Name.__select_column Name -> Name -> Name
forall a. Semigroup a => a -> a -> a
<> Name
Name.__ Name -> Name -> Name
forall a. Semigroup a => a -> a -> a
<> Name
predName
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
$
String -> Text
pack (String
"select " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Name -> String
forall a. Show a => a -> String
show Name
predName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"columns of table ") Text -> TableName b -> Text
forall t. ToTxt t => Text -> t -> Text
<>> TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b))))
-> Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall a b. (a -> b) -> a -> b
$
Name
-> Maybe Description
-> NonEmpty (Definition MetadataObjId EnumValueInfo, Column b)
-> Parser 'Both n (Column b)
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, Column b)
-> Parser 'Both n (Column b))
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
-> Maybe (Parser 'Both n (Column b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Definition MetadataObjId EnumValueInfo, Column b)]
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty
[ ( Name -> Definition MetadataObjId EnumValueInfo
forall origin. Name -> Definition origin EnumValueInfo
define (Name -> Definition MetadataObjId EnumValueInfo)
-> Name -> Definition MetadataObjId EnumValueInfo
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Name
forall (b :: BackendType). ColumnInfo b -> Name
ciName ColumnInfo b
column,
ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
column
)
| ColumnInfo b
column <- [ColumnInfo b]
columns
]
where
define :: Name -> Definition origin EnumValueInfo
define Name
name =
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
"column name") Maybe origin
forall a. Maybe a
Nothing [] EnumValueInfo
P.EnumValueInfo
tableUpdateColumnsEnum ::
forall b r m n.
MonadBuildSchema b r m n =>
TableInfo b ->
m (Maybe (Parser 'Both n (Column b)))
tableUpdateColumnsEnum :: TableInfo b -> m (Maybe (Parser 'Both n (Column b)))
tableUpdateColumnsEnum TableInfo b
tableInfo = do
RoleName
roleName <- (SchemaContext -> RoleName) -> m RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
NamingCase
tCase <- (r -> NamingCase) -> m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
GQLNameIdentifier
tableGQLName <- TableInfo b -> m GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo b
tableInfo
Name
enumName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m 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
mkTableUpdateColumnTypeName GQLNameIdentifier
tableGQLName
let tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
enumDesc :: Maybe Description
enumDesc = 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
"update columns of table " Text -> TableName b -> Text
forall t. ToTxt t => Text -> t -> Text
<>> TableName b
tableName
enumValues :: [(Definition MetadataObjId EnumValueInfo, Column b)]
enumValues = do
ColumnInfo b
column <- RoleName -> TableInfo b -> [ColumnInfo b]
forall (b :: BackendType).
Backend b =>
RoleName -> TableInfo b -> [ColumnInfo b]
tableUpdateColumns RoleName
roleName TableInfo b
tableInfo
(Definition MetadataObjId EnumValueInfo, Column b)
-> [(Definition MetadataObjId EnumValueInfo, Column b)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Name -> Definition MetadataObjId EnumValueInfo
forall origin. Name -> Definition origin EnumValueInfo
define (Name -> Definition MetadataObjId EnumValueInfo)
-> Name -> Definition MetadataObjId EnumValueInfo
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Name
forall (b :: BackendType). ColumnInfo b -> Name
ciName ColumnInfo b
column, ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
column)
Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b))))
-> Maybe (Parser 'Both n (Column b))
-> m (Maybe (Parser 'Both n (Column b)))
forall a b. (a -> b) -> a -> b
$ Name
-> Maybe Description
-> NonEmpty (Definition MetadataObjId EnumValueInfo, Column b)
-> Parser 'Both n (Column b)
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
enumDesc (NonEmpty (Definition MetadataObjId EnumValueInfo, Column b)
-> Parser 'Both n (Column b))
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
-> Maybe (Parser 'Both n (Column b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Definition MetadataObjId EnumValueInfo, Column b)]
-> Maybe
(NonEmpty (Definition MetadataObjId EnumValueInfo, Column b))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [(Definition MetadataObjId EnumValueInfo, Column b)]
enumValues
where
define :: Name -> Definition origin EnumValueInfo
define Name
name = 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
"column name") Maybe origin
forall a. Maybe a
Nothing [] EnumValueInfo
P.EnumValueInfo
updateColumnsPlaceholderParser ::
MonadBuildSchema backend r m n =>
TableInfo backend ->
m (Parser 'Both n (Maybe (Column backend)))
updateColumnsPlaceholderParser :: TableInfo backend -> m (Parser 'Both n (Maybe (Column backend)))
updateColumnsPlaceholderParser TableInfo backend
tableInfo = do
NamingCase
tCase <- (r -> NamingCase) -> m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
Maybe (Parser MetadataObjId 'Both n (Column backend))
maybeEnum <- TableInfo backend
-> m (Maybe (Parser MetadataObjId 'Both n (Column backend)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
TableInfo b -> m (Maybe (Parser 'Both n (Column b)))
tableUpdateColumnsEnum TableInfo backend
tableInfo
case Maybe (Parser MetadataObjId 'Both n (Column backend))
maybeEnum of
Just Parser MetadataObjId 'Both n (Column backend)
e -> Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend))))
-> Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend)))
forall a b. (a -> b) -> a -> b
$ Column backend -> Maybe (Column backend)
forall a. a -> Maybe a
Just (Column backend -> Maybe (Column backend))
-> Parser MetadataObjId 'Both n (Column backend)
-> Parser 'Both n (Maybe (Column backend))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser MetadataObjId 'Both n (Column backend)
e
Maybe (Parser MetadataObjId 'Both n (Column backend))
Nothing -> do
GQLNameIdentifier
tableGQLName <- TableInfo backend -> m GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo backend
tableInfo
Name
enumName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m 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
mkTableUpdateColumnTypeName GQLNameIdentifier
tableGQLName
Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend))))
-> Parser 'Both n (Maybe (Column backend))
-> m (Parser 'Both n (Maybe (Column backend)))
forall a b. (a -> b) -> a -> b
$
Name
-> Maybe Description
-> NonEmpty
(Definition MetadataObjId EnumValueInfo, Maybe (Column backend))
-> Parser 'Both n (Maybe (Column backend))
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> NonEmpty (Definition origin EnumValueInfo, a)
-> Parser origin 'Both m a
P.enum Name
enumName (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
"placeholder for update columns of table " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> TableInfo backend -> TableName backend
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo backend
tableInfo TableName backend -> Text -> Text
forall t. ToTxt t => t -> Text -> Text
<<> Text
" (current role has no relevant permissions)") (NonEmpty
(Definition MetadataObjId EnumValueInfo, Maybe (Column backend))
-> Parser 'Both n (Maybe (Column backend)))
-> NonEmpty
(Definition MetadataObjId EnumValueInfo, Maybe (Column backend))
-> Parser 'Both n (Maybe (Column backend))
forall a b. (a -> b) -> a -> b
$
(Definition MetadataObjId EnumValueInfo, Maybe (Column backend))
-> NonEmpty
(Definition MetadataObjId EnumValueInfo, Maybe (Column backend))
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( Name
-> Maybe Description
-> Maybe MetadataObjId
-> [Directive Void]
-> EnumValueInfo
-> Definition MetadataObjId EnumValueInfo
forall origin a.
Name
-> Maybe Description
-> Maybe origin
-> [Directive Void]
-> a
-> Definition origin a
P.Definition @_ @P.EnumValueInfo Name
Name.__PLACEHOLDER (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
"placeholder (do not use)") Maybe MetadataObjId
forall a. Maybe a
Nothing [] EnumValueInfo
P.EnumValueInfo,
Maybe (Column backend)
forall a. Maybe a
Nothing
)
tableSelectPermissions :: RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions :: RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions RoleName
role TableInfo b
tableInfo = RolePermInfo b -> Maybe (SelPermInfo b)
forall (b :: BackendType). RolePermInfo b -> Maybe (SelPermInfo b)
_permSel (RolePermInfo b -> Maybe (SelPermInfo b))
-> RolePermInfo b -> Maybe (SelPermInfo b)
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> RolePermInfo b
forall (b :: BackendType).
RoleName -> TableInfo b -> RolePermInfo b
getRolePermInfo RoleName
role TableInfo b
tableInfo
tableSelectFields ::
forall b r m.
( Backend b,
MonadError QErr m,
MonadReader r m,
Has SchemaContext r
) =>
SourceInfo b ->
TableInfo b ->
m [FieldInfo b]
tableSelectFields :: SourceInfo b -> TableInfo b -> m [FieldInfo b]
tableSelectFields SourceInfo b
sourceInfo TableInfo b
tableInfo = do
RoleName
roleName <- (SchemaContext -> RoleName) -> m RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
let tableFields :: FieldInfoMap (FieldInfo b)
tableFields = TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
-> FieldInfoMap (FieldInfo b)
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> FieldInfoMap field
_tciFieldInfoMap (TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
-> FieldInfoMap (FieldInfo b))
-> (TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b))
-> TableInfo b
-> FieldInfoMap (FieldInfo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo (TableInfo b -> FieldInfoMap (FieldInfo b))
-> TableInfo b -> FieldInfoMap (FieldInfo b)
forall a b. (a -> b) -> a -> b
$ TableInfo b
tableInfo
permissions :: Maybe (SelPermInfo b)
permissions = RoleName -> TableInfo b -> Maybe (SelPermInfo b)
forall (b :: BackendType).
RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions RoleName
roleName TableInfo b
tableInfo
(FieldInfo b -> m Bool) -> [FieldInfo b] -> m [FieldInfo b]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (RoleName -> Maybe (SelPermInfo b) -> FieldInfo b -> m Bool
canBeSelected RoleName
roleName Maybe (SelPermInfo b)
permissions) ([FieldInfo b] -> m [FieldInfo b])
-> [FieldInfo b] -> m [FieldInfo b]
forall a b. (a -> b) -> a -> b
$ FieldInfoMap (FieldInfo b) -> [FieldInfo b]
forall k v. HashMap k v -> [v]
Map.elems FieldInfoMap (FieldInfo b)
tableFields
where
canBeSelected :: RoleName -> Maybe (SelPermInfo b) -> FieldInfo b -> m Bool
canBeSelected RoleName
_ Maybe (SelPermInfo b)
Nothing FieldInfo b
_ = Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
canBeSelected RoleName
_ (Just SelPermInfo b
permissions) (FIColumn ColumnInfo b
columnInfo) =
Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ Column b
-> HashMap (Column b) (Maybe (AnnColumnCaseBoolExpPartialSQL b))
-> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
Map.member (ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
columnInfo) (SelPermInfo b
-> HashMap (Column b) (Maybe (AnnColumnCaseBoolExpPartialSQL b))
forall (b :: BackendType).
SelPermInfo b
-> HashMap (Column b) (Maybe (AnnColumnCaseBoolExpPartialSQL b))
spiCols SelPermInfo b
permissions)
canBeSelected RoleName
role Maybe (SelPermInfo b)
_ (FIRelationship RelInfo b
relationshipInfo) = do
TableInfo b
tableInfo' <- SourceInfo b -> TableName b -> m (TableInfo b)
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
SourceInfo b -> TableName b -> m (TableInfo b)
askTableInfo SourceInfo b
sourceInfo (TableName b -> m (TableInfo b)) -> TableName b -> m (TableInfo b)
forall a b. (a -> b) -> a -> b
$ RelInfo b -> TableName b
forall (b :: BackendType). RelInfo b -> TableName b
riRTable RelInfo b
relationshipInfo
Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ Maybe (SelPermInfo b) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (SelPermInfo b) -> Bool) -> Maybe (SelPermInfo b) -> Bool
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> Maybe (SelPermInfo b)
forall (b :: BackendType).
RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions @b RoleName
role TableInfo b
tableInfo'
canBeSelected RoleName
role (Just SelPermInfo b
permissions) (FIComputedField ComputedFieldInfo b
computedFieldInfo) =
case ComputedFieldReturn b -> ComputedFieldReturnType b
forall (b :: BackendType).
Backend b =>
ComputedFieldReturn b -> ComputedFieldReturnType b
computedFieldReturnType @b (ComputedFieldInfo b -> ComputedFieldReturn b
forall (b :: BackendType).
ComputedFieldInfo b -> ComputedFieldReturn b
_cfiReturnType ComputedFieldInfo b
computedFieldInfo) of
ReturnsScalar ScalarType b
_ ->
Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ ComputedFieldName
-> HashMap
ComputedFieldName (Maybe (AnnColumnCaseBoolExpPartialSQL b))
-> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
Map.member (ComputedFieldInfo b -> ComputedFieldName
forall (b :: BackendType). ComputedFieldInfo b -> ComputedFieldName
_cfiName ComputedFieldInfo b
computedFieldInfo) (HashMap
ComputedFieldName (Maybe (AnnColumnCaseBoolExpPartialSQL b))
-> Bool)
-> HashMap
ComputedFieldName (Maybe (AnnColumnCaseBoolExpPartialSQL b))
-> Bool
forall a b. (a -> b) -> a -> b
$ SelPermInfo b
-> HashMap
ComputedFieldName (Maybe (AnnColumnCaseBoolExpPartialSQL b))
forall (b :: BackendType).
SelPermInfo b
-> HashMap
ComputedFieldName (Maybe (AnnColumnCaseBoolExpPartialSQL b))
spiComputedFields SelPermInfo b
permissions
ReturnsTable TableName b
tableName -> do
TableInfo b
tableInfo' <- SourceInfo b -> TableName b -> m (TableInfo b)
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
SourceInfo b -> TableName b -> m (TableInfo b)
askTableInfo SourceInfo b
sourceInfo TableName b
tableName
Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ Maybe (SelPermInfo b) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (SelPermInfo b) -> Bool) -> Maybe (SelPermInfo b) -> Bool
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> Maybe (SelPermInfo b)
forall (b :: BackendType).
RoleName -> TableInfo b -> Maybe (SelPermInfo b)
tableSelectPermissions @b RoleName
role TableInfo b
tableInfo'
ComputedFieldReturnType b
ReturnsOthers -> Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
canBeSelected RoleName
_ Maybe (SelPermInfo b)
_ (FIRemoteRelationship RemoteFieldInfo (DBJoinField b)
_) = Bool -> m Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
tableColumns ::
forall b. TableInfo b -> [ColumnInfo b]
tableColumns :: TableInfo b -> [ColumnInfo b]
tableColumns TableInfo b
tableInfo =
(FieldInfo b -> Maybe (ColumnInfo b))
-> [FieldInfo b] -> [ColumnInfo b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe FieldInfo b -> Maybe (ColumnInfo b)
forall (b :: BackendType). FieldInfo b -> Maybe (ColumnInfo b)
columnInfo ([FieldInfo b] -> [ColumnInfo b])
-> (TableInfo b -> [FieldInfo b]) -> TableInfo b -> [ColumnInfo b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap FieldName (FieldInfo b) -> [FieldInfo b]
forall k v. HashMap k v -> [v]
Map.elems (HashMap FieldName (FieldInfo b) -> [FieldInfo b])
-> (TableInfo b -> HashMap FieldName (FieldInfo b))
-> TableInfo b
-> [FieldInfo b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
-> HashMap FieldName (FieldInfo b)
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> FieldInfoMap field
_tciFieldInfoMap (TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
-> HashMap FieldName (FieldInfo b))
-> (TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b))
-> TableInfo b
-> HashMap FieldName (FieldInfo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo (TableInfo b -> [ColumnInfo b]) -> TableInfo b -> [ColumnInfo b]
forall a b. (a -> b) -> a -> b
$ TableInfo b
tableInfo
where
columnInfo :: FieldInfo b -> Maybe (ColumnInfo b)
columnInfo (FIColumn ColumnInfo b
ci) = ColumnInfo b -> Maybe (ColumnInfo b)
forall a. a -> Maybe a
Just ColumnInfo b
ci
columnInfo FieldInfo b
_ = Maybe (ColumnInfo b)
forall a. Maybe a
Nothing
tableSelectColumns ::
forall b r m.
( Backend b,
MonadError QErr m,
MonadReader r m,
Has SchemaContext r
) =>
SourceInfo b ->
TableInfo b ->
m [ColumnInfo b]
tableSelectColumns :: SourceInfo b -> TableInfo b -> m [ColumnInfo b]
tableSelectColumns SourceInfo b
sourceInfo TableInfo b
tableInfo =
(FieldInfo b -> Maybe (ColumnInfo b))
-> [FieldInfo b] -> [ColumnInfo b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe FieldInfo b -> Maybe (ColumnInfo b)
forall (b :: BackendType). FieldInfo b -> Maybe (ColumnInfo b)
columnInfo ([FieldInfo b] -> [ColumnInfo b])
-> m [FieldInfo b] -> m [ColumnInfo b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SourceInfo b -> TableInfo b -> m [FieldInfo b]
forall (b :: BackendType) r (m :: * -> *).
(Backend b, MonadError QErr m, MonadReader r m,
Has SchemaContext r) =>
SourceInfo b -> TableInfo b -> m [FieldInfo b]
tableSelectFields SourceInfo b
sourceInfo TableInfo b
tableInfo
where
columnInfo :: FieldInfo b -> Maybe (ColumnInfo b)
columnInfo (FIColumn ColumnInfo b
ci) = ColumnInfo b -> Maybe (ColumnInfo b)
forall a. a -> Maybe a
Just ColumnInfo b
ci
columnInfo FieldInfo b
_ = Maybe (ColumnInfo b)
forall a. Maybe a
Nothing
tableUpdateColumns ::
forall b.
Backend b =>
RoleName ->
TableInfo b ->
[ColumnInfo b]
tableUpdateColumns :: RoleName -> TableInfo b -> [ColumnInfo b]
tableUpdateColumns RoleName
role TableInfo b
tableInfo =
let permissions :: Maybe (UpdPermInfo b)
permissions = RolePermInfo b -> Maybe (UpdPermInfo b)
forall (b :: BackendType). RolePermInfo b -> Maybe (UpdPermInfo b)
_permUpd (RolePermInfo b -> Maybe (UpdPermInfo b))
-> RolePermInfo b -> Maybe (UpdPermInfo b)
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> RolePermInfo b
forall (b :: BackendType).
RoleName -> TableInfo b -> RolePermInfo b
getRolePermInfo RoleName
role TableInfo b
tableInfo
in (ColumnInfo b -> Bool) -> [ColumnInfo b] -> [ColumnInfo b]
forall a. (a -> Bool) -> [a] -> [a]
filter (Maybe (UpdPermInfo b) -> ColumnInfo b -> Bool
isUpdatable Maybe (UpdPermInfo b)
permissions) ([ColumnInfo b] -> [ColumnInfo b])
-> [ColumnInfo b] -> [ColumnInfo b]
forall a b. (a -> b) -> a -> b
$ TableInfo b -> [ColumnInfo b]
forall (b :: BackendType). TableInfo b -> [ColumnInfo b]
tableColumns TableInfo b
tableInfo
where
isUpdatable :: Maybe (UpdPermInfo b) -> ColumnInfo b -> Bool
isUpdatable :: Maybe (UpdPermInfo b) -> ColumnInfo b -> Bool
isUpdatable (Just UpdPermInfo b
permissions) ColumnInfo b
columnInfo = Bool
columnIsUpdatable Bool -> Bool -> Bool
&& Bool
columnIsPermitted Bool -> Bool -> Bool
&& Bool
columnHasNoPreset
where
columnIsUpdatable :: Bool
columnIsUpdatable = ColumnMutability -> Bool
_cmIsUpdatable (ColumnInfo b -> ColumnMutability
forall (b :: BackendType). ColumnInfo b -> ColumnMutability
ciMutability ColumnInfo b
columnInfo)
columnIsPermitted :: Bool
columnIsPermitted = Column b -> HashSet (Column b) -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
Set.member (ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
columnInfo) (UpdPermInfo b -> HashSet (Column b)
forall (b :: BackendType). UpdPermInfo b -> HashSet (Column b)
upiCols UpdPermInfo b
permissions)
columnHasNoPreset :: Bool
columnHasNoPreset = Bool -> Bool
not (Column b -> HashMap (Column b) (PartialSQLExp b) -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
Map.member (ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
columnInfo) (UpdPermInfo b -> HashMap (Column b) (PartialSQLExp b)
forall (b :: BackendType). UpdPermInfo b -> PreSetColsPartial b
upiSet UpdPermInfo b
permissions))
isUpdatable Maybe (UpdPermInfo b)
Nothing ColumnInfo b
_ = Bool
False