module Hasql.Statement ( Statement, preparable, unpreparable, refineResult, toSql, -- * 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 = -- 'preparable' sql encoder decoder -- where -- sql = -- "insert into location (id, x, y) select * from unnest ($1, $2, $3)" -- encoder = -- Data.Vector.'Data.Vector.unzip3' '>$<' -- Contravariant.Extras.contrazip3 -- (Encoders.'Encoders.param' $ Encoders.'Encoders.nonNullable' $ Encoders.'Encoders.foldableArray' $ Encoders.'Encoders.nonNullable' Encoders.'Encoders.uuid') -- (Encoders.'Encoders.param' $ Encoders.'Encoders.nonNullable' $ Encoders.'Encoders.foldableArray' $ Encoders.'Encoders.nonNullable' Encoders.'Encoders.float8') -- (Encoders.'Encoders.param' $ Encoders.'Encoders.nonNullable' $ Encoders.'Encoders.foldableArray' $ Encoders.'Encoders.nonNullable' Encoders.'Encoders.float8') -- decoder = -- Decoders.'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 of @some_expression IN ($1)@ -- * Use @some_expression <> ALL($1)@ instead of @some_expression NOT IN ($1)@ -- -- For details refer to -- <https://www.postgresql.org/docs/9.6/static/functions-comparisons.html#AEN20944 the PostgreSQL docs>. ) where import Hasql.Engine.Statement