hasql-0.19.18: An efficient PostgreSQL driver and a flexible mapping API

Safe Haskell | None
Language | Haskell2010

Hasql.Encoders

Contents

- Params
- Value
- Array

Description

A DSL for declaration of query parameter encoders.

Synopsis

- data Params a
- unit :: Params ()
- value :: Value a -> Params a
- nullableValue :: Value a -> Params (Maybe a)
- data Value a
- bool :: Value Bool
- int2 :: Value Int16
- int4 :: Value Int32
- int8 :: Value Int64
- float4 :: Value Float
- float8 :: Value Double
- numeric :: Value Scientific
- char :: Value Char
- text :: Value Text
- bytea :: Value ByteString
- date :: Value Day
- timestamp :: Value LocalTime
- timestamptz :: Value UTCTime
- time :: Value TimeOfDay
- timetz :: Value (TimeOfDay, TimeZone)
- interval :: Value DiffTime
- uuid :: Value UUID
- inet :: Value (NetAddr IP)
- json :: Value Value
- jsonBytes :: Value ByteString
- jsonb :: Value Value
- jsonbBytes :: Value ByteString
- array :: Array a -> Value a
- enum :: (a -> Text) -> Value a
- unknown :: Value ByteString
- data Array a
- arrayValue :: Value a -> Array a
- arrayNullableValue :: Value a -> Array (Maybe a)
- arrayDimension :: (forall a. (a -> b -> a) -> a -> c -> a) -> Array b -> Array c

# Params

data Params a #

