module Hasql.Interpolate
( -- * QuasiQuoters
sql,
Sql,
-- * Interpolators
interp,
interpFoldl,
interpWith,
-- * Decoders
DecodeValue (..),
DecodeField (..),
DecodeRow (..),
DecodeResult (..),
-- * Encoders
EncodeValue (..),
EncodeField,
-- * Newtypes for decoding/encoding
OneRow (..),
OneColumn (..),
RowsAffected (..),
Json (..),
Jsonb (..),
JsonBytes (..),
JsonbBytes (..),
AsJson (..),
AsJsonb (..),
CompositeValue (..),
-- * toTable
toTable,
EncodeRow (..),
)
where
import Control.Monad.Trans.State.Strict (evalState)
import Data.ByteString.Builder (toLazyByteString)
import Data.ByteString.Lazy (toStrict)
import Hasql.Decoders (Result, foldlRows)
import Hasql.Interpolate.Internal.CompositeValue
import Hasql.Interpolate.Internal.Decoder
import Hasql.Interpolate.Internal.EncodeRow
import Hasql.Interpolate.Internal.Encoder
import Hasql.Interpolate.Internal.Json
import Hasql.Interpolate.Internal.OneColumn
import Hasql.Interpolate.Internal.OneRow
import Hasql.Interpolate.Internal.RowsAffected
import Hasql.Interpolate.Internal.Sql
import Hasql.Interpolate.Internal.TH
import Hasql.Statement (Statement (..))
-- | Interpolate a 'Sql' into a 'Statement' using the 'DecodeResult'
-- type class to determine the appropriate decoder.
--
-- @
-- example :: Int64 -> Statement () [(Int64, Int64)]
-- example bonk = interp False [sql| select x, y from t where t.x > #{bonk} |]
-- @
interp ::
DecodeResult b =>
-- | 'True' if the 'Statement' should be prepared
Bool ->
Sql ->
Statement () b
interp prepared = interpWith prepared decodeResult
-- | interpolate then consume with 'foldlRows'
interpFoldl :: DecodeRow a => Bool -> (b -> a -> b) -> b -> Sql -> Statement () b
interpFoldl prepared f z = interpWith prepared (foldlRows f z decodeRow)
-- | A more general version of 'interp' that allows for passing an
-- explicit decoder.
interpWith :: Bool -> Result b -> Sql -> Statement () b
interpWith prepare decoder (Sql bldr enc) = Statement (toStrict (toLazyByteString (evalState bldr 1))) enc decoder prepare