module Database.Beam.Query.Operator
  ( SqlBool

    -- ** General-purpose operators
  , (&&.), (||.), not_, div_, mod_
  , (&&?.), (||?.), sqlNot_

  , like_, similarTo_

  , concat_
  ) where

import           Database.Beam.Backend.SQL

import           Database.Beam.Query.Internal

import           Control.Applicative

import qualified Data.Text as T

-- | Phantom type representing a SQL /Tri-state/ boolean -- true, false, and unknown
--
-- This type has no values because it cannot be sent to or retrieved
-- from the database directly. Use 'isTrue_', 'isFalse_',
-- 'isNotTrue_', 'isNotFalse_', 'isUnknown_', 'isNotUnknown_', and
-- `unknownAs_` to retrieve the corresponding 'Bool' value.
data SqlBool

-- | SQL @AND@ operator
(&&.) :: BeamSqlBackend be
      => QGenExpr context be s Bool
      -> QGenExpr context be s Bool
      -> QGenExpr context be s Bool
&&. :: QGenExpr context be s Bool
-> QGenExpr context be s Bool -> QGenExpr context be s Bool
(&&.) = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s Bool
-> QGenExpr context be s Bool
-> QGenExpr context be s Bool
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
andE

-- | SQL @OR@ operator
(||.) :: BeamSqlBackend be
      => QGenExpr context be s Bool
      -> QGenExpr context be s Bool
      -> QGenExpr context be
      s Bool
||. :: QGenExpr context be s Bool
-> QGenExpr context be s Bool -> QGenExpr context be s Bool
(||.) = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s Bool
-> QGenExpr context be s Bool
-> QGenExpr context be s Bool
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
orE

-- | SQL @AND@ operator for 'SqlBool'
(&&?.) :: BeamSqlBackend be
       => QGenExpr context be s SqlBool
       -> QGenExpr context be s SqlBool
       -> QGenExpr context be s SqlBool
&&?. :: QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool
(&&?.) = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
andE

-- | SQL @OR@ operator
(||?.) :: BeamSqlBackend be
       => QGenExpr context be s SqlBool
       -> QGenExpr context be s SqlBool
       -> QGenExpr context be s SqlBool
||?. :: QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool
(||?.) = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool
-> QGenExpr context be s SqlBool
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
orE

infixr 3 &&., &&?.
infixr 2 ||., ||?.

-- | SQL @LIKE@ operator
like_ :: ( BeamSqlBackendIsString be text
         , BeamSqlBackend be )
      => QGenExpr ctxt be s text -> QGenExpr ctxt be s text -> QGenExpr ctxt be s Bool
