{-# LANGUAGE CPP #-}
{-# language DerivingStrategies, GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}

-- | This is an internal module, anything exported by this module
-- may change without a major version bump.  Please use only
-- "Database.Esqueleto" if possible.
--
-- If you use this module, please report what your use case is on the issue
-- tracker so we can safely support it.
module Database.Esqueleto.Internal.Internal where

import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NEL
import Control.Applicative ((<|>))
import Control.Arrow (first, (***))
import Control.Exception (Exception, throw, throwIO)
import Control.Monad (MonadPlus(..), guard, void)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Resource (MonadResource, release)
import Data.Acquire (Acquire, allocateAcquire, with)
import Data.Int (Int64)
import Data.List (intersperse)
import qualified Data.Maybe as Maybe
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup
#endif
import qualified Control.Monad.Trans.Reader as R
import qualified Control.Monad.Trans.State as S
import qualified Control.Monad.Trans.Writer as W
import qualified Data.ByteString as B
import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
import qualified Data.HashSet as HS
import qualified Data.Map.Strict as Map
import qualified Data.Monoid as Monoid
import Data.Proxy (Proxy(..))
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TLB
import Data.Typeable (Typeable)
import Database.Esqueleto.Internal.ExprParser (TableAccess(..), parseOnExpr)
import Database.Esqueleto.Internal.PersistentImport
import Database.Persist.SqlBackend
import qualified Database.Persist
import Database.Persist (FieldNameDB(..), EntityNameDB(..))
import Database.Persist.Sql.Util
       ( entityColumnCount
       , keyAndEntityColumnNames
       , hasNaturalKey
       , isIdField
       , parseEntityValues
       )
import Text.Blaze.Html (Html)
import Data.Coerce (coerce)

-- | (Internal) Start a 'from' query with an entity. 'from'
-- does two kinds of magic using 'fromStart', 'fromJoin' and
-- 'fromFinish':
--
--   1.  The simple but tedious magic of allowing tuples to be
--   used.
--
--   2.  The more advanced magic of creating @JOIN@s.  The
--   @JOIN@ is processed from right to left.  The rightmost
--   entity of the @JOIN@ is created with 'fromStart'.  Each
--   @JOIN@ step is then translated into a call to 'fromJoin'.
--   In the end, 'fromFinish' is called to materialize the
--   @JOIN@.
fromStart
    :: forall a.
    ( PersistEntity a
    , BackendCompatible SqlBackend (PersistEntityBackend a)
    )
    => SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
fromStart :: SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
fromStart = do
    let ed :: EntityDef
ed = Proxy a -> EntityDef
forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a)
    Ident
ident <- DBName -> SqlQuery Ident
newIdentFor (EntityNameDB -> DBName
coerce (EntityNameDB -> DBName) -> EntityNameDB -> DBName
forall a b. (a -> b) -> a -> b
$ EntityDef -> EntityNameDB
getEntityDBName EntityDef
ed)
    let ret :: SqlExpr (Entity a)
ret = Ident -> SqlExpr (Entity a)
forall val. Ident -> SqlExpr (Entity val)
EEntity Ident
ident
        f' :: FromClause
f' = Ident -> EntityDef -> FromClause
FromStart Ident
ident EntityDef
ed
    SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
-> SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
forall (m :: * -> *) a. Monad m => a -> m a
return (SqlExpr (Entity a)
-> FromClause -> SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
forall a. a -> FromClause -> SqlExpr (PreprocessedFrom a)
EPreprocessedFrom SqlExpr (Entity a)
ret FromClause
f')

-- | Copied from @persistent@
newtype DBName = DBName { DBName -> Text
unDBName :: T.Text }

-- | (Internal) Same as 'fromStart', but entity may be missing.
fromStartMaybe
    :: ( PersistEntity a
       , BackendCompatible SqlBackend (PersistEntityBackend a)
       )
    => SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a)))))
fromStartMaybe :: SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a)))))
fromStartMaybe = SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
-> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a))))
forall a.
SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
-> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a))))
maybelize (SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
 -> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a)))))
-> SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
-> SqlQuery
     (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a)))))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
forall a.
(PersistEntity a,
 BackendCompatible SqlBackend (PersistEntityBackend a)) =>
SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
fromStart
  where
    maybelize
        :: SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
        -> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a))))
    maybelize :: SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))
-> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a))))
maybelize (EPreprocessedFrom a
ret FromClause
f') = SqlExpr (Maybe (Entity a))
-> FromClause
-> SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity a))))
forall a. a -> FromClause -> SqlExpr (PreprocessedFrom a)
EPreprocessedFrom (SqlExpr (Entity a) -> SqlExpr (Maybe (Entity a))
forall a. SqlExpr a -> SqlExpr (Maybe a)
EMaybe a
SqlExpr (Entity a)
ret) FromClause
f'

-- | (Internal) Do a @JOIN@.
fromJoin
    :: IsJoinKind join
    => SqlExpr (PreprocessedFrom a)
    -> SqlExpr (PreprocessedFrom b)
    -> SqlQuery (SqlExpr (PreprocessedFrom (join a b)))
fromJoin :: SqlExpr (PreprocessedFrom a)
-> SqlExpr (PreprocessedFrom b)
-> SqlQuery (SqlExpr (PreprocessedFrom (join a b)))
fromJoin (EPreprocessedFrom a
lhsRet FromClause
lhsFrom)
         (EPreprocessedFrom a
rhsRet FromClause
rhsFrom) = WriterT
  SideData (State IdentState) (SqlExpr (PreprocessedFrom (join a a)))
-> SqlQuery (SqlExpr (PreprocessedFrom (join a a)))
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT
   SideData (State IdentState) (SqlExpr (PreprocessedFrom (join a a)))
 -> SqlQuery (SqlExpr (PreprocessedFrom (join a a))))
-> WriterT
     SideData (State IdentState) (SqlExpr (PreprocessedFrom (join a a)))
-> SqlQuery (SqlExpr (PreprocessedFrom (join a a)))
forall a b. (a -> b) -> a -> b
$ do
    let ret :: join a a
ret = a -> a -> join a a
forall (join :: * -> * -> *) a b.
IsJoinKind join =>
a -> b -> join a b
smartJoin a
lhsRet a
rhsRet
        from' :: FromClause
from' =
            FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin
                FromClause
lhsFrom             -- LHS
                (join a a -> JoinKind
forall (join :: * -> * -> *) a b.
IsJoinKind join =>
join a b -> JoinKind
reifyJoinKind join a a
ret) -- JOIN
                FromClause
rhsFrom             -- RHS
                Maybe (SqlExpr (Value Bool))
forall a. Maybe a
Nothing             -- ON
    SqlExpr (PreprocessedFrom (join a a))
-> WriterT
     SideData (State IdentState) (SqlExpr (PreprocessedFrom (join a a)))
forall (m :: * -> *) a. Monad m => a -> m a
return (join a a -> FromClause -> SqlExpr (PreprocessedFrom (join a a))
forall a. a -> FromClause -> SqlExpr (PreprocessedFrom a)
EPreprocessedFrom join a a
ret FromClause
from')

-- | (Internal) Finish a @JOIN@.
fromFinish
  :: SqlExpr (PreprocessedFrom a)
  -> SqlQuery a
fromFinish :: SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish (EPreprocessedFrom a
ret FromClause
f') = WriterT SideData (State IdentState) a -> SqlQuery a
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) a -> SqlQuery a)
-> WriterT SideData (State IdentState) a -> SqlQuery a
forall a b. (a -> b) -> a -> b
$ do
    SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdFromClause :: [FromClause]
sdFromClause = [FromClause
f'] }
    a -> WriterT SideData (State IdentState) a
forall (m :: * -> *) a. Monad m => a -> m a
return a
ret

-- | @WHERE@ clause: restrict the query's result.
where_ :: SqlExpr (Value Bool) -> SqlQuery ()
where_ :: SqlExpr (Value Bool) -> SqlQuery ()
where_ SqlExpr (Value Bool)
expr = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdWhereClause :: WhereClause
sdWhereClause = SqlExpr (Value Bool) -> WhereClause
Where SqlExpr (Value Bool)
expr }

-- | An @ON@ clause, useful to describe how two tables are related. Cross joins
-- and tuple-joins do not need an 'on' clause, but 'InnerJoin' and the various
-- outer joins do.
--
-- "Database.Esqueleto.Experimental" in version 4.0.0.0 of the library. The
-- @Experimental@ module has a dramatically improved means for introducing
-- tables and entities that provides more power and less potential for runtime
-- errors.
--
-- If you don't include an 'on' clause (or include too many!) then a runtime
-- exception will be thrown.
--
-- As an example, consider this simple join:
--
-- @
-- 'select' $
-- 'from' $ \\(foo `'InnerJoin`` bar) -> do
--   'on' (foo '^.' FooId '==.' bar '^.' BarFooId)
--   ...
-- @
--
-- We need to specify the clause for joining the two columns together. If we had
-- this:
--
-- @
-- 'select' $
-- 'from' $ \\(foo `'CrossJoin`` bar) -> do
--   ...
-- @
--
-- Then we can safely omit the 'on' clause, because the cross join will make
-- pairs of all records possible.
--
-- You can do multiple 'on' clauses in a query. This query joins three tables,
-- and has two 'on' clauses:
--
-- @
-- 'select' $
-- 'from' $ \\(foo `'InnerJoin`` bar `'InnerJoin`` baz) -> do
--   'on' (baz '^.' BazId '==.' bar '^.' BarBazId)
--   'on' (foo '^.' FooId '==.' bar '^.' BarFooId)
--   ...
-- @
--
-- Old versions of esqueleto required that you provide the 'on' clauses in
-- reverse order. This restriction has been lifted - you can now provide 'on'
-- clauses in any order, and the SQL should work itself out. The above query is
-- now totally equivalent to this:
--
-- @
-- 'select' $
-- 'from' $ \\(foo `'InnerJoin`` bar `'InnerJoin`` baz) -> do
--   'on' (foo '^.' FooId '==.' bar '^.' BarFooId)
--   'on' (baz '^.' BazId '==.' bar '^.' BarBazId)
--   ...
-- @
on :: SqlExpr (Value Bool) -> SqlQuery ()
on :: SqlExpr (Value Bool) -> SqlQuery ()
on SqlExpr (Value Bool)
expr = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdFromClause :: [FromClause]
sdFromClause = [SqlExpr (Value Bool) -> FromClause
OnClause SqlExpr (Value Bool)
expr] }

-- | @GROUP BY@ clause. You can enclose multiple columns
-- in a tuple.
--
-- @
-- select $ 'from' \\(foo `'InnerJoin`` bar) -> do
--   'on' (foo '^.' FooBarId '==.' bar '^.' BarId)
--   'groupBy' (bar '^.' BarId, bar '^.' BarName)
--   return (bar '^.' BarId, bar '^.' BarName, countRows)
-- @
--
-- With groupBy you can sort by aggregate functions, like so
-- (we used @let@ to restrict the more general 'countRows' to
-- @SqlSqlExpr (Value Int)@ to avoid ambiguity---the second use of
-- 'countRows' has its type restricted by the @:: Int@ below):
--
-- @
-- r \<- select $ 'from' \\(foo `'InnerJoin`` bar) -> do
--   'on' (foo '^.' FooBarId '==.' bar '^.' BarId)
--   'groupBy' $ bar '^.' BarName
--   let countRows' = 'countRows'
--   'orderBy' ['asc' countRows']
--   return (bar '^.' BarName, countRows')
-- forM_ r $ \\('Value' name, 'Value' count) -> do
--   print name
--   print (count :: Int)
-- @
--
-- === Need more columns?
--
-- The 'ToSomeValues' class is defined for 'SqlExpr' and tuples of 'SqlExpr's.
-- We only have definitions for up to 8 elements in a tuple right now, so it's
-- possible that you may need to have more than 8 elements.
--
-- For example, consider a query with a 'groupBy' call like this:
--
-- @
-- groupBy (e0, e1, e2, e3, e4, e5, e6, e7)
-- @
--
-- This is the biggest you can get with a single tuple. However, you can easily
-- nest the tuples to add more:
--
-- @
-- groupBy ((e0, e1, e2, e3, e4, e5, e6, e7), e8, e9)
-- @
groupBy :: (ToSomeValues a) => a -> SqlQuery ()
groupBy :: a -> SqlQuery ()
groupBy a
expr = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdGroupByClause :: GroupByClause
sdGroupByClause = [SomeValue] -> GroupByClause
GroupBy ([SomeValue] -> GroupByClause) -> [SomeValue] -> GroupByClause
forall a b. (a -> b) -> a -> b
$ a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
expr }

-- | @ORDER BY@ clause. See also 'asc' and 'desc'.
--
-- Multiple calls to 'orderBy' get concatenated on the final
-- query, including 'distinctOnOrderBy'.
orderBy :: [SqlExpr OrderBy] -> SqlQuery ()
orderBy :: [SqlExpr OrderBy] -> SqlQuery ()
orderBy [SqlExpr OrderBy]
exprs = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdOrderByClause :: [SqlExpr OrderBy]
sdOrderByClause = [SqlExpr OrderBy]
exprs }

-- | Ascending order of this field or SqlExpression.
asc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy
asc :: SqlExpr (Value a) -> SqlExpr OrderBy
asc  = OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy
forall a. OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy
EOrderBy OrderByType
ASC

-- | Descending order of this field or SqlExpression.
desc :: PersistField a => SqlExpr (Value a) -> SqlExpr OrderBy
desc :: SqlExpr (Value a) -> SqlExpr OrderBy
desc = OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy
forall a. OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy
EOrderBy OrderByType
DESC

-- | @LIMIT@.  Limit the number of returned rows.
limit :: Int64 -> SqlQuery ()
limit :: Int64 -> SqlQuery ()
limit  Int64
n = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdLimitClause :: LimitClause
sdLimitClause = Maybe Int64 -> Maybe Int64 -> LimitClause
Limit (Int64 -> Maybe Int64
forall a. a -> Maybe a
Just Int64
n) Maybe Int64
forall a. Maybe a
Nothing  }

-- | @OFFSET@.  Usually used with 'limit'.
offset :: Int64 -> SqlQuery ()
offset :: Int64 -> SqlQuery ()
offset Int64
n = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdLimitClause :: LimitClause
sdLimitClause = Maybe Int64 -> Maybe Int64 -> LimitClause
Limit Maybe Int64
forall a. Maybe a
Nothing  (Int64 -> Maybe Int64
forall a. a -> Maybe a
Just Int64
n) }

-- | @DISTINCT@.  Change the current @SELECT@ into @SELECT
-- DISTINCT@.  For example:
--
-- @
-- select $ distinct $
--   'from' \\foo -> do
--   ...
-- @
--
-- Note that this also has the same effect:
--
-- @
-- select $
--   'from' \\foo -> do
--   distinct (return ())
--   ...
-- @
--
-- @since 2.2.4
distinct :: SqlQuery a -> SqlQuery a
distinct :: SqlQuery a -> SqlQuery a
distinct SqlQuery a
act = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdDistinctClause :: DistinctClause
sdDistinctClause = DistinctClause
DistinctStandard }) SqlQuery () -> SqlQuery a -> SqlQuery a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> SqlQuery a
act

-- | @DISTINCT ON@.  Change the current @SELECT@ into
-- @SELECT DISTINCT ON (SqlExpressions)@.  For example:
--
-- @
-- select $
--   'from' \\foo ->
--   'distinctOn' ['don' (foo ^. FooName), 'don' (foo ^. FooState)] $ do
--   ...
-- @
--
-- You can also chain different calls to 'distinctOn'.  The
-- above is equivalent to:
--
-- @
-- select $
--   'from' \\foo ->
--   'distinctOn' ['don' (foo ^. FooName)] $
--   'distinctOn' ['don' (foo ^. FooState)] $ do
--   ...
-- @
--
-- Each call to 'distinctOn' adds more SqlExpressions.  Calls to
-- 'distinctOn' override any calls to 'distinct'.
--
-- Note that PostgreSQL requires the SqlExpressions on @DISTINCT
-- ON@ to be the first ones to appear on a @ORDER BY@.  This is
-- not managed automatically by esqueleto, keeping its spirit
-- of trying to be close to raw SQL.
--
-- Supported by PostgreSQL only.
--
-- @since 2.2.4
distinctOn :: [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a
distinctOn :: [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a
distinctOn [SqlExpr DistinctOn]
exprs SqlQuery a
act = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdDistinctClause :: DistinctClause
sdDistinctClause = [SqlExpr DistinctOn] -> DistinctClause
DistinctOn [SqlExpr DistinctOn]
exprs }) SqlQuery () -> SqlQuery a -> SqlQuery a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> SqlQuery a
act

-- | Erase an SqlExpression's type so that it's suitable to
-- be used by 'distinctOn'.
--
-- @since 2.2.4
don :: SqlExpr (Value a) -> SqlExpr DistinctOn
don :: SqlExpr (Value a) -> SqlExpr DistinctOn
don = SqlExpr (Value a) -> SqlExpr DistinctOn
forall a. SqlExpr (Value a) -> SqlExpr DistinctOn
EDistinctOn

-- | A convenience function that calls both 'distinctOn' and
-- 'orderBy'.  In other words,
--
-- @
-- 'distinctOnOrderBy' [asc foo, desc bar, desc quux] $ do
--   ...
-- @
--
-- is the same as:
--
-- @
-- 'distinctOn' [don foo, don  bar, don  quux] $ do
--   'orderBy'  [asc foo, desc bar, desc quux]
--   ...
-- @
--
-- @since 2.2.4
distinctOnOrderBy :: [SqlExpr OrderBy] -> SqlQuery a -> SqlQuery a
distinctOnOrderBy :: [SqlExpr OrderBy] -> SqlQuery a -> SqlQuery a
distinctOnOrderBy [SqlExpr OrderBy]
exprs SqlQuery a
act =
    [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a
forall a. [SqlExpr DistinctOn] -> SqlQuery a -> SqlQuery a
distinctOn (SqlExpr OrderBy -> SqlExpr DistinctOn
toDistinctOn (SqlExpr OrderBy -> SqlExpr DistinctOn)
-> [SqlExpr OrderBy] -> [SqlExpr DistinctOn]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SqlExpr OrderBy]
exprs) (SqlQuery a -> SqlQuery a) -> SqlQuery a -> SqlQuery a
forall a b. (a -> b) -> a -> b
$ do
        [SqlExpr OrderBy] -> SqlQuery ()
orderBy [SqlExpr OrderBy]
exprs
        SqlQuery a
act
  where
    toDistinctOn :: SqlExpr OrderBy -> SqlExpr DistinctOn
    toDistinctOn :: SqlExpr OrderBy -> SqlExpr DistinctOn
toDistinctOn (EOrderBy OrderByType
_ SqlExpr (Value a)
f) = SqlExpr (Value a) -> SqlExpr DistinctOn
forall a. SqlExpr (Value a) -> SqlExpr DistinctOn
EDistinctOn SqlExpr (Value a)
f
    toDistinctOn SqlExpr OrderBy
EOrderRandom =
        [Char] -> SqlExpr DistinctOn
forall a. HasCallStack => [Char] -> a
error [Char]
"We can't select distinct by a random order!"

-- | @ORDER BY random()@ clause.
--
-- @since 1.3.10
rand :: SqlExpr OrderBy
rand :: SqlExpr OrderBy
rand = SqlExpr OrderBy
EOrderRandom

-- | @HAVING@.
--
-- @since 1.2.2
having :: SqlExpr (Value Bool) -> SqlQuery ()
having :: SqlExpr (Value Bool) -> SqlQuery ()
having SqlExpr (Value Bool)
expr = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdHavingClause :: WhereClause
sdHavingClause = SqlExpr (Value Bool) -> WhereClause
Where SqlExpr (Value Bool)
expr }

-- | Add a locking clause to the query.  Please read
-- 'LockingKind' documentation and your RDBMS manual.
--
-- If multiple calls to 'locking' are made on the same query,
-- the last one is used.
--
-- @since 2.2.7
locking :: LockingKind -> SqlQuery ()
locking :: LockingKind -> SqlQuery ()
locking LockingKind
kind = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdLockingClause :: LockingClause
sdLockingClause = Maybe LockingKind -> LockingClause
forall a. Maybe a -> Last a
Monoid.Last (LockingKind -> Maybe LockingKind
forall a. a -> Maybe a
Just LockingKind
kind) }

