{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Database.MySQL.Hasqlator.Typed
  ( -- * Database Types
    Table(..), Field(..), Alias(..), (@@), Nullable (..), JoinType (..),
    quotedTableName, quotedFieldName,
    
    -- * Querying
    QueryClauses, Query, mkQuery, untypeQuery, executeQuery, unionAll,
    unionDistinct,

    -- * Selectors
    Selector, sel, selMaybe, forUpdate, forShare, shareMode,

    -- * Expressions
    Expression, SomeExpression, someExpr, Operator, 
    arg, argMaybe, isNull, isNotNull, nullable, notNull, orNull, unlessNull,
    cast, unsafeCast, op, fun1, fun2, fun3, (=.), (/=.), (>.), (<.), (>=.),
    (<=.), (&&.), (||.), substr, true_, false_, in_, notIn_,
    and_, or_, All_(..), Any_(..), all_, any_,
    
    -- * Clauses
    from, fromSubQuery, innerJoin, leftJoin, joinSubQuery, leftJoinSubQuery,
    where_, groupBy_, having, orderBy, QueryOrdering(..), limit, limitOffset,

    -- * Insertion
    Insertor, insertValues, insertUpdateValues, insertSelect, insertData,
    skipInsert, into,
    lensInto, maybeLensInto, opticInto, maybeOpticInto, insertOne, exprInto,
    Into, insertWithout, updateWithout,

    -- * Deletion
    delete,

    -- * Update
    Updator(..), update,

    -- * imported from Database.MySQL.Hasqlator
    H.Getter, H.ToSql, H.FromSql, subQueryExpr, H.executeCommand, H.Command,
    H.WaitLock
  )
where
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Coerce
import qualified Data.ByteString as StrictBS
import Data.Scientific
import Data.Word
import Data.Int
import Data.Time
import Data.String
import qualified Data.DList  as DList
import qualified Data.Map.Strict as Map
import Control.Monad.State
import Control.Monad.Reader
import GHC.TypeLits as TL
import Data.Functor.Contravariant
import Control.Applicative
import qualified GHC.Generics as Generics (from, to)
import GHC.Generics hiding (from, Selector)
import qualified Database.MySQL.Hasqlator as H
import Data.Proxy
import qualified Database.MySQL.Base as MySQL
import Optics.Core hiding (lens)

data Nullable = Nullable | NotNull
data JoinType = LeftJoined | InnerJoined

-- | check if a field is nullable after being joined
type family JoinNullable (leftJoined :: JoinType) (field :: Nullable)
     :: Nullable
  where
    JoinNullable 'InnerJoined nullable = nullable
    JoinNullable 'LeftJoined _ = 'Nullable

data Field (table :: Symbol) database (nullable :: Nullable) a =
  AllFields |
  Field Text Text
 
newtype Expression (nullable :: Nullable) a =
  Expression {forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression :: QueryInner H.QueryBuilder }

-- | An expression of any type
newtype SomeExpression =
  SomeExpression { SomeExpression -> QueryInner QueryBuilder
runSomeExpression :: QueryInner H.QueryBuilder }

newtype Selector a = Selector (QueryInner (H.Selector a))

instance Functor Selector where
  fmap :: forall a b. (a -> b) -> Selector a -> Selector b
fmap a -> b
f (Selector QueryInner (Selector a)
s) = QueryInner (Selector b) -> Selector b
forall a. QueryInner (Selector a) -> Selector a
Selector ((a -> b) -> Selector a -> Selector b
forall a b. (a -> b) -> Selector a -> Selector b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Selector a -> Selector b)
-> QueryInner (Selector a) -> QueryInner (Selector b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner (Selector a)
s)
instance Applicative Selector where
  pure :: forall a. a -> Selector a
pure a
x = QueryInner (Selector a) -> Selector a
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector a) -> Selector a)
-> QueryInner (Selector a) -> Selector a
forall a b. (a -> b) -> a -> b
$ Selector a -> QueryInner (Selector a)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Selector a -> QueryInner (Selector a))
-> Selector a -> QueryInner (Selector a)
forall a b. (a -> b) -> a -> b
$ a -> Selector a
forall a. a -> Selector a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
  Selector QueryInner (Selector (a -> b))
a <*> :: forall a b. Selector (a -> b) -> Selector a -> Selector b
<*> Selector QueryInner (Selector a)
b = QueryInner (Selector b) -> Selector b
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector b) -> Selector b)
-> QueryInner (Selector b) -> Selector b
forall a b. (a -> b) -> a -> b
$ (Selector (a -> b) -> Selector a -> Selector b)
-> QueryInner (Selector (a -> b))
-> QueryInner (Selector a)
-> QueryInner (Selector b)
forall a b c.
(a -> b -> c)
-> StateT ClauseState Identity a
-> StateT ClauseState Identity b
-> StateT ClauseState Identity c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Selector (a -> b) -> Selector a -> Selector b
forall a b. Selector (a -> b) -> Selector a -> Selector b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>) QueryInner (Selector (a -> b))
a QueryInner (Selector a)
b
instance Semigroup a => Semigroup (Selector a) where
  Selector QueryInner (Selector a)
a <> :: Selector a -> Selector a -> Selector a
<> Selector QueryInner (Selector a)
b = QueryInner (Selector a) -> Selector a
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector a) -> Selector a)
-> QueryInner (Selector a) -> Selector a
forall a b. (a -> b) -> a -> b
$ (Selector a -> Selector a -> Selector a)
-> QueryInner (Selector a)
-> QueryInner (Selector a)
-> QueryInner (Selector a)
forall a b c.
(a -> b -> c)
-> StateT ClauseState Identity a
-> StateT ClauseState Identity b
-> StateT ClauseState Identity c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Selector a -> Selector a -> Selector a
forall a. Semigroup a => a -> a -> a
(<>) QueryInner (Selector a)
a QueryInner (Selector a)
b
instance Monoid a => Monoid (Selector a) where
  mempty :: Selector a
mempty = QueryInner (Selector a) -> Selector a
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector a) -> Selector a)
-> QueryInner (Selector a) -> Selector a
forall a b. (a -> b) -> a -> b
$ Selector a -> QueryInner (Selector a)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Selector a
forall a. Monoid a => a
mempty

-- | Remove types of an expression
someExpr :: Expression nullable a -> SomeExpression
someExpr :: forall (nullable :: Nullable) a.
Expression nullable a -> SomeExpression
someExpr = Expression nullable a -> SomeExpression
forall a b. Coercible a b => a -> b
coerce

instance IsString (Expression nullable Text) where
  fromString :: String -> Expression nullable Text
fromString = Text -> Expression nullable Text
forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg (Text -> Expression nullable Text)
-> (String -> Text) -> String -> Expression nullable Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. IsString a => String -> a
fromString

instance Semigroup (Expression nullable Text) where
  <> :: Expression nullable Text
-> Expression nullable Text -> Expression nullable Text
(<>) = (QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable Text
-> Expression nullable Text
-> Expression nullable Text
forall (nullable :: Nullable) a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
fun2 QueryBuilder -> QueryBuilder -> QueryBuilder
(H.++.)

instance Monoid (Expression nullable Text) where
  mempty :: Expression nullable Text
mempty = Text -> Expression nullable Text
forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg Text
""

instance (Num n, H.ToSql n) => Num (Expression nullable n) where
  + :: Expression nullable n
-> Expression nullable n -> Expression nullable n
(+) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator n n n
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.+.)
  (-) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator n n n
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.-.)
  * :: Expression nullable n
-> Expression nullable n -> Expression nullable n
(*) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator n n n
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.*.)
  negate :: Expression nullable n -> Expression nullable n
negate = (QueryBuilder -> QueryBuilder)
-> Expression nullable n -> Expression nullable n
forall (nullable :: Nullable) a b.
(QueryBuilder -> QueryBuilder)
-> Expression nullable a -> Expression nullable b
fun1 QueryBuilder -> QueryBuilder
H.negate_
  abs :: Expression nullable n -> Expression nullable n
abs = (QueryBuilder -> QueryBuilder)
-> Expression nullable n -> Expression nullable n
forall (nullable :: Nullable) a b.
(QueryBuilder -> QueryBuilder)
-> Expression nullable a -> Expression nullable b
fun1 QueryBuilder -> QueryBuilder
H.abs_
  signum :: Expression nullable n -> Expression nullable n
signum = (QueryBuilder -> QueryBuilder)
-> Expression nullable n -> Expression nullable n
forall (nullable :: Nullable) a b.
(QueryBuilder -> QueryBuilder)
-> Expression nullable a -> Expression nullable b
fun1 QueryBuilder -> QueryBuilder
H.signum_
  fromInteger :: Integer -> Expression nullable n
fromInteger = n -> Expression nullable n
forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg (n -> Expression nullable n)
-> (Integer -> n) -> Integer -> Expression nullable n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> n
forall a. Num a => Integer -> a
fromInteger

instance (Fractional n, H.ToSql n)
         => Fractional (Expression nullable n) where
  / :: Expression nullable n
-> Expression nullable n -> Expression nullable n
(/) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator n n n
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H./.)
  fromRational :: Rational -> Expression nullable n
fromRational = n -> Expression nullable n
forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg (n -> Expression nullable n)
-> (Rational -> n) -> Rational -> Expression nullable n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> n
forall a. Fractional a => Rational -> a
fromRational
  
data Table (table :: Symbol) database = Table (Maybe Text) Text

-- | An table alias that can be used inside the Query.  The function
-- inside the newtype can also be applied directly to create an
-- expression from a field.  For constructing records, applicativeDo
-- is the recommended way.  However note that this may fail due to a
-- bug in ghc, that breaks the polymorphism.  In that case as a
-- workaround you should use the Alias newtype directly and use the
-- `@@` operator to create an expression instead
newtype Alias table database (joinType :: JoinType) =
  Alias { forall (table :: Symbol) database (joinType :: JoinType).
Alias table database joinType
-> forall (fieldNull :: Nullable) a.
   Field table database fieldNull a
   -> Expression (JoinNullable joinType fieldNull) a
getTableAlias ::
          forall fieldNull a .
          Field table database fieldNull a ->
          Expression (JoinNullable joinType fieldNull) a }

