module Hasql.Codecs.Encoders.Params where

import Data.HashMap.Strict qualified as HashMap
import Data.HashSet qualified as HashSet
import Hasql.Codecs.Encoders.NullableOrNot qualified as NullableOrNot
import Hasql.Codecs.Encoders.Value qualified as Value
import Hasql.Platform.Prelude
import PostgreSQL.Binary.Encoding qualified as Binary
import TextBuilder qualified

renderReadable :: Params a -> a -> [Text]
renderReadable :: forall a. Params a -> a -> [Text]
renderReadable (Params Int
_ HashSet (Maybe Text, Text)
_ DList (Either (Maybe Text, Text) Word32, Word, Bool)
_ HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
_ a -> DList Text
printer) a
params =
  a -> DList Text
printer a
params
    DList Text -> (DList Text -> [Text]) -> [Text]
forall a b. a -> (a -> b) -> b
& DList Text -> [Text]
DList Text -> [Item (DList Text)]
forall l. IsList l => l -> [Item l]
toList

compilePreparedStatementData ::
  Params a ->
  HashMap (Maybe Text, Text) (Word32, Word32) ->
  a ->
  ([Word32], [Maybe (ByteString, Bool)])
compilePreparedStatementData :: forall a.
Params a
-> HashMap (Maybe Text, Text) (Word32, Word32)
-> a
-> ([Word32], [Maybe (ByteString, Bool)])
compilePreparedStatementData (Params Int
_ HashSet (Maybe Text, Text)
_ DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer a -> DList Text
_) HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input =
  ([Word32]
oidList, [Maybe (ByteString, Bool)]
valueAndFormatList)
  where
    ([Word32]
oidList, [Bool]
formatList) =
      DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata
        DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> (DList (Either (Maybe Text, Text) Word32, Word, Bool)
    -> [(Either (Maybe Text, Text) Word32, Word, Bool)])
-> [(Either (Maybe Text, Text) Word32, Word, Bool)]
forall a b. a -> (a -> b) -> b
& DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> [(Either (Maybe Text, Text) Word32, Word, Bool)]
DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> [Item (DList (Either (Maybe Text, Text) Word32, Word, Bool))]
forall l. IsList l => l -> [Item l]
toList
        [(Either (Maybe Text, Text) Word32, Word, Bool)]
-> ([(Either (Maybe Text, Text) Word32, Word, Bool)]
    -> [(Word32, Bool)])
-> [(Word32, Bool)]
forall a b. a -> (a -> b) -> b
& ((Either (Maybe Text, Text) Word32, Word, Bool) -> (Word32, Bool))
-> [(Either (Maybe Text, Text) Word32, Word, Bool)]
-> [(Word32, Bool)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
          ( \case
              (Left (Maybe Text, Text)
name, Word
dimensionality, Bool
format) ->
                case (Maybe Text, Text)
-> HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe (Word32, Word32)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Maybe Text, Text)
name HashMap (Maybe Text, Text) (Word32, Word32)
oidCache of
                  Just (Word32
baseOid, Word32
arrayOid) ->
                    ( if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Word32
baseOid else Word32
arrayOid,
                      Bool
format
                    )
                  Maybe (Word32, Word32)
Nothing ->
                    (Word32
0, Bool
format)
              (Right Word32
oid, Word
_, Bool
format) ->
                (Word32
oid, Bool
format)
          )
        [(Word32, Bool)]
-> ([(Word32, Bool)] -> ([Word32], [Bool])) -> ([Word32], [Bool])
forall a b. a -> (a -> b) -> b
& [(Word32, Bool)] -> ([Word32], [Bool])
forall a b. [(a, b)] -> ([a], [b])
unzip

    valueAndFormatList :: [Maybe (ByteString, Bool)]
valueAndFormatList =
      HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input
        DList (Maybe ByteString)
-> (DList (Maybe ByteString) -> [Maybe ByteString])
-> [Maybe ByteString]
forall a b. a -> (a -> b) -> b
& DList (Maybe ByteString) -> [Maybe ByteString]
DList (Maybe ByteString) -> [Item (DList (Maybe ByteString))]
forall l. IsList l => l -> [Item l]
toList
        [Maybe ByteString]