{-#
  DEPRECATED
    sub_select
    "sub_select \n \
sub_select is an unsafe function to use. If used with a SqlQuery that \n \
returns 0 results, then it may return NULL despite not mentioning Maybe \n \
in the return type. If it returns more than 1 result, then it will throw a \n \
SQL error.\n\n Instead, consider using one of the following alternatives: \n \
- subSelect: attaches a LIMIT 1 and the Maybe return type, totally safe.  \n \
- subSelectMaybe: Attaches a LIMIT 1, useful for a query that already \n \
  has a Maybe in the return type. \n \
- subSelectCount: Performs a count of the query - this is always safe. \n \
- subSelectUnsafe: Performs no checks or guarantees. Safe to use with \n \
  countRows and friends."
  #-}
-- | Execute a subquery @SELECT@ in an SqlExpression.  Returns a
-- simple value so should be used only when the @SELECT@ query
-- is guaranteed to return just one row.
--
-- Deprecated in 3.2.0.
sub_select :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
sub_select :: SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
sub_select         = Mode -> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
Mode -> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
sub Mode
SELECT

-- | Execute a subquery @SELECT@ in a 'SqlExpr'. The query passed to this
-- function will only return a single result - it has a @LIMIT 1@ passed in to
-- the query to make it safe, and the return type is 'Maybe' to indicate that
-- the subquery might result in 0 rows.
--
-- If you find yourself writing @'joinV' . 'subSelect'@, then consider using
-- 'subSelectMaybe'.
--
-- If you're performing a 'countRows', then you can use 'subSelectCount' which
-- is safe.
--
-- If you know that the subquery will always return exactly one row (eg
-- a foreign key constraint guarantees that you'll get exactly one row), then
-- consider 'subSelectUnsafe', along with a comment explaining why it is safe.
--
-- @since 3.2.0
subSelect
  :: PersistField a
  => SqlQuery (SqlExpr (Value a))
  -> SqlExpr (Value (Maybe a))
subSelect :: SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value (Maybe a))
subSelect SqlQuery (SqlExpr (Value a))
query = SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just (SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
subSelectUnsafe (SqlQuery (SqlExpr (Value a))
query SqlQuery (SqlExpr (Value a))
-> SqlQuery () -> SqlQuery (SqlExpr (Value a))
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Int64 -> SqlQuery ()
limit Int64
1))

-- | Execute a subquery @SELECT@ in a 'SqlExpr'. This function is a shorthand
-- for the common @'joinV' . 'subSelect'@ idiom, where you are calling
-- 'subSelect' on an expression that would be 'Maybe' already.
--
-- As an example, you would use this function when calling 'sum_' or 'max_',
-- which have 'Maybe' in the result type (for a 0 row query).
--
-- @since 3.2.0
subSelectMaybe
    :: PersistField a
    => SqlQuery (SqlExpr (Value (Maybe a)))
    -> SqlExpr (Value (Maybe a))
subSelectMaybe :: SqlQuery (SqlExpr (Value (Maybe a))) -> SqlExpr (Value (Maybe a))
subSelectMaybe = SqlExpr (Value (Maybe (Maybe a))) -> SqlExpr (Value (Maybe a))
forall typ.
SqlExpr (Value (Maybe (Maybe typ))) -> SqlExpr (Value (Maybe typ))
joinV (SqlExpr (Value (Maybe (Maybe a))) -> SqlExpr (Value (Maybe a)))
-> (SqlQuery (SqlExpr (Value (Maybe a)))
    -> SqlExpr (Value (Maybe (Maybe a))))
-> SqlQuery (SqlExpr (Value (Maybe a)))
-> SqlExpr (Value (Maybe a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlQuery (SqlExpr (Value (Maybe a)))
-> SqlExpr (Value (Maybe (Maybe a)))
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value (Maybe a))
subSelect

-- | Performs a @COUNT@ of the given query in a @subSelect@ manner. This is
-- always guaranteed to return a result value, and is completely safe.
--
-- @since 3.2.0
subSelectCount
    :: (Num a, PersistField a)
    => SqlQuery ignored
    -> SqlExpr (Value a)
subSelectCount :: SqlQuery ignored -> SqlExpr (Value a)
subSelectCount SqlQuery ignored
query =
    SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
subSelectUnsafe (SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a))
-> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ do
        ignored
_ <- SqlQuery ignored
query
        SqlExpr (Value a) -> SqlQuery (SqlExpr (Value a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure SqlExpr (Value a)
forall a. Num a => SqlExpr (Value a)
countRows

-- | Execute a subquery @SELECT@ in a 'SqlExpr' that returns a list. This is an
-- alias for 'subList_select' and is provided for symmetry with the other safe
-- subselect functions.
--
-- @since 3.2.0
subSelectList
    :: PersistField a
    => SqlQuery (SqlExpr (Value a))
    -> SqlExpr (ValueList a)
subSelectList :: SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a)
subSelectList = SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a)
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a)
subList_select

-- | Performs a sub-select using the given foreign key on the entity. This is
-- useful to extract values that are known to be present by the database schema.
--
-- As an example, consider the following persistent definition:
--
-- @
-- User
--   profile ProfileId
--
-- Profile
--   name    Text
-- @
--
-- The following query will return the name of the user.
--
-- @
-- getUserWithName =
--     'select' $
--     'from' $ \user ->
--     'pure' (user, 'subSelectForeign' user UserProfile (^. ProfileName)
-- @
--
-- @since 3.2.0
subSelectForeign
    ::
    ( BackendCompatible SqlBackend (PersistEntityBackend val1)
    , PersistEntity val1, PersistEntity val2, PersistField a
    )
    => SqlExpr (Entity val2)
    -- ^ An expression representing the table you have access to now.
    -> EntityField val2 (Key val1)
    -- ^ The foreign key field on the table.
    -> (SqlExpr (Entity val1) -> SqlExpr (Value a))
    -- ^ A function to extract a value from the foreign reference table.
    -> SqlExpr (Value a)
subSelectForeign :: SqlExpr (Entity val2)
-> EntityField val2 (Key val1)
-> (SqlExpr (Entity val1) -> SqlExpr (Value a))
-> SqlExpr (Value a)
subSelectForeign SqlExpr (Entity val2)
expr EntityField val2 (Key val1)
foreignKey SqlExpr (Entity val1) -> SqlExpr (Value a)
k =
    SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
subSelectUnsafe (SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a))
-> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$
    (SqlExpr (Entity val1) -> SqlQuery (SqlExpr (Value a)))
-> SqlQuery (SqlExpr (Value a))
forall a b. From a => (a -> SqlQuery b) -> SqlQuery b
from ((SqlExpr (Entity val1) -> SqlQuery (SqlExpr (Value a)))
 -> SqlQuery (SqlExpr (Value a)))
-> (SqlExpr (Entity val1) -> SqlQuery (SqlExpr (Value a)))
-> SqlQuery (SqlExpr (Value a))
forall a b. (a -> b) -> a -> b
$ \SqlExpr (Entity val1)
table -> do
    SqlExpr (Value Bool) -> SqlQuery ()