newtype Insertor (table :: Symbol) database a =
  Insertor (H.Insertor a)
  deriving (Semigroup (Insertor table database a)
Insertor table database a
Semigroup (Insertor table database a) =>
Insertor table database a
-> (Insertor table database a
    -> Insertor table database a -> Insertor table database a)
-> ([Insertor table database a] -> Insertor table database a)
-> Monoid (Insertor table database a)
[Insertor table database a] -> Insertor table database a
Insertor table database a
-> Insertor table database a -> Insertor table database a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall (table :: Symbol) database a.
Semigroup (Insertor table database a)
forall (table :: Symbol) database a. Insertor table database a
forall (table :: Symbol) database a.
[Insertor table database a] -> Insertor table database a
forall (table :: Symbol) database a.
Insertor table database a
-> Insertor table database a -> Insertor table database a
$cmempty :: forall (table :: Symbol) database a. Insertor table database a
mempty :: Insertor table database a
$cmappend :: forall (table :: Symbol) database a.
Insertor table database a
-> Insertor table database a -> Insertor table database a
mappend :: Insertor table database a
-> Insertor table database a -> Insertor table database a
$cmconcat :: forall (table :: Symbol) database a.
[Insertor table database a] -> Insertor table database a
mconcat :: [Insertor table database a] -> Insertor table database a
Monoid, NonEmpty (Insertor table database a) -> Insertor table database a
Insertor table database a
-> Insertor table database a -> Insertor table database a
(Insertor table database a
 -> Insertor table database a -> Insertor table database a)
-> (NonEmpty (Insertor table database a)
    -> Insertor table database a)
-> (forall b.
    Integral b =>
    b -> Insertor table database a -> Insertor table database a)
-> Semigroup (Insertor table database a)
forall b.
Integral b =>
b -> Insertor table database a -> Insertor table database a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall (table :: Symbol) database a.
NonEmpty (Insertor table database a) -> Insertor table database a
forall (table :: Symbol) database a.
Insertor table database a
-> Insertor table database a -> Insertor table database a
forall (table :: Symbol) database a b.
Integral b =>
b -> Insertor table database a -> Insertor table database a
$c<> :: forall (table :: Symbol) database a.
Insertor table database a
-> Insertor table database a -> Insertor table database a
<> :: Insertor table database a
-> Insertor table database a -> Insertor table database a
$csconcat :: forall (table :: Symbol) database a.
NonEmpty (Insertor table database a) -> Insertor table database a
sconcat :: NonEmpty (Insertor table database a) -> Insertor table database a
$cstimes :: forall (table :: Symbol) database a b.
Integral b =>
b -> Insertor table database a -> Insertor table database a
stimes :: forall b.
Integral b =>
b -> Insertor table database a -> Insertor table database a
Semigroup, (forall a' a.
 (a' -> a)
 -> Insertor table database a -> Insertor table database a')
-> (forall b a.
    b -> Insertor table database b -> Insertor table database a)
-> Contravariant (Insertor table database)
forall b a.
b -> Insertor table database b -> Insertor table database a
forall a' a.
(a' -> a)
-> Insertor table database a -> Insertor table database a'
forall (table :: Symbol) database b a.
b -> Insertor table database b -> Insertor table database a
forall (table :: Symbol) database a' a.
(a' -> a)
-> Insertor table database a -> Insertor table database a'
forall (f :: * -> *).
(forall a' a. (a' -> a) -> f a -> f a')
-> (forall b a. b -> f b -> f a) -> Contravariant f
$ccontramap :: forall (table :: Symbol) database a' a.
(a' -> a)
-> Insertor table database a -> Insertor table database a'
contramap :: forall a' a.
(a' -> a)
-> Insertor table database a -> Insertor table database a'
$c>$ :: forall (table :: Symbol) database b a.
b -> Insertor table database b -> Insertor table database a
>$ :: forall b a.
b -> Insertor table database b -> Insertor table database a
Contravariant)

data ClauseState = ClauseState
  { ClauseState -> QueryClauses
clausesBuild :: H.QueryClauses  -- clauses build so far
  , ClauseState -> Map Text Int
aliases :: Map.Map Text Int   -- map of aliases to times used
  }

emptyClauseState :: ClauseState
emptyClauseState :: ClauseState
emptyClauseState = QueryClauses -> Map Text Int -> ClauseState
ClauseState QueryClauses
forall a. Monoid a => a
mempty Map Text Int
forall k a. Map k a
Map.empty

type QueryInner a = State ClauseState a

newtype QueryClauses database a = QueryClauses (QueryInner a)
  deriving ((forall a b.
 (a -> b) -> QueryClauses database a -> QueryClauses database b)
-> (forall a b.
    a -> QueryClauses database b -> QueryClauses database a)
-> Functor (QueryClauses database)
forall a b. a -> QueryClauses database b -> QueryClauses database a
forall a b.
(a -> b) -> QueryClauses database a -> QueryClauses database b
forall database a b.
a -> QueryClauses database b -> QueryClauses database a
forall database a b.
(a -> b) -> QueryClauses database a -> QueryClauses database b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall database a b.
(a -> b) -> QueryClauses database a -> QueryClauses database b
fmap :: forall a b.
(a -> b) -> QueryClauses database a -> QueryClauses database b
$c<$ :: forall database a b.
a -> QueryClauses database b -> QueryClauses database a
<$ :: forall a b. a -> QueryClauses database b -> QueryClauses database a
Functor, Functor (QueryClauses database)
Functor (QueryClauses database) =>
(forall a. a -> QueryClauses database a)
-> (forall a b.
    QueryClauses database (a -> b)
    -> QueryClauses database a -> QueryClauses database b)
-> (forall a b c.
    (a -> b -> c)
    -> QueryClauses database a
    -> QueryClauses database b
    -> QueryClauses database c)
-> (forall a b.
    QueryClauses database a
    -> QueryClauses database b -> QueryClauses database b)
-> (forall a b.
    QueryClauses database a
    -> QueryClauses database b -> QueryClauses database a)
-> Applicative (QueryClauses database)
forall database. Functor (QueryClauses database)
forall a. a -> QueryClauses database a
forall database a. a -> QueryClauses database a
forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database a
forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
forall a b.
QueryClauses database (a -> b)
-> QueryClauses database a -> QueryClauses database b
forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database a
forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
forall database a b.
QueryClauses database (a -> b)
-> QueryClauses database a -> QueryClauses database b
forall a b c.
(a -> b -> c)
-> QueryClauses database a
-> QueryClauses database b
-> QueryClauses database c
forall database a b c.
(a -> b -> c)
-> QueryClauses database a
-> QueryClauses database b
-> QueryClauses database 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
$cpure :: forall database a. a -> QueryClauses database a
pure :: forall a. a -> QueryClauses database a
$c<*> :: forall database a b.
QueryClauses database (a -> b)
-> QueryClauses database a -> QueryClauses database b
<*> :: forall a b.
QueryClauses database (a -> b)
-> QueryClauses database a -> QueryClauses database b
$cliftA2 :: forall database a b c.
(a -> b -> c)
-> QueryClauses database a
-> QueryClauses database b
-> QueryClauses database c
liftA2 :: forall a b c.
(a -> b -> c)
-> QueryClauses database a
-> QueryClauses database b
-> QueryClauses database c
$c*> :: forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
*> :: forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
$c<* :: forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database a
<* :: forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database a
Applicative, Applicative (QueryClauses database)
Applicative (QueryClauses database) =>
(forall a b.
 QueryClauses database a
 -> (a -> QueryClauses database b) -> QueryClauses database b)
-> (forall a b.
    QueryClauses database a
    -> QueryClauses database b -> QueryClauses database b)
-> (forall a. a -> QueryClauses database a)
-> Monad (QueryClauses database)
forall database. Applicative (QueryClauses database)
forall a. a -> QueryClauses database a
forall database a. a -> QueryClauses database a
forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
forall a b.
QueryClauses database a
-> (a -> QueryClauses database b) -> QueryClauses database b
forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
forall database a b.
QueryClauses database a
-> (a -> QueryClauses database b) -> QueryClauses database 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
$c>>= :: forall database a b.
QueryClauses database a
-> (a -> QueryClauses database b) -> QueryClauses database b
>>= :: forall a b.
QueryClauses database a
-> (a -> QueryClauses database b) -> QueryClauses database b
$c>> :: forall database a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
>> :: forall a b.
QueryClauses database a
-> QueryClauses database b -> QueryClauses database b
$creturn :: forall database a. a -> QueryClauses database a
return :: forall a. a -> QueryClauses database a
Monad)

data Query database a = Query (QueryClauses database a)
                      | UnionAll (Query database a) (Query database a)
                      | UnionDistinct (Query database a) (Query database a)

unionAll :: Query database a -> Query database a -> Query database a
unionAll :: forall database a.
Query database a -> Query database a -> Query database a
unionAll = Query database a -> Query database a -> Query database a
forall database a.
Query database a -> Query database a -> Query database a
UnionAll

unionDistinct :: Query database a -> Query database a -> Query database a
unionDistinct :: forall database a.
Query database a -> Query database a -> Query database a
unionDistinct = Query database a -> Query database a -> Query database a
forall database a.
Query database a -> Query database a -> Query database a
UnionDistinct

type Operator a b c = forall nullable .
                      (Expression nullable a ->
                       Expression nullable b ->
                       Expression nullable c)

infixl 9 @@

mkQuery :: QueryClauses database a -> Query database a
mkQuery :: forall database a. QueryClauses database a -> Query database a
mkQuery = QueryClauses database a -> Query database a
forall database a. QueryClauses database a -> Query database a
Query

untypeQuery :: Query database (Selector a) -> H.Query a
untypeQuery :: forall database a. Query database (Selector a) -> Query a
untypeQuery (Query (QueryClauses QueryInner (Selector a)
query)) =
  let (Selector a
selector, ClauseState
clauseState) =
        State ClauseState (Selector a)
-> ClauseState -> (Selector a, ClauseState)
forall s a. State s a -> s -> (a, s)
runState (do (Selector State ClauseState (Selector a)
sel_) <- QueryInner (Selector a)
query; State ClauseState (Selector a)
sel_) ClauseState
emptyClauseState
  in Selector a -> QueryClauses -> Query a
forall a. Selector a -> QueryClauses -> Query a
H.select Selector a
selector (QueryClauses -> Query a) -> QueryClauses -> Query a
forall a b. (a -> b) -> a -> b
$ ClauseState -> QueryClauses
clausesBuild ClauseState
clauseState
untypeQuery (UnionAll Query database (Selector a)
qr1 Query database (Selector a)
qr2) =
  Query a -> Query a -> Query a
forall a. Query a -> Query a -> Query a
H.unionAll (Query database (Selector a) -> Query a
forall database a. Query database (Selector a) -> Query a
untypeQuery Query database (Selector a)
qr1) (Query database (Selector a) -> Query a
forall database a. Query database (Selector a) -> Query a
untypeQuery Query database (Selector a)
qr2)
untypeQuery (UnionDistinct Query database (Selector a)
qr1 Query database (Selector a)
qr2) =
  Query a -> Query a -> Query a
forall a. Query a -> Query a -> Query a
H.unionDistinct (Query database (Selector a) -> Query a
forall database a. Query database (Selector a) -> Query a
untypeQuery Query database (Selector a)
qr1) (Query database (Selector a) -> Query a
forall database a. Query database (Selector a) -> Query a
untypeQuery Query database (Selector a)
qr2)

executeQuery :: MySQL.MySQLConn -> Query database (Selector a) -> IO [a]
executeQuery :: forall database a.
MySQLConn -> Query database (Selector a) -> IO [a]
executeQuery MySQLConn
conn Query database (Selector a)
qry = MySQLConn -> Query a -> IO [a]
forall a. MySQLConn -> Query a -> IO [a]
H.executeQuery MySQLConn
conn (Query a -> IO [a]) -> Query a -> IO [a]
forall a b. (a -> b) -> a -> b
$ Query database (Selector a) -> Query a
forall database a. Query database (Selector a) -> Query a
untypeQuery Query database (Selector a)
qry

  
-- | Create an expression from an aliased table and a field.
(@@) :: Alias table database (joinType :: JoinType)
     -> Field table database fieldNull a
     -> Expression (JoinNullable joinType fieldNull) a
@@ :: forall (table :: Symbol) database (joinType :: JoinType)
       (fieldNull :: Nullable) a.
Alias table database joinType
-> Field table database fieldNull a
-> Expression (JoinNullable joinType fieldNull) a
(@@) = Alias table database joinType
-> Field table database fieldNull a
-> Expression (JoinNullable joinType fieldNull) a
Alias table database joinType
-> forall (fieldNull :: Nullable) a.
   Field table database fieldNull a
   -> Expression (JoinNullable joinType fieldNull) a
forall (table :: Symbol) database (joinType :: JoinType).
Alias table database joinType
-> forall (fieldNull :: Nullable) a.
   Field table database fieldNull a
   -> Expression (JoinNullable joinType fieldNull) a
getTableAlias  
 
mkTableAlias :: Text -> Alias table database leftJoined
mkTableAlias :: forall (table :: Symbol) database (leftJoined :: JoinType).
Text -> Alias table database leftJoined
mkTableAlias Text
tableName = (forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall (table :: Symbol) database (joinType :: JoinType).
(forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable joinType fieldNull) a)
-> Alias table database joinType
Alias ((forall (fieldNull :: Nullable) a.
  Field table database fieldNull a
  -> Expression (JoinNullable leftJoined fieldNull) a)
 -> Alias table database leftJoined)
-> (forall (fieldNull :: Nullable) a.
    Field table database fieldNull a
    -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall a b. (a -> b) -> a -> b
$ \Field table database fieldNull a
field ->
  QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Field table database fieldNull a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database fieldNull a
field

emptyAlias :: Alias table database leftJoined
emptyAlias :: forall (table :: Symbol) database (leftJoined :: JoinType).
Alias table database leftJoined
emptyAlias = (forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall (table :: Symbol) database (joinType :: JoinType).
(forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable joinType fieldNull) a)
-> Alias table database joinType
Alias ((forall (fieldNull :: Nullable) a.
  Field table database fieldNull a
  -> Expression (JoinNullable leftJoined fieldNull) a)
 -> Alias table database leftJoined)
-> (forall (fieldNull :: Nullable) a.
    Field table database fieldNull a
    -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall a b. (a -> b) -> a -> b
$ \Field table database fieldNull a
field ->
  QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Field table database fieldNull a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database fieldNull a
field

data QueryOrdering = Asc SomeExpression | Desc SomeExpression

-- | make a selector from a column
sel :: H.FromSql a
    => Expression 'NotNull a
    -> Selector a
sel :: forall a. FromSql a => Expression 'NotNull a -> Selector a
sel (Expression QueryInner QueryBuilder
expr) = QueryInner (Selector a) -> Selector a
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector a) -> Selector a)
-> QueryInner (Selector a) -> Selector a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> Selector a
forall a. FromSql a => QueryBuilder -> Selector a
H.sel (QueryBuilder -> Selector a)
-> QueryInner QueryBuilder -> QueryInner (Selector a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
expr

-- | make a selector from a column that can be null
selMaybe :: H.FromSql (Maybe a)
         => Expression 'Nullable a
         -> Selector (Maybe a)
selMaybe :: forall a.
FromSql (Maybe a) =>
Expression 'Nullable a -> Selector (Maybe a)
selMaybe (Expression QueryInner QueryBuilder
expr) = QueryInner (Selector (Maybe a)) -> Selector (Maybe a)
forall a. QueryInner (Selector a) -> Selector a
Selector (QueryInner (Selector (Maybe a)) -> Selector (Maybe a))
-> QueryInner (Selector (Maybe a)) -> Selector (Maybe a)
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> Selector (Maybe a)
forall a. FromSql a => QueryBuilder -> Selector a
H.sel (QueryBuilder -> Selector (Maybe a))
-> QueryInner QueryBuilder -> QueryInner (Selector (Maybe a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
expr

-- | pass an argument
arg :: H.ToSql a => a -> Expression nullable a
arg :: forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg a
x = QueryInner QueryBuilder -> Expression nullable a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable a)
-> QueryInner QueryBuilder -> Expression nullable a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ a -> QueryBuilder
forall a. ToSql a => a -> QueryBuilder
H.arg a
x

-- | pass an argument which can be null
argMaybe :: H.ToSql a => Maybe a -> Expression 'Nullable a
argMaybe :: forall a. ToSql a => Maybe a -> Expression 'Nullable a
argMaybe Maybe a
x = QueryInner QueryBuilder -> Expression 'Nullable a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression 'Nullable a)
-> QueryInner QueryBuilder -> Expression 'Nullable a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Maybe a -> QueryBuilder
forall a. ToSql a => a -> QueryBuilder
H.arg Maybe a
x

-- | create an operator
op :: (H.QueryBuilder -> H.QueryBuilder -> H.QueryBuilder)
   -> Operator a b c
op :: forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op = (QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
forall (nullable :: Nullable) a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
fun2

fun1 :: (H.QueryBuilder -> H.QueryBuilder)
     -> Expression nullable a
     -> Expression nullable b
fun1 :: forall (nullable :: Nullable) a b.
(QueryBuilder -> QueryBuilder)
-> Expression nullable a -> Expression nullable b
fun1 QueryBuilder -> QueryBuilder
f (Expression QueryInner QueryBuilder
x) = QueryInner QueryBuilder -> Expression nullable b
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable b)
-> QueryInner QueryBuilder -> Expression nullable b
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryBuilder
f (QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder -> QueryInner QueryBuilder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
x

fun2 :: (H.QueryBuilder -> H.QueryBuilder -> H.QueryBuilder)
     -> Expression nullable a
     -> Expression nullable b
     -> Expression nullable c
fun2 :: forall (nullable :: Nullable) a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
fun2 QueryBuilder -> QueryBuilder -> QueryBuilder
f (Expression QueryInner QueryBuilder
x1) (Expression QueryInner QueryBuilder
x2) = QueryInner QueryBuilder -> Expression nullable c
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable c)
-> QueryInner QueryBuilder -> Expression nullable c
forall a b. (a -> b) -> a -> b
$ (QueryBuilder -> QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder
-> QueryInner QueryBuilder
-> QueryInner QueryBuilder
forall a b c.
(a -> b -> c)
-> StateT ClauseState Identity a
-> StateT ClauseState Identity b
-> StateT ClauseState Identity c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 QueryBuilder -> QueryBuilder -> QueryBuilder
f QueryInner QueryBuilder
x1 QueryInner QueryBuilder
x2

fun3 :: (H.QueryBuilder -> H.QueryBuilder -> H.QueryBuilder -> H.QueryBuilder)
     -> Expression nullable a
     -> Expression nullable b
     -> Expression nullable c
     -> Expression nullable d
fun3 :: forall (nullable :: Nullable) a b c d.
(QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
-> Expression nullable d
fun3 QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder
f (Expression QueryInner QueryBuilder
x1) (Expression QueryInner QueryBuilder
x2) (Expression QueryInner QueryBuilder
x3) =
  QueryInner QueryBuilder -> Expression nullable d
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable d)
-> QueryInner QueryBuilder -> Expression nullable d
forall a b. (a -> b) -> a -> b
$ (QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder
-> QueryInner QueryBuilder
-> QueryInner QueryBuilder
-> QueryInner QueryBuilder
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder
f QueryInner QueryBuilder
x1 QueryInner QueryBuilder
x2 QueryInner QueryBuilder
x3

substr :: Expression nullable Text -> Expression nullable Int
       -> Expression nullable Int
       -> Expression nullable Text
substr :: forall (nullable :: Nullable).
Expression nullable Text
-> Expression nullable Int
-> Expression nullable Int
-> Expression nullable Text
substr = (QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable Text
-> Expression nullable Int
-> Expression nullable Int
-> Expression nullable Text
forall (nullable :: Nullable) a b c d.
(QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Expression nullable a
-> Expression nullable b
-> Expression nullable c
-> Expression nullable d
fun3 QueryBuilder -> QueryBuilder -> QueryBuilder -> QueryBuilder
H.substr

infixr 3 &&., ||.
infix 4 <., >., >=., <=., =., /=.

(=.), (/=.), (>.), (<.), (>=.), (<=.) :: H.ToSql a => Operator a a Bool
=. :: forall a. ToSql a => Operator a a Bool
(=.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.=.)
/=. :: forall a. ToSql a => Operator a a Bool
(/=.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H./=.)
>. :: forall a. ToSql a => Operator a a Bool
(>.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.>.)
<. :: forall a. ToSql a => Operator a a Bool
(<.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.<.)
>=. :: forall a. ToSql a => Operator a a Bool
(>=.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.>=.)
<=. :: forall a. ToSql a => Operator a a Bool
(<=.) = (QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a a Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.<=.)

(||.), (&&.) :: Operator Bool Bool Bool
||. :: Operator Bool Bool Bool
(||.) = (QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Operator Bool Bool Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.||.)
&&. :: Operator Bool Bool Bool
(&&.) = (QueryBuilder -> QueryBuilder -> QueryBuilder)
-> Operator Bool Bool Bool
forall a b c.
(QueryBuilder -> QueryBuilder -> QueryBuilder) -> Operator a b c
op QueryBuilder -> QueryBuilder -> QueryBuilder
(H.&&.)

newtype All_ nullable = All_ { forall (nullable :: Nullable).
All_ nullable -> Expression nullable Bool
getAll_ :: Expression nullable Bool }

instance Semigroup (All_ nullable) where
  All_ Expression nullable Bool
x <> :: All_ nullable -> All_ nullable -> All_ nullable
<> All_ Expression nullable Bool
y = Expression nullable Bool -> All_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> All_ nullable
All_ (Expression nullable Bool -> All_ nullable)
-> Expression nullable Bool -> All_ nullable
forall a b. (a -> b) -> a -> b
$ Expression nullable Bool
x Expression nullable Bool
-> Expression nullable Bool -> Expression nullable Bool
Operator Bool Bool Bool
&&.Expression nullable Bool
y
instance Monoid (All_ nullable) where
  mempty :: All_ nullable
mempty = Expression nullable Bool -> All_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> All_ nullable
All_ Expression nullable Bool
forall (nullable :: Nullable). Expression nullable Bool
true_

and_ :: Foldable f => f (Expression nullable Bool) -> Expression nullable Bool
and_ :: forall (f :: * -> *) (nullable :: Nullable).
Foldable f =>
f (Expression nullable Bool) -> Expression nullable Bool
and_ = All_ nullable -> Expression nullable Bool
forall (nullable :: Nullable).
All_ nullable -> Expression nullable Bool
getAll_ (All_ nullable -> Expression nullable Bool)
-> (f (Expression nullable Bool) -> All_ nullable)
-> f (Expression nullable Bool)
-> Expression nullable Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expression nullable Bool -> All_ nullable)
-> f (Expression nullable Bool) -> All_ nullable
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Expression nullable Bool -> All_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> All_ nullable
All_

all_ :: Foldable f => (a -> Expression nullable Bool) -> f a
     -> Expression nullable Bool
all_ :: forall (f :: * -> *) a (nullable :: Nullable).
Foldable f =>
(a -> Expression nullable Bool) -> f a -> Expression nullable Bool
all_ a -> Expression nullable Bool
f = All_ nullable -> Expression nullable Bool
forall (nullable :: Nullable).
All_ nullable -> Expression nullable Bool
getAll_ (All_ nullable -> Expression nullable Bool)
-> (f a -> All_ nullable) -> f a -> Expression nullable Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> All_ nullable) -> f a -> All_ nullable
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Expression nullable Bool -> All_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> All_ nullable
All_ (Expression nullable Bool -> All_ nullable)
-> (a -> Expression nullable Bool) -> a -> All_ nullable
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Expression nullable Bool
f)

newtype Any_ nullable = Any_ { forall (nullable :: Nullable).
Any_ nullable -> Expression nullable Bool
getAny_ :: Expression nullable Bool }

instance Semigroup (Any_ nullable) where
  Any_ Expression nullable Bool
x <> :: Any_ nullable -> Any_ nullable -> Any_ nullable
<> Any_ Expression nullable Bool
y = Expression nullable Bool -> Any_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> Any_ nullable
Any_ (Expression nullable Bool -> Any_ nullable)
-> Expression nullable Bool -> Any_ nullable
forall a b. (a -> b) -> a -> b
$ Expression nullable Bool
x Expression nullable Bool
-> Expression nullable Bool -> Expression nullable Bool
Operator Bool Bool Bool
||. Expression nullable Bool
y
instance Monoid (Any_ nullable) where
  mempty :: Any_ nullable
mempty = Expression nullable Bool -> Any_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> Any_ nullable
Any_ Expression nullable Bool
forall (nullable :: Nullable). Expression nullable Bool
false_

or_ :: Foldable f => f (Expression nullable Bool) -> Expression nullable Bool
or_ :: forall (f :: * -> *) (nullable :: Nullable).
Foldable f =>
f (Expression nullable Bool) -> Expression nullable Bool
or_ = Any_ nullable -> Expression nullable Bool
forall (nullable :: Nullable).
Any_ nullable -> Expression nullable Bool
getAny_ (Any_ nullable -> Expression nullable Bool)
-> (f (Expression nullable Bool) -> Any_ nullable)
-> f (Expression nullable Bool)
-> Expression nullable Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expression nullable Bool -> Any_ nullable)
-> f (Expression nullable Bool) -> Any_ nullable
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Expression nullable Bool -> Any_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> Any_ nullable
Any_

any_ :: Foldable f => (a -> Expression nullable Bool) -> f a
     -> Expression nullable Bool
any_ :: forall (f :: * -> *) a (nullable :: Nullable).
Foldable f =>
(a -> Expression nullable Bool) -> f a -> Expression nullable Bool
any_ a -> Expression nullable Bool
f = Any_ nullable -> Expression nullable Bool
forall (nullable :: Nullable).
Any_ nullable -> Expression nullable Bool
getAny_ (Any_ nullable -> Expression nullable Bool)
-> (f a -> Any_ nullable) -> f a -> Expression nullable Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Any_ nullable) -> f a -> Any_ nullable
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Expression nullable Bool -> Any_ nullable
forall (nullable :: Nullable).
Expression nullable Bool -> Any_ nullable
Any_ (Expression nullable Bool -> Any_ nullable)
-> (a -> Expression nullable Bool) -> a -> Any_ nullable
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Expression nullable Bool
f)
         
isNull :: Expression nullable a -> Expression 'NotNull Bool
isNull :: forall (nullable :: Nullable) a.
Expression nullable a -> Expression 'NotNull Bool
isNull (Expression QueryInner QueryBuilder
e) = QueryInner QueryBuilder -> Expression 'NotNull Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression 'NotNull Bool)
-> QueryInner QueryBuilder -> Expression 'NotNull Bool
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryBuilder
H.isNull (QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder -> QueryInner QueryBuilder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
e

isNotNull :: Expression 'Nullable a -> Expression 'NotNull Bool
isNotNull :: forall a. Expression 'Nullable a -> Expression 'NotNull Bool
isNotNull (Expression QueryInner QueryBuilder
e) = QueryInner QueryBuilder -> Expression 'NotNull Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression 'NotNull Bool)
-> QueryInner QueryBuilder -> Expression 'NotNull Bool
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryBuilder
H.isNotNull (QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder -> QueryInner QueryBuilder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
e

true_, false_ :: Expression nullable Bool
true_ :: forall (nullable :: Nullable). Expression nullable Bool
true_ = QueryInner QueryBuilder -> Expression nullable Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable Bool)
-> QueryInner QueryBuilder -> Expression nullable Bool
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure QueryBuilder
H.false_
false_ :: forall (nullable :: Nullable). Expression nullable Bool
false_ = QueryInner QueryBuilder -> Expression nullable Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable Bool)
-> QueryInner QueryBuilder -> Expression nullable Bool
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure QueryBuilder
H.true_

in_ :: Expression nullable a -> [Expression nullable a]
    -> Expression nullable Bool
in_ :: forall (nullable :: Nullable) a.
Expression nullable a
-> [Expression nullable a] -> Expression nullable Bool
in_ Expression nullable a
e [Expression nullable a]
es = QueryInner QueryBuilder -> Expression nullable Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable Bool)
-> QueryInner QueryBuilder -> Expression nullable Bool
forall a b. (a -> b) -> a -> b
$
           (QueryBuilder -> [QueryBuilder] -> QueryBuilder)
-> QueryInner QueryBuilder
-> StateT ClauseState Identity [QueryBuilder]
-> QueryInner QueryBuilder
forall a b c.
(a -> b -> c)
-> StateT ClauseState Identity a
-> StateT ClauseState Identity b
-> StateT ClauseState Identity c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 QueryBuilder -> [QueryBuilder] -> QueryBuilder
H.in_ (Expression nullable a -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression Expression nullable a
e) ((Expression nullable a -> QueryInner QueryBuilder)
-> [Expression nullable a]
-> StateT ClauseState Identity [QueryBuilder]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Expression nullable a -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression [Expression nullable a]
es)

notIn_ :: Expression nullable a -> [Expression nullable a]
       -> Expression nullable Bool
notIn_ :: forall (nullable :: Nullable) a.
Expression nullable a
-> [Expression nullable a] -> Expression nullable Bool
notIn_ Expression nullable a
e [Expression nullable a]
es = QueryInner QueryBuilder -> Expression nullable Bool
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable Bool)
-> QueryInner QueryBuilder -> Expression nullable Bool
forall a b. (a -> b) -> a -> b
$
              (QueryBuilder -> [QueryBuilder] -> QueryBuilder)
-> QueryInner QueryBuilder
-> StateT ClauseState Identity [QueryBuilder]
-> QueryInner QueryBuilder
forall a b c.
(a -> b -> c)
-> StateT ClauseState Identity a
-> StateT ClauseState Identity b
-> StateT ClauseState Identity c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 QueryBuilder -> [QueryBuilder] -> QueryBuilder
H.notIn_ (Expression nullable a -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression Expression nullable a
e) ((Expression nullable a -> QueryInner QueryBuilder)
-> [Expression nullable a]
-> StateT ClauseState Identity [QueryBuilder]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Expression nullable a -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression [Expression nullable a]
es)

-- | make expression nullable
nullable :: Expression nullable a -> Expression 'Nullable a
nullable :: forall (nullable :: Nullable) a.
Expression nullable a -> Expression 'Nullable a
nullable = Expression nullable a -> Expression 'Nullable a
forall a b. Coercible a b => a -> b
coerce

-- | ensure expression is not null
notNull :: Expression 'NotNull a -> Expression 'NotNull a
notNull :: forall a. Expression 'NotNull a -> Expression 'NotNull a
notNull = Expression 'NotNull a -> Expression 'NotNull a
forall a. a -> a
id

-- | Return a true expression if the given expression is NULL (using
-- the IS NULL sql test), or pass the expression (coerced to
-- 'NotNull) to the given test.
orNull :: Expression nullable a
       -> (Expression 'NotNull a -> Expression 'NotNull Bool)
       -> Expression 'NotNull Bool
orNull :: forall (nullable :: Nullable) a.
Expression nullable a
-> (Expression 'NotNull a -> Expression 'NotNull Bool)
-> Expression 'NotNull Bool
orNull Expression nullable a
e Expression 'NotNull a -> Expression 'NotNull Bool
f = Expression nullable a -> Expression 'NotNull Bool
forall (nullable :: Nullable) a.
Expression nullable a -> Expression 'NotNull Bool
isNull Expression nullable a
e Expression 'NotNull Bool
-> Expression 'NotNull Bool -> Expression 'NotNull Bool
Operator Bool Bool Bool
||. Expression 'NotNull a -> Expression 'NotNull Bool
f (Expression nullable a -> Expression 'NotNull a
forall a b. Coercible a b => a -> b
coerce Expression nullable a
e)

-- | Perform test if given expression is not NULL
unlessNull :: Expression nullable a
           -> (Expression 'NotNull a -> Expression 'NotNull Bool)
           -> Expression 'NotNull Bool
unlessNull :: forall (nullable :: Nullable) a.
Expression nullable a
-> (Expression 'NotNull a -> Expression 'NotNull Bool)
-> Expression 'NotNull Bool
unlessNull Expression nullable a
e Expression 'NotNull a -> Expression 'NotNull Bool
f = Expression 'NotNull a -> Expression 'NotNull Bool
f (Expression nullable a -> Expression 'NotNull a
forall a b. Coercible a b => a -> b
coerce Expression nullable a
e)

class Castable a where
  -- | Safe cast.  This uses the SQL CAST function to convert safely
  -- from one type to another.
  cast :: Expression nullable b
       -> Expression nullable a

castTo :: H.QueryBuilder
       -> Expression nullable b
       -> Expression nullable a
castTo :: forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
tp (Expression QueryInner QueryBuilder
e) = QueryInner QueryBuilder -> Expression nullable a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable a)
-> QueryInner QueryBuilder -> Expression nullable a
forall a b. (a -> b) -> a -> b
$ do
  QueryBuilder
x <- QueryInner QueryBuilder
e
  QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text -> [QueryBuilder] -> QueryBuilder
H.fun Text
"cast" [QueryBuilder
x QueryBuilder -> QueryBuilder -> QueryBuilder
`H.as` QueryBuilder
tp]

instance Castable StrictBS.ByteString where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable ByteString
cast = QueryBuilder
-> Expression nullable b -> Expression nullable ByteString
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"BINARY"

instance Castable Text where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Text
cast = QueryBuilder -> Expression nullable b -> Expression nullable Text
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"CHAR UNICODE"

instance Castable Day where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Day
cast = QueryBuilder -> Expression nullable b -> Expression nullable Day
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"DATE"

instance Castable LocalTime where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable LocalTime
cast = QueryBuilder
-> Expression nullable b -> Expression nullable LocalTime
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"DATETIME"

instance Castable Scientific where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Scientific
cast = QueryBuilder
-> Expression nullable b -> Expression nullable Scientific
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"DECIMAL"

instance Castable Double where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Double
cast = QueryBuilder -> Expression nullable b -> Expression nullable Double
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"FLOAT[53]"

instance Castable Int where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Int
cast = QueryBuilder -> Expression nullable b -> Expression nullable Int
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"SIGNED"

instance Castable Int8 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Int8
cast = QueryBuilder -> Expression nullable b -> Expression nullable Int8
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"SIGNED"

instance Castable Int16 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Int16
cast = QueryBuilder -> Expression nullable b -> Expression nullable Int16
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"SIGNED"

instance Castable Int32 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Int32
cast = QueryBuilder -> Expression nullable b -> Expression nullable Int32
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"SIGNED"

instance Castable Int64 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Int64
cast = QueryBuilder -> Expression nullable b -> Expression nullable Int64
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"SIGNED"

instance Castable TimeOfDay where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable TimeOfDay
cast = QueryBuilder
-> Expression nullable b -> Expression nullable TimeOfDay
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"TIME"

instance Castable DiffTime where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable DiffTime
cast = QueryBuilder
-> Expression nullable b -> Expression nullable DiffTime
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"TIME"

instance Castable Word where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Word
cast = QueryBuilder -> Expression nullable b -> Expression nullable Word
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"UNSIGNED"

instance Castable Word8 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Word8
cast = QueryBuilder -> Expression nullable b -> Expression nullable Word8
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"UNSIGNED"

instance Castable Word16 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Word16
cast = QueryBuilder -> Expression nullable b -> Expression nullable Word16
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"UNSIGNED"

instance Castable Word32 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Word32
cast = QueryBuilder -> Expression nullable b -> Expression nullable Word32
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"UNSIGNED"

instance Castable Word64 where
  cast :: forall (nullable :: Nullable) b.
Expression nullable b -> Expression nullable Word64
cast = QueryBuilder -> Expression nullable b -> Expression nullable Word64
forall (nullable :: Nullable) b a.
QueryBuilder -> Expression nullable b -> Expression nullable a
castTo QueryBuilder
"UNSIGNED"

-- | Cast the return type of an expression to any other type, without
-- changing the query. Since this library adds static typing on top of
-- SQL, you may sometimes want to use this to get back the lenient
-- behaviour of SQL.  This opens up more possibilies for runtime
-- errors, so it's up to the programmer to ensure type correctness.
unsafeCast :: Expression nullable a -> Expression nullable b
unsafeCast :: forall (nullable :: Nullable) a b.
Expression nullable a -> Expression nullable b
unsafeCast = Expression nullable a -> Expression nullable b
forall a b. Coercible a b => a -> b
coerce

quotedFieldName :: Field table database nullable a -> Text
quotedFieldName :: forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName (Field Text
_ Text
fn) = Text
"`" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
fn Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"`"
quotedFieldName Field table database nullable a
AllFields = Text
"*"

insertOne :: H.ToSql a
          => Field table database 'NotNull fieldType
          -> Insertor table database a
insertOne :: forall a (table :: Symbol) database fieldType.
ToSql a =>
Field table database 'NotNull fieldType
-> Insertor table database a
insertOne = Insertor a -> Insertor table database a
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor a -> Insertor table database a)
-> (Field table database 'NotNull fieldType -> Insertor a)
-> Field table database 'NotNull fieldType
-> Insertor table database a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Insertor a
forall a. ToSql a => Text -> Insertor a
H.insertOne (Text -> Insertor a)
-> (Field table database 'NotNull fieldType -> Text)
-> Field table database 'NotNull fieldType
-> Insertor a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field table database 'NotNull fieldType -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName

insertOneMaybe :: H.ToSql a
               => Field table database 'Nullable fieldType
               -> Insertor table database (Maybe a)
insertOneMaybe :: forall a (table :: Symbol) database fieldType.
ToSql a =>
Field table database 'Nullable fieldType
-> Insertor table database (Maybe a)
insertOneMaybe = Insertor (Maybe a) -> Insertor table database (Maybe a)
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor (Maybe a) -> Insertor table database (Maybe a))
-> (Field table database 'Nullable fieldType -> Insertor (Maybe a))
-> Field table database 'Nullable fieldType
-> Insertor table database (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Insertor (Maybe a)
forall a. ToSql a => Text -> Insertor a
H.insertOne (Text -> Insertor (Maybe a))
-> (Field table database 'Nullable fieldType -> Text)
-> Field table database 'Nullable fieldType
-> Insertor (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field table database 'Nullable fieldType -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName

genFst :: (a :*: b) () -> a ()
genFst :: forall (a :: * -> *) (b :: * -> *). (:*:) a b () -> a ()
genFst (a ()
a :*: b ()
_) = a ()
a

genSnd :: (a :*: b) () -> b ()
genSnd :: forall (a :: * -> *) (b :: * -> *). (:*:) a b () -> b ()
genSnd (a ()
_ :*: b ()
b) = b ()
b

class InsertGeneric table database (fields :: *) (data_ :: *) where
  insertDataGeneric :: fields -> Insertor table database data_

instance (InsertGeneric tbl db (a ()) (c ()),
          InsertGeneric tbl db (b ()) (d ())) =>
         InsertGeneric tbl db ((a :*: b) ()) ((c :*: d) ()) where
  insertDataGeneric :: (:*:) a b () -> Insertor tbl db ((:*:) c d ())
insertDataGeneric (a ()
a :*: b ()
b) =
    ((:*:) c d () -> c ())
-> Insertor tbl db (c ()) -> Insertor tbl db ((:*:) c d ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (:*:) c d () -> c ()
forall (a :: * -> *) (b :: * -> *). (:*:) a b () -> a ()
genFst (a () -> Insertor tbl db (c ())
forall (table :: Symbol) database fields data_.
InsertGeneric table database fields data_ =>
fields -> Insertor table database data_
insertDataGeneric a ()
a) Insertor tbl db ((:*:) c d ())
-> Insertor tbl db ((:*:) c d ()) -> Insertor tbl db ((:*:) c d ())
forall a. Semigroup a => a -> a -> a
<>
    ((:*:) c d () -> d ())
-> Insertor tbl db (d ()) -> Insertor tbl db ((:*:) c d ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap (:*:) c d () -> d ()
forall (a :: * -> *) (b :: * -> *). (:*:) a b () -> b ()
genSnd (b () -> Insertor tbl db (d ())
forall (table :: Symbol) database fields data_.
InsertGeneric table database fields data_ =>
fields -> Insertor table database data_
insertDataGeneric b ()
b)

instance InsertGeneric tbl db (a ()) (b ()) =>
         InsertGeneric tbl db (M1 m1 m2 a ()) (M1 m3 m4 b ()) where
  insertDataGeneric :: M1 m1 m2 a () -> Insertor tbl db (M1 m3 m4 b ())
insertDataGeneric = (M1 m3 m4 b () -> b ())
-> Insertor tbl db (b ()) -> Insertor tbl db (M1 m3 m4 b ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap M1 m3 m4 b () -> b ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1 (Insertor tbl db (b ()) -> Insertor tbl db (M1 m3 m4 b ()))
-> (M1 m1 m2 a () -> Insertor tbl db (b ()))
-> M1 m1 m2 a ()
-> Insertor tbl db (M1 m3 m4 b ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a () -> Insertor tbl db (b ())
forall (table :: Symbol) database fields data_.
InsertGeneric table database fields data_ =>
fields -> Insertor table database data_
insertDataGeneric (a () -> Insertor tbl db (b ()))
-> (M1 m1 m2 a () -> a ())
-> M1 m1 m2 a ()
-> Insertor tbl db (b ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M1 m1 m2 a () -> a ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1

instance H.ToSql b =>
         InsertGeneric tbl db (K1 r (Field tbl db 'NotNull a) ()) (K1 r b ())
  where insertDataGeneric :: K1 r (Field tbl db 'NotNull a) () -> Insertor tbl db (K1 r b ())
insertDataGeneric = (K1 r b () -> b)
-> Insertor tbl db b -> Insertor tbl db (K1 r b ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap K1 r b () -> b
forall k i c (p :: k). K1 i c p -> c
unK1 (Insertor tbl db b -> Insertor tbl db (K1 r b ()))
-> (K1 r (Field tbl db 'NotNull a) () -> Insertor tbl db b)
-> K1 r (Field tbl db 'NotNull a) ()
-> Insertor tbl db (K1 r b ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field tbl db 'NotNull a -> Insertor tbl db b
forall a (table :: Symbol) database fieldType.
ToSql a =>
Field table database 'NotNull fieldType
-> Insertor table database a
insertOne (Field tbl db 'NotNull a -> Insertor tbl db b)
-> (K1 r (Field tbl db 'NotNull a) () -> Field tbl db 'NotNull a)
-> K1 r (Field tbl db 'NotNull a) ()
-> Insertor tbl db b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. K1 r (Field tbl db 'NotNull a) () -> Field tbl db 'NotNull a
forall k i c (p :: k). K1 i c p -> c
unK1

instance H.ToSql b =>
         InsertGeneric tbl db (K1 r (Field tbl db 'Nullable a) ())
         (K1 r (Maybe b) ())
  where insertDataGeneric :: K1 r (Field tbl db 'Nullable a) ()
-> Insertor tbl db (K1 r (Maybe b) ())
insertDataGeneric = (K1 r (Maybe b) () -> Maybe b)
-> Insertor tbl db (Maybe b) -> Insertor tbl db (K1 r (Maybe b) ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap K1 r (Maybe b) () -> Maybe b
forall k i c (p :: k). K1 i c p -> c
unK1 (Insertor tbl db (Maybe b) -> Insertor tbl db (K1 r (Maybe b) ()))
-> (K1 r (Field tbl db 'Nullable a) ()
    -> Insertor tbl db (Maybe b))
-> K1 r (Field tbl db 'Nullable a) ()
-> Insertor tbl db (K1 r (Maybe b) ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field tbl db 'Nullable a -> Insertor tbl db (Maybe b)
forall a (table :: Symbol) database fieldType.
ToSql a =>
Field table database 'Nullable fieldType
-> Insertor table database (Maybe a)
insertOneMaybe (Field tbl db 'Nullable a -> Insertor tbl db (Maybe b))
-> (K1 r (Field tbl db 'Nullable a) () -> Field tbl db 'Nullable a)
-> K1 r (Field tbl db 'Nullable a) ()
-> Insertor tbl db (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. K1 r (Field tbl db 'Nullable a) () -> Field tbl db 'Nullable a
forall k i c (p :: k). K1 i c p -> c
unK1

instance InsertGeneric tbl db (K1 r (Insertor tbl db a) ()) (K1 r a ()) where
  insertDataGeneric :: K1 r (Insertor tbl db a) () -> Insertor tbl db (K1 r a ())
insertDataGeneric = (K1 r a () -> a)
-> Insertor tbl db a -> Insertor tbl db (K1 r a ())
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap K1 r a () -> a
forall k i c (p :: k). K1 i c p -> c
unK1 (Insertor tbl db a -> Insertor tbl db (K1 r a ()))
-> (K1 r (Insertor tbl db a) () -> Insertor tbl db a)
-> K1 r (Insertor tbl db a) ()
-> Insertor tbl db (K1 r a ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. K1 r (Insertor tbl db a) () -> Insertor tbl db a
forall k i c (p :: k). K1 i c p -> c
unK1

insertData :: (Generic a, Generic b, InsertGeneric tbl db (Rep a ()) (Rep b ()))
           => a -> Insertor tbl db b
insertData :: forall a b (tbl :: Symbol) db.
(Generic a, Generic b,
 InsertGeneric tbl db (Rep a ()) (Rep b ())) =>
a -> Insertor tbl db b
insertData = (b -> Rep b ()) -> Insertor tbl db (Rep b ()) -> Insertor tbl db b
forall a' a. (a' -> a) -> Insertor tbl db a -> Insertor tbl db a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap b -> Rep b ()
forall a. Generic a => a -> Rep a ()
from' (Insertor tbl db (Rep b ()) -> Insertor tbl db b)
-> (a -> Insertor tbl db (Rep b ())) -> a -> Insertor tbl db b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep a () -> Insertor tbl db (Rep b ())
forall (table :: Symbol) database fields data_.
InsertGeneric table database fields data_ =>
fields -> Insertor table database data_
insertDataGeneric (Rep a () -> Insertor tbl db (Rep b ()))
-> (a -> Rep a ()) -> a -> Insertor tbl db (Rep b ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Rep a ()
forall a. Generic a => a -> Rep a ()
from'
  where from' :: Generic a => a -> Rep a ()
        from' :: forall a. Generic a => a -> Rep a ()
from' = a -> Rep a ()
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
Generics.from

skipInsert :: Insertor tbl db a
skipInsert :: forall (table :: Symbol) database a. Insertor table database a
skipInsert = Insertor tbl db a
forall a. Monoid a => a
mempty

{-
personInsertor :: Insertor table database Person
personInsertor = insertData (name, age)
-}

-- (a -> Expression) -> QueryInner (a -> QueryBuilder)
-- (a -> QueryInner QueryBuilder)
-- a -> queryState -> (queryState, result)
-- queryState -> a -> (query, result)
-- (a -> Expression) -> queryState -> a -> QueryBuilder
-- 

into :: (a -> Expression nullable b)
     -> Field table database nullable b
     -> Insertor table database a
into :: forall a (nullable :: Nullable) b (table :: Symbol) database.
(a -> Expression nullable b)
-> Field table database nullable b -> Insertor table database a
into a -> Expression nullable b
e Field table database nullable b
f =
  Insertor a -> Insertor table database a
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor a -> Insertor table database a)
-> Insertor a -> Insertor table database a
forall a b. (a -> b) -> a -> b
$
  (a -> QueryBuilder) -> Text -> Insertor a
forall a. (a -> QueryBuilder) -> Text -> Insertor a
H.exprInto (\a
x -> QueryInner QueryBuilder -> ClauseState -> QueryBuilder
forall s a. State s a -> s -> a
evalState (Expression nullable b -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression nullable b -> QueryInner QueryBuilder)
-> Expression nullable b -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ a -> Expression nullable b
e a
x) ClauseState
emptyClauseState)
  (Field table database nullable b -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database nullable b
f) 

lensInto :: H.ToSql b
         => H.Getter a b
         -> Field table database 'NotNull b
         -> Insertor table database a
lensInto :: forall b a (table :: Symbol) database.
ToSql b =>
Getter a b
-> Field table database 'NotNull b -> Insertor table database a
lensInto Getter a b
lens Field table database 'NotNull b
a = Insertor a -> Insertor table database a
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor a -> Insertor table database a)
-> Insertor a -> Insertor table database a
forall a b. (a -> b) -> a -> b
$ Getter a b -> Text -> Insertor a
forall b a. ToSql b => Getter a b -> Text -> Insertor a
H.lensInto Getter a b
lens (Text -> Insertor a) -> Text -> Insertor a
forall a b. (a -> b) -> a -> b
$ Field table database 'NotNull b -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database 'NotNull b
a

maybeLensInto :: H.ToSql b
              => H.Getter a (Maybe b)
              -> Field table database 'Nullable b
              -> Insertor table database a
maybeLensInto :: forall b a (table :: Symbol) database.
ToSql b =>
Getter a (Maybe b)
-> Field table database 'Nullable b -> Insertor table database a
maybeLensInto Getter a (Maybe b)
lens Field table database 'Nullable b
a = Insertor a -> Insertor table database a
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor a -> Insertor table database a)
-> Insertor a -> Insertor table database a
forall a b. (a -> b) -> a -> b
$ Getter a (Maybe b) -> Text -> Insertor a
forall b a. ToSql b => Getter a b -> Text -> Insertor a
H.lensInto Getter a (Maybe b)
lens (Text -> Insertor a) -> Text -> Insertor a
forall a b. (a -> b) -> a -> b
$ Field table database 'Nullable b -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database 'Nullable b
a

opticInto :: (H.ToSql b , Is k A_Getter )
          => Optic' k is a b
          -> Field table database 'NotNull b
          -> Insertor table database a
opticInto :: forall b k (is :: IxList) a (table :: Symbol) database.
(ToSql b, Is k A_Getter) =>
Optic' k is a b
-> Field table database 'NotNull b -> Insertor table database a
opticInto Optic' k is a b
getter Field table database 'NotNull b
field = (b -> Expression 'NotNull b
forall a (nullable :: Nullable).
ToSql a =>
a -> Expression nullable a
arg (b -> Expression 'NotNull b)
-> (a -> b) -> a -> Expression 'NotNull b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic' k is a b -> a -> b
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' k is a b
getter) (a -> Expression 'NotNull b)
-> Field table database 'NotNull b -> Insertor table database a
forall a (nullable :: Nullable) b (table :: Symbol) database.
(a -> Expression nullable b)
-> Field table database nullable b -> Insertor table database a
`into` Field table database 'NotNull b
field

maybeOpticInto :: (H.ToSql b , Is k A_Getter)
               => Optic' k is a (Maybe b)
               -> Field table database 'Nullable b
               -> Insertor table database a
maybeOpticInto :: forall b k (is :: IxList) a (table :: Symbol) database.
(ToSql b, Is k A_Getter) =>
Optic' k is a (Maybe b)
-> Field table database 'Nullable b -> Insertor table database a
maybeOpticInto Optic' k is a (Maybe b)
getter Field table database 'Nullable b
field = (Maybe b -> Expression 'Nullable b
forall a. ToSql a => Maybe a -> Expression 'Nullable a
argMaybe (Maybe b -> Expression 'Nullable b)
-> (a -> Maybe b) -> a -> Expression 'Nullable b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Optic' k is a (Maybe b) -> a -> Maybe b
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' k is a (Maybe b)
getter) (a -> Expression 'Nullable b)
-> Field table database 'Nullable b -> Insertor table database a
forall a (nullable :: Nullable) b (table :: Symbol) database.
(a -> Expression nullable b)
-> Field table database nullable b -> Insertor table database a
`into` Field table database 'Nullable b
field

insertWithout :: Field tables database nullable b
              -> Insertor table database a
              -> Insertor table database a
insertWithout :: forall (tables :: Symbol) database (nullable :: Nullable) b
       (table :: Symbol) a.
Field tables database nullable b
-> Insertor table database a -> Insertor table database a
insertWithout Field tables database nullable b
fld (Insertor Insertor a
ins) = Insertor a -> Insertor table database a
forall (table :: Symbol) database a.
Insertor a -> Insertor table database a
Insertor (Insertor a -> Insertor table database a)
-> Insertor a -> Insertor table database a
forall a b. (a -> b) -> a -> b
$ Insertor a -> [Text] -> Insertor a
forall a. Insertor a -> [Text] -> Insertor a
H.insertLess Insertor a
ins [Field tables database nullable b -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field tables database nullable b
fld]

updateWithout :: Field table database nullable a -> [Updator table database]
              -> [Updator table database]
updateWithout :: forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a
-> [Updator table database] -> [Updator table database]
updateWithout Field table database nullable a
fld = (Updator table database -> Bool)
-> [Updator table database] -> [Updator table database]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Updator table database -> Bool)
 -> [Updator table database] -> [Updator table database])
-> (Updator table database -> Bool)
-> [Updator table database]
-> [Updator table database]
forall a b. (a -> b) -> a -> b
$ \(Field table database nullable a
fld2 := Expression nullable a
_) -> Field table database nullable a
fld2 Field table database nullable a
-> Field table database nullable a -> Bool
forall {table :: Symbol} {database} {nullable :: Nullable} {a}
       {table :: Symbol} {database} {nullable :: Nullable} {a}.
Field table database nullable a
-> Field table database nullable a -> Bool
`fieldNeq` Field table database nullable a
fld
  where fieldNeq :: Field table database nullable a
-> Field table database nullable a -> Bool
fieldNeq (Field Text
tbl Text
col) (Field Text
tbl2 Text
col2) = (Text
tbl, Text
col) (Text, Text) -> (Text, Text) -> Bool
forall a. Eq a => a -> a -> Bool
/= (Text
tbl2, Text
col2)
        fieldNeq Field table database nullable a
AllFields Field table database nullable a
AllFields = Bool
False
        fieldNeq Field table database nullable a
_ Field table database nullable a
_ = Bool
True
    
quotedTableName :: Table table database -> Text
quotedTableName :: forall (table :: Symbol) database. Table table database -> Text
quotedTableName (Table Maybe Text
mbSchema Text
tableName) =
  (Text -> Text) -> Maybe Text -> Text
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\Text
schema -> Text
"`" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
schema Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"`.") Maybe Text
mbSchema Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
  Text
"`" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
  Text
tableName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
  Text
"`"
  
tableSql :: Table table database -> H.QueryBuilder
tableSql :: forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
tbl = Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Table table database -> Text
forall (table :: Symbol) database. Table table database -> Text
quotedTableName Table table database
tbl

insertValues :: Table table database
             -> Insertor table database a
             -> [a]
             -> H.Command
insertValues :: forall (table :: Symbol) database a.
Table table database -> Insertor table database a -> [a] -> Command
insertValues Table table database
table (Insertor Insertor a
i) =
  QueryBuilder -> Insertor a -> [a] -> Command
forall a. QueryBuilder -> Insertor a -> [a] -> Command
H.insertValues (Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table) Insertor a
i

valuesAlias :: Alias table database leftJoined
valuesAlias :: forall (table :: Symbol) database (leftJoined :: JoinType).
Alias table database leftJoined
valuesAlias = (forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall (table :: Symbol) database (joinType :: JoinType).
(forall (fieldNull :: Nullable) a.
 Field table database fieldNull a
 -> Expression (JoinNullable joinType fieldNull) a)
-> Alias table database joinType
Alias ((forall (fieldNull :: Nullable) a.
  Field table database fieldNull a
  -> Expression (JoinNullable leftJoined fieldNull) a)
 -> Alias table database leftJoined)
-> (forall (fieldNull :: Nullable) a.
    Field table database fieldNull a
    -> Expression (JoinNullable leftJoined fieldNull) a)
-> Alias table database leftJoined
forall a b. (a -> b) -> a -> b
$ \Field table database fieldNull a
field ->
  QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder
 -> Expression (JoinNullable leftJoined fieldNull) a)
-> QueryInner QueryBuilder
-> Expression (JoinNullable leftJoined fieldNull) a
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryBuilder
H.values (QueryBuilder -> QueryBuilder) -> QueryBuilder -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Field table database fieldNull a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database fieldNull a
field

insertUpdateValues :: Table table database
                   -> Insertor table database a
                   -> (Alias table database 'InnerJoined ->
                       Alias table database 'InnerJoined ->
                       [Updator table database])
                   -> [a]
                   -> H.Command
insertUpdateValues :: forall (table :: Symbol) database a.
Table table database
-> Insertor table database a
-> (Alias table database 'InnerJoined
    -> Alias table database 'InnerJoined -> [Updator table database])
-> [a]
-> Command
insertUpdateValues Table table database
table (Insertor Insertor a
i) Alias table database 'InnerJoined
-> Alias table database 'InnerJoined -> [Updator table database]
mkUpdators =
  QueryBuilder
-> Insertor a -> [(QueryBuilder, QueryBuilder)] -> [a] -> Command
forall a.
QueryBuilder
-> Insertor a -> [(QueryBuilder, QueryBuilder)] -> [a] -> Command
H.insertUpdateValues (Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table) Insertor a
i [(QueryBuilder, QueryBuilder)]
updators
  where updators :: [(QueryBuilder, QueryBuilder)]
updators = (State ClauseState [(QueryBuilder, QueryBuilder)]
 -> ClauseState -> [(QueryBuilder, QueryBuilder)])
-> ClauseState
-> State ClauseState [(QueryBuilder, QueryBuilder)]
-> [(QueryBuilder, QueryBuilder)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip State ClauseState [(QueryBuilder, QueryBuilder)]
-> ClauseState -> [(QueryBuilder, QueryBuilder)]
forall s a. State s a -> s -> a
evalState ClauseState
emptyClauseState (State ClauseState [(QueryBuilder, QueryBuilder)]
 -> [(QueryBuilder, QueryBuilder)])
-> State ClauseState [(QueryBuilder, QueryBuilder)]
-> [(QueryBuilder, QueryBuilder)]
forall a b. (a -> b) -> a -> b
$ 
                   (Updator table database
 -> StateT ClauseState Identity (QueryBuilder, QueryBuilder))
-> [Updator table database]
-> State ClauseState [(QueryBuilder, QueryBuilder)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
forall (table :: Symbol) database.
Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
runUpdator ([Updator table database]
 -> State ClauseState [(QueryBuilder, QueryBuilder)])
-> [Updator table database]
-> State ClauseState [(QueryBuilder, QueryBuilder)]
forall a b. (a -> b) -> a -> b
$ Alias table database 'InnerJoined
-> Alias table database 'InnerJoined -> [Updator table database]
mkUpdators Alias table database 'InnerJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Alias table database leftJoined
emptyAlias Alias table database 'InnerJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Alias table database leftJoined
valuesAlias
        runUpdator :: Updator table database
                   -> QueryInner (H.QueryBuilder, H.QueryBuilder)  
        runUpdator :: forall (table :: Symbol) database.
Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
runUpdator (Field table database nullable a
field := Expression QueryInner QueryBuilder
expr) = do
          (Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Field table database nullable a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database nullable a
field, ) (QueryBuilder -> (QueryBuilder, QueryBuilder))
-> QueryInner QueryBuilder
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
expr

delete :: QueryClauses database (Alias table database 'InnerJoined) -> H.Command
delete :: forall database (table :: Symbol).
QueryClauses database (Alias table database 'InnerJoined)
-> Command
delete (QueryClauses QueryInner (Alias table database 'InnerJoined)
qry) = QueryBuilder -> QueryClauses -> Command
H.delete QueryBuilder
fields QueryClauses
clauseBody
  where (Alias forall (fieldNull :: Nullable) a.
Field table database fieldNull a
-> Expression (JoinNullable 'InnerJoined fieldNull) a
al, ClauseState QueryClauses
clauseBody Map Text Int
_) = QueryInner (Alias table database 'InnerJoined)
-> ClauseState -> (Alias table database 'InnerJoined, ClauseState)
forall s a. State s a -> s -> (a, s)
runState QueryInner (Alias table database 'InnerJoined)
qry ClauseState
emptyClauseState
        fields :: QueryBuilder
fields = (QueryInner QueryBuilder -> ClauseState -> QueryBuilder)
-> ClauseState -> QueryInner QueryBuilder -> QueryBuilder
forall a b c. (a -> b -> c) -> b -> a -> c
flip QueryInner QueryBuilder -> ClauseState -> QueryBuilder
forall s a. State s a -> s -> a
evalState ClauseState
emptyClauseState (QueryInner QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Expression Any Any -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression Any Any -> QueryInner QueryBuilder)
-> Expression Any Any -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Field table database Any Any
-> Expression (JoinNullable 'InnerJoined Any) Any
forall (fieldNull :: Nullable) a.
Field table database fieldNull a
-> Expression (JoinNullable 'InnerJoined fieldNull) a
al Field table database Any Any
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a
AllFields
        
newAlias :: Text -> QueryInner Text
newAlias :: Text -> QueryInner Text
newAlias Text
prefix = do
  ClauseState
clsState <- StateT ClauseState Identity ClauseState
forall s (m :: * -> *). MonadState s m => m s
get
  let newIndex :: Int
newIndex = Int -> Text -> Map Text Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
0 Text
prefix (ClauseState -> Map Text Int
aliases ClauseState
clsState) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
  ClauseState -> StateT ClauseState Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (ClauseState -> StateT ClauseState Identity ())
-> ClauseState -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ ClauseState
clsState { aliases = Map.insert prefix newIndex $ aliases clsState}
  Text -> QueryInner Text
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> QueryInner Text) -> Text -> QueryInner Text
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (Int -> String
forall a. Show a => a -> String
show Int
newIndex)

addClauses :: H.QueryClauses -> QueryInner ()
addClauses :: QueryClauses -> StateT ClauseState Identity ()
addClauses QueryClauses
c = (ClauseState -> ClauseState) -> StateT ClauseState Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((ClauseState -> ClauseState) -> StateT ClauseState Identity ())
-> (ClauseState -> ClauseState) -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ \ClauseState
clsState ->
  ClauseState
clsState { clausesBuild = clausesBuild clsState <> c }

from :: Table table database
     -> QueryClauses database (Alias table database 'InnerJoined)
from :: forall (table :: Symbol) database.
Table table database
-> QueryClauses database (Alias table database 'InnerJoined)
from table :: Table table database
table@(Table Maybe Text
_ Text
tableName) = QueryInner (Alias table database 'InnerJoined)
-> QueryClauses database (Alias table database 'InnerJoined)
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner (Alias table database 'InnerJoined)
 -> QueryClauses database (Alias table database 'InnerJoined))
-> QueryInner (Alias table database 'InnerJoined)
-> QueryClauses database (Alias table database 'InnerJoined)
forall a b. (a -> b) -> a -> b
$
  do Text
alias <- Text -> QueryInner Text
newAlias (Int -> Text -> Text
Text.take Int
1 Text
tableName)
     QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryClauses
H.from (QueryBuilder -> QueryClauses) -> QueryBuilder -> QueryClauses
forall a b. (a -> b) -> a -> b
$ Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table QueryBuilder -> QueryBuilder -> QueryBuilder
`H.as` Text -> QueryBuilder
H.rawSql Text
alias
     Alias table database 'InnerJoined
-> QueryInner (Alias table database 'InnerJoined)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Alias table database 'InnerJoined
 -> QueryInner (Alias table database 'InnerJoined))
-> Alias table database 'InnerJoined
-> QueryInner (Alias table database 'InnerJoined)
forall a b. (a -> b) -> a -> b
$ Text -> Alias table database 'InnerJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Text -> Alias table database leftJoined
mkTableAlias Text
alias

innerJoin :: Table table database
          -> (Alias table database 'InnerJoined ->
              Expression nullable Bool)
          -> QueryClauses database (Alias table database 'InnerJoined)
innerJoin :: forall (table :: Symbol) database (nullable :: Nullable).
Table table database
-> (Alias table database 'InnerJoined -> Expression nullable Bool)
-> QueryClauses database (Alias table database 'InnerJoined)
innerJoin table :: Table table database
table@(Table Maybe Text
_ Text
tableName) Alias table database 'InnerJoined -> Expression nullable Bool
joinCondition = QueryInner (Alias table database 'InnerJoined)
-> QueryClauses database (Alias table database 'InnerJoined)
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner (Alias table database 'InnerJoined)
 -> QueryClauses database (Alias table database 'InnerJoined))
-> QueryInner (Alias table database 'InnerJoined)
-> QueryClauses database (Alias table database 'InnerJoined)
forall a b. (a -> b) -> a -> b
$ do
  Text
alias <- Text -> QueryInner Text
newAlias (Text -> QueryInner Text) -> Text -> QueryInner Text
forall a b. (a -> b) -> a -> b
$ Int -> Text -> Text
Text.take Int
1 Text
tableName
  let tblAlias :: Alias table database 'InnerJoined
tblAlias = Text -> Alias table database 'InnerJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Text -> Alias table database leftJoined
mkTableAlias Text
alias
  QueryBuilder
exprBuilder <- Expression nullable Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression nullable Bool -> QueryInner QueryBuilder)
-> Expression nullable Bool -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Alias table database 'InnerJoined -> Expression nullable Bool
joinCondition Alias table database 'InnerJoined
tblAlias
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$
    [QueryBuilder] -> [QueryBuilder] -> QueryClauses
H.innerJoin [Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table QueryBuilder -> QueryBuilder -> QueryBuilder
`H.as` Text -> QueryBuilder
H.rawSql Text
alias]
    [QueryBuilder
exprBuilder]
  Alias table database 'InnerJoined
-> QueryInner (Alias table database 'InnerJoined)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Alias table database 'InnerJoined
tblAlias

leftJoin :: Table table database
         -> (Alias table database 'LeftJoined ->
             Expression nullable Bool)
         -> QueryClauses database (Alias table database 'LeftJoined)
leftJoin :: forall (table :: Symbol) database (nullable :: Nullable).
Table table database
-> (Alias table database 'LeftJoined -> Expression nullable Bool)
-> QueryClauses database (Alias table database 'LeftJoined)
leftJoin table :: Table table database
table@(Table Maybe Text
_ Text
tableName) Alias table database 'LeftJoined -> Expression nullable Bool
joinCondition = QueryInner (Alias table database 'LeftJoined)
-> QueryClauses database (Alias table database 'LeftJoined)
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner (Alias table database 'LeftJoined)
 -> QueryClauses database (Alias table database 'LeftJoined))
-> QueryInner (Alias table database 'LeftJoined)
-> QueryClauses database (Alias table database 'LeftJoined)
forall a b. (a -> b) -> a -> b
$ do
  Text
alias <- Text -> QueryInner Text
newAlias (Text -> QueryInner Text) -> Text -> QueryInner Text
forall a b. (a -> b) -> a -> b
$ Int -> Text -> Text
Text.take Int
1 Text
tableName
  let tblAlias :: Alias table database 'LeftJoined
tblAlias = Text -> Alias table database 'LeftJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Text -> Alias table database leftJoined
mkTableAlias Text
alias
  QueryBuilder
exprBuilder <- Expression nullable Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression nullable Bool -> QueryInner QueryBuilder)
-> Expression nullable Bool -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Alias table database 'LeftJoined -> Expression nullable Bool
joinCondition Alias table database 'LeftJoined
tblAlias
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$
    [QueryBuilder] -> [QueryBuilder] -> QueryClauses
H.leftJoin [Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table QueryBuilder -> QueryBuilder -> QueryBuilder
`H.as` Text -> QueryBuilder
H.rawSql Text
alias]
    [QueryBuilder
exprBuilder]
  Alias table database 'LeftJoined
-> QueryInner (Alias table database 'LeftJoined)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Alias table database 'LeftJoined
tblAlias


class SubQueryExpr (joinType :: JoinType) inExpr outExpr where
  -- The ReaderT monad takes the alias of the subquery table.
  -- The State monad uses the index of the last expression in the select clause.
  -- It generates SELECT clause expressions with aliases e1, e2, ...
  -- The outExpr contains just the output aliases.
  -- input and output should be product types, and have the same number of
  -- elements.
  subJoinGeneric :: Proxy joinType
                 -> inExpr
                 -> ReaderT Text (State Int) 
                    (DList.DList SomeExpression, outExpr)

instance ( SubQueryExpr joinType (a ()) (c ())
         , SubQueryExpr joinType (b ()) (d ())) =>
         SubQueryExpr joinType ((a :*: b) ()) ((c :*: d) ()) where
  subJoinGeneric :: Proxy joinType
-> (:*:) a b ()
-> ReaderT Text (State Int) (DList SomeExpression, (:*:) c d ())
subJoinGeneric Proxy joinType
p (a ()
l :*: b ()
r) = do
    (DList SomeExpression
lftBuilder, c ()
outLft) <- Proxy joinType
-> a () -> ReaderT Text (State Int) (DList SomeExpression, c ())
forall (joinType :: JoinType) inExpr outExpr.
SubQueryExpr joinType inExpr outExpr =>
Proxy joinType
-> inExpr
-> ReaderT Text (State Int) (DList SomeExpression, outExpr)
subJoinGeneric Proxy joinType
p a ()
l
    (DList SomeExpression
rtBuilder, d ()
outRt) <- Proxy joinType
-> b () -> ReaderT Text (State Int) (DList SomeExpression, d ())
forall (joinType :: JoinType) inExpr outExpr.
SubQueryExpr joinType inExpr outExpr =>
Proxy joinType
-> inExpr
-> ReaderT Text (State Int) (DList SomeExpression, outExpr)
subJoinGeneric Proxy joinType
p b ()
r
    (DList SomeExpression, (:*:) c d ())
-> ReaderT Text (State Int) (DList SomeExpression, (:*:) c d ())
forall a. a -> ReaderT Text (State Int) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DList SomeExpression
lftBuilder DList SomeExpression
-> DList SomeExpression -> DList SomeExpression
forall a. Semigroup a => a -> a -> a
<> DList SomeExpression
rtBuilder, c ()
outLft c () -> d () -> (:*:) c d ()
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: d ()
outRt)
    
instance SubQueryExpr joinType (a ()) (b ()) =>
         SubQueryExpr joinType (M1 m1 m2 a ()) (M1 m3 m4 b ()) where
  subJoinGeneric :: Proxy joinType
-> M1 m1 m2 a ()
-> ReaderT Text (State Int) (DList SomeExpression, M1 m3 m4 b ())
subJoinGeneric Proxy joinType
p (M1 a ()
x) = (b () -> M1 m3 m4 b ())
-> (DList SomeExpression, b ())
-> (DList SomeExpression, M1 m3 m4 b ())
forall a b.
(a -> b) -> (DList SomeExpression, a) -> (DList SomeExpression, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b () -> M1 m3 m4 b ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 ((DList SomeExpression, b ())
 -> (DList SomeExpression, M1 m3 m4 b ()))
-> ReaderT Text (State Int) (DList SomeExpression, b ())
-> ReaderT Text (State Int) (DList SomeExpression, M1 m3 m4 b ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy joinType
-> a () -> ReaderT Text (State Int) (DList SomeExpression, b ())
forall (joinType :: JoinType) inExpr outExpr.
SubQueryExpr joinType inExpr outExpr =>
Proxy joinType
-> inExpr
-> ReaderT Text (State Int) (DList SomeExpression, outExpr)
subJoinGeneric Proxy joinType
p a ()
x
    
instance JoinNullable joinType nullable ~ nullable2 => 
         SubQueryExpr
         joinType
         (K1 r (Expression nullable a) ())
         (K1 r (Expression nullable2 b) ())
  where
  subJoinGeneric :: Proxy joinType
-> K1 r (Expression nullable a) ()
-> ReaderT
     Text
     (State Int)
     (DList SomeExpression, K1 r (Expression nullable2 b) ())
subJoinGeneric Proxy joinType
_ (K1 (Expression QueryInner QueryBuilder
exprBuilder)) =
    (Text
 -> State
      Int (DList SomeExpression, K1 r (Expression nullable2 b) ()))
-> ReaderT
     Text
     (State Int)
     (DList SomeExpression, K1 r (Expression nullable2 b) ())
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((Text
  -> State
       Int (DList SomeExpression, K1 r (Expression nullable2 b) ()))
 -> ReaderT
      Text
      (State Int)
      (DList SomeExpression, K1 r (Expression nullable2 b) ()))
-> (Text
    -> State
         Int (DList SomeExpression, K1 r (Expression nullable2 b) ()))
-> ReaderT
     Text
     (State Int)
     (DList SomeExpression, K1 r (Expression nullable2 b) ())
forall a b. (a -> b) -> a -> b
$ \Text
alias -> (Int
 -> ((DList SomeExpression, K1 r (Expression nullable2 b) ()), Int))
-> State
     Int (DList SomeExpression, K1 r (Expression nullable2 b) ())
forall a. (Int -> (a, Int)) -> StateT Int Identity a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state ((Int
  -> ((DList SomeExpression, K1 r (Expression nullable2 b) ()), Int))
 -> State
      Int (DList SomeExpression, K1 r (Expression nullable2 b) ()))
-> (Int
    -> ((DList SomeExpression, K1 r (Expression nullable2 b) ()), Int))
-> State
     Int (DList SomeExpression, K1 r (Expression nullable2 b) ())
forall a b. (a -> b) -> a -> b
$ \Int
i ->
    let name :: Text
name = String -> Text
Text.pack (Char
'e'Char -> String -> String
forall a. a -> [a] -> [a]
: Int -> String
forall a. Show a => a -> String
show Int
i)
    in ( ( SomeExpression -> DList SomeExpression
forall a. a -> DList a
DList.singleton (SomeExpression -> DList SomeExpression)
-> SomeExpression -> DList SomeExpression
forall a b. (a -> b) -> a -> b
$ QueryInner QueryBuilder -> SomeExpression
SomeExpression (QueryInner QueryBuilder -> SomeExpression)
-> QueryInner QueryBuilder -> SomeExpression
forall a b. (a -> b) -> a -> b
$
           (QueryBuilder -> QueryBuilder -> QueryBuilder
`H.as` Text -> QueryBuilder
H.rawSql Text
name) (QueryBuilder -> QueryBuilder)
-> QueryInner QueryBuilder -> QueryInner QueryBuilder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
exprBuilder
         , Expression nullable2 b -> K1 r (Expression nullable2 b) ()
forall k i c (p :: k). c -> K1 i c p
K1 (Expression nullable2 b -> K1 r (Expression nullable2 b) ())
-> Expression nullable2 b -> K1 r (Expression nullable2 b) ()
forall a b. (a -> b) -> a -> b
$ QueryInner QueryBuilder -> Expression nullable2 b
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable2 b)
-> QueryInner QueryBuilder -> Expression nullable2 b
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryInner QueryBuilder
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryBuilder -> QueryInner QueryBuilder)
-> QueryBuilder -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Text
alias Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name)
       , Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1
       )

-- update the aliases, but create and return new query clauses
runAsSubQuery :: QueryClauses database a -> QueryInner (H.QueryClauses, a)
runAsSubQuery :: forall database a.
QueryClauses database a -> QueryInner (QueryClauses, a)
runAsSubQuery (QueryClauses QueryInner a
sq) =
  do ClauseState QueryClauses
currentClauses Map Text Int
currentAliases <- StateT ClauseState Identity ClauseState
forall s (m :: * -> *). MonadState s m => m s
get
     let (a
subQueryRet, ClauseState QueryClauses
subQueryBody Map Text Int
newAliases) =
           QueryInner a -> ClauseState -> (a, ClauseState)
forall s a. State s a -> s -> (a, s)
runState QueryInner a
sq (QueryClauses -> Map Text Int -> ClauseState
ClauseState QueryClauses
forall a. Monoid a => a
mempty Map Text Int
currentAliases)
     ClauseState -> StateT ClauseState Identity ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (ClauseState -> StateT ClauseState Identity ())
-> ClauseState -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ QueryClauses -> Map Text Int -> ClauseState
ClauseState QueryClauses
currentClauses Map Text Int
newAliases
     (QueryClauses, a) -> QueryInner (QueryClauses, a)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryClauses
subQueryBody, a
subQueryRet)

subQuerySelect :: Query database (Expression nullable a)
               -> QueryInner (H.Query ())
subQuerySelect :: forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect (Query QueryClauses database (Expression nullable a)
sq) = do
  (QueryClauses
subQueryBody, Expression QueryInner QueryBuilder
sqSelect) <- QueryClauses database (Expression nullable a)
-> QueryInner (QueryClauses, Expression nullable a)
forall database a.
QueryClauses database a -> QueryInner (QueryClauses, a)
runAsSubQuery QueryClauses database (Expression nullable a)
sq 
  QueryBuilder
selectBuilder <- QueryInner QueryBuilder
sqSelect
  Query () -> QueryInner (Query ())
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> QueryInner (Query ()))
-> Query () -> QueryInner (Query ())
forall a b. (a -> b) -> a -> b
$ Selector () -> QueryClauses -> Query ()
forall a. Selector a -> QueryClauses -> Query a
H.select ([QueryBuilder] -> Selector ()
H.rawValues_ [QueryBuilder
selectBuilder]) QueryClauses
subQueryBody
subQuerySelect (UnionAll Query database (Expression nullable a)
sq1 Query database (Expression nullable a)
sq2) = do
  Query ()
q1 <- Query database (Expression nullable a) -> QueryInner (Query ())
forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect Query database (Expression nullable a)
sq1
  Query ()
q2 <- Query database (Expression nullable a) -> QueryInner (Query ())
forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect Query database (Expression nullable a)
sq2
  Query () -> QueryInner (Query ())
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> QueryInner (Query ()))
-> Query () -> QueryInner (Query ())
forall a b. (a -> b) -> a -> b
$ Query () -> Query () -> Query ()
forall a. Query a -> Query a -> Query a
H.unionAll Query ()
q1 Query ()
q2
subQuerySelect (UnionDistinct Query database (Expression nullable a)
sq1 Query database (Expression nullable a)
sq2) = do
  Query ()
q1 <- Query database (Expression nullable a) -> QueryInner (Query ())
forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect Query database (Expression nullable a)
sq1
  Query ()
q2 <- Query database (Expression nullable a) -> QueryInner (Query ())
forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect Query database (Expression nullable a)
sq2
  Query () -> QueryInner (Query ())
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> QueryInner (Query ()))
-> Query () -> QueryInner (Query ())
forall a b. (a -> b) -> a -> b
$ Query () -> Query () -> Query ()
forall a. Query a -> Query a -> Query a
H.unionDistinct Query ()
q1 Query ()
q2
  
subQueryExpr :: Query database (Expression nullable a) -> Expression nullable a
subQueryExpr :: forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> Expression nullable a
subQueryExpr Query database (Expression nullable a)
sqr = QueryInner QueryBuilder -> Expression nullable a
forall (nullable :: Nullable) a.
QueryInner QueryBuilder -> Expression nullable a
Expression (QueryInner QueryBuilder -> Expression nullable a)
-> QueryInner QueryBuilder -> Expression nullable a
forall a b. (a -> b) -> a -> b
$ Query () -> QueryBuilder
forall a. ToQueryBuilder a => a -> QueryBuilder
H.subQuery (Query () -> QueryBuilder)
-> QueryInner (Query ()) -> QueryInner QueryBuilder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Query database (Expression nullable a) -> QueryInner (Query ())
forall database (nullable :: Nullable) a.
Query database (Expression nullable a) -> QueryInner (Query ())
subQuerySelect Query database (Expression nullable a)
sqr

subJoinSelect :: forall inExprs outExprs joinType database.
                 (Generic inExprs,
                  Generic outExprs,
                  SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ()))
              => Proxy joinType
              -> Query database inExprs
              -> QueryInner (H.Query (), outExprs)
subJoinSelect :: forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect Proxy joinType
p (Query QueryClauses database inExprs
sq) = do
  Text
sqAlias <- Text -> QueryInner Text
newAlias Text
"sq"
  (QueryClauses
subQueryBody, inExprs
sqExprs) <- QueryClauses database inExprs -> QueryInner (QueryClauses, inExprs)
forall database a.
QueryClauses database a -> QueryInner (QueryClauses, a)
runAsSubQuery QueryClauses database inExprs
sq
  let from' :: Generic inExprs => inExprs -> Rep inExprs ()
      from' :: Generic inExprs => inExprs -> Rep inExprs ()
from' = inExprs -> Rep inExprs ()
forall x. inExprs -> Rep inExprs x
forall a x. Generic a => a -> Rep a x
Generics.from
      to' :: Generic outExpr => Rep outExpr () -> outExpr
      to' :: forall outExpr. Generic outExpr => Rep outExpr () -> outExpr
to' = Rep outExpr () -> outExpr
forall a x. Generic a => Rep a x -> a
forall x. Rep outExpr x -> outExpr
Generics.to
      (DList SomeExpression
selectExprs, Rep outExprs ()
outExprRep) = (State Int (DList SomeExpression, Rep outExprs ())
 -> Int -> (DList SomeExpression, Rep outExprs ()))
-> Int
-> State Int (DList SomeExpression, Rep outExprs ())
-> (DList SomeExpression, Rep outExprs ())
forall a b c. (a -> b -> c) -> b -> a -> c
flip State Int (DList SomeExpression, Rep outExprs ())
-> Int -> (DList SomeExpression, Rep outExprs ())
forall s a. State s a -> s -> a
evalState Int
1 (State Int (DList SomeExpression, Rep outExprs ())
 -> (DList SomeExpression, Rep outExprs ()))
-> State Int (DList SomeExpression, Rep outExprs ())
-> (DList SomeExpression, Rep outExprs ())
forall a b. (a -> b) -> a -> b
$
                                  (ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
 -> Text -> State Int (DList SomeExpression, Rep outExprs ()))
-> Text
-> ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
-> State Int (DList SomeExpression, Rep outExprs ())
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
-> Text -> State Int (DList SomeExpression, Rep outExprs ())
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT Text
sqAlias (ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
 -> State Int (DList SomeExpression, Rep outExprs ()))
-> ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
-> State Int (DList SomeExpression, Rep outExprs ())
forall a b. (a -> b) -> a -> b
$
                                  Proxy joinType
-> Rep inExprs ()
-> ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
forall (joinType :: JoinType) inExpr outExpr.
SubQueryExpr joinType inExpr outExpr =>
Proxy joinType
-> inExpr
-> ReaderT Text (State Int) (DList SomeExpression, outExpr)
subJoinGeneric Proxy joinType
p (Rep inExprs ()
 -> ReaderT
      Text (State Int) (DList SomeExpression, Rep outExprs ()))
-> Rep inExprs ()
-> ReaderT Text (State Int) (DList SomeExpression, Rep outExprs ())
forall a b. (a -> b) -> a -> b
$
                                  inExprs -> Rep inExprs ()
Generic inExprs => inExprs -> Rep inExprs ()
from' inExprs
sqExprs
      outExpr :: outExprs
outExpr = Rep outExprs () -> outExprs
forall outExpr. Generic outExpr => Rep outExpr () -> outExpr
to' Rep outExprs ()
outExprRep
  [QueryBuilder]
selectBuilder <- DList QueryBuilder -> [QueryBuilder]
forall a. DList a -> [a]
DList.toList (DList QueryBuilder -> [QueryBuilder])
-> StateT ClauseState Identity (DList QueryBuilder)
-> StateT ClauseState Identity [QueryBuilder]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (SomeExpression -> QueryInner QueryBuilder)
-> DList SomeExpression
-> StateT ClauseState Identity (DList QueryBuilder)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> DList a -> f (DList b)
traverse SomeExpression -> QueryInner QueryBuilder
runSomeExpression DList SomeExpression
selectExprs
  (Query (), outExprs) -> QueryInner (Query (), outExprs)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Selector () -> QueryClauses -> Query ()
forall a. Selector a -> QueryClauses -> Query a
H.select ([QueryBuilder] -> Selector ()
H.rawValues_ [QueryBuilder]
selectBuilder) QueryClauses
subQueryBody
       , outExprs
outExpr)
subJoinSelect Proxy joinType
p (UnionAll Query database inExprs
sq1 Query database inExprs
sq2) = do
  (Query ()
sqr1, outExprs
outExpr) <- Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect Proxy joinType
p Query database inExprs
sq1
  (Query ()
sqr2, outExprs
_) <- forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect @inExprs @outExprs Proxy joinType
p Query database inExprs
sq2
  (Query (), outExprs) -> QueryInner (Query (), outExprs)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> Query () -> Query ()
forall a. Query a -> Query a -> Query a
H.unionAll Query ()
sqr1 Query ()
sqr2, outExprs
outExpr)
subJoinSelect Proxy joinType
p (UnionDistinct Query database inExprs
sq1 Query database inExprs
sq2) = do
  (Query ()
sqr1, outExprs
outExpr) <- Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect Proxy joinType
p Query database inExprs
sq1
  (Query ()
sqr2, outExprs
_) <- forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect @inExprs @outExprs Proxy joinType
p Query database inExprs
sq2
  (Query (), outExprs) -> QueryInner (Query (), outExprs)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> Query () -> Query ()
forall a. Query a -> Query a -> Query a
H.unionDistinct Query ()
sqr1 Query ()
sqr2, outExprs
outExpr)

subJoinBody :: (Generic inExprs,
              Generic outExprs,
              SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ()))
            => Proxy joinType
            -> Query database inExprs
            -> QueryInner (H.QueryBuilder, outExprs)
subJoinBody :: forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
subJoinBody Proxy joinType
p Query database inExprs
sq = do
  (Query ()
sqr, outExprs
outExpr) <- Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (Query (), outExprs)
subJoinSelect Proxy joinType
p Query database inExprs
sq
  (QueryBuilder, outExprs) -> QueryInner (QueryBuilder, outExprs)
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Query () -> QueryBuilder
forall a. ToQueryBuilder a => a -> QueryBuilder
H.subQuery Query ()
sqr, outExprs
outExpr)

joinSubQuery :: (Generic inExprs,
                 Generic outExprs,
                 SubQueryExpr 'InnerJoined (Rep inExprs ()) (Rep outExprs ()))
             => Query database inExprs
             -> (outExprs -> Expression nullable Bool)
             -> QueryClauses database outExprs
joinSubQuery :: forall inExprs outExprs database (nullable :: Nullable).
(Generic inExprs, Generic outExprs,
 SubQueryExpr 'InnerJoined (Rep inExprs ()) (Rep outExprs ())) =>
Query database inExprs
-> (outExprs -> Expression nullable Bool)
-> QueryClauses database outExprs
joinSubQuery Query database inExprs
sq outExprs -> Expression nullable Bool
condition = QueryInner outExprs -> QueryClauses database outExprs
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner outExprs -> QueryClauses database outExprs)
-> QueryInner outExprs -> QueryClauses database outExprs
forall a b. (a -> b) -> a -> b
$ do
  (QueryBuilder
subQueryBody, outExprs
outExpr) <- Proxy 'InnerJoined
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
subJoinBody (Proxy 'InnerJoined
forall {k} (t :: k). Proxy t
Proxy :: Proxy 'InnerJoined) Query database inExprs
sq
  QueryBuilder
conditionBuilder <- Expression nullable Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression nullable Bool -> QueryInner QueryBuilder)
-> Expression nullable Bool -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ outExprs -> Expression nullable Bool
condition outExprs
outExpr
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> [QueryBuilder] -> QueryClauses
H.innerJoin [QueryBuilder
subQueryBody] [QueryBuilder
conditionBuilder]
  outExprs -> QueryInner outExprs
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure outExprs
outExpr

leftJoinSubQuery :: (Generic inExprs,
                     Generic outExprs,
                     SubQueryExpr 'LeftJoined (Rep inExprs ()) (Rep outExprs ()))
                 => Query database inExprs
                 -> (outExprs -> Expression nullable Bool)
                 -> QueryClauses database outExprs
leftJoinSubQuery :: forall inExprs outExprs database (nullable :: Nullable).
(Generic inExprs, Generic outExprs,
 SubQueryExpr 'LeftJoined (Rep inExprs ()) (Rep outExprs ())) =>
Query database inExprs
-> (outExprs -> Expression nullable Bool)
-> QueryClauses database outExprs
leftJoinSubQuery Query database inExprs
sq outExprs -> Expression nullable Bool
condition = QueryInner outExprs -> QueryClauses database outExprs
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner outExprs -> QueryClauses database outExprs)
-> QueryInner outExprs -> QueryClauses database outExprs
forall a b. (a -> b) -> a -> b
$ do
  (QueryBuilder
subQueryBody, outExprs
outExpr) <- Proxy 'LeftJoined
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
subJoinBody (Proxy 'LeftJoined
forall {k} (t :: k). Proxy t
Proxy :: Proxy 'LeftJoined) Query database inExprs
sq
  QueryBuilder
conditionBuilder <- Expression nullable Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression (Expression nullable Bool -> QueryInner QueryBuilder)
-> Expression nullable Bool -> QueryInner QueryBuilder
forall a b. (a -> b) -> a -> b
$ outExprs -> Expression nullable Bool
condition outExprs
outExpr
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> [QueryBuilder] -> QueryClauses
H.leftJoin [QueryBuilder
subQueryBody] [QueryBuilder
conditionBuilder]
  outExprs -> QueryInner outExprs
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure outExprs
outExpr

fromSubQuery :: (Generic inExprs,
                 Generic outExprs,
                 SubQueryExpr 'LeftJoined (Rep inExprs ()) (Rep outExprs ()))
             => Query database inExprs
             -> QueryClauses database outExprs
fromSubQuery :: forall inExprs outExprs database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr 'LeftJoined (Rep inExprs ()) (Rep outExprs ())) =>
Query database inExprs -> QueryClauses database outExprs
fromSubQuery Query database inExprs
sq = QueryInner outExprs -> QueryClauses database outExprs
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (QueryInner outExprs -> QueryClauses database outExprs)
-> QueryInner outExprs -> QueryClauses database outExprs
forall a b. (a -> b) -> a -> b
$ do              
  (QueryBuilder
subQueryBody, outExprs
outExpr) <- Proxy 'LeftJoined
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
forall inExprs outExprs (joinType :: JoinType) database.
(Generic inExprs, Generic outExprs,
 SubQueryExpr joinType (Rep inExprs ()) (Rep outExprs ())) =>
Proxy joinType
-> Query database inExprs -> QueryInner (QueryBuilder, outExprs)
subJoinBody (Proxy 'LeftJoined
forall {k} (t :: k). Proxy t
Proxy :: Proxy 'LeftJoined) Query database inExprs
sq 
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ QueryBuilder -> QueryClauses
H.from QueryBuilder
subQueryBody
  outExprs -> QueryInner outExprs
forall a. a -> StateT ClauseState Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure outExprs
outExpr

where_ :: Expression 'NotNull Bool -> QueryClauses database ()
where_ :: forall database.
Expression 'NotNull Bool -> QueryClauses database ()
where_ Expression 'NotNull Bool
expr = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ do
  QueryBuilder
exprBuilder <- Expression 'NotNull Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression Expression 'NotNull Bool
expr
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> QueryClauses
H.where_ [QueryBuilder
exprBuilder]

groupBy_ :: [SomeExpression] -> QueryClauses database ()
groupBy_ :: forall database. [SomeExpression] -> QueryClauses database ()
groupBy_ [SomeExpression]
columns = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ do
  [QueryBuilder]
columnBuilders <- (SomeExpression -> QueryInner QueryBuilder)
-> [SomeExpression] -> StateT ClauseState Identity [QueryBuilder]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse SomeExpression -> QueryInner QueryBuilder
runSomeExpression [SomeExpression]
columns
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> QueryClauses
H.groupBy_ [QueryBuilder]
columnBuilders

having :: Expression nullable Bool -> QueryClauses database ()
having :: forall (nullable :: Nullable) database.
Expression nullable Bool -> QueryClauses database ()
having Expression nullable Bool
expr = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ do
  QueryBuilder
exprBuilder <- Expression nullable Bool -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression Expression nullable Bool
expr
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> QueryClauses
H.having [QueryBuilder
exprBuilder]

orderBy :: [QueryOrdering] -> QueryClauses database ()
orderBy :: forall database. [QueryOrdering] -> QueryClauses database ()
orderBy [QueryOrdering]
ordering = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$
  do [QueryOrdering]
newOrdering <- (QueryOrdering -> StateT ClauseState Identity QueryOrdering)
-> [QueryOrdering] -> StateT ClauseState Identity [QueryOrdering]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse QueryOrdering -> StateT ClauseState Identity QueryOrdering
orderingToH [QueryOrdering]
ordering
     QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryOrdering] -> QueryClauses
H.orderBy [QueryOrdering]
newOrdering
  where orderingToH :: QueryOrdering -> StateT ClauseState Identity QueryOrdering
orderingToH (Asc SomeExpression
x) = QueryBuilder -> QueryOrdering
H.Asc (QueryBuilder -> QueryOrdering)
-> QueryInner QueryBuilder
-> StateT ClauseState Identity QueryOrdering
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SomeExpression -> QueryInner QueryBuilder
runSomeExpression SomeExpression
x
        orderingToH (Desc SomeExpression
x) = QueryBuilder -> QueryOrdering
H.Desc (QueryBuilder -> QueryOrdering)
-> QueryInner QueryBuilder
-> StateT ClauseState Identity QueryOrdering
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SomeExpression -> QueryInner QueryBuilder
runSomeExpression SomeExpression
x

limit :: Int -> QueryClauses database ()
limit :: forall database. Int -> QueryClauses database ()
limit Int
count = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ Int -> QueryClauses
H.limit Int
count

limitOffset :: Int -> Int -> QueryClauses database ()
limitOffset :: forall database. Int -> Int -> QueryClauses database ()
limitOffset Int
count Int
offset = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> QueryClauses
H.limitOffset Int
count Int
offset

forUpdate :: [Table table database] -> H.WaitLock -> QueryClauses database ()
forUpdate :: forall (table :: Symbol) database.
[Table table database] -> WaitLock -> QueryClauses database ()
forUpdate [Table table database]
tables WaitLock
waitLock = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ do
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> WaitLock -> QueryClauses
H.forUpdate ((Table table database -> QueryBuilder)
-> [Table table database] -> [QueryBuilder]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder)
-> (Table table database -> Text)
-> Table table database
-> QueryBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Table table database -> Text
forall (table :: Symbol) database. Table table database -> Text
quotedTableName) [Table table database]
tables) WaitLock
waitLock

forShare :: [Table table database] -> H.WaitLock -> QueryClauses database ()
forShare :: forall (table :: Symbol) database.
[Table table database] -> WaitLock -> QueryClauses database ()
forShare [Table table database]
tables WaitLock
waitLock = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ do
  QueryClauses -> StateT ClauseState Identity ()
addClauses (QueryClauses -> StateT ClauseState Identity ())
-> QueryClauses -> StateT ClauseState Identity ()
forall a b. (a -> b) -> a -> b
$ [QueryBuilder] -> WaitLock -> QueryClauses
H.forShare ((Table table database -> QueryBuilder)
-> [Table table database] -> [QueryBuilder]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder)
-> (Table table database -> Text)
-> Table table database
-> QueryBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Table table database -> Text
forall (table :: Symbol) database. Table table database -> Text
quotedTableName) [Table table database]
tables) WaitLock
waitLock

shareMode :: QueryClauses database ()
shareMode :: forall database. QueryClauses database ()
shareMode = StateT ClauseState Identity () -> QueryClauses database ()
forall database a. QueryInner a -> QueryClauses database a
QueryClauses (StateT ClauseState Identity () -> QueryClauses database ())
-> StateT ClauseState Identity () -> QueryClauses database ()
forall a b. (a -> b) -> a -> b
$ QueryClauses -> StateT ClauseState Identity ()
addClauses QueryClauses
H.shareMode

newtype Into database (table :: Symbol) =
  Into { forall database (table :: Symbol).
Into database table -> QueryInner (Text, QueryBuilder)
runInto :: QueryInner (Text, H.QueryBuilder) }

exprInto :: Expression nullable a ->
            Field table database nullable a ->
            Into database table
exprInto :: forall (nullable :: Nullable) a (table :: Symbol) database.
Expression nullable a
-> Field table database nullable a -> Into database table
exprInto Expression nullable a
expr Field table database nullable a
field =
  QueryInner (Text, QueryBuilder) -> Into database table
forall database (table :: Symbol).
QueryInner (Text, QueryBuilder) -> Into database table
Into (QueryInner (Text, QueryBuilder) -> Into database table)
-> QueryInner (Text, QueryBuilder) -> Into database table
forall a b. (a -> b) -> a -> b
$ (Field table database nullable a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database nullable a
field,) (QueryBuilder -> (Text, QueryBuilder))
-> QueryInner QueryBuilder -> QueryInner (Text, QueryBuilder)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Expression nullable a -> QueryInner QueryBuilder
forall (nullable :: Nullable) a.
Expression nullable a -> QueryInner QueryBuilder
runExpression Expression nullable a
expr

insertSelect :: Table table database
             -> QueryClauses database [Into database table]
             -> H.Command
insertSelect :: forall (table :: Symbol) database.
Table table database
-> QueryClauses database [Into database table] -> Command
insertSelect Table table database
table (QueryClauses QueryInner [Into database table]
qry) =
  QueryBuilder
-> [QueryBuilder] -> [QueryBuilder] -> QueryClauses -> Command
H.insertSelect (Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table)
  (((Text, QueryBuilder) -> QueryBuilder)
-> [(Text, QueryBuilder)] -> [QueryBuilder]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder)
-> ((Text, QueryBuilder) -> Text)
-> (Text, QueryBuilder)
-> QueryBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, QueryBuilder) -> Text
forall a b. (a, b) -> a
fst) [(Text, QueryBuilder)]
intos)
  (((Text, QueryBuilder) -> QueryBuilder)
-> [(Text, QueryBuilder)] -> [QueryBuilder]
forall a b. (a -> b) -> [a] -> [b]
map (Text, QueryBuilder) -> QueryBuilder
forall a b. (a, b) -> b
snd [(Text, QueryBuilder)]
intos) QueryClauses
clauses
  where ([(Text, QueryBuilder)]
intos, ClauseState QueryClauses
clauses Map Text Int
_) =
          State ClauseState [(Text, QueryBuilder)]
-> ClauseState -> ([(Text, QueryBuilder)], ClauseState)
forall s a. State s a -> s -> (a, s)
runState (QueryInner [Into database table]
qry QueryInner [Into database table]
-> ([Into database table]
    -> State ClauseState [(Text, QueryBuilder)])
-> State ClauseState [(Text, QueryBuilder)]
forall a b.
StateT ClauseState Identity a
-> (a -> StateT ClauseState Identity b)
-> StateT ClauseState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Into database table -> QueryInner (Text, QueryBuilder))
-> [Into database table]
-> State ClauseState [(Text, QueryBuilder)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Into database table -> QueryInner (Text, QueryBuilder)
forall database (table :: Symbol).
Into database table -> QueryInner (Text, QueryBuilder)
runInto) ClauseState
emptyClauseState

infix 0 :=

data Updator table database =
  forall nullable a.
  Field table database nullable a := Expression nullable a

update :: Table table database
       -> (Alias table database 'InnerJoined ->
           QueryClauses database [Updator table database])
       -> H.Command
update :: forall (table :: Symbol) database.
Table table database
-> (Alias table database 'InnerJoined
    -> QueryClauses database [Updator table database])
-> Command
update Table table database
table Alias table database 'InnerJoined
-> QueryClauses database [Updator table database]
qry =
  [QueryBuilder]
-> [(QueryBuilder, QueryBuilder)] -> QueryClauses -> Command
H.update [Table table database -> QueryBuilder
forall (table :: Symbol) database.
Table table database -> QueryBuilder
tableSql Table table database
table] [(QueryBuilder, QueryBuilder)]
updators QueryClauses
clauses
  where QueryClauses QueryInner [Updator table database]
runQuery = Alias table database 'InnerJoined
-> QueryClauses database [Updator table database]
qry Alias table database 'InnerJoined
forall (table :: Symbol) database (leftJoined :: JoinType).
Alias table database leftJoined
emptyAlias
        ([(QueryBuilder, QueryBuilder)]
updators, ClauseState QueryClauses
clauses Map Text Int
_) =
          State ClauseState [(QueryBuilder, QueryBuilder)]
-> ClauseState -> ([(QueryBuilder, QueryBuilder)], ClauseState)
forall s a. State s a -> s -> (a, s)
runState (QueryInner [Updator table database]
runQuery QueryInner [Updator table database]
-> ([Updator table database]
    -> State ClauseState [(QueryBuilder, QueryBuilder)])
-> State ClauseState [(QueryBuilder, QueryBuilder)]
forall a b.
StateT ClauseState Identity a
-> (a -> StateT ClauseState Identity b)
-> StateT ClauseState Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Updator table database
 -> StateT ClauseState Identity (QueryBuilder, QueryBuilder))
-> [Updator table database]
-> State ClauseState [(QueryBuilder, QueryBuilder)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
forall (table :: Symbol) database.
Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
runUpdator) ClauseState
emptyClauseState
        runUpdator :: Updator table database
                   -> QueryInner (H.QueryBuilder, H.QueryBuilder)  
        runUpdator :: forall (table :: Symbol) database.
Updator table database
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
runUpdator (Field table database nullable a
field := Expression QueryInner QueryBuilder
expr) = do
          (Text -> QueryBuilder
H.rawSql (Text -> QueryBuilder) -> Text -> QueryBuilder
forall a b. (a -> b) -> a -> b
$ Field table database nullable a -> Text
forall (table :: Symbol) database (nullable :: Nullable) a.
Field table database nullable a -> Text
quotedFieldName Field table database nullable a
field, ) (QueryBuilder -> (QueryBuilder, QueryBuilder))
-> QueryInner QueryBuilder
-> StateT ClauseState Identity (QueryBuilder, QueryBuilder)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueryInner QueryBuilder
expr
          
          
        
          

{- TODO:

DML values:

values :: Insertable database a inExpres outExprs =>
  inExprs -> [a] -> Query database outExprs

specialized:

(Person -> Int, Person -> Maybe String) ->
  [Person] -> 
  Query database (Expression nullable Int, Expression 'Nullable String)

-}