-> ([Maybe ByteString] -> [Maybe (ByteString, Bool)])
-> [Maybe (ByteString, Bool)]
forall a b. a -> (a -> b) -> b
& (Bool -> Maybe ByteString -> Maybe (ByteString, Bool))
-> [Bool] -> [Maybe ByteString] -> [Maybe (ByteString, Bool)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Bool
format Maybe ByteString
encoding -> (,Bool
format) (ByteString -> (ByteString, Bool))
-> Maybe ByteString -> Maybe (ByteString, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
encoding) [Bool]
formatList

compileUnpreparedStatementData ::
  Params a ->
  HashMap (Maybe Text, Text) (Word32, Word32) ->
  a ->
  [Maybe (Word32, ByteString, Bool)]
compileUnpreparedStatementData :: forall a.
Params a
-> HashMap (Maybe Text, Text) (Word32, Word32)
-> a
-> [Maybe (Word32, ByteString, Bool)]
compileUnpreparedStatementData (Params Int
_ HashSet (Maybe Text, Text)
_ DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer a -> DList Text
_) HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input =
  ((Either (Maybe Text, Text) Word32, Word, Bool)
 -> Maybe ByteString -> Maybe (Word32, ByteString, Bool))
-> [(Either (Maybe Text, Text) Word32, Word, Bool)]
-> [Maybe ByteString]
-> [Maybe (Word32, ByteString, Bool)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
    ( \(Either (Maybe Text, Text) Word32
nameOrOid, Word
dimensionality, Bool
format) Maybe ByteString
encoding ->
        let oid :: Word32
oid = case Either (Maybe Text, Text) Word32
nameOrOid of
              Left (Maybe Text, Text)
name -> case (Maybe Text, Text)
-> HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe (Word32, Word32)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Maybe Text, Text)
name HashMap (Maybe Text, Text) (Word32, Word32)
oidCache of
                Just (Word32
baseOid, Word32
arrayOid) ->
                  if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Word32
baseOid else Word32
arrayOid
                Maybe (Word32, Word32)
Nothing -> Word32
0
              Right Word32
oid -> Word32
oid
         in (,,) (Word32 -> ByteString -> Bool -> (Word32, ByteString, Bool))
-> Maybe Word32
-> Maybe (ByteString -> Bool -> (Word32, ByteString, Bool))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word32 -> Maybe Word32
forall a. a -> Maybe a
Just Word32
oid Maybe (ByteString -> Bool -> (Word32, ByteString, Bool))
-> Maybe ByteString -> Maybe (Bool -> (Word32, ByteString, Bool))
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe ByteString
encoding Maybe (Bool -> (Word32, ByteString, Bool))
-> Maybe Bool -> Maybe (Word32, ByteString, Bool)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
format
    )
    (DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> [Item (DList (Either (Maybe Text, Text) Word32, Word, Bool))]
forall l. IsList l => l -> [Item l]
toList DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata)
    (DList (Maybe ByteString) -> [Item (DList (Maybe ByteString))]
forall l. IsList l => l -> [Item l]
toList (HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input))

toUnknownTypes :: Params a -> HashSet (Maybe Text, Text)
toUnknownTypes :: forall a. Params a -> HashSet (Maybe Text, Text)
toUnknownTypes (Params Int
_ HashSet (Maybe Text, Text)
unknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
_ HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
_ a -> DList Text
_) =
  HashSet (Maybe Text, Text)
unknownTypes

-- |
-- Encoder of some representation of a parameters product.
--
-- Has instances of 'Contravariant', 'Divisible' and 'Monoid',
-- which you can use to compose multiple parameters together.
-- E.g.,
--
-- @
-- someParamsEncoder :: 'Params' (Int64, Maybe Text)
-- someParamsEncoder =
--   ('fst' '>$<' 'param' ('nonNullable' 'int8')) '<>'
--   ('snd' '>$<' 'param' ('nullable' 'text'))
-- @
--
-- As a general solution for tuples of any arity, instead of 'fst' and 'snd',
-- consider the functions of the @contrazip@ family
-- from the \"contravariant-extras\" package.
-- E.g., here's how you can achieve the same as the above:
--
-- @
-- someParamsEncoder :: 'Params' (Int64, Maybe Text)
-- someParamsEncoder =
--   'contrazip2' ('param' ('nonNullable' 'int8')) ('param' ('nullable' 'text'))
-- @
--
-- Here's how you can implement encoders for custom composite types:
--
-- @
-- data Person = Person { name :: Text, gender :: Gender, age :: Int }
--
-- data Gender = Male | Female
--
-- personParams :: 'Params' Person
-- personParams =
--   (name '>$<' 'param' ('nonNullable' 'text')) '<>'
--   (gender '>$<' 'param' ('nonNullable' genderValue)) '<>'
--   ('fromIntegral' . age '>$<' 'param' ('nonNullable' 'int8'))
--
-- genderValue :: 'Value.Value' Gender
-- genderValue = 'enum' Nothing (Just "gender") genderText where
--   genderText gender = case gender of
--     Male -> "male"
--     Female -> "female"
-- @
data Params a = Params
  { forall a. Params a -> Int
size :: Int,
    forall a. Params a -> HashSet (Maybe Text, Text)
unknownTypes :: HashSet (Maybe Text, Text),
    -- | (Name or OID, dimensionality, Text Format) for each parameter.
    forall a.
Params a -> DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool),
    forall a.
Params a
-> HashMap (Maybe Text, Text) (Word32, Word32)
-> a
-> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32) -> a -> DList (Maybe ByteString),
    forall a. Params a -> a -> DList Text