where_ (SqlExpr (Value Bool) -> SqlQuery ())
-> SqlExpr (Value Bool) -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SqlExpr (Entity val2)
expr SqlExpr (Entity val2)
-> EntityField val2 (Key val1) -> SqlExpr (Value (Key val1))
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val2 (Key val1)
foreignKey SqlExpr (Value (Key val1))
-> SqlExpr (Value (Key val1)) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
==. SqlExpr (Entity val1)
table SqlExpr (Entity val1)
-> EntityField val1 (Key val1) -> SqlExpr (Value (Key val1))
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val1 (Key val1)
forall record.
PersistEntity record =>
EntityField record (Key record)
persistIdField
    SqlExpr (Value a) -> SqlQuery (SqlExpr (Value a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SqlExpr (Entity val1) -> SqlExpr (Value a)
k SqlExpr (Entity val1)
table)

-- | Execute a subquery @SELECT@ in a 'SqlExpr'. This function is unsafe,
-- because it can throw runtime exceptions in two cases:
--
-- 1. If the query passed has 0 result rows, then it will return a @NULL@ value.
--    The @persistent@ parsing operations will fail on an unexpected @NULL@.
-- 2. If the query passed returns more than one row, then the SQL engine will
--    fail with an error like "More than one row returned by a subquery used as
--    an expression".
--
-- This function is safe if you guarantee that exactly one row will be returned,
-- or if the result already has a 'Maybe' type for some reason.
--
-- For variants with the safety encoded already, see 'subSelect' and
-- 'subSelectMaybe'. For the most common safe use of this, see 'subSelectCount'.
--
-- @since 3.2.0
subSelectUnsafe :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
subSelectUnsafe :: SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
subSelectUnsafe = Mode -> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
Mode -> SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
sub Mode
SELECT

-- | Project a field of an entity.
(^.)
    :: forall typ val. (PersistEntity val, PersistField typ)
    => SqlExpr (Entity val)
    -> EntityField val typ
    -> SqlExpr (Value typ)
(EAliasedEntityReference Ident
source Ident
base) ^. :: SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val typ
field =
    Ident -> (IdentInfo -> Ident) -> SqlExpr (Value typ)
forall a. Ident -> (IdentInfo -> Ident) -> SqlExpr (Value a)
EValueReference Ident
source (\IdentInfo
_ -> Ident -> FieldDef -> Ident
aliasedEntityColumnIdent Ident
base FieldDef
fieldDef)
  where
    fieldDef :: FieldDef
fieldDef =
        if EntityField val typ -> Bool
forall record typ.
PersistEntity record =>
EntityField record typ -> Bool
isIdField EntityField val typ
field then
            -- TODO what about composite natural keys in a join this will ignore them
            NonEmpty FieldDef -> FieldDef
forall a. NonEmpty a -> a
NEL.head (NonEmpty FieldDef -> FieldDef) -> NonEmpty FieldDef -> FieldDef
forall a b. (a -> b) -> a -> b
$ EntityDef -> NonEmpty FieldDef
getEntityKeyFields EntityDef
ed
        else
            EntityField val typ -> FieldDef
forall record typ.
PersistEntity record =>
EntityField record typ -> FieldDef
persistFieldDef EntityField val typ
field

    ed :: EntityDef
ed = Proxy val -> EntityDef
forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef (Proxy val -> EntityDef) -> Proxy val -> EntityDef
forall a b. (a -> b) -> a -> b
$ Proxy (SqlExpr (Entity val)) -> Proxy val
forall a. Proxy (SqlExpr (Entity a)) -> Proxy a
getEntityVal (Proxy (SqlExpr (Entity val))
forall k (t :: k). Proxy t
Proxy :: Proxy (SqlExpr (Entity val)))

SqlExpr (Entity val)
e ^. EntityField val typ
field
    | EntityField val typ -> Bool
forall record typ.
PersistEntity record =>
EntityField record typ -> Bool
isIdField EntityField val typ
field = SqlExpr (Value typ)
idFieldValue
    | Bool
otherwise = NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
info -> (IdentInfo -> FieldDef -> Builder
dot IdentInfo
info (FieldDef -> Builder) -> FieldDef -> Builder
forall a b. (a -> b) -> a -> b
$ EntityField val typ -> FieldDef
forall record typ.
PersistEntity record =>
EntityField record typ -> FieldDef
persistFieldDef EntityField val typ
field, [])
  where
    idFieldValue :: SqlExpr (Value typ)
idFieldValue =
        case EntityDef -> NonEmpty FieldDef
getEntityKeyFields EntityDef
ed of
            FieldDef
idField :| [] ->
                NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never    ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
info -> (IdentInfo -> FieldDef -> Builder
dot IdentInfo
info FieldDef
idField, [])

            NonEmpty FieldDef
idFields ->
                (IdentInfo -> [Builder]) -> SqlExpr (Value typ)
forall a. (IdentInfo -> [Builder]) -> SqlExpr (Value a)
ECompositeKey ((IdentInfo -> [Builder]) -> SqlExpr (Value typ))
-> (IdentInfo -> [Builder]) -> SqlExpr (Value typ)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
info ->  NonEmpty Builder -> [Builder]
forall a. NonEmpty a -> [a]
NEL.toList (NonEmpty Builder -> [Builder]) -> NonEmpty Builder -> [Builder]
forall a b. (a -> b) -> a -> b
$ IdentInfo -> FieldDef -> Builder
dot IdentInfo
info (FieldDef -> Builder) -> NonEmpty FieldDef -> NonEmpty Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty FieldDef
idFields


    ed :: EntityDef
ed = Proxy val -> EntityDef
forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef (Proxy val -> EntityDef) -> Proxy val -> EntityDef
forall a b. (a -> b) -> a -> b
$ Proxy (SqlExpr (Entity val)) -> Proxy val
forall a. Proxy (SqlExpr (Entity a)) -> Proxy a
getEntityVal (Proxy (SqlExpr (Entity val))
forall k (t :: k). Proxy t
Proxy :: Proxy (SqlExpr (Entity val)))

    dot :: IdentInfo -> FieldDef -> Builder
dot IdentInfo
info FieldDef
fieldDef =
        IdentInfo -> Ident -> Builder
useIdent IdentInfo
info Ident
sourceIdent Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"." Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
fieldIdent
      where
        sourceIdent :: Ident
sourceIdent =
            case SqlExpr (Entity val)
e of
                EEntity Ident
ident -> Ident
ident
                EAliasedEntity Ident
baseI Ident
_ -> Ident
baseI
                EAliasedEntityReference Ident
a Ident
b ->
                    [Char] -> Ident
forall a. HasCallStack => [Char] -> a
error ([Char] -> Ident) -> [Char] -> Ident
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
                        [ [Char]
"Used (^.) with an EAliasedEntityReference."
                        , [Char]
"Please file this as an Esqueleto bug."
                        , [Char]
"EAliasedEntityReference", Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
a, Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
b
                        ]
        fieldIdent :: Builder
fieldIdent =
            case SqlExpr (Entity val)
e of
                EEntity Ident
_ -> IdentInfo -> DBName -> Builder
fromDBName IdentInfo
info (FieldNameDB -> DBName
coerce (FieldNameDB -> DBName) -> FieldNameDB -> DBName
forall a b. (a -> b) -> a -> b
$ FieldDef -> FieldNameDB
fieldDB FieldDef
fieldDef)
                EAliasedEntity Ident
baseI Ident
_ -> IdentInfo -> Ident -> Builder
useIdent IdentInfo
info (Ident -> Builder) -> Ident -> Builder
forall a b. (a -> b) -> a -> b
$ Ident -> FieldDef -> Ident
aliasedEntityColumnIdent Ident
baseI FieldDef
fieldDef
                EAliasedEntityReference Ident
a Ident
b ->
                    [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ([Char] -> Builder) -> [Char] -> Builder
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
                        [ [Char]
"Used (^.) with an EAliasedEntityReference."
                        , [Char]
"Please file this as an Esqueleto bug."
                        , [Char]
"EAliasedEntityReference", Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
a, Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
b
                        ]


-- | Project an SqlExpression that may be null, guarding against null cases.
withNonNull
    :: PersistField typ
    => SqlExpr (Value (Maybe typ))
    -> (SqlExpr (Value typ) -> SqlQuery a)
    -> SqlQuery a
withNonNull :: SqlExpr (Value (Maybe typ))
-> (SqlExpr (Value typ) -> SqlQuery a) -> SqlQuery a
withNonNull SqlExpr (Value (Maybe typ))
field SqlExpr (Value typ) -> SqlQuery a
f = do
    SqlExpr (Value Bool) -> SqlQuery ()
where_ (SqlExpr (Value Bool) -> SqlQuery ())
-> SqlExpr (Value Bool) -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SqlExpr (Value Bool) -> SqlExpr (Value Bool)
not_ (SqlExpr (Value Bool) -> SqlExpr (Value Bool))
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool)
isNothing SqlExpr (Value (Maybe typ))
field
    SqlExpr (Value typ) -> SqlQuery a
f (SqlExpr (Value typ) -> SqlQuery a)
-> SqlExpr (Value typ) -> SqlQuery a
forall a b. (a -> b) -> a -> b
$ SqlExpr (Value (Maybe typ)) -> SqlExpr (Value typ)
forall a b. SqlExpr (Value a) -> SqlExpr (Value b)
veryUnsafeCoerceSqlExprValue SqlExpr (Value (Maybe typ))
field

-- | Project a field of an entity that may be null.
(?.)
    :: (PersistEntity val, PersistField typ)
    => SqlExpr (Maybe (Entity val))
    -> EntityField val typ
    -> SqlExpr (Value (Maybe typ))
EMaybe SqlExpr a
r ?. :: SqlExpr (Maybe (Entity val))
-> EntityField val typ -> SqlExpr (Value (Maybe typ))
?. EntityField val typ
field = SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just (SqlExpr a
SqlExpr (Entity val)
r SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val typ
field)

-- | Lift a constant value from Haskell-land to the query.
val  :: PersistField typ => typ -> SqlExpr (Value typ)
val :: typ -> SqlExpr (Value typ)
val typ
v = NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a b. (a -> b) -> a -> b
$ (Builder, [PersistValue]) -> IdentInfo -> (Builder, [PersistValue])
forall a b. a -> b -> a
const (Builder
"?", [typ -> PersistValue
forall a. PersistField a => a -> PersistValue
toPersistValue typ
v])

-- | @IS NULL@ comparison.
--
-- For @IS NOT NULL@, you can negate this with 'not_', as in @not_ (isNothing (person ^. PersonAge))@
--
-- Warning: Persistent and Esqueleto have different behavior for @!= Nothing@:
--
-- +----------------+----------------------------------+---------------+
-- |                | Haskell                          | SQL           |
-- +================+==================================+===============+
-- | __Persistent__ | @'Database.Persist.!=.' Nothing@ | @IS NOT NULL@ |
-- +----------------+----------------------------------+---------------+
-- | __Esqueleto__  | @'!=.' Nothing@                  | @!= NULL@     |
-- +----------------+----------------------------------+---------------+
--
-- In SQL, @= NULL@ and @!= NULL@ return NULL instead of true or false. For this reason, you very likely do not want to use @'!=.' Nothing@ in Esqueleto.
-- You may find these @hlint@ rules helpful to enforce this:
--
-- > - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
-- > - error: {lhs: v Database.Esqueleto.==. Database.Esqueleto.val Nothing, rhs: Database.Esqueleto.isNothing v, name: Use Esqueleto's isNothing}
-- > - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
-- > - error: {lhs: v Database.Esqueleto.!=. Database.Esqueleto.val Nothing, rhs: not_ (Database.Esqueleto.isNothing v), name: Use Esqueleto's not isNothing}
isNothing :: PersistField typ => SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool)
isNothing :: SqlExpr (Value (Maybe typ)) -> SqlExpr (Value Bool)
isNothing SqlExpr (Value (Maybe typ))
v =
    case SqlExpr (Value (Maybe typ))
v of
        ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f ->
            (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
isNullExpr ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ (Builder -> Builder)
-> (Builder, [PersistValue]) -> (Builder, [PersistValue])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (NeedParens -> Builder -> Builder
parensM NeedParens
p) ((Builder, [PersistValue]) -> (Builder, [PersistValue]))
-> (IdentInfo -> (Builder, [PersistValue]))
-> IdentInfo
-> (Builder, [PersistValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentInfo -> (Builder, [PersistValue])
f
        EAliasedValue Ident
i SqlExpr (Value a)
_ ->
            (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
isNullExpr ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i
        EValueReference Ident
i IdentInfo -> Ident
i' ->
            (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
isNullExpr ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i'
        ECompositeKey IdentInfo -> [Builder]
f ->
            NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Parens ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ (Builder -> [PersistValue] -> (Builder, [PersistValue]))
-> [PersistValue] -> Builder -> (Builder, [PersistValue])
forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) [] (Builder -> (Builder, [PersistValue]))
-> (IdentInfo -> Builder) -> IdentInfo -> (Builder, [PersistValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> [Builder] -> Builder
intersperseB Builder
" AND " ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Builder) -> [Builder] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" IS NULL")) ([Builder] -> Builder)
-> (IdentInfo -> [Builder]) -> IdentInfo -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentInfo -> [Builder]
f
  where
    isNullExpr :: (IdentInfo -> (TLB.Builder, [PersistValue])) -> SqlExpr (Value Bool)
    isNullExpr :: (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
isNullExpr IdentInfo -> (Builder, [PersistValue])
g = NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Parens ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ (Builder -> Builder)
-> (Builder, [PersistValue]) -> (Builder, [PersistValue])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ((Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" IS NULL")) ((Builder, [PersistValue]) -> (Builder, [PersistValue]))
-> (IdentInfo -> (Builder, [PersistValue]))
-> IdentInfo
-> (Builder, [PersistValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentInfo -> (Builder, [PersistValue])
g

-- | Analogous to 'Just', promotes a value of type @typ@ into
-- one of type @Maybe typ@.  It should hold that @'val' . Just
-- === just . 'val'@.
just :: SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just :: SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just SqlExpr (Value typ)
exprVal = case SqlExpr (Value typ)
exprVal of
    ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f -> NeedParens
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Value (Maybe typ))
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f
    ECompositeKey IdentInfo -> [Builder]
f -> (IdentInfo -> [Builder]) -> SqlExpr (Value (Maybe typ))
forall a. (IdentInfo -> [Builder]) -> SqlExpr (Value a)
ECompositeKey IdentInfo -> [Builder]
f
    EAliasedValue Ident
i SqlExpr (Value a)
v -> Ident -> SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe a))
forall a. Ident -> SqlExpr (Value a) -> SqlExpr (Value a)
EAliasedValue Ident
i (SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just SqlExpr (Value a)
v)
    EValueReference Ident
i IdentInfo -> Ident
i' -> Ident -> (IdentInfo -> Ident) -> SqlExpr (Value (Maybe typ))
forall a. Ident -> (IdentInfo -> Ident) -> SqlExpr (Value a)
EValueReference Ident
i IdentInfo -> Ident
i'

-- | @NULL@ value.
nothing :: SqlExpr (Value (Maybe typ))
nothing :: SqlExpr (Value (Maybe typ))
nothing = Builder -> SqlExpr (Value (Maybe typ))
forall a. Builder -> SqlExpr (Value a)
unsafeSqlValue Builder
"NULL"

-- | Join nested 'Maybe's in a 'Value' into one. This is useful when
-- calling aggregate functions on nullable fields.
joinV :: SqlExpr (Value (Maybe (Maybe typ))) -> SqlExpr (Value (Maybe typ))
joinV :: SqlExpr (Value (Maybe (Maybe typ))) -> SqlExpr (Value (Maybe typ))
joinV SqlExpr (Value (Maybe (Maybe typ)))
exprMM = case SqlExpr (Value (Maybe (Maybe typ)))
exprMM of
    ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f -> NeedParens
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Value (Maybe typ))
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f
    ECompositeKey IdentInfo -> [Builder]
f -> (IdentInfo -> [Builder]) -> SqlExpr (Value (Maybe typ))
forall a. (IdentInfo -> [Builder]) -> SqlExpr (Value a)
ECompositeKey IdentInfo -> [Builder]
f
    EAliasedValue Ident
i SqlExpr (Value a)
v -> Ident -> SqlExpr (Value (Maybe typ)) -> SqlExpr (Value (Maybe typ))
forall a. Ident -> SqlExpr (Value a) -> SqlExpr (Value a)
EAliasedValue Ident
i (SqlExpr (Value (Maybe (Maybe typ))) -> SqlExpr (Value (Maybe typ))
forall typ.
SqlExpr (Value (Maybe (Maybe typ))) -> SqlExpr (Value (Maybe typ))
joinV SqlExpr (Value a)
SqlExpr (Value (Maybe (Maybe typ)))
v)
    EValueReference Ident
i IdentInfo -> Ident
i' -> Ident -> (IdentInfo -> Ident) -> SqlExpr (Value (Maybe typ))
forall a. Ident -> (IdentInfo -> Ident) -> SqlExpr (Value a)
EValueReference Ident
i IdentInfo -> Ident
i'


countHelper :: Num a => TLB.Builder -> TLB.Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
countHelper :: Builder -> Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
countHelper Builder
open Builder
close SqlExpr (Value typ)
v =
    case SqlExpr (Value typ)
v of
        ERaw NeedParens
_ IdentInfo -> (Builder, [PersistValue])
f -> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
(IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
countRawSql IdentInfo -> (Builder, [PersistValue])
f
        EAliasedValue Ident
i SqlExpr (Value a)
_ -> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
(IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
countRawSql ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i
        EValueReference Ident
i IdentInfo -> Ident
i' -> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
(IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
countRawSql ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i'
        ECompositeKey IdentInfo -> [Builder]
_ -> SqlExpr (Value a)
forall a. Num a => SqlExpr (Value a)
countRows
  where
    countRawSql :: (IdentInfo -> (TLB.Builder, [PersistValue])) -> SqlExpr (Value a)
    countRawSql :: (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
countRawSql IdentInfo -> (Builder, [PersistValue])
x = NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ (Builder -> Builder)
-> (Builder, [PersistValue]) -> (Builder, [PersistValue])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (\Builder
b -> Builder
"COUNT" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
open Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder
parens Builder
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
close) ((Builder, [PersistValue]) -> (Builder, [PersistValue]))
-> (IdentInfo -> (Builder, [PersistValue]))
-> IdentInfo
-> (Builder, [PersistValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentInfo -> (Builder, [PersistValue])
x

-- | @COUNT(*)@ value.
countRows :: Num a => SqlExpr (Value a)
countRows :: SqlExpr (Value a)
countRows = Builder -> SqlExpr (Value a)
forall a. Builder -> SqlExpr (Value a)
unsafeSqlValue Builder
"COUNT(*)"

-- | @COUNT@.
count :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a)
count :: SqlExpr (Value typ) -> SqlExpr (Value a)
count = Builder -> Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
forall a typ.
Num a =>
Builder -> Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
countHelper Builder
""           Builder
""

-- | @COUNT(DISTINCT x)@.
--
-- @since 2.4.1
countDistinct :: Num a => SqlExpr (Value typ) -> SqlExpr (Value a)
countDistinct :: SqlExpr (Value typ) -> SqlExpr (Value a)
countDistinct = Builder -> Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
forall a typ.
Num a =>
Builder -> Builder -> SqlExpr (Value typ) -> SqlExpr (Value a)
countHelper Builder
"(DISTINCT " Builder
")"

not_ :: SqlExpr (Value Bool) -> SqlExpr (Value Bool)
not_ :: SqlExpr (Value Bool) -> SqlExpr (Value Bool)
not_ SqlExpr (Value Bool)
v = NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value Bool)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never (\IdentInfo
info -> (Builder -> Builder)
-> (Builder, [PersistValue]) -> (Builder, [PersistValue])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (Builder
"NOT " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>) ((Builder, [PersistValue]) -> (Builder, [PersistValue]))
-> (Builder, [PersistValue]) -> (Builder, [PersistValue])
forall a b. (a -> b) -> a -> b
$ IdentInfo -> (Builder, [PersistValue])
x IdentInfo
info)
  where
    x :: IdentInfo -> (Builder, [PersistValue])
x IdentInfo
info =
        case SqlExpr (Value Bool)
v of
            ERaw NeedParens
p IdentInfo -> (Builder, [PersistValue])
f ->
                let (Builder
b, [PersistValue]
vals) = IdentInfo -> (Builder, [PersistValue])
f IdentInfo
info
                in (NeedParens -> Builder -> Builder
parensM NeedParens
p Builder
b, [PersistValue]
vals)
            ECompositeKey IdentInfo -> [Builder]
_      ->
                EsqueletoError -> (Builder, [PersistValue])
forall a e. Exception e => e -> a
throw (CompositeKeyError -> EsqueletoError
CompositeKeyErr CompositeKeyError
NotError)
            EAliasedValue Ident
i SqlExpr (Value a)
_    ->
                Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i IdentInfo
info
            EValueReference Ident
i IdentInfo -> Ident
i' ->
                Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i' IdentInfo
info

(==.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
==. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(==.) = Builder
-> Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> Builder
-> SqlExpr (Value a)
-> SqlExpr (Value b)
-> SqlExpr (Value c)
unsafeSqlBinOpComposite Builder
" = " Builder
" AND "

(>=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
>=. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(>=.) = Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" >= "

(>.)  :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
>. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(>.)  = Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" > "

(<=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
<=. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(<=.) = Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" <= "

(<.)  :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
<. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(<.)  = Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" < "
(!=.) :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
!=. :: SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
(!=.) = Builder
-> Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> Builder
-> SqlExpr (Value a)
-> SqlExpr (Value b)
-> SqlExpr (Value c)
unsafeSqlBinOpComposite Builder
" != " Builder
" OR "

(&&.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
&&. :: SqlExpr (Value Bool)
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
(&&.) = Builder
-> SqlExpr (Value Bool)
-> SqlExpr (Value Bool)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" AND "

(||.) :: SqlExpr (Value Bool) -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
||. :: SqlExpr (Value Bool)
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
(||.) = Builder
-> SqlExpr (Value Bool)
-> SqlExpr (Value Bool)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" OR "

(+.)  :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
+. :: SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
(+.)  = Builder
-> SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" + "

(-.)  :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
-. :: SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
(-.)  = Builder
-> SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" - "

(/.)  :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
/. :: SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
(/.)  = Builder
-> SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" / "

(*.)  :: PersistField a => SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
*. :: SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
(*.)  = Builder
-> SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" * "

-- | @BETWEEN@.
--
-- @since: 3.1.0
between :: PersistField a => SqlExpr (Value a) -> (SqlExpr (Value a), SqlExpr (Value a)) -> SqlExpr (Value Bool)
SqlExpr (Value a)
a between :: SqlExpr (Value a)
-> (SqlExpr (Value a), SqlExpr (Value a)) -> SqlExpr (Value Bool)
`between` (SqlExpr (Value a)
b, SqlExpr (Value a)
c) = SqlExpr (Value a)
a SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
>=. SqlExpr (Value a)
b SqlExpr (Value Bool)
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
&&. SqlExpr (Value a)
a SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
<=. SqlExpr (Value a)
c

random_  :: (PersistField a, Num a) => SqlExpr (Value a)
random_ :: SqlExpr (Value a)
random_  = Builder -> SqlExpr (Value a)
forall a. Builder -> SqlExpr (Value a)
unsafeSqlValue Builder
"RANDOM()"

round_   :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b)
round_ :: SqlExpr (Value a) -> SqlExpr (Value b)
round_   = Builder -> SqlExpr (Value a) -> SqlExpr (Value b)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"ROUND"

ceiling_ :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b)
ceiling_ :: SqlExpr (Value a) -> SqlExpr (Value b)
ceiling_ = Builder -> SqlExpr (Value a) -> SqlExpr (Value b)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"CEILING"

floor_   :: (PersistField a, Num a, PersistField b, Num b) => SqlExpr (Value a) -> SqlExpr (Value b)
floor_ :: SqlExpr (Value a) -> SqlExpr (Value b)
floor_   = Builder -> SqlExpr (Value a) -> SqlExpr (Value b)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"FLOOR"

sum_     :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
sum_ :: SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
sum_     = Builder -> SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"SUM"
min_     :: (PersistField a) => SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
min_ :: SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
min_     = Builder -> SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"MIN"
max_     :: (PersistField a) => SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
max_ :: SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
max_     = Builder -> SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"MAX"
avg_     :: (PersistField a, PersistField b) => SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
avg_ :: SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
avg_     = Builder -> SqlExpr (Value a) -> SqlExpr (Value (Maybe b))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"AVG"

-- | Allow a number of one type to be used as one of another
-- type via an implicit cast.  An explicit cast is not made,
-- this function changes only the types on the Haskell side.
--
-- /Caveat/: Trying to use @castNum@ from @Double@ to @Int@
-- will not result in an integer, the original fractional
-- number will still be used!  Use 'round_', 'ceiling_' or
-- 'floor_' instead.
--
-- /Safety/: This operation is mostly safe due to the 'Num'
-- constraint between the types and the fact that RDBMSs
-- usually allow numbers of different types to be used
-- interchangeably.  However, there may still be issues with
-- the query not being accepted by the RDBMS or @persistent@
-- not being able to parse it.
--
-- @since 2.2.9
castNum :: (Num a, Num b) => SqlExpr (Value a) -> SqlExpr (Value b)
castNum :: SqlExpr (Value a) -> SqlExpr (Value b)
castNum  = SqlExpr (Value a) -> SqlExpr (Value b)
forall a b. SqlExpr (Value a) -> SqlExpr (Value b)
veryUnsafeCoerceSqlExprValue

-- | Same as 'castNum', but for nullable values.
--
-- @since 2.2.9
castNumM :: (Num a, Num b) => SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe b))
castNumM :: SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe b))
castNumM = SqlExpr (Value (Maybe a)) -> SqlExpr (Value (Maybe b))
forall a b. SqlExpr (Value a) -> SqlExpr (Value b)
veryUnsafeCoerceSqlExprValue

-- | @COALESCE@ function. Evaluates the arguments in order and
-- returns the value of the first non-NULL SqlExpression, or NULL
-- (Nothing) otherwise. Some RDBMSs (such as SQLite) require
-- at least two arguments; please refer to the appropriate
-- documentation.
--
-- @since 1.4.3
coalesce :: PersistField a => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value (Maybe a))
coalesce :: [SqlExpr (Value (Maybe a))] -> SqlExpr (Value (Maybe a))
coalesce              = Builder -> [SqlExpr (Value (Maybe a))] -> SqlExpr (Value (Maybe a))
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunctionParens Builder
"COALESCE"

-- | Like @coalesce@, but takes a non-nullable SqlExpression
-- placed at the end of the SqlExpression list, which guarantees
-- a non-NULL result.
--
-- @since 1.4.3
coalesceDefault :: PersistField a => [SqlExpr (Value (Maybe a))] -> SqlExpr (Value a) -> SqlExpr (Value a)
coalesceDefault :: [SqlExpr (Value (Maybe a))]
-> SqlExpr (Value a) -> SqlExpr (Value a)
coalesceDefault [SqlExpr (Value (Maybe a))]
exprs = Builder -> [SqlExpr (Value (Maybe a))] -> SqlExpr (Value a)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunctionParens Builder
"COALESCE" ([SqlExpr (Value (Maybe a))] -> SqlExpr (Value a))
-> (SqlExpr (Value a) -> [SqlExpr (Value (Maybe a))])
-> SqlExpr (Value a)
-> SqlExpr (Value a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([SqlExpr (Value (Maybe a))]
exprs [SqlExpr (Value (Maybe a))]
-> [SqlExpr (Value (Maybe a))] -> [SqlExpr (Value (Maybe a))]
forall a. [a] -> [a] -> [a]
++) ([SqlExpr (Value (Maybe a))] -> [SqlExpr (Value (Maybe a))])
-> (SqlExpr (Value a) -> [SqlExpr (Value (Maybe a))])
-> SqlExpr (Value a)
-> [SqlExpr (Value (Maybe a))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlExpr (Value (Maybe a)) -> [SqlExpr (Value (Maybe a))]
forall (m :: * -> *) a. Monad m => a -> m a
return (SqlExpr (Value (Maybe a)) -> [SqlExpr (Value (Maybe a))])
-> (SqlExpr (Value a) -> SqlExpr (Value (Maybe a)))
-> SqlExpr (Value a)
-> [SqlExpr (Value (Maybe a))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just

-- | @LOWER@ function.
lower_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s)
lower_ :: SqlExpr (Value s) -> SqlExpr (Value s)
lower_  = Builder -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"LOWER"

-- | @UPPER@ function.
-- @since 3.3.0
upper_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s)
upper_ :: SqlExpr (Value s) -> SqlExpr (Value s)
upper_  = Builder -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"UPPER"

-- | @TRIM@ function.
-- @since 3.3.0
trim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s)
trim_ :: SqlExpr (Value s) -> SqlExpr (Value s)
trim_  = Builder -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"TRIM"

-- | @RTRIM@ function.
-- @since 3.3.0
rtrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s)
rtrim_ :: SqlExpr (Value s) -> SqlExpr (Value s)
rtrim_  = Builder -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"RTRIM"

-- | @LTRIM@ function.
-- @since 3.3.0
ltrim_ :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s)
ltrim_ :: SqlExpr (Value s) -> SqlExpr (Value s)
ltrim_  = Builder -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"LTRIM"

-- | @LENGTH@ function.
-- @since 3.3.0
length_ :: (SqlString s, Num a) => SqlExpr (Value s) -> SqlExpr (Value a)
length_ :: SqlExpr (Value s) -> SqlExpr (Value a)
length_ = Builder -> SqlExpr (Value s) -> SqlExpr (Value a)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"LENGTH"

-- | @LEFT@ function.
-- @since 3.3.0
left_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
left_ :: (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
left_ = Builder
-> (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"LEFT"

-- | @RIGHT@ function.
-- @since 3.3.0
right_ :: (SqlString s, Num a) => (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
right_ :: (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
right_ = Builder
-> (SqlExpr (Value s), SqlExpr (Value a)) -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"RIGHT"

-- | @LIKE@ operator.
like :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
like :: SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
like    = Builder
-> SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp    Builder
" LIKE "

-- | @ILIKE@ operator (case-insensitive @LIKE@).
--
-- Supported by PostgreSQL only.
--
-- @since 2.2.3
ilike :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
ilike :: SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
ilike   = Builder
-> SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp    Builder
" ILIKE "

-- | The string @'%'@.  May be useful while using 'like' and
-- concatenation ('concat_' or '++.', depending on your
-- database).  Note that you always have to type the parenthesis,
-- for example:
--
-- @
-- name `'like`` (%) ++. 'val' \"John\" ++. (%)
-- @
(%) :: SqlString s => SqlExpr (Value s)
% :: SqlExpr (Value s)
(%)     = Builder -> SqlExpr (Value s)
forall a. Builder -> SqlExpr (Value a)
unsafeSqlValue    Builder
"'%'"

-- | The @CONCAT@ function with a variable number of
-- parameters.  Supported by MySQL and PostgreSQL.
concat_ :: SqlString s => [SqlExpr (Value s)] -> SqlExpr (Value s)
concat_ :: [SqlExpr (Value s)] -> SqlExpr (Value s)
concat_ = Builder -> [SqlExpr (Value s)] -> SqlExpr (Value s)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"CONCAT"

-- | The @||@ string concatenation operator (named after
-- Haskell's '++' in order to avoid naming clash with '||.').
-- Supported by SQLite and PostgreSQL.
(++.) :: SqlString s => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s)
++. :: SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s)
(++.)   = Builder
-> SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp    Builder
" || "

-- | Cast a string type into 'Text'.  This function
-- is very useful if you want to use @newtype@s, or if you want
-- to apply functions such as 'like' to strings of different
-- types.
--
-- /Safety:/ This is a slightly unsafe function, especially if
-- you have defined your own instances of 'SqlString'.  Also,
-- since 'Maybe' is an instance of 'SqlString', it's possible
-- to turn a nullable value into a non-nullable one.  Avoid
-- using this function if possible.
castString :: (SqlString s, SqlString r) => SqlExpr (Value s) -> SqlExpr (Value r)
castString :: SqlExpr (Value s) -> SqlExpr (Value r)
castString = SqlExpr (Value s) -> SqlExpr (Value r)
forall a b. SqlExpr (Value a) -> SqlExpr (Value b)
veryUnsafeCoerceSqlExprValue

-- | Execute a subquery @SELECT@ in an SqlExpression.  Returns a
-- list of values.
subList_select :: PersistField a => SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a)
subList_select :: SqlQuery (SqlExpr (Value a)) -> SqlExpr (ValueList a)
subList_select         = SqlExpr (Value a) -> SqlExpr (ValueList a)
forall a. SqlExpr (Value a) -> SqlExpr (ValueList a)
EList (SqlExpr (Value a) -> SqlExpr (ValueList a))
-> (SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a))
-> SqlQuery (SqlExpr (Value a))
-> SqlExpr (ValueList a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlQuery (SqlExpr (Value a)) -> SqlExpr (Value a)
sub_select

-- | Lift a list of constant value from Haskell-land to the query.
valList :: PersistField typ => [typ] -> SqlExpr (ValueList typ)
valList :: [typ] -> SqlExpr (ValueList typ)
valList []   = SqlExpr (ValueList typ)
forall a. SqlExpr (ValueList a)
EEmptyList
valList [typ]
vals = SqlExpr (Value typ) -> SqlExpr (ValueList typ)
forall a. SqlExpr (Value a) -> SqlExpr (ValueList a)
EList (SqlExpr (Value typ) -> SqlExpr (ValueList typ))
-> SqlExpr (Value typ) -> SqlExpr (ValueList typ)
forall a b. (a -> b) -> a -> b
$ NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Parens ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value typ)
forall a b. (a -> b) -> a -> b
$ (Builder, [PersistValue]) -> IdentInfo -> (Builder, [PersistValue])
forall a b. a -> b -> a
const ( [Builder] -> Builder
uncommas (Builder
"?" Builder -> [typ] -> [Builder]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [typ]
vals)
                                           , (typ -> PersistValue) -> [typ] -> [PersistValue]
forall a b. (a -> b) -> [a] -> [b]
map typ -> PersistValue
forall a. PersistField a => a -> PersistValue
toPersistValue [typ]
vals )

-- | Same as 'just' but for 'ValueList'.  Most of the time you
-- won't need it, though, because you can use 'just' from
-- inside 'subList_select' or 'Just' from inside 'valList'.
--
-- @since 2.2.12
justList :: SqlExpr (ValueList typ) -> SqlExpr (ValueList (Maybe typ))
justList :: SqlExpr (ValueList typ) -> SqlExpr (ValueList (Maybe typ))
justList SqlExpr (ValueList typ)
EEmptyList = SqlExpr (ValueList (Maybe typ))
forall a. SqlExpr (ValueList a)
EEmptyList
justList (EList SqlExpr (Value a)
v)  = SqlExpr (Value (Maybe a)) -> SqlExpr (ValueList (Maybe a))
forall a. SqlExpr (Value a) -> SqlExpr (ValueList a)
EList (SqlExpr (Value a) -> SqlExpr (Value (Maybe a))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just SqlExpr (Value a)
v)

-- | @IN@ operator. For example if you want to select all @Person@s by a list
-- of IDs:
--
-- @
-- SELECT *
-- FROM Person
-- WHERE Person.id IN (?)
-- @
--
-- In @esqueleto@, we may write the same query above as:
--
-- @
-- select $
-- 'from' $ \\person -> do
-- 'where_' $ person '^.' PersonId `'in_`` 'valList' personIds
-- return person
-- @
--
-- Where @personIds@ is of type @[Key Person]@.
in_ :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool)
SqlExpr (Value typ)
v in_ :: SqlExpr (Value typ)
-> SqlExpr (ValueList typ) -> SqlExpr (Value Bool)
`in_`   SqlExpr (ValueList typ)
e = SqlExpr (ValueList typ)
-> Bool -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a.
SqlExpr (ValueList a)
-> Bool -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
ifNotEmptyList SqlExpr (ValueList typ)
e Bool
False (SqlExpr (Value Bool) -> SqlExpr (Value Bool))
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp     Builder
" IN " SqlExpr (Value typ)
v (SqlExpr (ValueList typ) -> SqlExpr (Value typ)
forall a. SqlExpr (ValueList a) -> SqlExpr (Value a)
veryUnsafeCoerceSqlExprValueList SqlExpr (ValueList typ)
e)

-- | @NOT IN@ operator.
notIn :: PersistField typ => SqlExpr (Value typ) -> SqlExpr (ValueList typ) -> SqlExpr (Value Bool)
SqlExpr (Value typ)
v notIn :: SqlExpr (Value typ)
-> SqlExpr (ValueList typ) -> SqlExpr (Value Bool)
`notIn` SqlExpr (ValueList typ)
e = SqlExpr (ValueList typ)
-> Bool -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a.
SqlExpr (ValueList a)
-> Bool -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
ifNotEmptyList SqlExpr (ValueList typ)
e Bool
True  (SqlExpr (Value Bool) -> SqlExpr (Value Bool))
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ Builder
-> SqlExpr (Value typ)
-> SqlExpr (Value typ)
-> SqlExpr (Value Bool)
forall a b c.
Builder
-> SqlExpr (Value a) -> SqlExpr (Value b) -> SqlExpr (Value c)
unsafeSqlBinOp Builder
" NOT IN " SqlExpr (Value typ)
v (SqlExpr (ValueList typ) -> SqlExpr (Value typ)
forall a. SqlExpr (ValueList a) -> SqlExpr (Value a)
veryUnsafeCoerceSqlExprValueList SqlExpr (ValueList typ)
e)

-- | @EXISTS@ operator.  For example:
--
-- @
-- select $
-- 'from' $ \\person -> do
-- 'where_' $ 'exists' $
--          'from' $ \\post -> do
--          'where_' (post '^.' BlogPostAuthorId '==.' person '^.' PersonId)
-- return person
-- @
exists :: SqlQuery () -> SqlExpr (Value Bool)
exists :: SqlQuery () -> SqlExpr (Value Bool)
exists    = Builder -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction     Builder
"EXISTS " (SqlExpr (Value Bool) -> SqlExpr (Value Bool))
-> (SqlQuery () -> SqlExpr (Value Bool))
-> SqlQuery ()
-> SqlExpr (Value Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlQuery () -> SqlExpr (Value Bool)
existsHelper

-- | @NOT EXISTS@ operator.
notExists :: SqlQuery () -> SqlExpr (Value Bool)
notExists :: SqlQuery () -> SqlExpr (Value Bool)
notExists = Builder -> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
forall a b.
UnsafeSqlFunctionArgument a =>
Builder -> a -> SqlExpr (Value b)
unsafeSqlFunction Builder
"NOT EXISTS " (SqlExpr (Value Bool) -> SqlExpr (Value Bool))
-> (SqlQuery () -> SqlExpr (Value Bool))
-> SqlQuery ()
-> SqlExpr (Value Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlQuery () -> SqlExpr (Value Bool)
existsHelper

-- | @SET@ clause used on @UPDATE@s.  Note that while it's not
-- a type error to use this function on a @SELECT@, it will
-- most certainly result in a runtime error.
set :: PersistEntity val => SqlExpr (Entity val) -> [SqlExpr (Update val)] -> SqlQuery ()
set :: SqlExpr (Entity val) -> [SqlExpr (Update val)] -> SqlQuery ()
set SqlExpr (Entity val)
ent [SqlExpr (Update val)]
upds = WriterT SideData (State IdentState) () -> SqlQuery ()
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) () -> SqlQuery ())
-> WriterT SideData (State IdentState) () -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ SideData -> WriterT SideData (State IdentState) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
W.tell SideData
forall a. Monoid a => a
mempty { sdSetClause :: [SetClause]
sdSetClause = (SqlExpr (Update val) -> SetClause)
-> [SqlExpr (Update val)] -> [SetClause]
forall a b. (a -> b) -> [a] -> [b]
map SqlExpr (Update val) -> SetClause
apply [SqlExpr (Update val)]
upds }
  where
    apply :: SqlExpr (Update val) -> SetClause
apply (ESet SqlExpr (Entity val) -> SqlExpr (Value ())
f) = SqlExpr (Value ()) -> SetClause
SetClause (SqlExpr (Entity val) -> SqlExpr (Value ())
f SqlExpr (Entity val)
SqlExpr (Entity val)
ent)

(=.)  :: (PersistEntity val, PersistField typ) => EntityField val typ -> SqlExpr (Value typ) -> SqlExpr (Update val)
EntityField val typ
field  =. :: EntityField val typ -> SqlExpr (Value typ) -> SqlExpr (Update val)
=. SqlExpr (Value typ)
expr = EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
setAux EntityField val typ
field (SqlExpr (Value typ) -> SqlExpr (Entity val) -> SqlExpr (Value typ)
forall a b. a -> b -> a
const SqlExpr (Value typ)
expr)

(+=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
EntityField val a
field +=. :: EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
+=. SqlExpr (Value a)
expr = EntityField val a
-> (SqlExpr (Entity val) -> SqlExpr (Value a))
-> SqlExpr (Update val)
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
setAux EntityField val a
field (\SqlExpr (Entity val)
ent -> SqlExpr (Entity val)
ent SqlExpr (Entity val) -> EntityField val a -> SqlExpr (Value a)
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val a
field SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
+. SqlExpr (Value a)
expr)

(-=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
EntityField val a
field -=. :: EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
-=. SqlExpr (Value a)
expr = EntityField val a
-> (SqlExpr (Entity val) -> SqlExpr (Value a))
-> SqlExpr (Update val)
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
setAux EntityField val a
field (\SqlExpr (Entity val)
ent -> SqlExpr (Entity val)
ent SqlExpr (Entity val) -> EntityField val a -> SqlExpr (Value a)
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val a
field SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
-. SqlExpr (Value a)
expr)

(*=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
EntityField val a
field *=. :: EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
*=. SqlExpr (Value a)
expr = EntityField val a
-> (SqlExpr (Entity val) -> SqlExpr (Value a))
-> SqlExpr (Update val)
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
setAux EntityField val a
field (\SqlExpr (Entity val)
ent -> SqlExpr (Entity val)
ent SqlExpr (Entity val) -> EntityField val a -> SqlExpr (Value a)
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val a
field SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
*. SqlExpr (Value a)
expr)

(/=.) :: (PersistEntity val, PersistField a) => EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
EntityField val a
field /=. :: EntityField val a -> SqlExpr (Value a) -> SqlExpr (Update val)
/=. SqlExpr (Value a)
expr = EntityField val a
-> (SqlExpr (Entity val) -> SqlExpr (Value a))
-> SqlExpr (Update val)
forall val typ.
(PersistEntity val, PersistField typ) =>
EntityField val typ
-> (SqlExpr (Entity val) -> SqlExpr (Value typ))
-> SqlExpr (Update val)
setAux EntityField val a
field (\SqlExpr (Entity val)
ent -> SqlExpr (Entity val)
ent SqlExpr (Entity val) -> EntityField val a -> SqlExpr (Value a)
forall typ val.
(PersistEntity val, PersistField typ) =>
SqlExpr (Entity val) -> EntityField val typ -> SqlExpr (Value typ)
^. EntityField val a
field SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
forall a.
PersistField a =>
SqlExpr (Value a) -> SqlExpr (Value a) -> SqlExpr (Value a)
/. SqlExpr (Value a)
expr)

-- | Apply a 'PersistField' constructor to @SqlExpr Value@ arguments.
(<#) :: (a -> b) -> SqlExpr (Value a) -> SqlExpr (Insertion b)
<# :: (a -> b) -> SqlExpr (Value a) -> SqlExpr (Insertion b)
(<#) a -> b
_ (ERaw NeedParens
_ IdentInfo -> (Builder, [PersistValue])
f)        = Proxy b
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a.
Proxy a
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion a)
EInsert Proxy b
forall k (t :: k). Proxy t
Proxy IdentInfo -> (Builder, [PersistValue])
f
(<#) a -> b
_ (ECompositeKey IdentInfo -> [Builder]
_) = EsqueletoError -> SqlExpr (Insertion b)
forall a e. Exception e => e -> a
throw (CompositeKeyError -> EsqueletoError
CompositeKeyErr CompositeKeyError
ToInsertionError)
(<#) a -> b
_ (EAliasedValue Ident
i SqlExpr (Value a)
_) = Proxy b
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a.
Proxy a
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion a)
EInsert Proxy b
forall k (t :: k). Proxy t
Proxy ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Insertion b))
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a b. (a -> b) -> a -> b
$ Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i
(<#) a -> b
_ (EValueReference Ident
i IdentInfo -> Ident
i') = Proxy b
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a.
Proxy a
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion a)
EInsert Proxy b
forall k (t :: k). Proxy t
Proxy ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Insertion b))
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a b. (a -> b) -> a -> b
$ Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i'


-- | Apply extra @SqlExpr Value@ arguments to a 'PersistField' constructor
(<&>) :: SqlExpr (Insertion (a -> b)) -> SqlExpr (Value a) -> SqlExpr (Insertion b)
(EInsert Proxy a
_ IdentInfo -> (Builder, [PersistValue])
f) <&> :: SqlExpr (Insertion (a -> b))
-> SqlExpr (Value a) -> SqlExpr (Insertion b)
<&> SqlExpr (Value a)
v =
    Proxy b
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a.
Proxy a
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion a)
EInsert Proxy b
forall k (t :: k). Proxy t
Proxy ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Insertion b))
-> (IdentInfo -> (Builder, [PersistValue]))
-> SqlExpr (Insertion b)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
x ->
        let (Builder
fb, [PersistValue]
fv) = IdentInfo -> (Builder, [PersistValue])
f IdentInfo
x
            (Builder
gb, [PersistValue]
gv) = IdentInfo -> (Builder, [PersistValue])
g IdentInfo
x
        in
            (Builder
fb Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
", " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
gb, [PersistValue]
fv [PersistValue] -> [PersistValue] -> [PersistValue]
forall a. [a] -> [a] -> [a]
++ [PersistValue]
gv)
  where
    g :: IdentInfo -> (Builder, [PersistValue])
g =
        case SqlExpr (Value a)
v of
            ERaw NeedParens
_ IdentInfo -> (Builder, [PersistValue])
f' -> IdentInfo -> (Builder, [PersistValue])
f'
            EAliasedValue Ident
i SqlExpr (Value a)
_ -> Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i
            EValueReference Ident
i IdentInfo -> Ident
i' -> Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i'
            ECompositeKey IdentInfo -> [Builder]
_ -> EsqueletoError -> IdentInfo -> (Builder, [PersistValue])
forall a e. Exception e => e -> a
throw (CompositeKeyError -> EsqueletoError
CompositeKeyErr CompositeKeyError
CombineInsertionError)

-- | @CASE@ statement.  For example:
--
-- @
-- select $
-- return $
-- 'case_'
--    [ 'when_'
--        ('exists' $
--        'from' $ \\p -> do
--        'where_' (p '^.' PersonName '==.' 'val' \"Mike\"))
--      'then_'
--        ('sub_select' $
--        'from' $ \\v -> do
--        let sub =
--                'from' $ \\c -> do
--                'where_' (c '^.' PersonName '==.' 'val' \"Mike\")
--                return (c '^.' PersonFavNum)
--        'where_' (v '^.' PersonFavNum >. 'sub_select' sub)
--        return $ 'count' (v '^.' PersonName) +. 'val' (1 :: Int)) ]
--    ('else_' $ 'val' (-1))
-- @
--
-- This query is a bit complicated, but basically it checks if a person
-- named @\"Mike\"@ exists, and if that person does, run the subquery to find
-- out how many people have a ranking (by Fav Num) higher than @\"Mike\"@.
--
-- __NOTE:__ There are a few things to be aware about this statement.
--
--    * This only implements the full CASE statement, it does not
--      implement the \"simple\" CASE statement.
--
--
--    * At least one 'when_' and 'then_' is mandatory otherwise it will
--      emit an error.
--
--
--    * The 'else_' is also mandatory, unlike the SQL statement in which
--      if the @ELSE@ is omitted it will return a @NULL@. You can
--      reproduce this via 'nothing'.
--
-- @since 2.1.2
case_ :: PersistField a => [(SqlExpr (Value Bool), SqlExpr (Value a))] -> SqlExpr (Value a) -> SqlExpr (Value a)
case_ :: [(SqlExpr (Value Bool), SqlExpr (Value a))]
-> SqlExpr (Value a) -> SqlExpr (Value a)
case_ = [(SqlExpr (Value Bool), SqlExpr (Value a))]
-> SqlExpr (Value a) -> SqlExpr (Value a)
forall a.
PersistField a =>
[(SqlExpr (Value Bool), SqlExpr (Value a))]
-> SqlExpr (Value a) -> SqlExpr (Value a)
unsafeSqlCase

-- | Convert an entity's key into another entity's.
--
-- This function is to be used when you change an entity's @Id@ to be
-- that of another entity. For example:
--
-- @
-- Bar
--   barNum Int
-- Foo
--   bar BarId
--   fooNum Int
--   Primary bar
-- @
--
-- In this example, Bar is said to be the BaseEnt(ity), and Foo the child.
-- To model this in Esqueleto, declare:
--
-- @
-- instance ToBaseId Foo where
--   type BaseEnt Foo = Bar
--   toBaseIdWitness barId = FooKey barId
-- @
--
-- Now you're able to write queries such as:
--
-- @
-- 'select' $
-- 'from' $ \(bar `'InnerJoin`` foo) -> do
-- 'on' ('toBaseId' (foo '^.' FooId) '==.' bar '^.' BarId)
-- return (bar, foo)
-- @
--
-- Note: this function may be unsafe to use in conditions not like the
-- one of the example above.
--
-- @since 2.4.3
toBaseId :: ToBaseId ent => SqlExpr (Value (Key ent)) -> SqlExpr (Value (Key (BaseEnt ent)))
toBaseId :: SqlExpr (Value (Key ent)) -> SqlExpr (Value (Key (BaseEnt ent)))
toBaseId = SqlExpr (Value (Key ent)) -> SqlExpr (Value (Key (BaseEnt ent)))
forall a b. SqlExpr (Value a) -> SqlExpr (Value b)
veryUnsafeCoerceSqlExprValue

{-# DEPRECATED random_ "Since 2.6.0: `random_` is not uniform across all databases! Please use a specific one such as 'Database.Esqueleto.PostgreSQL.random_', 'Database.Esqueleto.MySQL.random_', or 'Database.Esqueleto.SQLite.random_'" #-}

{-# DEPRECATED rand "Since 2.6.0: `rand` ordering function is not uniform across all databases! To avoid accidental partiality it will be removed in the next major version." #-}

-- Fixity declarations
infixl 9 ^.
infixl 7 *., /.
infixl 6 +., -.
infixr 5 ++.
infix  4 ==., >=., >., <=., <., !=.
infixr 3 &&., =., +=., -=., *=., /=.
infixr 2 ||., `like`, `ilike`
infixl 2 `InnerJoin`, `CrossJoin`, `LeftOuterJoin`, `RightOuterJoin`, `FullOuterJoin`

-- | Syntax sugar for 'case_'.
--
-- @since 2.1.2
when_ :: expr (Value Bool) -> () -> expr a -> (expr (Value Bool), expr a)
when_ :: expr (Value Bool) -> () -> expr a -> (expr (Value Bool), expr a)
when_ expr (Value Bool)
cond ()
_ expr a
expr = (expr (Value Bool)
cond, expr a
expr)

-- | Syntax sugar for 'case_'.
--
-- @since 2.1.2
then_ :: ()
then_ :: ()
then_ = ()

-- | Syntax sugar for 'case_'.
--
-- @since 2.1.2
else_ :: expr a -> expr a
else_ :: expr a -> expr a
else_ = expr a -> expr a
forall a. a -> a
id

-- | A single value (as opposed to a whole entity).  You may use
-- @('^.')@ or @('?.')@ to get a 'Value' from an 'Entity'.
newtype Value a = Value { Value a -> a
unValue :: a } deriving (Value a -> Value a -> Bool
(Value a -> Value a -> Bool)
-> (Value a -> Value a -> Bool) -> Eq (Value a)
forall a. Eq a => Value a -> Value a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Value a -> Value a -> Bool
$c/= :: forall a. Eq a => Value a -> Value a -> Bool
== :: Value a -> Value a -> Bool
$c== :: forall a. Eq a => Value a -> Value a -> Bool
Eq, Eq (Value a)
Eq (Value a)
-> (Value a -> Value a -> Ordering)
-> (Value a -> Value a -> Bool)
-> (Value a -> Value a -> Bool)
-> (Value a -> Value a -> Bool)
-> (Value a -> Value a -> Bool)
-> (Value a -> Value a -> Value a)
-> (Value a -> Value a -> Value a)
-> Ord (Value a)
Value a -> Value a -> Bool
Value a -> Value a -> Ordering
Value a -> Value a -> Value a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Value a)
forall a. Ord a => Value a -> Value a -> Bool
forall a. Ord a => Value a -> Value a -> Ordering
forall a. Ord a => Value a -> Value a -> Value a
min :: Value a -> Value a -> Value a
$cmin :: forall a. Ord a => Value a -> Value a -> Value a
max :: Value a -> Value a -> Value a
$cmax :: forall a. Ord a => Value a -> Value a -> Value a
>= :: Value a -> Value a -> Bool
$c>= :: forall a. Ord a => Value a -> Value a -> Bool
> :: Value a -> Value a -> Bool
$c> :: forall a. Ord a => Value a -> Value a -> Bool
<= :: Value a -> Value a -> Bool
$c<= :: forall a. Ord a => Value a -> Value a -> Bool
< :: Value a -> Value a -> Bool
$c< :: forall a. Ord a => Value a -> Value a -> Bool
compare :: Value a -> Value a -> Ordering
$ccompare :: forall a. Ord a => Value a -> Value a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Value a)
Ord, Int -> Value a -> ShowS
[Value a] -> ShowS
Value a -> [Char]
(Int -> Value a -> ShowS)
-> (Value a -> [Char]) -> ([Value a] -> ShowS) -> Show (Value a)
forall a. Show a => Int -> Value a -> ShowS
forall a. Show a => [Value a] -> ShowS
forall a. Show a => Value a -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Value a] -> ShowS
$cshowList :: forall a. Show a => [Value a] -> ShowS
show :: Value a -> [Char]
$cshow :: forall a. Show a => Value a -> [Char]
showsPrec :: Int -> Value a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Value a -> ShowS
Show, Typeable)

-- | @since 1.4.4
instance Functor Value where
    fmap :: (a -> b) -> Value a -> Value b
fmap a -> b
f (Value a
a) = b -> Value b
forall a. a -> Value a
Value (a -> b
f a
a)

instance Applicative Value where
  <*> :: Value (a -> b) -> Value a -> Value b
(<*>) (Value a -> b
f) (Value a
a) = b -> Value b
forall a. a -> Value a
Value (a -> b
f a
a)
  pure :: a -> Value a
pure = a -> Value a
forall a. a -> Value a
Value

instance Monad Value where
  >>= :: Value a -> (a -> Value b) -> Value b
(>>=) Value a
x a -> Value b
f = Value (Value b) -> Value b
forall a. Value a -> a
valueJoin (Value (Value b) -> Value b) -> Value (Value b) -> Value b
forall a b. (a -> b) -> a -> b
$ (a -> Value b) -> Value a -> Value (Value b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Value b
f Value a
x
    where valueJoin :: Value a -> a
valueJoin (Value a
v) = a
v

-- | A list of single values.  There's a limited set of functions
-- able to work with this data type (such as 'subList_select',
-- 'valList', 'in_' and 'exists').
newtype ValueList a = ValueList a deriving (ValueList a -> ValueList a -> Bool
(ValueList a -> ValueList a -> Bool)
-> (ValueList a -> ValueList a -> Bool) -> Eq (ValueList a)
forall a. Eq a => ValueList a -> ValueList a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ValueList a -> ValueList a -> Bool
$c/= :: forall a. Eq a => ValueList a -> ValueList a -> Bool
== :: ValueList a -> ValueList a -> Bool
$c== :: forall a. Eq a => ValueList a -> ValueList a -> Bool
Eq, Eq (ValueList a)
Eq (ValueList a)
-> (ValueList a -> ValueList a -> Ordering)
-> (ValueList a -> ValueList a -> Bool)
-> (ValueList a -> ValueList a -> Bool)
-> (ValueList a -> ValueList a -> Bool)
-> (ValueList a -> ValueList a -> Bool)
-> (ValueList a -> ValueList a -> ValueList a)
-> (ValueList a -> ValueList a -> ValueList a)
-> Ord (ValueList a)
ValueList a -> ValueList a -> Bool
ValueList a -> ValueList a -> Ordering
ValueList a -> ValueList a -> ValueList a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (ValueList a)
forall a. Ord a => ValueList a -> ValueList a -> Bool
forall a. Ord a => ValueList a -> ValueList a -> Ordering
forall a. Ord a => ValueList a -> ValueList a -> ValueList a
min :: ValueList a -> ValueList a -> ValueList a
$cmin :: forall a. Ord a => ValueList a -> ValueList a -> ValueList a
max :: ValueList a -> ValueList a -> ValueList a
$cmax :: forall a. Ord a => ValueList a -> ValueList a -> ValueList a
>= :: ValueList a -> ValueList a -> Bool
$c>= :: forall a. Ord a => ValueList a -> ValueList a -> Bool
> :: ValueList a -> ValueList a -> Bool
$c> :: forall a. Ord a => ValueList a -> ValueList a -> Bool
<= :: ValueList a -> ValueList a -> Bool
$c<= :: forall a. Ord a => ValueList a -> ValueList a -> Bool
< :: ValueList a -> ValueList a -> Bool
$c< :: forall a. Ord a => ValueList a -> ValueList a -> Bool
compare :: ValueList a -> ValueList a -> Ordering
$ccompare :: forall a. Ord a => ValueList a -> ValueList a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (ValueList a)
Ord, Int -> ValueList a -> ShowS
[ValueList a] -> ShowS
ValueList a -> [Char]
(Int -> ValueList a -> ShowS)
-> (ValueList a -> [Char])
-> ([ValueList a] -> ShowS)
-> Show (ValueList a)
forall a. Show a => Int -> ValueList a -> ShowS
forall a. Show a => [ValueList a] -> ShowS
forall a. Show a => ValueList a -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [ValueList a] -> ShowS
$cshowList :: forall a. Show a => [ValueList a] -> ShowS
show :: ValueList a -> [Char]
$cshow :: forall a. Show a => ValueList a -> [Char]
showsPrec :: Int -> ValueList a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> ValueList a -> ShowS
Show, Typeable)

-- | A wrapper type for for any @expr (Value a)@ for all a.
data SomeValue where
    SomeValue :: SqlExpr (Value a) -> SomeValue

-- | A class of things that can be converted into a list of SomeValue. It has
-- instances for tuples and is the reason why 'groupBy' can take tuples, like
-- @'groupBy' (foo '^.' FooId, foo '^.' FooName, foo '^.' FooType)@.
class ToSomeValues a where
    toSomeValues :: a -> [SomeValue]

instance
    ( ToSomeValues a
    , ToSomeValues b
    )
  =>
    ToSomeValues (a, b)
  where
    toSomeValues :: (a, b) -> [SomeValue]
toSomeValues (a
a,b
b) = a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    )
  =>
    ToSomeValues (a, b, c)
  where
    toSomeValues :: (a, b, c) -> [SomeValue]
toSomeValues (a
a,b
b,c
c) = a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    , ToSomeValues d
    )
  =>
    ToSomeValues (a, b, c, d)
  where
    toSomeValues :: (a, b, c, d) -> [SomeValue]
toSomeValues (a
a,b
b,c
c,d
d) =
        a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. [a] -> [a] -> [a]
++ d -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues d
d

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    , ToSomeValues d
    , ToSomeValues e
    )
  =>
    ToSomeValues (a, b, c, d, e)
  where
    toSomeValues :: (a, b, c, d, e) -> [SomeValue]
toSomeValues (a
a,b
b,c
c,d
d,e
e) = [[SomeValue]] -> [SomeValue]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a, b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b, c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c , d -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues d
d
        , e -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues e
e
        ]

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    , ToSomeValues d
    , ToSomeValues e
    , ToSomeValues f
    )
  =>
    ToSomeValues (a, b, c, d, e, f)
  where
    toSomeValues :: (a, b, c, d, e, f) -> [SomeValue]
toSomeValues (a
a,b
b,c
c,d
d,e
e,f
f) = [[SomeValue]] -> [SomeValue]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a, b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b, c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c, d -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues d
d
        , e -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues e
e , f -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues f
f
        ]

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    , ToSomeValues d
    , ToSomeValues e
    , ToSomeValues f
    , ToSomeValues g
    )
  =>
    ToSomeValues (a, b, c, d, e, f, g)
  where
    toSomeValues :: (a, b, c, d, e, f, g) -> [SomeValue]
toSomeValues (a
a,b
b,c
c,d
d,e
e,f
f,g
g) = [[SomeValue]] -> [SomeValue]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a,  b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b, c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c,  d -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues d
d
        , e -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues e
e,  f -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues f
f, g -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues g
g
        ]

instance
    ( ToSomeValues a
    , ToSomeValues b
    , ToSomeValues c
    , ToSomeValues d
    , ToSomeValues e
    , ToSomeValues f
    , ToSomeValues g
    , ToSomeValues h
    )
  =>
    ToSomeValues (a, b, c, d, e, f, g, h)
  where
    toSomeValues :: (a, b, c, d, e, f, g, h) -> [SomeValue]
toSomeValues (a
a,b
b,c
c,d
d,e
e,f
f,g
g,h
h) = [[SomeValue]] -> [SomeValue]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ a -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues a
a, b -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues b
b, c -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues c
c, d -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues d
d
        , e -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues e
e, f -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues f
f, g -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues g
g, h -> [SomeValue]
forall a. ToSomeValues a => a -> [SomeValue]
toSomeValues h
h
        ]

type family KnowResult a where
    KnowResult (i -> o) = KnowResult o
    KnowResult a = a

-- | A class for constructors or function which result type is known.
--
-- @since 3.1.3
class FinalResult a where
  finalR :: a -> KnowResult a

instance FinalResult (Unique val) where
  finalR :: Unique val -> KnowResult (Unique val)
finalR = Unique val -> KnowResult (Unique val)
forall a. a -> a
id

instance (FinalResult b) => FinalResult (a -> b) where
  finalR :: (a -> b) -> KnowResult (a -> b)
finalR a -> b
f = b -> KnowResult b
forall a. FinalResult a => a -> KnowResult a
finalR (a -> b
f a
forall a. HasCallStack => a
undefined)

-- | Convert a constructor for a 'Unique' key on a record to the 'UniqueDef'
-- that defines it. You can supply just the constructor itself, or a value of
-- the type - the library is capable of figuring it out from there.
--
-- @since 3.1.3
toUniqueDef
    :: forall a val.
    ( KnowResult a ~ Unique val
    , PersistEntity val
    , FinalResult a
    )
    => a
    -> UniqueDef
toUniqueDef :: a -> UniqueDef
toUniqueDef a
uniqueConstructor = UniqueDef
uniqueDef
  where
    proxy :: Proxy val
    proxy :: Proxy val
proxy = Proxy val
forall k (t :: k). Proxy t
Proxy
    unique :: Unique val
    unique :: Unique val
unique = a -> KnowResult a
forall a. FinalResult a => a -> KnowResult a
finalR a
uniqueConstructor
    -- there must be a better way to get the constrain name from a unique, make this not a list search
    filterF :: UniqueDef -> Bool
filterF = NonEmpty (FieldNameHS, FieldNameDB)
-> NonEmpty (FieldNameHS, FieldNameDB) -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Unique val -> NonEmpty (FieldNameHS, FieldNameDB)
forall record.
PersistEntity record =>
Unique record -> NonEmpty (FieldNameHS, FieldNameDB)
persistUniqueToFieldNames Unique val
unique) (NonEmpty (FieldNameHS, FieldNameDB) -> Bool)
-> (UniqueDef -> NonEmpty (FieldNameHS, FieldNameDB))
-> UniqueDef
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UniqueDef -> NonEmpty (FieldNameHS, FieldNameDB)
uniqueFields
    uniqueDef :: UniqueDef
uniqueDef = [UniqueDef] -> UniqueDef
forall a. [a] -> a
head ([UniqueDef] -> UniqueDef)
-> (Proxy val -> [UniqueDef]) -> Proxy val -> UniqueDef
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UniqueDef -> Bool) -> [UniqueDef] -> [UniqueDef]
forall a. (a -> Bool) -> [a] -> [a]
filter UniqueDef -> Bool
filterF ([UniqueDef] -> [UniqueDef])
-> (Proxy val -> [UniqueDef]) -> Proxy val -> [UniqueDef]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EntityDef -> [UniqueDef]
getEntityUniques (EntityDef -> [UniqueDef])
-> (Proxy val -> EntityDef) -> Proxy val -> [UniqueDef]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy val -> EntityDef
forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef (Proxy val -> UniqueDef) -> Proxy val -> UniqueDef
forall a b. (a -> b) -> a -> b
$ Proxy val
proxy

-- | Render updates to be use in a SET clause for a given sql backend.
--
-- @since 3.1.3
renderUpdates
    :: (BackendCompatible SqlBackend backend)
    => backend
    -> [SqlExpr (Update val)]
    -> (TLB.Builder, [PersistValue])
renderUpdates :: backend -> [SqlExpr (Update val)] -> (Builder, [PersistValue])
renderUpdates backend
conn = [(Builder, [PersistValue])] -> (Builder, [PersistValue])
forall a. Monoid a => [(Builder, a)] -> (Builder, a)
uncommas' ([(Builder, [PersistValue])] -> (Builder, [PersistValue]))
-> ([SqlExpr (Update val)] -> [(Builder, [PersistValue])])
-> [SqlExpr (Update val)]
-> (Builder, [PersistValue])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SqlExpr (Update val) -> [(Builder, [PersistValue])])
-> [SqlExpr (Update val)] -> [(Builder, [PersistValue])]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap SqlExpr (Update val) -> [(Builder, [PersistValue])]
forall val. SqlExpr (Update val) -> [(Builder, [PersistValue])]
renderUpdate
  where
    mk :: SqlExpr (Value ()) -> [(TLB.Builder, [PersistValue])]
    mk :: SqlExpr (Value ()) -> [(Builder, [PersistValue])]
mk (ERaw NeedParens
_ IdentInfo -> (Builder, [PersistValue])
f)             = [IdentInfo -> (Builder, [PersistValue])
f IdentInfo
info]
    mk (ECompositeKey IdentInfo -> [Builder]
_)      = EsqueletoError -> [(Builder, [PersistValue])]
forall a e. Exception e => e -> a
throw (CompositeKeyError -> EsqueletoError
CompositeKeyErr CompositeKeyError
MakeSetError) -- FIXME
    mk (EAliasedValue Ident
i SqlExpr (Value a)
_)    = [Ident -> IdentInfo -> (Builder, [PersistValue])
aliasedValueIdentToRawSql Ident
i IdentInfo
info]
    mk (EValueReference Ident
i IdentInfo -> Ident
i') = [Ident
-> (IdentInfo -> Ident) -> IdentInfo -> (Builder, [PersistValue])
valueReferenceToRawSql Ident
i IdentInfo -> Ident
i' IdentInfo
info]

    renderUpdate :: SqlExpr (Update val) -> [(TLB.Builder, [PersistValue])]
    renderUpdate :: SqlExpr (Update val) -> [(Builder, [PersistValue])]
renderUpdate (ESet SqlExpr (Entity val) -> SqlExpr (Value ())
f) = SqlExpr (Value ()) -> [(Builder, [PersistValue])]
mk (SqlExpr (Entity val) -> SqlExpr (Value ())
f SqlExpr (Entity val)
forall a. HasCallStack => a
undefined) -- second parameter of f is always unused
    info :: IdentInfo
info = (backend -> SqlBackend
forall sup sub. BackendCompatible sup sub => sub -> sup
projectBackend backend
conn, IdentState
initialIdentState)

-- | Data type that represents an @INNER JOIN@ (see 'LeftOuterJoin' for an example).
data InnerJoin a b = a `InnerJoin` b

-- | Data type that represents a @CROSS JOIN@ (see 'LeftOuterJoin' for an example).
data CrossJoin a b = a `CrossJoin` b

-- | Data type that represents a @LEFT OUTER JOIN@. For example,
--
-- @
-- select $
-- 'from' $ \\(person `'LeftOuterJoin`` pet) ->
--   ...
-- @
--
-- is translated into
--
-- @
-- SELECT ...
-- FROM Person LEFT OUTER JOIN Pet
-- ...
-- @
--
-- See also: 'from'.
data LeftOuterJoin a b = a `LeftOuterJoin` b

-- | Data type that represents a @RIGHT OUTER JOIN@ (see 'LeftOuterJoin' for an example).
data RightOuterJoin a b = a `RightOuterJoin` b

-- | Data type that represents a @FULL OUTER JOIN@ (see 'LeftOuterJoin' for an example).
data FullOuterJoin a b = a `FullOuterJoin` b


-- | (Internal) A kind of @JOIN@.
data JoinKind
    = InnerJoinKind      -- ^ @INNER JOIN@
    | CrossJoinKind      -- ^ @CROSS JOIN@
    | LeftOuterJoinKind  -- ^ @LEFT OUTER JOIN@
    | RightOuterJoinKind -- ^ @RIGHT OUTER JOIN@
    | FullOuterJoinKind  -- ^ @FULL OUTER JOIN@
    deriving (JoinKind -> JoinKind -> Bool
(JoinKind -> JoinKind -> Bool)
-> (JoinKind -> JoinKind -> Bool) -> Eq JoinKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JoinKind -> JoinKind -> Bool
$c/= :: JoinKind -> JoinKind -> Bool
== :: JoinKind -> JoinKind -> Bool
$c== :: JoinKind -> JoinKind -> Bool
Eq, Int -> JoinKind -> ShowS
[JoinKind] -> ShowS
JoinKind -> [Char]
(Int -> JoinKind -> ShowS)
-> (JoinKind -> [Char]) -> ([JoinKind] -> ShowS) -> Show JoinKind
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [JoinKind] -> ShowS
$cshowList :: [JoinKind] -> ShowS
show :: JoinKind -> [Char]
$cshow :: JoinKind -> [Char]
showsPrec :: Int -> JoinKind -> ShowS
$cshowsPrec :: Int -> JoinKind -> ShowS
Show)


-- | (Internal) Functions that operate on types (that should be)
-- of kind 'JoinKind'.
class IsJoinKind join where
    -- | (Internal) @smartJoin a b@ is a @JOIN@ of the correct kind.
    smartJoin :: a -> b -> join a b
    -- | (Internal) Reify a @JoinKind@ from a @JOIN@.  This
    -- function is non-strict.
    reifyJoinKind :: join a b -> JoinKind

instance IsJoinKind InnerJoin where
    smartJoin :: a -> b -> InnerJoin a b
smartJoin a
a b
b = a
a a -> b -> InnerJoin a b
forall a b. a -> b -> InnerJoin a b
`InnerJoin` b
b
    reifyJoinKind :: InnerJoin a b -> JoinKind
reifyJoinKind InnerJoin a b
_ = JoinKind
InnerJoinKind
instance IsJoinKind CrossJoin where
    smartJoin :: a -> b -> CrossJoin a b
smartJoin a
a b
b = a
a a -> b -> CrossJoin a b
forall a b. a -> b -> CrossJoin a b
`CrossJoin` b
b
    reifyJoinKind :: CrossJoin a b -> JoinKind
reifyJoinKind CrossJoin a b
_ = JoinKind
CrossJoinKind
instance IsJoinKind LeftOuterJoin where
    smartJoin :: a -> b -> LeftOuterJoin a b
smartJoin a
a b
b = a
a a -> b -> LeftOuterJoin a b
forall a b. a -> b -> LeftOuterJoin a b
`LeftOuterJoin` b
b
    reifyJoinKind :: LeftOuterJoin a b -> JoinKind
reifyJoinKind LeftOuterJoin a b
_ = JoinKind
LeftOuterJoinKind
instance IsJoinKind RightOuterJoin where
    smartJoin :: a -> b -> RightOuterJoin a b
smartJoin a
a b
b = a
a a -> b -> RightOuterJoin a b
forall a b. a -> b -> RightOuterJoin a b
`RightOuterJoin` b
b
    reifyJoinKind :: RightOuterJoin a b -> JoinKind
reifyJoinKind RightOuterJoin a b
_ = JoinKind
RightOuterJoinKind
instance IsJoinKind FullOuterJoin where
    smartJoin :: a -> b -> FullOuterJoin a b
smartJoin a
a b
b = a
a a -> b -> FullOuterJoin a b
forall a b. a -> b -> FullOuterJoin a b
`FullOuterJoin` b
b
    reifyJoinKind :: FullOuterJoin a b -> JoinKind
reifyJoinKind FullOuterJoin a b
_ = JoinKind
FullOuterJoinKind


-- | Exception thrown whenever 'on' is used to create an @ON@
-- clause but no matching @JOIN@ is found.
data OnClauseWithoutMatchingJoinException =
    OnClauseWithoutMatchingJoinException String
    deriving (OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
(OnClauseWithoutMatchingJoinException
 -> OnClauseWithoutMatchingJoinException -> Bool)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Bool)
-> Eq OnClauseWithoutMatchingJoinException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c/= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
== :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c== :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
Eq, Eq OnClauseWithoutMatchingJoinException
Eq OnClauseWithoutMatchingJoinException
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Ordering)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Bool)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Bool)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Bool)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException -> Bool)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException)
-> (OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException
    -> OnClauseWithoutMatchingJoinException)
-> Ord OnClauseWithoutMatchingJoinException
OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Ordering
OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
$cmin :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
max :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
$cmax :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException
>= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c>= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
> :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c> :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
<= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c<= :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
< :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
$c< :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Bool
compare :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Ordering
$ccompare :: OnClauseWithoutMatchingJoinException
-> OnClauseWithoutMatchingJoinException -> Ordering
$cp1Ord :: Eq OnClauseWithoutMatchingJoinException
Ord, Int -> OnClauseWithoutMatchingJoinException -> ShowS
[OnClauseWithoutMatchingJoinException] -> ShowS
OnClauseWithoutMatchingJoinException -> [Char]
(Int -> OnClauseWithoutMatchingJoinException -> ShowS)
-> (OnClauseWithoutMatchingJoinException -> [Char])
-> ([OnClauseWithoutMatchingJoinException] -> ShowS)
-> Show OnClauseWithoutMatchingJoinException
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [OnClauseWithoutMatchingJoinException] -> ShowS
$cshowList :: [OnClauseWithoutMatchingJoinException] -> ShowS
show :: OnClauseWithoutMatchingJoinException -> [Char]
$cshow :: OnClauseWithoutMatchingJoinException -> [Char]
showsPrec :: Int -> OnClauseWithoutMatchingJoinException -> ShowS
$cshowsPrec :: Int -> OnClauseWithoutMatchingJoinException -> ShowS
Show, Typeable)

instance Exception OnClauseWithoutMatchingJoinException

-- | (Internal) Phantom type used to process 'from' (see 'fromStart').
data PreprocessedFrom a

-- | Phantom type used by 'orderBy', 'asc' and 'desc'.
data OrderBy

-- | Phantom type used by 'distinctOn' and 'don'.
data DistinctOn

-- | Phantom type for a @SET@ operation on an entity of the given
-- type (see 'set' and '(=.)').
data Update typ

-- | Phantom type used by 'insertSelect'.
data Insertion a

-- | Different kinds of locking clauses supported by 'locking'.
--
-- Note that each RDBMS has different locking support.  The
-- constructors of this datatype specify only the /syntax/ of the
-- locking mechanism, not its /semantics/.  For example, even
-- though both MySQL and PostgreSQL support 'ForUpdate', there
-- are no guarantees that they will behave the same.
--
-- @since 2.2.7
data LockingKind
    = ForUpdate
      -- ^ @FOR UPDATE@ syntax.  Supported by MySQL, Oracle and
      -- PostgreSQL.
      --
      -- @since 2.2.7
    | ForUpdateSkipLocked
      -- ^ @FOR UPDATE SKIP LOCKED@ syntax.  Supported by MySQL, Oracle and
      -- PostgreSQL.
      --
      -- @since 2.2.7
    | ForShare
      -- ^ @FOR SHARE@ syntax.  Supported by PostgreSQL.
      --
      -- @since 2.2.7
    | LockInShareMode
      -- ^ @LOCK IN SHARE MODE@ syntax.  Supported by MySQL.
      --
      -- @since 2.2.7

-- | Phantom class of data types that are treated as strings by the
-- RDBMS.  It has no methods because it's only used to avoid type
-- errors such as trying to concatenate integers.
--
-- If you have a custom data type or @newtype@, feel free to make
-- it an instance of this class.
--
-- @since 2.4.0
class PersistField a => SqlString a where

-- | @since 2.3.0
instance (a ~ Char) => SqlString [a] where

-- | @since 2.3.0
instance SqlString T.Text where

-- | @since 2.3.0
instance SqlString TL.Text where

-- | @since 2.3.0
instance SqlString B.ByteString where

-- | @since 2.3.0
instance SqlString Html where

-- | @since 2.4.0
instance SqlString a => SqlString (Maybe a) where

-- | Class that enables one to use 'toBaseId' to convert an entity's
-- key on a query into another (cf. 'toBaseId').
class ToBaseId ent where
    -- | e.g. @type BaseEnt MyBase = MyChild@
    type BaseEnt ent :: *
    -- | Convert from the key of the BaseEnt(ity) to the key of the child entity.
    -- This function is not actually called, but that it typechecks proves this operation is safe.
    toBaseIdWitness :: Key (BaseEnt ent) -> Key ent


-- | @FROM@ clause: bring entities into scope.
--
-- Note that this function will be replaced by the one in
-- "Database.Esqueleto.Experimental" in version 4.0.0.0 of the library. The
-- @Experimental@ module has a dramatically improved means for introducing
-- tables and entities that provides more power and less potential for runtime
-- errors.
--
-- This function internally uses two type classes in order to
-- provide some flexibility of how you may call it.  Internally
-- we refer to these type classes as the two different magics.
--
-- The innermost magic allows you to use @from@ with the
-- following types:
--
--  * @expr (Entity val)@, which brings a single entity into
--  scope.
--
--  * @expr (Maybe (Entity val))@, which brings a single entity
--  that may be @NULL@ into scope.  Used for @OUTER JOIN@s.
--
--  * A @JOIN@ of any other two types allowed by the innermost
--  magic, where a @JOIN@ may be an 'InnerJoin', a 'CrossJoin', a
--  'LeftOuterJoin', a 'RightOuterJoin', or a 'FullOuterJoin'.
--  The @JOINs@ have left fixity.
--
-- The outermost magic allows you to use @from@ on any tuples of
-- types supported by innermost magic (and also tuples of tuples,
-- and so on), up to 8-tuples.
--
-- Note that using @from@ for the same entity twice does work and
-- corresponds to a self-join.  You don't even need to use two
-- different calls to @from@, you may use a @JOIN@ or a tuple.
--
-- The following are valid examples of uses of @from@ (the types
-- of the arguments of the lambda are inside square brackets):
--
-- @
-- 'from' $ \\person -> ...
-- 'from' $ \\(person, blogPost) -> ...
-- 'from' $ \\(p `'LeftOuterJoin`` mb) -> ...
-- 'from' $ \\(p1 `'InnerJoin`` f `'InnerJoin`` p2) -> ...
-- 'from' $ \\((p1 `'InnerJoin`` f) `'InnerJoin`` p2) -> ...
-- @
--
-- The types of the arguments to the lambdas above are,
-- respectively:
--
-- @
-- person
--   :: ( Esqueleto query expr backend
--      , PersistEntity Person
--      , PersistEntityBackend Person ~ backend
--      ) => expr (Entity Person)
-- (person, blogPost)
--   :: (...) => (expr (Entity Person), expr (Entity BlogPost))
-- (p `'LeftOuterJoin`` mb)
--   :: (...) => InnerJoin (expr (Entity Person)) (expr (Maybe (Entity BlogPost)))
-- (p1 `'InnerJoin`` f `'InnerJoin`` p2)
--   :: (...) => InnerJoin
--                 (InnerJoin (expr (Entity Person))
--                            (expr (Entity Follow)))
--                 (expr (Entity Person))
-- (p1 `'InnerJoin`` (f `'InnerJoin`` p2)) ::
--   :: (...) => InnerJoin
--                 (expr (Entity Person))
--                 (InnerJoin (expr (Entity Follow))
--                            (expr (Entity Person)))
-- @
--
-- Note that some backends may not support all kinds of @JOIN@s.
from :: From a => (a -> SqlQuery b) -> SqlQuery b
from :: (a -> SqlQuery b) -> SqlQuery b
from = (SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=)


-- | (Internal) Class that implements the tuple 'from' magic (see
-- 'fromStart').
class From a where
    from_ :: SqlQuery a

instance
    ( FromPreprocess (SqlExpr (Entity val))
    )
  =>
    From (SqlExpr (Entity val))
  where
    from_ :: SqlQuery (SqlExpr (Entity val))
from_ = SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity val))))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity val))))
-> (SqlExpr (PreprocessedFrom (SqlExpr (Entity val)))
    -> SqlQuery (SqlExpr (Entity val)))
