@@ -3,6 +3,7 @@ module Hasura.GraphQL.Schema.Select where
3
3
import Hasura.Prelude
4
4
5
5
import qualified Data.HashMap.Strict as Map
6
+ import qualified Data.HashSet as Set
6
7
import qualified Language.GraphQL.Draft.Syntax as G
7
8
8
9
import qualified Hasura.GraphQL.Parser as P
@@ -19,10 +20,11 @@ import Hasura.SQL.Value
19
20
20
21
21
22
22
- type SelectExp = RQL. AnnSimpleSelG UnpreparedValue
23
- type TableArgs = RQL. TableArgsG UnpreparedValue
24
- type TablePerms = RQL. TablePermG UnpreparedValue
25
-
23
+ type SelectExp = RQL. AnnSimpleSelG UnpreparedValue
24
+ type TableArgs = RQL. TableArgsG UnpreparedValue
25
+ type TablePerms = RQL. TablePermG UnpreparedValue
26
+ type AnnotatedFields = RQL. AnnFldsG UnpreparedValue
27
+ type AnnotatedField = RQL. AnnFldG UnpreparedValue
26
28
27
29
28
30
queryExp
@@ -32,54 +34,59 @@ queryExp
32
34
-> m (Parser 'Output n (HashMap G. Name SelectExp ))
33
35
queryExp allTables stringifyNum = do
34
36
selectExpParsers <- for (toList allTables) $ \ tableName -> do
35
- tablePermissions <- tablePerms tableName
36
- for tablePermissions $ \ perms ->
37
- selectExp tableName perms stringifyNum
37
+ selPerms <- tableSelectPermissions tableName
38
+ for selPerms $ \ perms -> selectExp tableName perms stringifyNum
38
39
let queryFieldsParser = fmap (Map. fromList . catMaybes) $ sequenceA $ catMaybes selectExpParsers
39
40
pure $ P. selectionSet $$ (G. litName " Query" ) Nothing queryFieldsParser
40
41
41
-
42
-
43
-
44
42
selectExp
45
43
:: forall m n . (MonadSchema n m , MonadError QErr m )
46
44
=> QualifiedTable
47
- -> TablePerms
45
+ -> SelPermInfo
48
46
-> Bool
49
47
-> m (FieldsParser 'Output n (Maybe (G. Name , SelectExp )))
50
- selectExp table tablePermissions stringifyNum = do
48
+ selectExp table selectPermissions stringifyNum = do
51
49
name <- qualifiedObjectToName table
52
50
tableArgsParser <- tableArgs table
53
- selectionSetParser <- tableSelectionSet table
51
+ selectionSetParser <- tableSelectionSet table selectPermissions
54
52
return $ P. selection name Nothing tableArgsParser selectionSetParser <&> fmap
55
53
\ (aliasName, tableArgs, tableFields) -> (aliasName, RQL. AnnSelG
56
54
{ RQL. _asnFields = tableFields
57
55
, RQL. _asnFrom = RQL. FromTable table
58
- , RQL. _asnPerm = tablePermissions
56
+ , RQL. _asnPerm = tablePermissions selectPermissions
59
57
, RQL. _asnArgs = tableArgs
60
58
, RQL. _asnStrfyNum = stringifyNum
61
59
})
62
60
63
-
64
- tablePerms
61
+ tableSelectPermissions
65
62
:: forall m n . (MonadSchema n m )
66
63
=> QualifiedTable
67
- -> m (Maybe TablePerms )
68
- tablePerms table = do
64
+ -> m (Maybe SelPermInfo )
65
+ tableSelectPermissions table = do
69
66
roleName <- askRoleName
70
67
tableInfo <- _tiRolePermInfoMap <$> askTableInfo table
71
- return $ do
72
- rolePermissions <- Map. lookup roleName tableInfo
73
- selectPermissions <- _permSel rolePermissions
74
- return $ RQL. TablePerm
75
- { RQL. _tpFilter = fmapAnnBoolExp toUnpreparedValue $ spiFilter selectPermissions
76
- , RQL. _tpLimit = spiLimit selectPermissions
77
- }
68
+ return $ _permSel =<< Map. lookup roleName tableInfo
69
+
70
+ tablePermissions :: SelPermInfo -> TablePerms
71
+ tablePermissions selectPermissions =
72
+ RQL. TablePerm { RQL. _tpFilter = fmapAnnBoolExp toUnpreparedValue $ spiFilter selectPermissions
73
+ , RQL. _tpLimit = spiLimit selectPermissions
74
+ }
78
75
where
79
76
toUnpreparedValue (PSESessVar pftype var) = P. UVSessionVar pftype var
80
- toUnpreparedValue (PSESQLExp exp ) = P. UVLiteral exp
77
+ toUnpreparedValue (PSESQLExp sqlExp ) = P. UVLiteral sqlExp
81
78
82
79
80
+ -- | Corresponds to an object type for table argumuments:
81
+ --
82
+ -- FIXME: is that the correct name?
83
+ -- > type table_arguments {
84
+ -- > distinct_on: [card_types_select_column!]
85
+ -- > limit: Int
86
+ -- > offset: Int
87
+ -- > order_by: [card_types_order_by!]
88
+ -- > where: card_types_bool_exp
89
+ -- > }
83
90
tableArgs
84
91
:: forall m n . (MonadSchema n m , MonadError QErr m )
85
92
=> QualifiedTable
@@ -95,25 +102,12 @@ tableArgs table = do
95
102
, RQL. _taOrderBy = Nothing -- TODO
96
103
, RQL. _taLimit = fromIntegral <$> limit
97
104
, RQL. _taOffset = txtEncoder . PGValInteger <$> offset
98
- , RQL. _taDistCols = Nothing
105
+ , RQL. _taDistCols = Nothing -- TODO
99
106
}
100
107
where limitName = $$ (G. litName " limit" )
101
108
offsetName = $$ (G. litName " offset" )
102
109
whereName = $$ (G. litName " where" )
103
110
104
- -- SELit . Text.pack . show <$>
105
- {-
106
- distinct_on: [card_types_select_column!]
107
- limit: Intoffset: Int
108
- order_by: [card_types_order_by!]
109
- where: card_types_bool_exp
110
- -}
111
-
112
-
113
- type AnnotatedFields = RQL. AnnFldsG UnpreparedValue
114
- type AnnotatedField = RQL. AnnFldG UnpreparedValue
115
-
116
-
117
111
118
112
-- | Corresponds to an object type for a table:
119
113
--
@@ -125,12 +119,14 @@ type AnnotatedField = RQL.AnnFldG UnpreparedValue
125
119
tableSelectionSet
126
120
:: (MonadSchema n m , MonadError QErr m )
127
121
=> QualifiedTable
122
+ -> SelPermInfo
128
123
-> m (Parser 'Output n AnnotatedFields )
129
- tableSelectionSet = P. memoize 'tableSelectionSet \ tableName -> do
124
+ tableSelectionSet tableName selectPermissions = memoizeOn 'tableSelectionSet tableName $ do
130
125
tableInfo <- _tiCoreInfo <$> askTableInfo tableName
131
126
name <- qualifiedObjectToName $ _tciName tableInfo
132
- -- FIXME: permissions!
133
- fields <- catMaybes <$> traverse fieldSelection (Map. elems $ _tciFieldInfoMap tableInfo)
127
+ fields <- fmap catMaybes $ traverse (fieldSelection selectPermissions)
128
+ $ Map. elems
129
+ $ _tciFieldInfoMap tableInfo
134
130
pure $ P. selectionSet name (_tciDescription tableInfo) $ catMaybes <$> sequenceA fields
135
131
136
132
-- | A field for a table. Returns 'Nothing' if the field’s name is not a valid
@@ -139,14 +135,17 @@ tableSelectionSet = P.memoize 'tableSelectionSet \tableName -> do
139
135
-- > field_name(arg_name: arg_type, ...): field_type
140
136
fieldSelection
141
137
:: (MonadSchema n m , MonadError QErr m )
142
- => FieldInfo
138
+ => SelPermInfo
139
+ -> FieldInfo
143
140
-> m (Maybe (FieldsParser 'Output n (Maybe (FieldName , AnnotatedField ))))
144
- fieldSelection fieldInfo = for (fieldInfoGraphQLName fieldInfo) \ fieldName ->
141
+ fieldSelection selectPermissions fieldInfo = for (fieldInfoGraphQLName fieldInfo) \ fieldName ->
145
142
aliasToFieldName <$> case fieldInfo of
146
143
FIColumn columnInfo -> do
147
144
let annotated = RQL. mkAnnColField columnInfo Nothing -- FIXME: support ColOp
148
145
field <- P. column (pgiType columnInfo) (G. Nullability $ pgiIsNullable columnInfo)
149
- pure $ fmap (, annotated) <$> P. selection_ fieldName fieldDescription field
146
+ pure $ if Set. member (pgiColumn columnInfo) $ spiCols selectPermissions
147
+ then fmap (, annotated) <$> P. selection_ fieldName fieldDescription field
148
+ else pure Nothing
150
149
FIRelationship relationshipInfo -> undefined -- TODO: implement
151
150
FIComputedField computedFieldInfo -> undefined -- TODO: implement
152
151
where
0 commit comments