Encoder of some representation of the 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 =
      contramap fst (value int8) <>
      contramap snd (nullableValue 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 (value int8) (nullableValue 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 =
      contramap name (value text) <>
      contramap gender (value genderValue) <>
      contramap (fromIntegral . age) (value int8)

    genderValue :: Value Gender
    genderValue =
      contramap genderText text
      where
        genderText gender =
          case gender of
            Male -> "male"
            Female -> "female"

Instances

Divisible Params # |
Methods divide :: (a -> (b, c)) -> Params b -> Params c -> Params a # conquer :: Params a #
Decidable Params # |
Methods lose :: (a -> Void) -> Params a # choose :: (a -> Either b c) -> Params b -> Params c -> Params a #
Contravariant Params # |
Methods contramap :: (a -> b) -> Params b -> Params a # (>$) :: b -> Params b -> Params a #
Semigroup (Params a) # |
Methods (<>) :: Params a -> Params a -> Params a # sconcat :: NonEmpty (Params a) -> Params a # stimes :: Integral b => b -> Params a -> Params a #
Monoid (Params a) # |
Methods mempty :: Params a # mappend :: Params a -> Params a -> Params a # mconcat :: [Params a] -> Params a #
Default (Params ()) # | Maps to `unit`.
Methods def :: Params () #
(Default (Value a1), Default (Value a2)) => Default (Params (a1, a2)) # |
Methods def :: Params (a1, a2) #
(Default (Value a1), Default (Value a2), Default (Value a3)) => Default (Params (a1, a2, a3)) # |
Methods def :: Params (a1, a2, a3) #
(Default (Value a1), Default (Value a2), Default (Value a3), Default (Value a4)) => Default (Params (a1, a2, a3, a4)) # |
Methods def :: Params (a1, a2, a3, a4) #
(Default (Value a1), Default (Value a2), Default (Value a3), Default (Value a4), Default (Value a5)) => Default (Params (a1, a2, a3, a4, a5)) # |
Methods def :: Params (a1, a2, a3, a4, a5) #
Default (Value a) => Default (Params (Identity a)) # |
Methods def :: Params (Identity a) #

unit :: Params () #

Encode no parameters.

value :: Value a -> Params a #

Lift an individual value encoder to a parameters encoder.

nullableValue :: Value a -> Params (Maybe a) #

Lift an individual nullable value encoder to a parameters encoder.

# Value

data Value a #

An individual value encoder. Will be mapped to a single placeholder in the query.

Instances

Contravariant Value # |
Methods contramap :: (a -> b) -> Value b -> Value a # (>$) :: b -> Value b -> Value a #
Default (Value Bool) # | Maps to `bool`.
Methods def :: Value Bool #
Default (Value Char) # | Maps to `char`.
Methods def :: Value Char #
Default (Value Double) # | Maps to `float8`.
Methods def :: Value Double #
Default (Value Float) # | Maps to `float4`.
Methods def :: Value Float #
Default (Value Int16) # | Maps to `int2`.
Methods def :: Value Int16 #
Default (Value Int32) # | Maps to `int4`.
Methods def :: Value Int32 #
Default (Value Int64) # | Maps to `int8`.
Methods def :: Value Int64 #
Default (Value (TimeOfDay, TimeZone)) # | Maps to `timetz`.
Methods def :: Value (TimeOfDay, TimeZone) #
Default (Value ByteString) # | Maps to `bytea`.
Methods def :: Value ByteString #
Default (Value Scientific) # | Maps to `numeric`.
Methods def :: Value Scientific #
Default (Value Text) # | Maps to `text`.
Methods def :: Value Text #
Default (Value UTCTime) # | Maps to `timestamptz`.
Methods def :: Value UTCTime #
Default (Value Value) # | Maps to `json`.
Methods def :: Value Value #
Default (Value UUID) # | Maps to `uuid`.
Methods def :: Value UUID #
Default (Value DiffTime) # | Maps to `interval`.
Methods def :: Value DiffTime #
Default (Value Day) # | Maps to `date`.
Methods def :: Value Day #
Default (Value TimeOfDay) # | Maps to `time`.
Methods def :: Value TimeOfDay #
Default (Value LocalTime) # | Maps to `timestamp`.
Methods def :: Value LocalTime #

bool :: Value Bool #

Encoder of `BOOL` values.

int2 :: Value Int16 #

Encoder of `INT2` values.

int4 :: Value Int32 #

Encoder of `INT4` values.

int8 :: Value Int64 #

Encoder of `INT8` values.

float4 :: Value Float #

Encoder of `FLOAT4` values.

float8 :: Value Double #

Encoder of `FLOAT8` values.

numeric :: Value Scientific #

Encoder of `NUMERIC` values.

char :: Value Char #

Encoder of `CHAR` values. Note that it supports UTF-8 values and identifies itself under the `TEXT` OID because of that.

text :: Value Text #

Encoder of `TEXT` values.

bytea :: Value ByteString #

Encoder of `BYTEA` values.

date :: Value Day #

Encoder of `DATE` values.

timestamp :: Value LocalTime #

Encoder of `TIMESTAMP` values.

timestamptz :: Value UTCTime #

Encoder of `TIMESTAMPTZ` values.

time :: Value TimeOfDay #

Encoder of `TIME` values.

timetz :: Value (TimeOfDay, TimeZone) #

Encoder of `TIMETZ` values.

interval :: Value DiffTime #

Encoder of `INTERVAL` values.

uuid :: Value UUID #

Encoder of `UUID` values.

inet :: Value (NetAddr IP) #

Encoder of `INET` values.

json :: Value Value #

Encoder of `JSON` values from JSON AST.

jsonBytes :: Value ByteString #

Encoder of `JSON` values from raw JSON.

jsonb :: Value Value #

Encoder of `JSONB` values from JSON AST.

jsonbBytes :: Value ByteString #

Encoder of `JSONB` values from raw JSON.

array :: Array a -> Value a #

Unlifts the `Array` encoder to the plain `Value` encoder.

enum :: (a -> Text) -> Value a #

Given a function, which maps the value into the textual enum label from the DB side, produces a encoder of that value.

unknown :: Value ByteString #

Identifies the value with the PostgreSQL's "unknown" type, thus leaving it up to Postgres to infer the actual type of the value.

The bytestring needs to be encoded according to the Postgres' binary format of the type it expects.

Essentially this is a low-level hook for encoding of values with custom codecs. The "postgresql-binary" library will provide you with the toolchain.

# Array

data Array a #

A generic array encoder.

Here's an example of its usage:

    x :: Value [[Int64]]
    x =
      array (arrayDimension foldl' (arrayDimension foldl' (arrayValue int8)))

Please note that the PostgreSQL IN keyword does not "accept" an array, but rather a syntactical list of values, thus this encoder is not suited for that. Use a **field** = ANY($1) query instead.

arrayValue :: Value a -> Array a #

Lifts the `Value` encoder into the `Array` encoder of a non-nullable value.

arrayNullableValue :: Value a -> Array (Maybe a) #

Lifts the `Value` encoder into the `Array` encoder of a nullable value.

arrayDimension :: (forall a. (a -> b -> a) -> a -> c -> a) -> Array b -> Array c #

An encoder of an array dimension, which thus provides support for multidimensional arrays.

Accepts:

- An implementation of the left-fold operation, such as `Data.Foldable.`foldl'``, which determines the input value.
- A component encoder, which can be either another `arrayDimension`, `arrayValue` or `arrayNullableValue`.