-> SqlQuery (SqlExpr (Entity val))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (SqlExpr (Entity val)))
-> SqlQuery (SqlExpr (Entity val))
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance
    ( FromPreprocess (SqlExpr (Maybe (Entity val)))
    )
  =>
    From (SqlExpr (Maybe (Entity val)))
  where
    from_ :: SqlQuery (SqlExpr (Maybe (Entity val)))
from_ = SqlQuery
  (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val)))))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery
  (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val)))))
-> (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val))))
    -> SqlQuery (SqlExpr (Maybe (Entity val))))
-> SqlQuery (SqlExpr (Maybe (Entity val)))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val))))
-> SqlQuery (SqlExpr (Maybe (Entity val)))
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance
    ( FromPreprocess (InnerJoin a b)
    )
  =>
    From (InnerJoin a b)
  where
    from_ :: SqlQuery (InnerJoin a b)
from_ = SqlQuery (SqlExpr (PreprocessedFrom (InnerJoin a b)))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (InnerJoin a b)))
-> (SqlExpr (PreprocessedFrom (InnerJoin a b))
    -> SqlQuery (InnerJoin a b))
-> SqlQuery (InnerJoin a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (InnerJoin a b))
-> SqlQuery (InnerJoin a b)
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance
    ( FromPreprocess (CrossJoin a b)
    )
  =>
    From (CrossJoin a b)
  where
    from_ :: SqlQuery (CrossJoin a b)