like_ :: QGenExpr ctxt be s text
-> QGenExpr ctxt be s text -> QGenExpr ctxt be s Bool
like_ (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
scrutinee) (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
search) =
  (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr ctxt be s Bool
forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr ((Sql92UpdateExpressionSyntax
   (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
 -> Sql92UpdateExpressionSyntax
      (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
 -> Sql92UpdateExpressionSyntax
      (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> (TablePrefix
    -> Sql92UpdateExpressionSyntax
         (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> (TablePrefix
    -> Sql92UpdateExpressionSyntax
         (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Sql92UpdateExpressionSyntax
  (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
likeE TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
TablePrefix -> BeamSqlBackendExpressionSyntax be
scrutinee TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
TablePrefix -> BeamSqlBackendExpressionSyntax be
search)

-- | SQL99 @SIMILAR TO@ operator
similarTo_ :: ( BeamSqlBackendIsString be text
              , BeamSql99ExpressionBackend be )
           => QGenExpr ctxt be s text -> QGenExpr ctxt be s text -> QGenExpr ctxt be s text
similarTo_ :: QGenExpr ctxt be s text
-> QGenExpr ctxt be s text -> QGenExpr ctxt be s text
similarTo_ (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
scrutinee) (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
search) =
  (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr ctxt be s text
forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr ((BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> TablePrefix
-> BeamSqlBackendExpressionSyntax be
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql99ExpressionSyntax expr => expr -> expr -> expr
similarToE TablePrefix -> BeamSqlBackendExpressionSyntax be
scrutinee TablePrefix -> BeamSqlBackendExpressionSyntax be
search)

infix 4 `like_`, `similarTo_`

-- | SQL @NOT@ operator
not_ :: forall be context s
      . BeamSqlBackend be
     => QGenExpr context be s Bool
     -> QGenExpr context be s Bool
not_ :: QGenExpr context be s Bool -> QGenExpr context be s Bool
not_ (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
a) = (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s Bool
forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr ((Sql92UpdateExpressionSyntax
   (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
 -> Sql92UpdateExpressionSyntax
      (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> (TablePrefix
    -> Sql92UpdateExpressionSyntax
         (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sql92UpdateExpressionSyntax
  (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall expr. IsSql92ExpressionSyntax expr => expr -> expr
notE TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
TablePrefix -> BeamSqlBackendExpressionSyntax be
a)

-- | SQL @NOT@ operator, but operating on 'SqlBool' instead
sqlNot_ :: forall be context s
         . BeamSqlBackend be
        => QGenExpr context be s SqlBool
        -> QGenExpr context be s SqlBool
sqlNot_ :: QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool
sqlNot_ (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
a) = (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s SqlBool
forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr ((Sql92UpdateExpressionSyntax
   (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
 -> Sql92UpdateExpressionSyntax
      (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> (TablePrefix
    -> Sql92UpdateExpressionSyntax
         (Sql92UpdateSyntax (BeamSqlBackendSyntax be)))
-> TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sql92UpdateExpressionSyntax
  (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
forall expr. IsSql92ExpressionSyntax expr => expr -> expr
notE TablePrefix
-> Sql92UpdateExpressionSyntax
     (Sql92UpdateSyntax (BeamSqlBackendSyntax be))
TablePrefix -> BeamSqlBackendExpressionSyntax be
a)

-- | SQL @/@ operator
div_ :: (Integral a, BeamSqlBackend be)
     => QGenExpr context be s a -> QGenExpr context be s a
     -> QGenExpr context be s a
div_ :: QGenExpr context be s a
-> QGenExpr context be s a -> QGenExpr context be s a
div_ = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s a
-> QGenExpr context be s a
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
divE

infixl 7 `div_`, `mod_`

-- | SQL @%@ operator
mod_ :: (Integral a, BeamSqlBackend be)
     => QGenExpr context be s a -> QGenExpr context be s a
     -> QGenExpr context be s a
mod_ :: QGenExpr context be s a
-> QGenExpr context be s a -> QGenExpr context be s a
mod_ = (BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s a
-> QGenExpr context be s a
forall be context s a b c.
BeamSqlBackend be =>
(BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be
 -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s a
-> QGenExpr context be s b
-> QGenExpr context be s c
qBinOpE BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
modE

-- | SQL @CONCAT@ function
concat_ :: BeamSql99ConcatExpressionBackend be
        => [ QGenExpr context be s T.Text ] -> QGenExpr context be s T.Text
concat_ :: [QGenExpr context be s TablePrefix]
-> QGenExpr context be s TablePrefix
concat_ [QGenExpr context be s TablePrefix]
es = (TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s TablePrefix
forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr ([BeamSqlBackendExpressionSyntax be]
-> BeamSqlBackendExpressionSyntax be
forall expr. IsSql99ConcatExpressionSyntax expr => [expr] -> expr
concatE ([BeamSqlBackendExpressionSyntax be]
 -> BeamSqlBackendExpressionSyntax be)
-> (TablePrefix -> [BeamSqlBackendExpressionSyntax be])
-> TablePrefix
-> BeamSqlBackendExpressionSyntax be
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QGenExpr context be s TablePrefix
 -> TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> [QGenExpr context be s TablePrefix]
-> TablePrefix
-> [BeamSqlBackendExpressionSyntax be]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
e) -> TablePrefix -> BeamSqlBackendExpressionSyntax be
e) [QGenExpr context be s TablePrefix]
es)