| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Hasql.Statement
Contents
Documentation
data Statement params result Source #
Specification of a strictly single-statement query, which can be parameterized and prepared. It encapsulates the mapping of parameters and results in association with an SQL template.
Following is an example of a declaration of a prepared statement with its associated codecs.
selectSum ::Statement(Int64, Int64) Int64 selectSum =Statementsql encoder decoder True where sql = "select ($1 + $2)" encoder = (fst>$<Encoders.param(Encoders.nonNullableEncoders.int8))<>(snd>$<Encoders.param(Encoders.nonNullableEncoders.int8)) decoder = Decoders.singleRow(Decoders.column(Decoders.nonNullableDecoders.int8))
The statement above accepts a product of two parameters of type Int64 and produces a single result of type Int64.
Constructors
| Statement | |
Fields
| |
Instances
| Profunctor Statement Source # | |
Defined in Hasql.Statement Methods dimap :: (a -> b) -> (c -> d) -> Statement b c -> Statement a d # lmap :: (a -> b) -> Statement b c -> Statement a c # rmap :: (b -> c) -> Statement a b -> Statement a c # (#.) :: forall a b c q. Coercible c b => q b c -> Statement a b -> Statement a c # (.#) :: forall a b c q. Coercible b a => Statement b c -> q a b -> Statement a c # | |
| Functor (Statement params) Source # | |
| Filterable (Statement params) Source # | |
refineResult :: (a -> Either Text b) -> Statement params a -> Statement params b Source #
Refine the result of a statement, causing the running session to fail with the UnexpectedResult error in case of a refinement failure.
This function is especially useful for refining the results of statements produced with the "hasql-th" library.
Recipes
Insert many
Starting from PostgreSQL 9.4 there is an unnest function which we can use in an analogous way to haskell's zip to pass in multiple arrays of values to be zipped into the rows to insert as in the following example:
insertMultipleLocations ::Statement(Vector (UUID, Double, Double)) () insertMultipleLocations =Statementsql encoder decoder True where sql = "insert into location (id, x, y) select * from unnest ($1, $2, $3)" encoder = Data.Vector.unzip3>$<Contravariant.Extras.contrazip3 (Encoders.param$ Encoders.nonNullable$ Encoders.foldableArray$ Encoders.nonNullableEncoders.uuid) (Encoders.param$ Encoders.nonNullable$ Encoders.foldableArray$ Encoders.nonNullableEncoders.float8) (Encoders.param$ Encoders.nonNullable$ Encoders.foldableArray$ Encoders.nonNullableEncoders.float8) decoder = Decoders.noResult
While this approach is much more efficient than executing a single-row insert-statement multiple times from within Session, a comparable performance can also be achieved by executing a single-insert statement from within a Pipeline.
IN and NOT IN
There is a common misconception that PostgreSQL supports array as the parameter for the IN operator. However Postgres only supports a syntactical list of values with it, i.e., you have to specify each option as an individual parameter. E.g., some_expression IN ($1, $2, $3).
Fortunately, Postgres does provide the expected functionality for arrays with other operators:
- Use
some_expression = ANY($1)instead ofsome_expression IN ($1) - Use
some_expression <> ALL($1)instead ofsome_expression NOT IN ($1)
For details refer to the PostgreSQL docs.