from_ = SqlQuery (SqlExpr (PreprocessedFrom (CrossJoin a b)))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (CrossJoin a b)))
-> (SqlExpr (PreprocessedFrom (CrossJoin a b))
    -> SqlQuery (CrossJoin a b))
-> SqlQuery (CrossJoin a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (CrossJoin a b))
-> SqlQuery (CrossJoin a b)
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance (FromPreprocess (LeftOuterJoin a b)) => From (LeftOuterJoin a b) where
    from_ :: SqlQuery (LeftOuterJoin a b)
from_ = SqlQuery (SqlExpr (PreprocessedFrom (LeftOuterJoin a b)))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (LeftOuterJoin a b)))
-> (SqlExpr (PreprocessedFrom (LeftOuterJoin a b))
    -> SqlQuery (LeftOuterJoin a b))
-> SqlQuery (LeftOuterJoin a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (LeftOuterJoin a b))
-> SqlQuery (LeftOuterJoin a b)
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance (FromPreprocess (RightOuterJoin a b)) => From (RightOuterJoin a b) where
    from_ :: SqlQuery (RightOuterJoin a b)
from_ = SqlQuery (SqlExpr (PreprocessedFrom (RightOuterJoin a b)))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (RightOuterJoin a b)))
-> (SqlExpr (PreprocessedFrom (RightOuterJoin a b))
    -> SqlQuery (RightOuterJoin a b))
