orville-postgresql-1.0.0.0: src/Orville/PostgreSQL/Expr/BinaryOperator.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Copyright : Flipstone Technology Partners 2023
License : MIT
Stability : Stable
Provides a type representing SQL operators with exactly two arguments, as well
as values of that type for many common operators.
@since 1.0.0.0
-}
module Orville.PostgreSQL.Expr.BinaryOperator
( BinaryOperator
, binaryOperator
, binaryOpExpression
, equalsOp
, notEqualsOp
, greaterThanOp
, lessThanOp
, greaterThanOrEqualsOp
, lessThanOrEqualsOp
, likeOp
, iLikeOp
, orOp
, andOp
, plusOp
, minusOp
, multiplicationOp
, divisionOp
, moduloOp
, exponentiationOp
, bitwiseAndOp
, bitwiseOrOp
, bitwiseXorOp
, bitwiseShiftLeftOp
, bitwiseShiftRightOp
)
where
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
{- |
Type to represent any SQL operator of two arguments. E.G.
> AND
'BinaryOperator' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype BinaryOperator
= BinaryOperator RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Construct a binary operator. Note that this does not include any check to determine if the
operator is valid, either by being a native SQL operator, or a custom-defined operator in the
database.
@since 1.0.0.0
-}
binaryOperator :: String -> BinaryOperator
binaryOperator =
BinaryOperator . RawSql.fromString
{- | The SQL equal binary operator.
@since 1.0.0.0
-}
equalsOp :: BinaryOperator
equalsOp =
binaryOperator "="
{- | The SQL not equal binary operator.
@since 1.0.0.0
-}
notEqualsOp :: BinaryOperator
notEqualsOp =
binaryOperator "<>"
{- | The SQL strictly greater than binary operator.
@since 1.0.0.0
-}
greaterThanOp :: BinaryOperator
greaterThanOp =
binaryOperator ">"
{- | The SQL strictly less than binary operator.
@since 1.0.0.0
-}
lessThanOp :: BinaryOperator
lessThanOp =
binaryOperator "<"
{- | The SQL greater than or equal binary operator.
@since 1.0.0.0
-}
greaterThanOrEqualsOp :: BinaryOperator
greaterThanOrEqualsOp =
binaryOperator ">="
{- | The SQL less than or equal binary operator.
@since 1.0.0.0
-}
lessThanOrEqualsOp :: BinaryOperator
lessThanOrEqualsOp =
binaryOperator "<="
{- | The SQL LIKE binary operator.
@since 1.0.0.0
-}
likeOp :: BinaryOperator
likeOp =
binaryOperator "LIKE"
{- | The SQL ILIKE binary operator.
@since 1.0.0.0
-}
iLikeOp :: BinaryOperator
iLikeOp =
binaryOperator "ILIKE"
{- | The SQL logical or binary operator.
@since 1.0.0.0
-}
orOp :: BinaryOperator
orOp =
binaryOperator "OR"
{- | The SQL logical and binary operator.
@since 1.0.0.0
-}
andOp :: BinaryOperator
andOp =
binaryOperator "AND"
{- | The SQL + binary operator.
@since 1.0.0.0
-}
plusOp :: BinaryOperator
plusOp =
binaryOperator "+"
{- | The SQL - binary operator.
@since 1.0.0.0
-}
minusOp :: BinaryOperator
minusOp =
binaryOperator "-"
{- | The SQL * binary operator.
@since 1.0.0.0
-}
multiplicationOp :: BinaryOperator
multiplicationOp =
binaryOperator "*"
{- | The SQL / binary operator.
@since 1.0.0.0
-}
divisionOp :: BinaryOperator
divisionOp =
binaryOperator "/"
{- | The SQL % binary operator.
@since 1.0.0.0
-}
moduloOp :: BinaryOperator
moduloOp =
binaryOperator "%"
{- | The SQL ^ binary operator.
@since 1.0.0.0
-}
exponentiationOp :: BinaryOperator
exponentiationOp =
binaryOperator "^"
{- | The SQL bitwise and (a.k.a &) binary operator.
@since 1.0.0.0
-}
bitwiseAndOp :: BinaryOperator
bitwiseAndOp =
binaryOperator "&"
{- | The SQL bitwise or (a.k.a |) binary operator.
@since 1.0.0.0
-}
bitwiseOrOp :: BinaryOperator
bitwiseOrOp =
binaryOperator "|"
{- | The SQL bitwise exclusive or (a.k.a #) binary operator.
@since 1.0.0.0
-}
bitwiseXorOp :: BinaryOperator
bitwiseXorOp =
binaryOperator "#"
{- | The SQL bitwise left shift (a.k.a <<) binary operator.
@since 1.0.0.0
-}
bitwiseShiftLeftOp :: BinaryOperator
bitwiseShiftLeftOp =
binaryOperator "<<"
{- | The SQL bitwise right shift (a.k.a >>) binary operator.
@since 1.0.0.0
-}
bitwiseShiftRightOp :: BinaryOperator
bitwiseShiftRightOp =
binaryOperator ">>"
{- | Apply a binary operator to two 'ValueExpression's resulting in some
'RawSql.SqlExpression'. Note that this does *NOT* extend typechecking to the 'ValueExpression's
being used with the 'BinaryOperator'. It is left to the caller to ensure that the operator makes
sense with the arguments being passed.
@since 1.0.0.0
-}
binaryOpExpression ::
RawSql.SqlExpression sql =>
BinaryOperator ->
ValueExpression ->
ValueExpression ->
sql
binaryOpExpression op left right =
binaryOpExpressionUnparenthenizedArguments
op
(RawSql.unsafeFromRawSql (RawSql.leftParen <> RawSql.toRawSql left <> RawSql.rightParen))
(RawSql.unsafeFromRawSql (RawSql.leftParen <> RawSql.toRawSql right <> RawSql.rightParen))
-- internal helper function
binaryOpExpressionUnparenthenizedArguments ::
RawSql.SqlExpression sql =>
BinaryOperator ->
ValueExpression ->
ValueExpression ->
sql
binaryOpExpressionUnparenthenizedArguments op left right =
RawSql.unsafeFromRawSql $
RawSql.toRawSql left
<> RawSql.space
<> RawSql.toRawSql op
<> RawSql.space
<> RawSql.toRawSql right