orville-postgresql-1.1.0.0: src/Orville/PostgreSQL/Expr/ConditionalExpr.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Copyright : Flipstone Technology Partners 2024
License : MIT
Stability : Stable
@since 1.1.0.0
-}
module Orville.PostgreSQL.Expr.ConditionalExpr
( coalesce
, WhenExpr
, whenExpr
, caseExpr
, nullIf
, greatest
, least
) where
import qualified Data.List.NonEmpty as NE
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression)
import Orville.PostgreSQL.Expr.WhereClause (BooleanExpr)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
{- | Creates a 'ValueExpression' corresponding to the SQL @COALESE@.
@since 1.1.0.0
-}
coalesce :: NE.NonEmpty ValueExpression -> ValueExpression
coalesce valExprs =
RawSql.unsafeFromRawSql $
RawSql.fromString "COALESCE"
<> RawSql.leftParen
<> RawSql.intercalate RawSql.comma (fmap RawSql.toRawSql valExprs)
<> RawSql.rightParen
{- | Type to represent the @WHEN@ portion of a SQL @CASE@ expressions.
E.G.
> WHEN condition THEN result
'WhenExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.1.0.0
-}
newtype WhenExpr = WhenExpr RawSql.RawSql
deriving
( -- | @since 1.1.0.0
RawSql.SqlExpression
)
{- | Builds a 'WhenExpr' that will apply when the given 'BooleanExpr' evaluates to @TRUE@, resulting in the 'ValueExpression'
@since 1.1.0.0
-}
whenExpr :: BooleanExpr -> ValueExpression -> WhenExpr
whenExpr boolExpr resultExpr =
WhenExpr $
RawSql.fromString "WHEN"
<> RawSql.space
<> RawSql.toRawSql boolExpr
<> RawSql.space
<> RawSql.fromString "THEN"
<> RawSql.space
<> RawSql.toRawSql resultExpr
{- | Builds a 'ValueExpression' corresponding to a SQL @CASE@ using the given 'WhenExpr' as the tested value with results and an optional 'ValueExpression' that corresponds to the @ELSE@ portion of the @CASE@.
@since 1.1.0.0
-}
caseExpr ::
NE.NonEmpty WhenExpr ->
Maybe ValueExpression ->
ValueExpression
caseExpr whens mbElse =
RawSql.unsafeFromRawSql $
RawSql.fromString "CASE"
<> RawSql.space
<> RawSql.intercalate RawSql.space (fmap RawSql.toRawSql whens)
<> RawSql.space
<> case mbElse of
Nothing ->
RawSql.fromString "END"
Just elseVal ->
RawSql.fromString "ELSE"
<> RawSql.space
<> RawSql.toRawSql elseVal
<> RawSql.space
<> RawSql.fromString "END"
{- | Creates a 'ValueExpression' corresponding to the SQL @NULLIF@.
@since 1.1.0.0
-}
nullIf :: ValueExpression -> ValueExpression -> ValueExpression
nullIf leftVal rightVal =
RawSql.unsafeFromRawSql $
RawSql.fromString "NULLIF"
<> RawSql.leftParen
<> RawSql.toRawSql leftVal
<> RawSql.commaSpace
<> RawSql.toRawSql rightVal
<> RawSql.rightParen
{- | Creates a 'ValueExpression' corresponding to the SQL @GREATEST@.
@since 1.1.0.0
-}
greatest :: NE.NonEmpty ValueExpression -> ValueExpression
greatest valExprs =
RawSql.unsafeFromRawSql $
RawSql.fromString "GREATEST"
<> RawSql.leftParen
<> RawSql.intercalate RawSql.comma (fmap RawSql.toRawSql valExprs)
<> RawSql.rightParen
{- | Creates a 'ValueExpression' corresponding to the SQL @LEAST@.
@since 1.1.0.0
-}
least :: NE.NonEmpty ValueExpression -> ValueExpression
least valExprs =
RawSql.unsafeFromRawSql $
RawSql.fromString "LEAST"
<> RawSql.leftParen
<> RawSql.intercalate RawSql.comma (fmap RawSql.toRawSql valExprs)
<> RawSql.rightParen