2022-03-16 07:12:15 +03:00
{- # LANGUAGE DeriveAnyClass # -}
2022-03-31 07:45:03 +03:00
{- # LANGUAGE OverloadedLists # -}
2022-03-16 07:12:15 +03:00
2022-05-02 08:03:12 +03:00
module Hasura.Backends.DataConnector.API.V0.Expression
2022-03-16 07:12:15 +03:00
( Expression ( .. ) ,
2022-06-02 05:06:45 +03:00
BinaryComparisonOperator ( .. ) ,
BinaryArrayComparisonOperator ( .. ) ,
UnaryComparisonOperator ( .. ) ,
2022-06-24 09:58:25 +03:00
ComparisonColumn ( .. ) ,
2022-06-02 05:06:45 +03:00
ComparisonValue ( .. ) ,
2022-03-16 07:12:15 +03:00
)
where
2022-03-31 07:45:03 +03:00
import Autodocodec.Extended
import Autodocodec.OpenAPI ( )
2022-04-01 04:20:23 +03:00
import Control.DeepSeq ( NFData )
2022-09-06 07:24:46 +03:00
import Data.Aeson ( FromJSON , ToJSON , Value )
2022-04-01 04:20:23 +03:00
import Data.Data ( Data )
2022-07-27 08:27:34 +03:00
import Data.HashMap.Strict qualified as HashMap
2022-04-01 04:20:23 +03:00
import Data.Hashable ( Hashable )
2022-03-31 07:45:03 +03:00
import Data.OpenApi ( ToSchema )
2022-07-15 06:27:31 +03:00
import Data.Text ( Text )
2022-07-27 08:27:34 +03:00
import Data.Tuple.Extra
2022-04-01 04:20:23 +03:00
import GHC.Generics ( Generic )
2022-05-02 08:03:12 +03:00
import Hasura.Backends.DataConnector.API.V0.Column qualified as API . V0
2022-06-24 09:58:25 +03:00
import Hasura.Backends.DataConnector.API.V0.Relationships qualified as API . V0
2022-04-01 04:20:23 +03:00
import Prelude
2022-03-16 07:12:15 +03:00
--------------------------------------------------------------------------------
2022-06-02 05:06:45 +03:00
-- | A serializable representation of binary comparison operators.
data BinaryComparisonOperator
2022-03-16 07:12:15 +03:00
= LessThan
| LessThanOrEqual
| GreaterThan
| GreaterThanOrEqual
2022-04-28 04:51:58 +03:00
| Equal
2022-07-15 06:27:31 +03:00
| CustomBinaryComparisonOperator { getCustomBinaryComparisonOperator :: Text }
deriving stock ( Data , Eq , Generic , Ord , Show )
2022-04-01 04:20:23 +03:00
deriving anyclass ( Hashable , NFData )
2022-06-02 05:06:45 +03:00
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec BinaryComparisonOperator
2022-03-31 07:45:03 +03:00
2022-06-02 05:06:45 +03:00
instance HasCodec BinaryComparisonOperator where
2022-03-31 07:45:03 +03:00
codec =
2022-06-02 05:06:45 +03:00
named " BinaryComparisonOperator " $
2022-07-15 06:27:31 +03:00
matchChoiceCodec
2022-07-27 08:27:34 +03:00
( stringConstCodec
2022-07-15 06:27:31 +03:00
[ ( LessThan , " less_than " ) ,
( LessThanOrEqual , " less_than_or_equal " ) ,
( GreaterThan , " greater_than " ) ,
( GreaterThanOrEqual , " greater_than_or_equal " ) ,
( Equal , " equal " )
]
)
( dimapCodec CustomBinaryComparisonOperator getCustomBinaryComparisonOperator textCodec )
2022-09-06 07:24:46 +03:00
\ case
2022-07-15 06:27:31 +03:00
op @ CustomBinaryComparisonOperator { } -> Right op
op -> Left op
2022-03-31 07:45:03 +03:00
2022-06-02 05:06:45 +03:00
-- | A serializable representation of binary array comparison operators.
data BinaryArrayComparisonOperator
= In
2022-07-15 06:27:31 +03:00
| CustomBinaryArrayComparisonOperator { getCustomBinaryArrayComparisonOperator :: Text }
deriving stock ( Data , Eq , Generic , Ord , Show )
2022-06-02 05:06:45 +03:00
deriving anyclass ( Hashable , NFData )
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec BinaryArrayComparisonOperator
instance HasCodec BinaryArrayComparisonOperator where
codec =
named " BinaryArrayComparisonOperator " $
2022-07-15 06:27:31 +03:00
matchChoiceCodec
2022-07-27 08:27:34 +03:00
( stringConstCodec
2022-07-15 06:27:31 +03:00
[ ( In , " in " )
]
)
( dimapCodec CustomBinaryArrayComparisonOperator getCustomBinaryArrayComparisonOperator textCodec )
2022-09-06 07:24:46 +03:00
\ case
2022-07-15 06:27:31 +03:00
op @ CustomBinaryArrayComparisonOperator { } -> Right op
op -> Left op
2022-06-02 05:06:45 +03:00
-- | A serializable representation of unary comparison operators.
data UnaryComparisonOperator
= IsNull
2022-07-15 06:27:31 +03:00
| CustomUnaryComparisonOperator { getCustomUnaryComparisonOperator :: Text }
deriving stock ( Data , Eq , Generic , Ord , Show )
2022-06-02 05:06:45 +03:00
deriving anyclass ( Hashable , NFData )
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec UnaryComparisonOperator
instance HasCodec UnaryComparisonOperator where
codec =
named " UnaryComparisonOperator " $
2022-07-15 06:27:31 +03:00
matchChoiceCodec
2022-07-27 08:27:34 +03:00
( stringConstCodec
2022-07-15 06:27:31 +03:00
[ ( IsNull , " is_null " )
]
)
( dimapCodec CustomUnaryComparisonOperator getCustomUnaryComparisonOperator textCodec )
2022-09-06 07:24:46 +03:00
\ case
2022-07-15 06:27:31 +03:00
op @ CustomUnaryComparisonOperator { } -> Right op
op -> Left op
2022-03-31 07:45:03 +03:00
-- | A serializable representation of query expressions.
data Expression
2022-07-27 08:27:34 +03:00
= And [ Expression ]
| Or [ Expression ]
| Not Expression
| ApplyBinaryComparisonOperator BinaryComparisonOperator ComparisonColumn ComparisonValue
2022-09-06 07:24:46 +03:00
| ApplyBinaryArrayComparisonOperator BinaryArrayComparisonOperator ComparisonColumn [ Value ]
2022-07-27 08:27:34 +03:00
| ApplyUnaryComparisonOperator UnaryComparisonOperator ComparisonColumn
2022-06-02 05:06:45 +03:00
deriving stock ( Data , Eq , Generic , Ord , Show )
deriving anyclass ( Hashable , NFData )
2022-07-27 08:27:34 +03:00
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec Expression
instance HasCodec Expression where
codec =
named " Expression " $
object " Expression " $
discriminatedUnionCodec " type " enc dec
where
expressionsCodec = requiredField' " expressions "
expressionCodec = requiredField' " expression "
binaryOperatorCodec =
( , , )
<$> requiredField' " operator " .= fst3
<*> requiredField' " column " .= snd3
<*> requiredField' " value " .= thd3
binaryArrayOperatorCodec =
( , , )
<$> requiredField' " operator " .= fst3
<*> requiredField' " column " .= snd3
<*> requiredField' " values " .= thd3
unaryOperatorCodec =
( , )
<$> requiredField' " operator " .= fst
<*> requiredField' " column " .= snd
enc = \ case
And expressions -> ( " and " , mapToEncoder expressions expressionsCodec )
Or expressions -> ( " or " , mapToEncoder expressions expressionsCodec )
Not expression -> ( " not " , mapToEncoder expression expressionCodec )
ApplyBinaryComparisonOperator o c v ->
( " binary_op " , mapToEncoder ( o , c , v ) binaryOperatorCodec )
ApplyBinaryArrayComparisonOperator o c vs ->
( " binary_arr_op " , mapToEncoder ( o , c , vs ) binaryArrayOperatorCodec )
ApplyUnaryComparisonOperator o c ->
( " unary_op " , mapToEncoder ( o , c ) unaryOperatorCodec )
dec =
HashMap . fromList
[ ( " and " , ( " AndExpression " , mapToDecoder And expressionsCodec ) ) ,
( " or " , ( " OrExpression " , mapToDecoder Or expressionsCodec ) ) ,
( " not " , ( " NotExpression " , mapToDecoder Not expressionCodec ) ) ,
( " binary_op " ,
( " ApplyBinaryComparisonOperator " ,
mapToDecoder ( uncurry3 ApplyBinaryComparisonOperator ) binaryOperatorCodec
)
) ,
( " binary_arr_op " ,
( " ApplyBinaryArrayComparisonOperator " ,
mapToDecoder ( uncurry3 ApplyBinaryArrayComparisonOperator ) binaryArrayOperatorCodec
)
) ,
( " unary_op " ,
( " ApplyUnaryComparisonOperator " ,
mapToDecoder ( uncurry ApplyUnaryComparisonOperator ) unaryOperatorCodec
)
)
]
2022-06-02 05:06:45 +03:00
2022-06-24 09:58:25 +03:00
-- | Specifies a particular column to use in a comparison via its path and name
data ComparisonColumn = ComparisonColumn
{ -- | The path of relationships from the current query table to the table that contains the column
_ccPath :: [ API . V0 . RelationshipName ] ,
-- | The name of the column
_ccName :: API . V0 . ColumnName
}
deriving stock ( Eq , Ord , Show , Generic , Data )
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec ComparisonColumn
deriving anyclass ( Hashable , NFData )
instance HasCodec ComparisonColumn where
codec =
object " ComparisonColumn " $
ComparisonColumn
<$> requiredField " path " " The relationship path from the current query table to the table that contains the specified column. Empty array means the current query table. " .= _ccPath
<*> requiredField " name " " The name of the column " .= _ccName
2022-06-02 05:06:45 +03:00
-- | A serializable representation of comparison values used in comparisons inside 'Expression's.
data ComparisonValue
2022-06-24 09:58:25 +03:00
= -- | Allows a comparison to a column on the current table or another table
2022-07-27 08:27:34 +03:00
AnotherColumn ComparisonColumn
2022-09-06 07:24:46 +03:00
| ScalarValue Value
2022-03-16 07:12:15 +03:00
deriving stock ( Data , Eq , Generic , Ord , Show )
2022-04-01 04:20:23 +03:00
deriving anyclass ( Hashable , NFData )
2022-07-27 08:27:34 +03:00
deriving ( FromJSON , ToJSON , ToSchema ) via Autodocodec ComparisonValue
2022-06-02 05:06:45 +03:00
instance HasCodec ComparisonValue where
codec =
2022-07-27 08:27:34 +03:00
object " ComparisonValue " $
discriminatedUnionCodec " type " enc dec
where
columnCodec = requiredField' " column "
scalarValueCodec = requiredField' " value "
enc = \ case
AnotherColumn c -> ( " column " , mapToEncoder c columnCodec )
ScalarValue v -> ( " scalar " , mapToEncoder v scalarValueCodec )
dec =
HashMap . fromList
[ ( " column " , ( " AnotherColumnComparison " , mapToDecoder AnotherColumn columnCodec ) ) ,
( " scalar " , ( " ScalarValueComparison " , mapToDecoder ScalarValue scalarValueCodec ) )
]