-> SqlQuery (RightOuterJoin a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (RightOuterJoin a b))
-> SqlQuery (RightOuterJoin a b)
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance (FromPreprocess (FullOuterJoin a b)) => From (FullOuterJoin a b) where
    from_ :: SqlQuery (FullOuterJoin a b)
from_ = SqlQuery (SqlExpr (PreprocessedFrom (FullOuterJoin a b)))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess SqlQuery (SqlExpr (PreprocessedFrom (FullOuterJoin a b)))
-> (SqlExpr (PreprocessedFrom (FullOuterJoin a b))
    -> SqlQuery (FullOuterJoin a b))
-> SqlQuery (FullOuterJoin a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SqlExpr (PreprocessedFrom (FullOuterJoin a b))
-> SqlQuery (FullOuterJoin a b)
forall a. SqlExpr (PreprocessedFrom a) -> SqlQuery a
fromFinish

instance (From a, From b) => From (a, b) where
    from_ :: SqlQuery (a, b)
from_ = (,) (a -> b -> (a, b)) -> SqlQuery a -> SqlQuery (b -> (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> (a, b)) -> SqlQuery b -> SqlQuery (a, b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_

instance (From a, From b, From c) => From (a, b, c) where
    from_ :: SqlQuery (a, b, c)
from_ = (,,) (a -> b -> c -> (a, b, c))
-> SqlQuery a -> SqlQuery (b -> c -> (a, b, c))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> c -> (a, b, c))
-> SqlQuery b -> SqlQuery (c -> (a, b, c))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> (a, b, c)) -> SqlQuery c -> SqlQuery (a, b, c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_

instance (From a, From b, From c, From d) => From (a, b, c, d) where
    from_ :: SqlQuery (a, b, c, d)
from_ = (,,,) (a -> b -> c -> d -> (a, b, c, d))
-> SqlQuery a -> SqlQuery (b -> c -> d -> (a, b, c, d))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> c -> d -> (a, b, c, d))
-> SqlQuery b -> SqlQuery (c -> d -> (a, b, c, d))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> d -> (a, b, c, d))
-> SqlQuery c -> SqlQuery (d -> (a, b, c, d))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_ SqlQuery (d -> (a, b, c, d)) -> SqlQuery d -> SqlQuery (a, b, c, d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery d
forall a. From a => SqlQuery a
from_

instance (From a, From b, From c, From d, From e) => From (a, b, c, d, e) where
    from_ :: SqlQuery (a, b, c, d, e)
from_ = (,,,,) (a -> b -> c -> d -> e -> (a, b, c, d, e))
-> SqlQuery a -> SqlQuery (b -> c -> d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> c -> d -> e -> (a, b, c, d, e))
-> SqlQuery b -> SqlQuery (c -> d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> d -> e -> (a, b, c, d, e))
-> SqlQuery c -> SqlQuery (d -> e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_ SqlQuery (d -> e -> (a, b, c, d, e))
-> SqlQuery d -> SqlQuery (e -> (a, b, c, d, e))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery d
forall a. From a => SqlQuery a
from_ SqlQuery (e -> (a, b, c, d, e))
-> SqlQuery e -> SqlQuery (a, b, c, d, e)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery e
forall a. From a => SqlQuery a
from_

instance
    (From a, From b, From c, From d, From e, From f)
  =>
    From (a, b, c, d, e, f)
  where
    from_ :: SqlQuery (a, b, c, d, e, f)
from_ = (,,,,,) (a -> b -> c -> d -> e -> f -> (a, b, c, d, e, f))
-> SqlQuery a
-> SqlQuery (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> c -> d -> e -> f -> (a, b, c, d, e, f))
-> SqlQuery b -> SqlQuery (c -> d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> d -> e -> f -> (a, b, c, d, e, f))
-> SqlQuery c -> SqlQuery (d -> e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_ SqlQuery (d -> e -> f -> (a, b, c, d, e, f))
-> SqlQuery d -> SqlQuery (e -> f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery d
forall a. From a => SqlQuery a
from_ SqlQuery (e -> f -> (a, b, c, d, e, f))
-> SqlQuery e -> SqlQuery (f -> (a, b, c, d, e, f))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery e
forall a. From a => SqlQuery a
from_ SqlQuery (f -> (a, b, c, d, e, f))
-> SqlQuery f -> SqlQuery (a, b, c, d, e, f)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery f
forall a. From a => SqlQuery a
from_

instance
    (From a, From b, From c, From d, From e, From f, From g)
  =>
    From (a, b, c, d, e, f, g)
  where
    from_ :: SqlQuery (a, b, c, d, e, f, g)
from_ =
        (,,,,,,) (a -> b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery a
-> SqlQuery (b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery (b -> c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery b
-> SqlQuery (c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> d -> e -> f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery c
-> SqlQuery (d -> e -> f -> g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_ SqlQuery (d -> e -> f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery d -> SqlQuery (e -> f -> g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery d
forall a. From a => SqlQuery a
from_ SqlQuery (e -> f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery e -> SqlQuery (f -> g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery e
forall a. From a => SqlQuery a
from_ SqlQuery (f -> g -> (a, b, c, d, e, f, g))
-> SqlQuery f -> SqlQuery (g -> (a, b, c, d, e, f, g))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery f
forall a. From a => SqlQuery a
from_ SqlQuery (g -> (a, b, c, d, e, f, g))
-> SqlQuery g -> SqlQuery (a, b, c, d, e, f, g)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery g
forall a. From a => SqlQuery a
from_

instance
    (From a, From b, From c, From d, From e, From f, From g, From h)
  =>
    From (a, b, c, d, e, f, g, h)
  where
    from_ :: SqlQuery (a, b, c, d, e, f, g, h)
from_ =
        (,,,,,,,) (a -> b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery a
-> SqlQuery
     (b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SqlQuery a
forall a. From a => SqlQuery a
from_ SqlQuery
  (b -> c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery b
-> SqlQuery
     (c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery b
forall a. From a => SqlQuery a
from_ SqlQuery (c -> d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery c
-> SqlQuery (d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery c
forall a. From a => SqlQuery a
from_ SqlQuery (d -> e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery d
-> SqlQuery (e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery d
forall a. From a => SqlQuery a
from_ SqlQuery (e -> f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery e -> SqlQuery (f -> g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery e
forall a. From a => SqlQuery a
from_ SqlQuery (f -> g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery f -> SqlQuery (g -> h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery f
forall a. From a => SqlQuery a
from_ SqlQuery (g -> h -> (a, b, c, d, e, f, g, h))
-> SqlQuery g -> SqlQuery (h -> (a, b, c, d, e, f, g, h))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery g
forall a. From a => SqlQuery a
from_ SqlQuery (h -> (a, b, c, d, e, f, g, h))
-> SqlQuery h -> SqlQuery (a, b, c, d, e, f, g, h)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SqlQuery h
forall a. From a => SqlQuery a
from_



-- | (Internal) Class that implements the @JOIN@ 'from' magic
-- (see 'fromStart').
class FromPreprocess a where
    fromPreprocess :: SqlQuery (SqlExpr (PreprocessedFrom a))

instance
    (PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val))
  =>
    FromPreprocess (SqlExpr (Entity val))
  where
    fromPreprocess :: SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity val))))
fromPreprocess = SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity val))))
forall a.
(PersistEntity a,
 BackendCompatible SqlBackend (PersistEntityBackend a)) =>
SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a))))
fromStart

instance
    (PersistEntity val, BackendCompatible SqlBackend (PersistEntityBackend val))
  =>
    FromPreprocess (SqlExpr (Maybe (Entity val)))
  where
    fromPreprocess :: SqlQuery
  (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val)))))
fromPreprocess = SqlQuery
  (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val)))))
forall val.
(PersistEntity val,
 BackendCompatible SqlBackend (PersistEntityBackend val)) =>
SqlQuery
  (SqlExpr (PreprocessedFrom (SqlExpr (Maybe (Entity val)))))
fromStartMaybe

instance
    (FromPreprocess a, FromPreprocess b, IsJoinKind join)
  =>
    FromPreprocess (join a b)
  where
    fromPreprocess :: SqlQuery (SqlExpr (PreprocessedFrom (join a b)))
fromPreprocess = do
        SqlExpr (PreprocessedFrom a)
a <- SqlQuery (SqlExpr (PreprocessedFrom a))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess
        SqlExpr (PreprocessedFrom b)
b <- SqlQuery (SqlExpr (PreprocessedFrom b))
forall a.
FromPreprocess a =>
SqlQuery (SqlExpr (PreprocessedFrom a))
fromPreprocess
        SqlExpr (PreprocessedFrom a)
-> SqlExpr (PreprocessedFrom b)
-> SqlQuery (SqlExpr (PreprocessedFrom (join a b)))
forall (join :: * -> * -> *) a b.
IsJoinKind join =>
SqlExpr (PreprocessedFrom a)
-> SqlExpr (PreprocessedFrom b)
-> SqlQuery (SqlExpr (PreprocessedFrom (join a b)))
fromJoin SqlExpr (PreprocessedFrom a)
a SqlExpr (PreprocessedFrom b)
b

-- | Exception data type for @esqueleto@ internal errors
data EsqueletoError
    = CompositeKeyErr CompositeKeyError
    | AliasedValueErr UnexpectedValueError
    | UnexpectedCaseErr UnexpectedCaseError
    | SqlBinOpCompositeErr SqlBinOpCompositeError
    deriving (Int -> EsqueletoError -> ShowS
[EsqueletoError] -> ShowS
EsqueletoError -> [Char]
(Int -> EsqueletoError -> ShowS)
-> (EsqueletoError -> [Char])
-> ([EsqueletoError] -> ShowS)
-> Show EsqueletoError
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [EsqueletoError] -> ShowS
$cshowList :: [EsqueletoError] -> ShowS
show :: EsqueletoError -> [Char]
$cshow :: EsqueletoError -> [Char]
showsPrec :: Int -> EsqueletoError -> ShowS
$cshowsPrec :: Int -> EsqueletoError -> ShowS
Show)

instance Exception EsqueletoError

data UnexpectedValueError
    = NotError
    | ToInsertionError
    | CombineInsertionError
    | FoldHelpError
    | SqlCaseError
    | SqlCastAsError
    | SqlFunctionError
    | MakeOnClauseError
    | MakeExcError
    | MakeSetError
    | MakeWhereError
    | MakeHavingError
    | FilterWhereAggError
    | FilterWhereClauseError
    deriving (Int -> CompositeKeyError -> ShowS
[CompositeKeyError] -> ShowS
CompositeKeyError -> [Char]
(Int -> CompositeKeyError -> ShowS)
-> (CompositeKeyError -> [Char])
-> ([CompositeKeyError] -> ShowS)
-> Show CompositeKeyError
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [CompositeKeyError] -> ShowS
$cshowList :: [CompositeKeyError] -> ShowS
show :: CompositeKeyError -> [Char]
$cshow :: CompositeKeyError -> [Char]
showsPrec :: Int -> CompositeKeyError -> ShowS
$cshowsPrec :: Int -> CompositeKeyError -> ShowS
Show)

type CompositeKeyError = UnexpectedValueError

data UnexpectedCaseError
    = EmptySqlExprValueList
    | MakeFromError
    | UnsupportedSqlInsertIntoType
    | InsertionFinalError
    | NewIdentForError
    | UnsafeSqlCaseError
    | OperationNotSupported
    | NotImplemented
    deriving (Int -> UnexpectedCaseError -> ShowS
[UnexpectedCaseError] -> ShowS
UnexpectedCaseError -> [Char]
(Int -> UnexpectedCaseError -> ShowS)
-> (UnexpectedCaseError -> [Char])
-> ([UnexpectedCaseError] -> ShowS)
-> Show UnexpectedCaseError
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [UnexpectedCaseError] -> ShowS
$cshowList :: [UnexpectedCaseError] -> ShowS
show :: UnexpectedCaseError -> [Char]
$cshow :: UnexpectedCaseError -> [Char]
showsPrec :: Int -> UnexpectedCaseError -> ShowS
$cshowsPrec :: Int -> UnexpectedCaseError -> ShowS
Show)

data SqlBinOpCompositeError
    = MismatchingLengthsError
    | NullPlaceholdersError
    | DeconstructionError
    deriving (Int -> SqlBinOpCompositeError -> ShowS
[SqlBinOpCompositeError] -> ShowS
SqlBinOpCompositeError -> [Char]
(Int -> SqlBinOpCompositeError -> ShowS)
-> (SqlBinOpCompositeError -> [Char])
-> ([SqlBinOpCompositeError] -> ShowS)
-> Show SqlBinOpCompositeError
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [SqlBinOpCompositeError] -> ShowS
$cshowList :: [SqlBinOpCompositeError] -> ShowS
show :: SqlBinOpCompositeError -> [Char]
$cshow :: SqlBinOpCompositeError -> [Char]
showsPrec :: Int -> SqlBinOpCompositeError -> ShowS
$cshowsPrec :: Int -> SqlBinOpCompositeError -> ShowS
Show)

-- | SQL backend for @esqueleto@ using 'SqlPersistT'.
newtype SqlQuery a = Q { SqlQuery a -> WriterT SideData (State IdentState) a
unQ :: W.WriterT SideData (S.State IdentState) a }
    deriving newtype (a -> SqlQuery b -> SqlQuery a
(a -> b) -> SqlQuery a -> SqlQuery b
(forall a b. (a -> b) -> SqlQuery a -> SqlQuery b)
-> (forall a b. a -> SqlQuery b -> SqlQuery a) -> Functor SqlQuery
forall a b. a -> SqlQuery b -> SqlQuery a
forall a b. (a -> b) -> SqlQuery a -> SqlQuery b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SqlQuery b -> SqlQuery a
$c<$ :: forall a b. a -> SqlQuery b -> SqlQuery a
fmap :: (a -> b) -> SqlQuery a -> SqlQuery b
$cfmap :: forall a b. (a -> b) -> SqlQuery a -> SqlQuery b
Functor, Functor SqlQuery
a -> SqlQuery a
Functor SqlQuery
-> (forall a. a -> SqlQuery a)
-> (forall a b. SqlQuery (a -> b) -> SqlQuery a -> SqlQuery b)
-> (forall a b c.
    (a -> b -> c) -> SqlQuery a -> SqlQuery b -> SqlQuery c)
-> (forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b)
-> (forall a b. SqlQuery a -> SqlQuery b -> SqlQuery a)
-> Applicative SqlQuery
SqlQuery a -> SqlQuery b -> SqlQuery b
SqlQuery a -> SqlQuery b -> SqlQuery a
SqlQuery (a -> b) -> SqlQuery a -> SqlQuery b
(a -> b -> c) -> SqlQuery a -> SqlQuery b -> SqlQuery c
forall a. a -> SqlQuery a
forall a b. SqlQuery a -> SqlQuery b -> SqlQuery a
forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b
forall a b. SqlQuery (a -> b) -> SqlQuery a -> SqlQuery b
forall a b c.
(a -> b -> c) -> SqlQuery a -> SqlQuery b -> SqlQuery c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: SqlQuery a -> SqlQuery b -> SqlQuery a
$c<* :: forall a b. SqlQuery a -> SqlQuery b -> SqlQuery a
*> :: SqlQuery a -> SqlQuery b -> SqlQuery b
$c*> :: forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b
liftA2 :: (a -> b -> c) -> SqlQuery a -> SqlQuery b -> SqlQuery c
$cliftA2 :: forall a b c.
(a -> b -> c) -> SqlQuery a -> SqlQuery b -> SqlQuery c
<*> :: SqlQuery (a -> b) -> SqlQuery a -> SqlQuery b
$c<*> :: forall a b. SqlQuery (a -> b) -> SqlQuery a -> SqlQuery b
pure :: a -> SqlQuery a
$cpure :: forall a. a -> SqlQuery a
$cp1Applicative :: Functor SqlQuery
Applicative, Applicative SqlQuery
a -> SqlQuery a
Applicative SqlQuery
-> (forall a b. SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b)
-> (forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b)
-> (forall a. a -> SqlQuery a)
-> Monad SqlQuery
SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b
SqlQuery a -> SqlQuery b -> SqlQuery b
forall a. a -> SqlQuery a
forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b
forall a b. SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> SqlQuery a
$creturn :: forall a. a -> SqlQuery a
>> :: SqlQuery a -> SqlQuery b -> SqlQuery b
$c>> :: forall a b. SqlQuery a -> SqlQuery b -> SqlQuery b
>>= :: SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b
$c>>= :: forall a b. SqlQuery a -> (a -> SqlQuery b) -> SqlQuery b
$cp1Monad :: Applicative SqlQuery
Monad)

-- | Constraint synonym for @persistent@ entities whose backend
-- is 'SqlBackend'.
type SqlEntity ent = (PersistEntity ent, PersistEntityBackend ent ~ SqlBackend)


----------------------------------------------------------------------


-- | Side data written by 'SqlQuery'.
data SideData = SideData
    { SideData -> DistinctClause
sdDistinctClause :: !DistinctClause
    , SideData -> [FromClause]
sdFromClause     :: ![FromClause]
    , SideData -> [SetClause]
sdSetClause      :: ![SetClause]
    , SideData -> WhereClause
sdWhereClause    :: !WhereClause
    , SideData -> GroupByClause
sdGroupByClause  :: !GroupByClause
    , SideData -> WhereClause
sdHavingClause   :: !HavingClause
    , SideData -> [SqlExpr OrderBy]
sdOrderByClause  :: ![OrderByClause]
    , SideData -> LimitClause
sdLimitClause    :: !LimitClause
    , SideData -> LockingClause
sdLockingClause  :: !LockingClause
    , SideData -> [CommonTableExpressionClause]
sdCteClause      :: ![CommonTableExpressionClause]
    }

instance Semigroup SideData where
    SideData DistinctClause
d [FromClause]
f [SetClause]
s WhereClause
w GroupByClause
g WhereClause
h [SqlExpr OrderBy]
o LimitClause
l LockingClause
k [CommonTableExpressionClause]
c <> :: SideData -> SideData -> SideData
<> SideData DistinctClause
d' [FromClause]
f' [SetClause]
s' WhereClause
w' GroupByClause
g' WhereClause
h' [SqlExpr OrderBy]
o' LimitClause
l' LockingClause
k' [CommonTableExpressionClause]
c' =
        DistinctClause
-> [FromClause]
-> [SetClause]
-> WhereClause
-> GroupByClause
-> WhereClause
-> [SqlExpr OrderBy]
-> LimitClause
-> LockingClause
-> [CommonTableExpressionClause]
-> SideData
SideData (DistinctClause
d DistinctClause -> DistinctClause -> DistinctClause
forall a. Semigroup a => a -> a -> a
<> DistinctClause
d') ([FromClause]
f [FromClause] -> [FromClause] -> [FromClause]
forall a. Semigroup a => a -> a -> a
<> [FromClause]
f') ([SetClause]
s [SetClause] -> [SetClause] -> [SetClause]
forall a. Semigroup a => a -> a -> a
<> [SetClause]
s') (WhereClause
w WhereClause -> WhereClause -> WhereClause
forall a. Semigroup a => a -> a -> a
<> WhereClause
w') (GroupByClause
g GroupByClause -> GroupByClause -> GroupByClause
forall a. Semigroup a => a -> a -> a
<> GroupByClause
g') (WhereClause
h WhereClause -> WhereClause -> WhereClause
forall a. Semigroup a => a -> a -> a
<> WhereClause
h') ([SqlExpr OrderBy]
o [SqlExpr OrderBy] -> [SqlExpr OrderBy] -> [SqlExpr OrderBy]
forall a. Semigroup a => a -> a -> a
<> [SqlExpr OrderBy]
o') (LimitClause
l LimitClause -> LimitClause -> LimitClause
forall a. Semigroup a => a -> a -> a
<> LimitClause
l') (LockingClause
k LockingClause -> LockingClause -> LockingClause
forall a. Semigroup a => a -> a -> a
<> LockingClause
k') ([CommonTableExpressionClause]
c [CommonTableExpressionClause]
-> [CommonTableExpressionClause] -> [CommonTableExpressionClause]
forall a. Semigroup a => a -> a -> a
<> [CommonTableExpressionClause]
c')

instance Monoid SideData where
    mempty :: SideData
mempty = DistinctClause
-> [FromClause]
-> [SetClause]
-> WhereClause
-> GroupByClause
-> WhereClause
-> [SqlExpr OrderBy]
-> LimitClause
-> LockingClause
-> [CommonTableExpressionClause]
-> SideData
SideData DistinctClause
forall a. Monoid a => a
mempty [FromClause]
forall a. Monoid a => a
mempty [SetClause]
forall a. Monoid a => a
mempty WhereClause
forall a. Monoid a => a
mempty GroupByClause
forall a. Monoid a => a
mempty WhereClause
forall a. Monoid a => a
mempty [SqlExpr OrderBy]
forall a. Monoid a => a
mempty LimitClause
forall a. Monoid a => a
mempty LockingClause
forall a. Monoid a => a
mempty [CommonTableExpressionClause]
forall a. Monoid a => a
mempty
    mappend :: SideData -> SideData -> SideData
mappend = SideData -> SideData -> SideData
forall a. Semigroup a => a -> a -> a
(<>)

-- | The @DISTINCT@ "clause".
data DistinctClause
    = DistinctAll
    -- ^ The default, everything.
    | DistinctStandard
    -- ^ Only @DISTINCT@, SQL standard.
    | DistinctOn [SqlExpr DistinctOn]
    -- ^ @DISTINCT ON@, PostgreSQL extension.

instance Semigroup DistinctClause where
    DistinctOn [SqlExpr DistinctOn]
a     <> :: DistinctClause -> DistinctClause -> DistinctClause
<> DistinctOn [SqlExpr DistinctOn]
b = [SqlExpr DistinctOn] -> DistinctClause
DistinctOn ([SqlExpr DistinctOn]
a [SqlExpr DistinctOn]
-> [SqlExpr DistinctOn] -> [SqlExpr DistinctOn]
forall a. Semigroup a => a -> a -> a
<> [SqlExpr DistinctOn]
b)
    DistinctOn [SqlExpr DistinctOn]
a     <> DistinctClause
_            = [SqlExpr DistinctOn] -> DistinctClause
DistinctOn [SqlExpr DistinctOn]
a
    DistinctClause
DistinctStandard <> DistinctClause
_            = DistinctClause
DistinctStandard
    DistinctClause
DistinctAll      <> DistinctClause
b            = DistinctClause
b

instance Monoid DistinctClause where
    mempty :: DistinctClause
mempty = DistinctClause
DistinctAll
    mappend :: DistinctClause -> DistinctClause -> DistinctClause
mappend = DistinctClause -> DistinctClause -> DistinctClause
forall a. Semigroup a => a -> a -> a
(<>)

-- | A part of a @FROM@ clause.
data FromClause
    = FromStart Ident EntityDef
    | FromJoin FromClause JoinKind FromClause (Maybe (SqlExpr (Value Bool)))
    | OnClause (SqlExpr (Value Bool))
    | FromQuery Ident (IdentInfo -> (TLB.Builder, [PersistValue])) SubQueryType
    | FromIdent Ident

data CommonTableExpressionKind
    = RecursiveCommonTableExpression
    | NormalCommonTableExpression
    deriving CommonTableExpressionKind -> CommonTableExpressionKind -> Bool
(CommonTableExpressionKind -> CommonTableExpressionKind -> Bool)
-> (CommonTableExpressionKind -> CommonTableExpressionKind -> Bool)
-> Eq CommonTableExpressionKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CommonTableExpressionKind -> CommonTableExpressionKind -> Bool
$c/= :: CommonTableExpressionKind -> CommonTableExpressionKind -> Bool
== :: CommonTableExpressionKind -> CommonTableExpressionKind -> Bool
$c== :: CommonTableExpressionKind -> CommonTableExpressionKind -> Bool
Eq

data CommonTableExpressionClause =
    CommonTableExpressionClause CommonTableExpressionKind Ident (IdentInfo -> (TLB.Builder, [PersistValue]))

data SubQueryType
    = NormalSubQuery
    | LateralSubQuery
    deriving Int -> SubQueryType -> ShowS
[SubQueryType] -> ShowS
SubQueryType -> [Char]
(Int -> SubQueryType -> ShowS)
-> (SubQueryType -> [Char])
-> ([SubQueryType] -> ShowS)
-> Show SubQueryType
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [SubQueryType] -> ShowS
$cshowList :: [SubQueryType] -> ShowS
show :: SubQueryType -> [Char]
$cshow :: SubQueryType -> [Char]
showsPrec :: Int -> SubQueryType -> ShowS
$cshowsPrec :: Int -> SubQueryType -> ShowS
Show

collectIdents :: FromClause -> Set Ident
collectIdents :: FromClause -> Set Ident
collectIdents FromClause
fc = case FromClause
fc of
    FromStart Ident
i EntityDef
_ -> Ident -> Set Ident
forall a. a -> Set a
Set.singleton Ident
i
    FromJoin FromClause
lhs JoinKind
_ FromClause
rhs Maybe (SqlExpr (Value Bool))
_ -> FromClause -> Set Ident
collectIdents FromClause
lhs Set Ident -> Set Ident -> Set Ident
forall a. Semigroup a => a -> a -> a
<> FromClause -> Set Ident
collectIdents FromClause
rhs
    OnClause SqlExpr (Value Bool)
_ -> Set Ident
forall a. Monoid a => a
mempty
    FromQuery Ident
_ IdentInfo -> (Builder, [PersistValue])
_ SubQueryType
_ -> Set Ident
forall a. Monoid a => a
mempty
    FromIdent Ident
_ -> Set Ident
forall a. Monoid a => a
mempty

instance Show FromClause where
    show :: FromClause -> [Char]
show FromClause
fc = case FromClause
fc of
        FromStart Ident
i EntityDef
_ ->
            [Char]
"(FromStart " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
i [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
")"
        FromJoin FromClause
lhs JoinKind
jk FromClause
rhs Maybe (SqlExpr (Value Bool))
mexpr ->
            [[Char]] -> [Char]
forall a. Monoid a => [a] -> a
mconcat
            [ [Char]
"(FromJoin "
            , FromClause -> [Char]
forall a. Show a => a -> [Char]
show FromClause
lhs
            , [Char]
" "
            , JoinKind -> [Char]
forall a. Show a => a -> [Char]
show JoinKind
jk
            , [Char]
" "
            , case Maybe (SqlExpr (Value Bool))
mexpr of
                Maybe (SqlExpr (Value Bool))
Nothing -> [Char]
"(no on clause)"
                Just SqlExpr (Value Bool)
expr -> [Char]
"(" [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> SqlExpr (Value Bool) -> [Char]
render' SqlExpr (Value Bool)
expr [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
")"
            , [Char]
" "
            , FromClause -> [Char]
forall a. Show a => a -> [Char]
show FromClause
rhs
            , [Char]
")"
            ]
        OnClause SqlExpr (Value Bool)
expr ->
            [Char]
"(OnClause " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> SqlExpr (Value Bool) -> [Char]
render' SqlExpr (Value Bool)
expr [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
")"
        FromQuery Ident
ident IdentInfo -> (Builder, [PersistValue])
_ SubQueryType
subQueryType ->
            [Char]
"(FromQuery " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
ident [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
" " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> SubQueryType -> [Char]
forall a. Show a => a -> [Char]
show SubQueryType
subQueryType [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
")"
        FromIdent Ident
ident ->
            [Char]
"(FromIdent " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Ident -> [Char]
forall a. Show a => a -> [Char]
show Ident
ident [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
")"

      where
        dummy :: SqlBackend
dummy = MkSqlBackendArgs -> SqlBackend
mkSqlBackend MkSqlBackendArgs :: (Text -> IO Statement)
-> (EntityDef -> [PersistValue] -> InsertSqlResult)
-> IORef (Map Text Statement)
-> IO ()
-> ([EntityDef]
    -> (Text -> IO Statement)
    -> EntityDef
    -> IO (Either [Text] [(Bool, Text)]))
-> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ())
-> ((Text -> IO Statement) -> IO ())
-> ((Text -> IO Statement) -> IO ())
-> (FieldNameDB -> Text)
-> (EntityDef -> Text)
-> (Text -> Text)
-> Text
-> Text
-> ((Int, Int) -> Text -> Text)
-> LogFunc
-> MkSqlBackendArgs
MkSqlBackendArgs
            { connEscapeRawName :: Text -> Text
connEscapeRawName = Text -> Text
forall a. a -> a
id
            }
        render' :: SqlExpr (Value Bool) -> [Char]
render' = Text -> [Char]
T.unpack (Text -> [Char])
-> (SqlExpr (Value Bool) -> Text) -> SqlExpr (Value Bool) -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlBackend -> SqlExpr (Value Bool) -> Text
renderExpr SqlBackend
dummy

-- | A part of a @SET@ clause.
newtype SetClause = SetClause (SqlExpr (Value ()))

-- | Collect 'OnClause's on 'FromJoin's.  Returns the first
-- unmatched 'OnClause's data on error.  Returns a list without
-- 'OnClauses' on success.
collectOnClauses
    :: SqlBackend
    -> [FromClause]
    -> Either (SqlExpr (Value Bool)) [FromClause]
collectOnClauses :: SqlBackend
-> [FromClause] -> Either (SqlExpr (Value Bool)) [FromClause]
collectOnClauses SqlBackend
sqlBackend = Set Ident
-> [FromClause]
-> [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
go Set Ident
forall a. Set a
Set.empty []
  where
    go :: Set Ident
-> [FromClause]
-> [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
go Set Ident
is []  (f :: FromClause
f@(FromStart Ident
i EntityDef
_) : [FromClause]
fs) =
        ([FromClause] -> [FromClause])
-> Either (SqlExpr (Value Bool)) [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FromClause
fFromClause -> [FromClause] -> [FromClause]
forall a. a -> [a] -> [a]
:) (Set Ident
-> [FromClause]
-> [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
go (Ident -> Set Ident -> Set Ident
forall a. Ord a => a -> Set a -> Set a
Set.insert Ident
i Set Ident
is) [] [FromClause]
fs) -- fast path
    go Set Ident
idents [FromClause]
acc (OnClause SqlExpr (Value Bool)
expr : [FromClause]
fs) = do
        (Set Ident
idents', [FromClause]
a) <- Set Ident
-> [FromClause]
-> SqlExpr (Value Bool)
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
findMatching Set Ident
idents [FromClause]
acc SqlExpr (Value Bool)
expr
        Set Ident
-> [FromClause]
-> [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
go Set Ident
idents' [FromClause]
a [FromClause]
fs
    go Set Ident
idents [FromClause]
acc (FromClause
f:[FromClause]
fs) =
        Set Ident
-> [FromClause]
-> [FromClause]
-> Either (SqlExpr (Value Bool)) [FromClause]
go Set Ident
idents (FromClause
fFromClause -> [FromClause] -> [FromClause]
forall a. a -> [a] -> [a]
:[FromClause]
acc) [FromClause]
fs
    go Set Ident
_ [FromClause]
acc [] =
        [FromClause] -> Either (SqlExpr (Value Bool)) [FromClause]
forall (m :: * -> *) a. Monad m => a -> m a
return ([FromClause] -> Either (SqlExpr (Value Bool)) [FromClause])
-> [FromClause] -> Either (SqlExpr (Value Bool)) [FromClause]
forall a b. (a -> b) -> a -> b
$ [FromClause] -> [FromClause]
forall a. [a] -> [a]
reverse [FromClause]
acc

    findMatching
        :: Set Ident
        -> [FromClause]
        -> SqlExpr (Value Bool)
        -> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
    findMatching :: Set Ident
-> [FromClause]
-> SqlExpr (Value Bool)
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
findMatching Set Ident
idents [FromClause]
fromClauses SqlExpr (Value Bool)
expr =
        case [FromClause]
fromClauses of
            FromClause
f : [FromClause]
acc ->
              let idents' :: Set Ident
idents' =
                      Set Ident
idents
                      Set Ident -> Set Ident -> Set Ident
forall a. Semigroup a => a -> a -> a
<> [Ident] -> Set Ident
forall a. Ord a => [a] -> Set a
Set.fromList
                          ([Maybe Ident] -> [Ident]
forall a. [Maybe a] -> [a]
Maybe.catMaybes [FromClause -> Maybe Ident
findLeftmostIdent FromClause
f, FromClause -> Maybe Ident
findRightmostIdent FromClause
f])
              in
                  case Set Ident
-> SqlExpr (Value Bool)
-> FromClause
-> Maybe (Set Ident, FromClause)
tryMatch Set Ident
idents' SqlExpr (Value Bool)
expr FromClause
f of
                      Just (Set Ident
idents'', FromClause
f') ->
                          (Set Ident, [FromClause])
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
forall (m :: * -> *) a. Monad m => a -> m a
return (Set Ident
idents'', FromClause
f' FromClause -> [FromClause] -> [FromClause]
forall a. a -> [a] -> [a]
: [FromClause]
acc)
                      Maybe (Set Ident, FromClause)
Nothing ->
                          ([FromClause] -> [FromClause])
-> (Set Ident, [FromClause]) -> (Set Ident, [FromClause])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FromClause
fFromClause -> [FromClause] -> [FromClause]
forall a. a -> [a] -> [a]
:) ((Set Ident, [FromClause]) -> (Set Ident, [FromClause]))
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Ident
-> [FromClause]
-> SqlExpr (Value Bool)
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
findMatching Set Ident
idents' [FromClause]
acc SqlExpr (Value Bool)
expr
            [] ->
                SqlExpr (Value Bool)
-> Either (SqlExpr (Value Bool)) (Set Ident, [FromClause])
forall a b. a -> Either a b
Left SqlExpr (Value Bool)
expr

    findRightmostIdent :: FromClause -> Maybe Ident
findRightmostIdent (FromStart Ident
i EntityDef
_) = Ident -> Maybe Ident
forall a. a -> Maybe a
Just Ident
i
    findRightmostIdent (FromJoin FromClause
_ JoinKind
_ FromClause
r Maybe (SqlExpr (Value Bool))
_) = FromClause -> Maybe Ident
findRightmostIdent FromClause
r
    findRightmostIdent (OnClause {}) = Maybe Ident
forall a. Maybe a
Nothing
    findRightmostIdent (FromQuery Ident
_ IdentInfo -> (Builder, [PersistValue])
_ SubQueryType
_) = Maybe Ident
forall a. Maybe a
Nothing
    findRightmostIdent (FromIdent Ident
_) = Maybe Ident
forall a. Maybe a
Nothing

    findLeftmostIdent :: FromClause -> Maybe Ident
findLeftmostIdent (FromStart Ident
i EntityDef
_) = Ident -> Maybe Ident
forall a. a -> Maybe a
Just Ident
i
    findLeftmostIdent (FromJoin FromClause
l JoinKind
_ FromClause
_ Maybe (SqlExpr (Value Bool))
_) = FromClause -> Maybe Ident
findLeftmostIdent FromClause
l
    findLeftmostIdent (OnClause {}) = Maybe Ident
forall a. Maybe a
Nothing
    findLeftmostIdent (FromQuery Ident
_ IdentInfo -> (Builder, [PersistValue])
_ SubQueryType
_) = Maybe Ident
forall a. Maybe a
Nothing
    findLeftmostIdent (FromIdent Ident
_) = Maybe Ident
forall a. Maybe a
Nothing

    tryMatch
        :: Set Ident
        -> SqlExpr (Value Bool)
        -> FromClause
        -> Maybe (Set Ident, FromClause)
    tryMatch :: Set Ident
-> SqlExpr (Value Bool)
-> FromClause
-> Maybe (Set Ident, FromClause)
tryMatch Set Ident
idents SqlExpr (Value Bool)
expr FromClause
fromClause =
      case FromClause
fromClause of
        FromJoin FromClause
l JoinKind
k FromClause
r Maybe (SqlExpr (Value Bool))
onClause ->
          Maybe (Set Ident, FromClause)
matchTable Maybe (Set Ident, FromClause)
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Set Ident, FromClause)
matchR Maybe (Set Ident, FromClause)
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Set Ident, FromClause)
matchC Maybe (Set Ident, FromClause)
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Set Ident, FromClause)
matchL Maybe (Set Ident, FromClause)
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Set Ident, FromClause)
matchPartial -- right to left
            where
              matchR :: Maybe (Set Ident, FromClause)
matchR = (FromClause -> FromClause)
-> (Set Ident, FromClause) -> (Set Ident, FromClause)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\FromClause
r' -> FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l JoinKind
k FromClause
r' Maybe (SqlExpr (Value Bool))
onClause)
                ((Set Ident, FromClause) -> (Set Ident, FromClause))
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Ident
-> SqlExpr (Value Bool)
-> FromClause
-> Maybe (Set Ident, FromClause)
tryMatch Set Ident
idents SqlExpr (Value Bool)
expr FromClause
r
              matchL :: Maybe (Set Ident, FromClause)
matchL = (FromClause -> FromClause)
-> (Set Ident, FromClause) -> (Set Ident, FromClause)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\FromClause
l' -> FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l' JoinKind
k FromClause
r Maybe (SqlExpr (Value Bool))
onClause)
                ((Set Ident, FromClause) -> (Set Ident, FromClause))
-> Maybe (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set Ident
-> SqlExpr (Value Bool)
-> FromClause
-> Maybe (Set Ident, FromClause)
tryMatch Set Ident
idents SqlExpr (Value Bool)
expr FromClause
l

              matchPartial :: Maybe (Set Ident, FromClause)
matchPartial = do
                --Debug.traceM $ "matchPartial"
                --Debug.traceM $ "matchPartial: identsInOnClause: " <> show identsInOnClause
                Ident
i1 <- FromClause -> Maybe Ident
findLeftmostIdent FromClause
l
                Ident
i2 <- FromClause -> Maybe Ident
findLeftmostIdent FromClause
r
                let leftIdents :: Set Ident
leftIdents = FromClause -> Set Ident
collectIdents FromClause
l
                -- Debug.traceM $ "matchPartial: i1: " <> show i1
                -- Debug.traceM $ "matchPartial: i2: " <> show i2
                -- Debug.traceM $ "matchPartial: idents: " <> show idents
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$
                  Set Ident -> Set Ident -> Bool
forall a. Ord a => Set a -> Set a -> Bool
Set.isSubsetOf
                    Set Ident
identsInOnClause
                    ([Ident] -> Set Ident
forall a. Ord a => [a] -> Set a
Set.fromList [Ident
i1, Ident
i2] Set Ident -> Set Ident -> Set Ident
forall a. Semigroup a => a -> a -> a
<> Set Ident
leftIdents)
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ JoinKind
k JoinKind -> JoinKind -> Bool
forall a. Eq a => a -> a -> Bool
/= JoinKind
CrossJoinKind
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Maybe (SqlExpr (Value Bool)) -> Bool
forall a. Maybe a -> Bool
Maybe.isNothing Maybe (SqlExpr (Value Bool))
onClause
                (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set Ident
idents, FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l JoinKind
k FromClause
r (SqlExpr (Value Bool) -> Maybe (SqlExpr (Value Bool))
forall a. a -> Maybe a
Just SqlExpr (Value Bool)
expr))

              matchC :: Maybe (Set Ident, FromClause)
matchC =
                case Maybe (SqlExpr (Value Bool))
onClause of
                  Maybe (SqlExpr (Value Bool))
Nothing
                    | Text
"?" Text -> Text -> Bool
`T.isInfixOf` Text
renderedExpr ->
                        (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (m :: * -> *) a. Monad m => a -> m a
return (Set Ident
idents, FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l JoinKind
k FromClause
r (SqlExpr (Value Bool) -> Maybe (SqlExpr (Value Bool))
forall a. a -> Maybe a
Just SqlExpr (Value Bool)
expr))
                    | Set Ident -> Bool
forall a. Set a -> Bool
Set.null Set Ident
identsInOnClause ->
                        (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (m :: * -> *) a. Monad m => a -> m a
return (Set Ident
idents, FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l JoinKind
k FromClause
r (SqlExpr (Value Bool) -> Maybe (SqlExpr (Value Bool))
forall a. a -> Maybe a
Just SqlExpr (Value Bool)
expr))
                    | Bool
otherwise ->
                        Maybe (Set Ident, FromClause)
forall a. Maybe a
Nothing
                  Just SqlExpr (Value Bool)
_ ->
                    Maybe (Set Ident, FromClause)
forall a. Maybe a
Nothing
              matchTable :: Maybe (Set Ident, FromClause)
matchTable = do
                Ident
i1 <- FromClause -> Maybe Ident
findLeftmostIdent FromClause
r
                Ident
i2 <- FromClause -> Maybe Ident
findRightmostIdent FromClause
l
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ [Ident] -> Set Ident
forall a. Ord a => [a] -> Set a
Set.fromList [Ident
i1, Ident
i2] Set Ident -> Set Ident -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set Ident
identsInOnClause
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ JoinKind
k JoinKind -> JoinKind -> Bool
forall a. Eq a => a -> a -> Bool
/= JoinKind
CrossJoinKind
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Maybe (SqlExpr (Value Bool)) -> Bool
forall a. Maybe a -> Bool
Maybe.isNothing Maybe (SqlExpr (Value Bool))
onClause
                (Set Ident, FromClause) -> Maybe (Set Ident, FromClause)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Ident] -> Set Ident
forall a. Ord a => [a] -> Set a
Set.fromList [Ident
i1, Ident
i2] Set Ident -> Set Ident -> Set Ident
forall a. Semigroup a => a -> a -> a
<> Set Ident
idents, FromClause
-> JoinKind
-> FromClause
-> Maybe (SqlExpr (Value Bool))
-> FromClause
FromJoin FromClause
l JoinKind
k FromClause
r (SqlExpr (Value Bool) -> Maybe (SqlExpr (Value Bool))
forall a. a -> Maybe a
Just SqlExpr (Value Bool)
expr))

        FromClause
_ ->
          Maybe (Set Ident, FromClause)
forall a. Maybe a
Nothing
      where
        identsInOnClause :: Set Ident
identsInOnClause =
          Set Ident
onExprToTableIdentifiers

        renderedExpr :: Text
renderedExpr =
          SqlBackend -> SqlExpr (Value Bool) -> Text
renderExpr SqlBackend
sqlBackend SqlExpr (Value Bool)
expr

        onExprToTableIdentifiers :: Set Ident
onExprToTableIdentifiers =
          (TableAccess -> Ident) -> Set TableAccess -> Set Ident
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map (Text -> Ident
I (Text -> Ident) -> (TableAccess -> Text) -> TableAccess -> Ident
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TableAccess -> Text
tableAccessTable)
          (Set TableAccess -> Set Ident)
-> (Text -> Set TableAccess) -> Text -> Set Ident
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Set TableAccess)
-> (Set TableAccess -> Set TableAccess)
-> Either [Char] (Set TableAccess)
-> Set TableAccess
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [Char] -> Set TableAccess
forall a. HasCallStack => [Char] -> a
error Set TableAccess -> Set TableAccess
forall a. a -> a
id
          (Either [Char] (Set TableAccess) -> Set TableAccess)
-> (Text -> Either [Char] (Set TableAccess))
-> Text
-> Set TableAccess
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SqlBackend -> Text -> Either [Char] (Set TableAccess)
parseOnExpr SqlBackend
sqlBackend
          (Text -> Set Ident) -> Text -> Set Ident
forall a b. (a -> b) -> a -> b
$ Text
renderedExpr

-- | A complete @WHERE@ clause.
data WhereClause = Where (SqlExpr (Value Bool))
                 | NoWhere

instance Semigroup WhereClause where
  WhereClause
NoWhere  <> :: WhereClause -> WhereClause -> WhereClause
<> WhereClause
w        = WhereClause
w
  WhereClause
w        <> WhereClause
NoWhere  = WhereClause
w
  Where SqlExpr (Value Bool)
e1 <> Where SqlExpr (Value Bool)
e2 = SqlExpr (Value Bool) -> WhereClause
Where (SqlExpr (Value Bool)
e1 SqlExpr (Value Bool)
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
&&. SqlExpr (Value Bool)
e2)

instance Monoid WhereClause where
  mempty :: WhereClause
mempty = WhereClause
NoWhere
  mappend :: WhereClause -> WhereClause -> WhereClause
mappend = WhereClause -> WhereClause -> WhereClause
forall a. Semigroup a => a -> a -> a
(<>)

-- | A @GROUP BY@ clause.
newtype GroupByClause = GroupBy [SomeValue]

instance Semigroup GroupByClause where
  GroupBy [SomeValue]
fs <> :: GroupByClause -> GroupByClause -> GroupByClause
<> GroupBy [SomeValue]
fs' = [SomeValue] -> GroupByClause
GroupBy ([SomeValue]
fs [SomeValue] -> [SomeValue] -> [SomeValue]
forall a. Semigroup a => a -> a -> a
<> [SomeValue]
fs')

instance Monoid GroupByClause where
  mempty :: GroupByClause
mempty = [SomeValue] -> GroupByClause
GroupBy []
  mappend :: GroupByClause -> GroupByClause -> GroupByClause
mappend = GroupByClause -> GroupByClause -> GroupByClause
forall a. Semigroup a => a -> a -> a
(<>)

-- | A @HAVING@ cause.
type HavingClause = WhereClause

-- | A @ORDER BY@ clause.
type OrderByClause = SqlExpr OrderBy

-- | A @LIMIT@ clause.
data LimitClause = Limit (Maybe Int64) (Maybe Int64)
  deriving LimitClause -> LimitClause -> Bool
(LimitClause -> LimitClause -> Bool)
-> (LimitClause -> LimitClause -> Bool) -> Eq LimitClause
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LimitClause -> LimitClause -> Bool
$c/= :: LimitClause -> LimitClause -> Bool
== :: LimitClause -> LimitClause -> Bool
$c== :: LimitClause -> LimitClause -> Bool
Eq

instance Semigroup LimitClause where
  Limit Maybe Int64
l1 Maybe Int64
o1 <> :: LimitClause -> LimitClause -> LimitClause
<> Limit Maybe Int64
l2 Maybe Int64
o2 =
    Maybe Int64 -> Maybe Int64 -> LimitClause
Limit (Maybe Int64
l2 Maybe Int64 -> Maybe Int64 -> Maybe Int64
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Maybe Int64
l1) (Maybe Int64
o2 Maybe Int64 -> Maybe Int64 -> Maybe Int64
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Maybe Int64
o1)
    -- More than one 'limit' or 'offset' is issued, we want to
    -- keep the latest one.  That's why we use mplus with
    -- "reversed" arguments.

instance Monoid LimitClause where
  mempty :: LimitClause
mempty = Maybe Int64 -> Maybe Int64 -> LimitClause
Limit Maybe Int64
forall (m :: * -> *) a. MonadPlus m => m a
mzero Maybe Int64
forall (m :: * -> *) a. MonadPlus m => m a
mzero
  mappend :: LimitClause -> LimitClause -> LimitClause
mappend = LimitClause -> LimitClause -> LimitClause
forall a. Semigroup a => a -> a -> a
(<>)

-- | A locking clause.
type LockingClause = Monoid.Last LockingKind

----------------------------------------------------------------------

-- | Identifier used for table names.
newtype Ident = I T.Text
  deriving (Ident -> Ident -> Bool
(Ident -> Ident -> Bool) -> (Ident -> Ident -> Bool) -> Eq Ident
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ident -> Ident -> Bool
$c/= :: Ident -> Ident -> Bool
== :: Ident -> Ident -> Bool
$c== :: Ident -> Ident -> Bool
Eq, Eq Ident
Eq Ident
-> (Ident -> Ident -> Ordering)
-> (Ident -> Ident -> Bool)
-> (Ident -> Ident -> Bool)
-> (Ident -> Ident -> Bool)
-> (Ident -> Ident -> Bool)
-> (Ident -> Ident -> Ident)
-> (Ident -> Ident -> Ident)
-> Ord Ident
Ident -> Ident -> Bool
Ident -> Ident -> Ordering
Ident -> Ident -> Ident
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Ident -> Ident -> Ident
$cmin :: Ident -> Ident -> Ident
max :: Ident -> Ident -> Ident
$cmax :: Ident -> Ident -> Ident
>= :: Ident -> Ident -> Bool
$c>= :: Ident -> Ident -> Bool
> :: Ident -> Ident -> Bool
$c> :: Ident -> Ident -> Bool
<= :: Ident -> Ident -> Bool
$c<= :: Ident -> Ident -> Bool
< :: Ident -> Ident -> Bool
$c< :: Ident -> Ident -> Bool
compare :: Ident -> Ident -> Ordering
$ccompare :: Ident -> Ident -> Ordering
$cp1Ord :: Eq Ident
Ord, Int -> Ident -> ShowS
[Ident] -> ShowS
Ident -> [Char]
(Int -> Ident -> ShowS)
-> (Ident -> [Char]) -> ([Ident] -> ShowS) -> Show Ident
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [Ident] -> ShowS
$cshowList :: [Ident] -> ShowS
show :: Ident -> [Char]
$cshow :: Ident -> [Char]
showsPrec :: Int -> Ident -> ShowS
$cshowsPrec :: Int -> Ident -> ShowS
Show)

-- | List of identifiers already in use and supply of temporary
-- identifiers.
newtype IdentState = IdentState { IdentState -> HashSet Text
inUse :: HS.HashSet T.Text }

initialIdentState :: IdentState
initialIdentState :: IdentState
initialIdentState = HashSet Text -> IdentState
IdentState HashSet Text
forall a. Monoid a => a
mempty

-- | Create a fresh 'Ident'.  If possible, use the given
-- 'DBName'.
newIdentFor :: DBName -> SqlQuery Ident
newIdentFor :: DBName -> SqlQuery Ident
newIdentFor (DBName Text
original) = WriterT SideData (State IdentState) Ident -> SqlQuery Ident
forall a. WriterT SideData (State IdentState) a -> SqlQuery a
Q (WriterT SideData (State IdentState) Ident -> SqlQuery Ident)
-> WriterT SideData (State IdentState) Ident -> SqlQuery Ident
forall a b. (a -> b) -> a -> b
$ StateT IdentState Identity Ident
-> WriterT SideData (State IdentState) Ident
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (StateT IdentState Identity Ident
 -> WriterT SideData (State IdentState) Ident)
-> StateT IdentState Identity Ident
-> WriterT SideData (State IdentState) Ident
forall a b. (a -> b) -> a -> b
$ Maybe Int -> StateT IdentState Identity Ident
findFree Maybe Int
forall a. Maybe a
Nothing
  where
    findFree :: Maybe Int -> StateT IdentState Identity Ident
findFree Maybe Int
msuffix = do
      let
        withSuffix :: Text
withSuffix =
          (Text -> Text)
-> (Int -> Text -> Text) -> Maybe Int -> Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text -> Text
forall a. a -> a
id (\Int
suffix -> (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
suffix))) Maybe Int
msuffix Text
original
      Bool
isInUse <- (IdentState -> Bool) -> StateT IdentState Identity Bool
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
S.gets (Text -> HashSet Text -> Bool
forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
HS.member Text
withSuffix (HashSet Text -> Bool)
-> (IdentState -> HashSet Text) -> IdentState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentState -> HashSet Text
inUse)
      if Bool
isInUse
        then Maybe Int -> StateT IdentState Identity Ident
findFree (Int -> Int
forall a. Enum a => a -> a
succ (Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Maybe Int
msuffix Maybe Int -> Maybe Int -> Maybe Int
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
1 :: Int)))
        else do
          (IdentState -> IdentState) -> StateT IdentState Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
S.modify (\IdentState
s -> IdentState
s { inUse :: HashSet Text
inUse = Text -> HashSet Text -> HashSet Text
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
HS.insert Text
withSuffix (IdentState -> HashSet Text
inUse IdentState
s) })
          Ident -> StateT IdentState Identity Ident
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Ident
I Text
withSuffix)

-- | Information needed to escape and use identifiers.
type IdentInfo = (SqlBackend, IdentState)

-- | Use an identifier.
useIdent :: IdentInfo -> Ident -> TLB.Builder
useIdent :: IdentInfo -> Ident -> Builder
useIdent IdentInfo
info (I Text
ident) = IdentInfo -> DBName -> Builder
fromDBName IdentInfo
info (DBName -> Builder) -> DBName -> Builder
forall a b. (a -> b) -> a -> b
$ Text -> DBName
DBName Text
ident

entityAsValue
    :: SqlExpr (Entity val)
    -> SqlExpr (Value (Entity val))
entityAsValue :: SqlExpr (Entity val) -> SqlExpr (Value (Entity val))
entityAsValue SqlExpr (Entity val)
eent =
    case SqlExpr (Entity val)
eent of
        EEntity Ident
ident ->
            Ident -> SqlExpr (Value (Entity val))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
        EAliasedEntity Ident
ident Ident
_ ->
            Ident -> SqlExpr (Value (Entity val))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
        EAliasedEntityReference Ident
_ Ident
ident ->
            Ident -> SqlExpr (Value (Entity val))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
  where
    identToRaw :: Ident -> SqlExpr (Value a)
identToRaw Ident
ident =
        NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
identInfo ->
            ( IdentInfo -> Ident -> Builder
useIdent IdentInfo
identInfo Ident
ident
            , []
            )

entityAsValueMaybe
    :: SqlExpr (Maybe (Entity val))
    -> SqlExpr (Value (Maybe (Entity val)))
entityAsValueMaybe :: SqlExpr (Maybe (Entity val))
-> SqlExpr (Value (Maybe (Entity val)))
entityAsValueMaybe (EMaybe SqlExpr a
eent) =
    case SqlExpr a
eent of
        EEntity Ident
ident ->
            Ident -> SqlExpr (Value (Maybe (Entity val)))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
        EAliasedEntity Ident
ident Ident
_ ->
            Ident -> SqlExpr (Value (Maybe (Entity val)))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
        EAliasedEntityReference Ident
_ Ident
ident ->
            Ident -> SqlExpr (Value (Maybe (Entity val)))
forall a. Ident -> SqlExpr (Value a)
identToRaw Ident
ident
  where
    identToRaw :: Ident -> SqlExpr (Value a)
identToRaw Ident
ident =
        NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a.
NeedParens
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
ERaw NeedParens
Never ((IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a))
-> (IdentInfo -> (Builder, [PersistValue])) -> SqlExpr (Value a)
forall a b. (a -> b) -> a -> b
$ \IdentInfo
identInfo ->
            ( IdentInfo -> Ident -> Builder
useIdent IdentInfo
identInfo Ident
ident
            , []
            )


-- | An expression on the SQL backend.
--
-- There are many comments describing the constructors of this
-- data type.  However, Haddock doesn't like GADTs, so you'll have to read them by hitting \"Source\".
data SqlExpr a where
    -- An entity, created by 'from' (cf. 'fromStart').
    EEntity  :: Ident -> SqlExpr (Entity val)
    --                Base     Table
    EAliasedEntity :: Ident -> Ident -> SqlExpr (Entity val)
    --                         Source   Base
    EAliasedEntityReference :: Ident -> Ident -> SqlExpr (Entity val)

    -- Just a tag stating that something is nullable.
    EMaybe   :: SqlExpr a -> SqlExpr (Maybe a)

    -- Raw expression: states whether parenthesis are needed
    -- around this expression, and takes information about the SQL
    -- connection (mainly for escaping names) and returns both an
    -- string ('TLB.Builder') and a list of values to be
    -- interpolated by the SQL backend.
    ERaw     :: NeedParens -> (IdentInfo -> (TLB.Builder, [PersistValue])) -> SqlExpr (Value a)


    -- A raw expression with an alias
    EAliasedValue :: Ident -> SqlExpr (Value a) -> SqlExpr (Value a)

    -- A reference to an aliased field in a table or subquery
    EValueReference :: Ident -> (IdentInfo -> Ident) -> SqlExpr (Value a)

    -- A composite key.
    --
    -- Persistent uses the same 'PersistList' constructor for both
    -- fields which are (homogeneous) lists of values and the
    -- (probably heterogeneous) values of a composite primary key.
    --
    -- We need to treat composite keys as fields.  For example, we
    -- have to support using ==., otherwise you wouldn't be able to
    -- join.  OTOH, lists of values should be treated exactly the
    -- same as any other scalar value.
    --
    -- In particular, this is valid for persistent via rawSql for
    -- an F field that is a list:
    --
    --   A.F in ?    -- [PersistList [foo, bar]]
    --
    -- However, this is not for a composite key entity:
    --
    --   A.ID = ?    -- [PersistList [foo, bar]]
    --
    -- The ID field doesn't exist on the DB for a composite key
    -- table, it exists only on the Haskell side.  Those variations
    -- also don't work:
    --
    --   (A.KeyA, A.KeyB) = ?    -- [PersistList [foo, bar]]
    --   [A.KeyA, A.KeyB] = ?    -- [PersistList [foo, bar]]
    --
    -- We have to generate:
    --
    --   A.KeyA = ? AND A.KeyB = ?      -- [foo, bar]
    --
    -- Note that the PersistList had to be deconstructed into its
    -- components.
    --
    -- In order to disambiguate behaviors, this constructor is used
    -- /only/ to represent a composite field access.  It does not
    -- represent a 'PersistList', not even if the 'PersistList' is
    -- used in the context of a composite key.  That's because it's
    -- impossible, e.g., for 'val' to disambiguate between these
    -- uses.
    ECompositeKey :: (IdentInfo -> [TLB.Builder]) -> SqlExpr (Value a)

    -- 'EList' and 'EEmptyList' are used by list operators.
    EList      :: SqlExpr (Value a) -> SqlExpr (ValueList a)
    EEmptyList :: SqlExpr (ValueList a)

    -- A 'SqlExpr' accepted only by 'orderBy'.
    EOrderBy :: OrderByType -> SqlExpr (Value a) -> SqlExpr OrderBy

    EOrderRandom :: SqlExpr OrderBy

    -- A 'SqlExpr' accepted only by 'distinctOn'.
    EDistinctOn :: SqlExpr (Value a) -> SqlExpr DistinctOn

    -- A 'SqlExpr' accepted only by 'set'.
    ESet :: (SqlExpr (Entity val) -> SqlExpr (Value ())) -> SqlExpr