module Hasql.Private.Encoders.Params where

import qualified Database.PostgreSQL.LibPQ as A
import qualified Hasql.Private.Encoders.Value as C
import qualified Hasql.Private.PTI as D
import Hasql.Private.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 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
>$ :: forall b a. b -> Params b -> Params a
$c>$ :: forall b a. b -> Params b -> Params a
contramap :: forall a' a. (a' -> a) -> Params a -> Params a'
$ccontramap :: forall a' a. (a' -> a) -> Params a -> Params a'
Contravariant, Contravariant 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
conquer :: forall a. Params a
$cconquer :: forall a. Params a
divide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
$cdivide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
Divisible, Divisible 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
choose :: forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
$cchoose :: forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
lose :: forall a. (a -> Void) -> Params a
$close :: forall a. (a -> Void) -> Params a
Decidable, NonEmpty (Params a) -> Params a
Params a -> Params a -> 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
stimes :: forall b. Integral b => b -> Params a -> Params a
$cstimes :: forall a b. Integral b => b -> Params a -> Params a
sconcat :: NonEmpty (Params a) -> Params a
$csconcat :: forall a. NonEmpty (Params a) -> Params a
<> :: Params a -> Params a -> Params a
$c<> :: forall a. Params a -> Params a -> Params a
Semigroup, 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
mconcat :: [Params a] -> Params a
$cmconcat :: forall a. [Params a] -> Params a
mappend :: Params a -> Params a -> Params a
$cmappend :: forall a. Params a -> Params a -> Params a
mempty :: Params a
$cmempty :: forall a. Params a
Monoid)

value :: C.Value a -> Params a
value :: forall a. Value a -> Params a
value =
  forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. 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) =
  forall a.
Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) a
-> Params a
Params forall a b. (a -> b) -> a -> b
$
    forall a b. (b -> a) -> Op a b
Op 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 =
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Encoding -> ByteString
B.encodingBytes 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 =
            forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"null" (Builder -> Text
E.run 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 forall (f :: * -> *) a. Applicative f => a -> f a
pure (Oid
pqOid, Format
format, Bool -> Maybe ByteString
encoder, Text
rendering)