printer :: a -> DList Text
  }

instance Contravariant Params where
  contramap :: forall a' a. (a' -> a) -> Params a -> Params a'
contramap a' -> a
fn (Params Int
size HashSet (Maybe Text, Text)
unknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
oldSerializer a -> DList Text
oldPrinter) = Params {Int
DList (Either (Maybe Text, Text) Word32, Word, Bool)
HashSet (Maybe Text, Text)
a' -> DList Text
HashMap (Maybe Text, Text) (Word32, Word32)
-> a' -> DList (Maybe ByteString)
size :: Int
unknownTypes :: HashSet (Maybe Text, Text)
columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a' -> DList (Maybe ByteString)
printer :: a' -> DList Text
size :: Int
unknownTypes :: HashSet (Maybe Text, Text)
columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a' -> DList (Maybe ByteString)
printer :: a' -> DList Text
..}
    where
      serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a' -> DList (Maybe ByteString)
serializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache = HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
oldSerializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache (a -> DList (Maybe ByteString))
-> (a' -> a) -> a' -> DList (Maybe 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
. a' -> a
fn
      printer :: a' -> DList Text
printer = a -> DList Text
oldPrinter (a -> DList Text) -> (a' -> a) -> a' -> DList 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' -> a
fn

instance Divisible Params where
  divide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
divide
    a -> (b, c)
divisor
    (Params Int
leftSize HashSet (Maybe Text, Text)
leftUnknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
leftColumnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> b -> DList (Maybe ByteString)
leftSerializer b -> DList Text
leftPrinter)
    (Params Int
rightSize HashSet (Maybe Text, Text)
rightUnknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
rightColumnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> c -> DList (Maybe ByteString)
rightSerializer c -> DList Text
rightPrinter) =
      Params
        { size :: Int
size = Int
leftSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rightSize,
          unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes = HashSet (Maybe Text, Text)
leftUnknownTypes HashSet (Maybe Text, Text)
-> HashSet (Maybe Text, Text) -> HashSet (Maybe Text, Text)
forall a. Semigroup a => a -> a -> a
<> HashSet (Maybe Text, Text)
rightUnknownTypes,
          columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = DList (Either (Maybe Text, Text) Word32, Word, Bool)
leftColumnsMetadata DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. Semigroup a => a -> a -> a
<> DList (Either (Maybe Text, Text) Word32, Word, Bool)
rightColumnsMetadata,
          serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer = \HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input -> case a -> (b, c)
divisor a
input of
            (b
leftInput, c
rightInput) -> HashMap (Maybe Text, Text) (Word32, Word32)
-> b -> DList (Maybe ByteString)
leftSerializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache b
leftInput DList (Maybe ByteString)
-> DList (Maybe ByteString) -> DList (Maybe ByteString)
forall a. Semigroup a => a -> a -> a
<> HashMap (Maybe Text, Text) (Word32, Word32)
-> c -> DList (Maybe ByteString)
rightSerializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache c
rightInput,
          printer :: a -> DList Text
printer = \a
input -> case a -> (b, c)
divisor a
input of
            (b
leftInput, c
rightInput) -> b -> DList Text
leftPrinter b
leftInput DList Text -> DList Text -> DList Text
forall a. Semigroup a => a -> a -> a
<> c -> DList Text
rightPrinter c
rightInput
        }
  conquer :: forall a. Params a
conquer =
    Params
      { size :: Int
size = Int
0,
        unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes = HashSet (Maybe Text, Text)
forall a. Monoid a => a
mempty,
        columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. Monoid a => a
mempty,
        serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer = HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
forall a. Monoid a => a
mempty,
        printer :: a -> DList Text
printer = a -> DList Text
forall a. Monoid a => a
mempty
      }

instance Semigroup (Params a) where
  Params Int
leftSize HashSet (Maybe Text, Text)
leftUnknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
leftColumnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
leftSerializer a -> DList Text
leftPrinter <> :: Params a -> Params a -> Params a
<> Params Int
rightSize HashSet (Maybe Text, Text)
rightUnknownTypes DList (Either (Maybe Text, Text) Word32, Word, Bool)
rightColumnsMetadata HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
rightSerializer a -> DList Text
rightPrinter =
    Params
      { size :: Int
size = Int
leftSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rightSize,
        unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes = HashSet (Maybe Text, Text)
leftUnknownTypes HashSet (Maybe Text, Text)
-> HashSet (Maybe Text, Text) -> HashSet (Maybe Text, Text)
forall a. Semigroup a => a -> a -> a
<> HashSet (Maybe Text, Text)
rightUnknownTypes,
        columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = DList (Either (Maybe Text, Text) Word32, Word, Bool)
leftColumnsMetadata DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. Semigroup a => a -> a -> a
<> DList (Either (Maybe Text, Text) Word32, Word, Bool)
rightColumnsMetadata,
        serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer = \HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input -> HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
leftSerializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input DList (Maybe ByteString)
-> DList (Maybe ByteString) -> DList (Maybe ByteString)
forall a. Semigroup a => a -> a -> a
<> HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
rightSerializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache a
input,
        printer :: a -> DList Text
printer = \a
input -> a -> DList Text
leftPrinter a
input DList Text -> DList Text -> DList Text
forall a. Semigroup a => a -> a -> a
<> a -> DList Text
rightPrinter a
input
      }

instance Monoid (Params a) where
  mempty :: Params a
mempty = Params a
forall a. Params a
forall (f :: * -> *) a. Divisible f => f a
conquer

value :: Value.Value a -> Params a
value :: forall a. Value a -> Params a
value (Value.Value Maybe Text
schemaName Text
typeName Maybe Word32
scalarOid Maybe Word32
arrayOid Word
dimensionality Bool
textFormat HashSet (Maybe Text, Text)
unknownTypes HashMap (Maybe Text, Text) (Word32, Word32) -> a -> Encoding
serialize a -> TextBuilder
print) =
  let staticOid :: Maybe Word32
staticOid = if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Maybe Word32
scalarOid else Maybe Word32
arrayOid
      serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache = Maybe ByteString -> DList (Maybe ByteString)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ByteString -> DList (Maybe ByteString))
-> (a -> Maybe ByteString) -> a -> DList (Maybe 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
. ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> (a -> ByteString) -> a -> Maybe 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
. Encoding -> ByteString
Binary.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
. HashMap (Maybe Text, Text) (Word32, Word32) -> a -> Encoding
serialize HashMap (Maybe Text, Text) (Word32, Word32)
oidCache
      printer :: a -> DList Text
printer = Text -> DList Text
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> DList Text) -> (a -> Text) -> a -> DList 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
. TextBuilder -> Text
TextBuilder.toText (TextBuilder -> Text) -> (a -> TextBuilder) -> 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 -> TextBuilder
print
      size :: a
size = a
1
   in case Maybe Word32
staticOid of
        Just Word32
oid ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              HashSet (Maybe Text, Text)
unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes,
              columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word32 -> Either (Maybe Text, Text) Word32
forall a b. b -> Either a b
Right Word32
oid, Word
dimensionality, Bool
textFormat),
              HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer,
              a -> DList Text
printer :: a -> DList Text
printer :: a -> DList Text
printer
            }
        Maybe Word32
