module Database.Beam.Query.Operator
  ( SqlBool

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

  , like_, similarTo_
  , 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
&&. :: forall be context s.
BeamSqlBackend 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 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
||. :: forall be context s.
BeamSqlBackend 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 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
&&?. :: forall be context s.
BeamSqlBackend 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 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
||?. :: forall be context s.
BeamSqlBackend 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 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_ :: forall be text ctxt s.
(BeamSqlBackendIsString be text, BeamSqlBackend be) =>
QGenExpr ctxt be s text
-> QGenExpr ctxt be s text -> QGenExpr ctxt be s Bool
like_ = forall be left right ctxt s.
(BeamSqlBackendIsString be left, BeamSqlBackendIsString be right,
 BeamSqlBackend be) =>
QGenExpr ctxt be s left
-> QGenExpr ctxt be s right -> QGenExpr ctxt be s Bool
like_'

-- | SQL @LIKE@ operator but heterogeneous over the text type
like_'
  :: ( BeamSqlBackendIsString be left
     , BeamSqlBackendIsString be right
     , BeamSqlBackend be
     )
  => QGenExpr ctxt be s left
  -> QGenExpr ctxt be s right
  -> QGenExpr ctxt be s Bool
like_' :: forall be left right ctxt s.
(BeamSqlBackendIsString be left, BeamSqlBackendIsString be right,
 BeamSqlBackend be) =>
QGenExpr ctxt be s left
-> QGenExpr ctxt be s right -> QGenExpr ctxt be s Bool
like_' (QExpr TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
scrutinee) (QExpr TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
search) =
  forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall expr. IsSql92ExpressionSyntax expr => expr -> expr -> expr
likeE TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
scrutinee TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax 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_ :: forall be text ctxt s.
(BeamSqlBackendIsString be text, BeamSql99ExpressionBackend be) =>
QGenExpr ctxt be s text
-> QGenExpr ctxt be s text -> QGenExpr ctxt be s text
similarTo_ = forall be left right ctxt s.
(BeamSqlBackendIsString be left, BeamSqlBackendIsString be right,
 BeamSql99ExpressionBackend be) =>
QGenExpr ctxt be s left
-> QGenExpr ctxt be s right -> QGenExpr ctxt be s left
similarTo_'

-- | SQL99 @SIMILAR TO@ operator but heterogeneous over the text type
similarTo_'
  :: ( BeamSqlBackendIsString be left
     , BeamSqlBackendIsString be right
     , BeamSql99ExpressionBackend be
     )
  => QGenExpr ctxt be s left
  -> QGenExpr ctxt be s right
  -> QGenExpr ctxt be s left
similarTo_' :: forall be left right ctxt s.
(BeamSqlBackendIsString be left, BeamSqlBackendIsString be right,
 BeamSql99ExpressionBackend be) =>
QGenExpr ctxt be s left
-> QGenExpr ctxt be s right -> QGenExpr ctxt be s left
similarTo_' (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
scrutinee) (QExpr TablePrefix -> BeamSqlBackendExpressionSyntax be
search) =
  forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 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_ :: forall be context s.
BeamSqlBackend be =>
QGenExpr context be s Bool -> QGenExpr context be s Bool
not_ (QExpr TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
a) = forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall expr. IsSql92ExpressionSyntax expr => expr -> expr
notE TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax 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_ :: forall be context s.
BeamSqlBackend be =>
QGenExpr context be s SqlBool -> QGenExpr context be s SqlBool
sqlNot_ (QExpr TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
a) = forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall expr. IsSql92ExpressionSyntax expr => expr -> expr
notE TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax 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_ :: forall a be context s.
(Integral a, BeamSqlBackend be) =>
QGenExpr context be s a
-> QGenExpr context be s a -> QGenExpr context be s a
div_ = 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 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_ :: forall a be context s.
(Integral a, BeamSqlBackend be) =>
QGenExpr context be s a
-> QGenExpr context be s a -> QGenExpr context be s a
mod_ = 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 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_ :: forall be context s.
BeamSql99ConcatExpressionBackend be =>
[QGenExpr context be s TablePrefix]
-> QGenExpr context be s TablePrefix
concat_ [QGenExpr context be s TablePrefix]
es = forall context be s t.
(TablePrefix -> BeamSqlBackendExpressionSyntax be)
-> QGenExpr context be s t
QExpr (forall expr. IsSql99ConcatExpressionSyntax expr => [expr] -> expr
concatE forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(QExpr TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
e) -> TablePrefix
-> Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be)))
e) [QGenExpr context be s TablePrefix]
es)