module Hasql.Encoders.Params where

import qualified Database.PostgreSQL.LibPQ as A
import qualified Hasql.Encoders.Value as C
import qualified Hasql.PTI as D
import Hasql.Prelude
import qualified PostgreSQL.Binary.Encoding as B
import qualified Text.Builder as E

-- |
-- Encoder of some representation of a parameters product.
newtype Params a
  = Params (Op (DList (A.Oid, A.Format, Bool -> Maybe ByteString, Text)) a)
  deriving ((forall a' a. (a' -> a) -> Params a -> Params a')
-> (forall b a. b -> Params b -> Params a) -> Contravariant Params
forall b a. b -> Params b -> Params a
forall a' a. (a' -> a) -> Params a -> Params a'
forall (f :: * -> *).
(forall a' a. (a' -> a) -> f a -> f a')
-> (forall b a. b -> f b -> f a) -> Contravariant f
$ccontramap :: forall a' a. (a' -> a) -> Params a -> Params a'
contramap :: forall a' a. (a' -> a) -> Params a -> Params a'
$c>$ :: forall b a. b -> Params b -> Params a
>$ :: forall b a. b -> Params b -> Params a
Contravariant, Contravariant Params
Contravariant Params =>
(forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a)
-> (forall a. Params a) -> Divisible Params
forall a. Params a
forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
forall (f :: * -> *).
Contravariant f =>
(forall a b c. (a -> (b, c)) -> f b -> f c -> f a)
-> (forall a. f a) -> Divisible f
$cdivide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
divide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
$cconquer :: forall a. Params a
conquer :: forall a. Params a
Divisible, Divisible Params
Divisible Params =>
(forall a. (a -> Void) -> Params a)
-> (forall a b c.
    (a -> Either b c) -> Params b -> Params c -> Params a)
-> Decidable Params
forall a. (a -> Void) -> Params a
forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
forall (f :: * -> *).
Divisible f =>
(forall a. (a -> Void) -> f a)
-> (forall a b c. (a -> Either b c) -> f b -> f c -> f a)
-> Decidable f
$close :: forall a. (a -> Void) -> Params a
lose :: forall a. (a -> Void) -> Params a
$cchoose :: forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
choose :: forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
Decidable, NonEmpty (Params a) -> Params a
Params a -> Params a -> Params a
(Params a -> Params a -> Params a)
-> (NonEmpty (Params a) -> Params a)
-> (forall b. Integral b => b -> Params a -> Params a)
-> Semigroup (Params a)
forall b. Integral b => b -> Params a -> Params a
forall a. NonEmpty (Params a) -> Params a
forall a. Params a -> Params a -> Params a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> Params a -> Params a
$c<> :: forall a. Params a -> Params a -> Params a
<> :: Params a -> Params a -> Params a
$csconcat :: forall a. NonEmpty (Params a) -> Params a
sconcat :: NonEmpty (Params a) -> Params a
$cstimes :: forall a b. Integral b => b -> Params a -> Params a
stimes :: forall b. Integral b => b -> Params a -> Params a
Semigroup, Semigroup (Params a)
Params a
Semigroup (Params a) =>
Params a
-> (Params a -> Params a -> Params a)
-> ([Params a] -> Params a)
-> Monoid (Params a)
[Params a] -> Params a
Params a -> Params a -> Params a
forall a. Semigroup (Params a)
forall a. Params a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. [Params a] -> Params a
forall a. Params a -> Params a -> Params a
$cmempty :: forall a. Params a
mempty :: Params a
$cmappend :: forall a. Params a -> Params a -> Params a
mappend :: Params a -> Params a -> Params a
$cmconcat :: forall a. [Params a] -> Params a
mconcat :: [Params a] -> Params a
Monoid)

value :: C.Value a -> Params a
value :: forall a. Value a -> Params a
value =
  (a -> Maybe a) -> Params (Maybe a) -> Params a
forall a' a. (a' -> a) -> Params a -> Params a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap a -> Maybe a
forall a. a -> Maybe a
Just (Params (Maybe a) -> Params a)
-> (Value a -> Params (Maybe a)) -> Value a -> Params a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Value a -> Params (Maybe a)
forall a. Value a -> Params (Maybe a)
nullableValue

nullableValue :: C.Value a -> Params (Maybe a)
nullableValue :: forall a. Value a -> Params (Maybe a)
nullableValue (C.Value OID
valueOID OID
arrayOID Bool -> a -> Encoding
encode a -> Builder
render) =
  Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
-> Params (Maybe a)
forall a.
Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) a
-> Params a
Params
    (Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
 -> Params (Maybe a))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
-> Params (Maybe a)
forall a b. (a -> b) -> a -> b
$ (Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
forall a b. (b -> a) -> Op a b
Op
    ((Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
 -> Op
      (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a))
-> (Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Maybe a
input ->
      let D.OID Word32
_ Oid
pqOid Format
format =
            OID
valueOID
          encoder :: Bool -> Maybe ByteString
encoder Bool
env =
            (a -> ByteString) -> Maybe a -> Maybe ByteString
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Encoding -> ByteString
B.encodingBytes (Encoding -> ByteString) -> (a -> Encoding) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Bool -> a -> Encoding
encode Bool
env) Maybe a
input
          rendering :: Text
rendering =
            Text -> (a -> Text) -> Maybe a -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"null" (Builder -> Text
E.run (Builder -> Text) -> (a -> Builder) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> Builder
render) Maybe a
input
       in (Oid, Format, Bool -> Maybe ByteString, Text)
-> DList (Oid, Format, Bool -> Maybe ByteString, Text)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Oid
pqOid, Format
format, Bool -> Maybe ByteString
encoder, Text
rendering)