Nothing ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes = (Maybe Text, Text)
-> HashSet (Maybe Text, Text) -> HashSet (Maybe Text, Text)
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
HashSet.insert (Maybe Text
schemaName, Text
typeName) HashSet (Maybe Text, Text)
unknownTypes,
              columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Maybe Text, Text) -> Either (Maybe Text, Text) Word32
forall a b. a -> Either a b
Left (Maybe Text
schemaName, Text
typeName), Word
dimensionality, Bool
textFormat),
              HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> a -> DList (Maybe ByteString)
serializer,
              a -> DList Text
printer :: a -> DList Text
printer :: a -> DList Text
printer
            }

nullableValue :: Value.Value a -> Params (Maybe a)
nullableValue :: forall a. Value a -> Params (Maybe a)
nullableValue (Value.Value Maybe Text
schemaName Text
typeName Maybe Word32
scalarOid Maybe Word32
arrayOid Word
dimensionality Bool
textFormat HashSet (Maybe Text, Text)
unknownTypes HashMap (Maybe Text, Text) (Word32, Word32) -> a -> Encoding
serialize a -> TextBuilder
print) =
  let staticOid :: Maybe Word32
staticOid = if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Maybe Word32
scalarOid else Maybe Word32
arrayOid
      serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer HashMap (Maybe Text, Text) (Word32, Word32)
oidCache = Maybe ByteString -> DList (Maybe ByteString)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ByteString -> DList (Maybe ByteString))
-> (Maybe a -> Maybe ByteString)
-> Maybe a
-> DList (Maybe 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
. (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
Binary.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
. HashMap (Maybe Text, Text) (Word32, Word32) -> a -> Encoding
serialize HashMap (Maybe Text, Text) (Word32, Word32)
oidCache)
      printer :: Maybe a -> DList Text
printer = Text -> DList Text
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> DList Text) -> (Maybe a -> Text) -> Maybe a -> DList 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
. Text -> (a -> Text) -> Maybe a -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"null" (TextBuilder -> Text
TextBuilder.toText (TextBuilder -> Text) -> (a -> TextBuilder) -> 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 -> TextBuilder
print)
      size :: a
size = a
1
   in case Maybe Word32
staticOid of
        Just Word32
oid ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              HashSet (Maybe Text, Text)
unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes,
              columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Word32 -> Either (Maybe Text, Text) Word32
forall a b. b -> Either a b
Right Word32
oid, Word
dimensionality, Bool
textFormat),
              HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer,
              Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer
            }
        Maybe Word32
Nothing ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              unknownTypes :: HashSet (Maybe Text, Text)
unknownTypes = (Maybe Text, Text)
-> HashSet (Maybe Text, Text) -> HashSet (Maybe Text, Text)
forall a. (Eq a, Hashable a) => a -> HashSet a -> HashSet a
HashSet.insert (Maybe Text
schemaName, Text
typeName) HashSet (Maybe Text, Text)
unknownTypes,
              columnsMetadata :: DList (Either (Maybe Text, Text) Word32, Word, Bool)
columnsMetadata = (Either (Maybe Text, Text) Word32, Word, Bool)
-> DList (Either (Maybe Text, Text) Word32, Word, Bool)
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Maybe Text, Text) -> Either (Maybe Text, Text) Word32
forall a b. a -> Either a b
Left (Maybe Text
schemaName, Text
typeName), Word
dimensionality, Bool
textFormat),
              HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer :: HashMap (Maybe Text, Text) (Word32, Word32)
-> Maybe a -> DList (Maybe ByteString)
serializer,
              Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer
            }

-- |
-- No parameters. Same as `mempty` and `conquered`.
noParams :: Params ()
noParams :: Params ()
noParams = Params ()
forall a. Monoid a => a
mempty

-- |
-- Lift a single parameter encoder, with its nullability specified,
-- associating it with a single placeholder.
param :: NullableOrNot.NullableOrNot Value.Value a -> Params a
param :: forall a. NullableOrNot Value a -> Params a
param = \case
  NullableOrNot.NonNullable Value a
valueEnc -> Value a -> Params a
forall a. Value a -> Params a
value Value a
valueEnc
  NullableOrNot.Nullable Value a1
valueEnc -> Value a1 -> Params (Maybe a1)
forall a. Value a -> Params (Maybe a)
nullableValue Value a1
valueEnc