hpgsql
Safe HaskellNone
LanguageHaskell2010

Hpgsql.Pipeline

Description

Pipelines are a way to build a sequence of SQL statements that get sent in a single round-trip to PostgreSQL. This helps avoid latencies.

Here's an example:

f :: Int -> IO (Stream (Of Aeson.Value) IO ())
f val = do
  (updateTbl :: IO (), aggRes :: IO (Only Int), largeResults) <-
    runPipeline conn $
      (,,)
        <$> pipelineExec_ [sql|UPDATE tbl SET val=#{val}|]
        <*> pipeline1 [sql|SELECT SUM(val) FROM tbl|]
        <*> pipelineSWith
          (rowDecoder @(Vector Int, Vector Text))
          -- We use a prepared statement for the query below
          [sqlPrep|SELECT x, y FROM tbl|]
  updateTbl
  Only total <- aggRes
  Streaming.map Aeson.toJSON <$> largeResults

All the queries above are sent in a single round-trip and execute in order in the server.

For all pipeline usage, you must always:

  • Run the returned IO values in order.
  • Run the returned IO values in the same thread that called runPipeline. This also applies to consuming Streams.

Or else Hpgsql can deadlock or run into undefined behaviour.

Synopsis

Documentation

data Pipeline a Source #

Instances

Instances details
Applicative Pipeline Source # 
Instance details

Defined in Hpgsql.InternalTypes

Methods

pure :: a -> Pipeline a #

(<*>) :: Pipeline (a -> b) -> Pipeline a -> Pipeline b #

liftA2 :: (a -> b -> c) -> Pipeline a -> Pipeline b -> Pipeline c #

(*>) :: Pipeline a -> Pipeline b -> Pipeline b #

(<*) :: Pipeline a -> Pipeline b -> Pipeline a #

Functor Pipeline Source # 
Instance details

Defined in Hpgsql.InternalTypes

Methods

fmap :: (a -> b) -> Pipeline a -> Pipeline b #

(<$) :: a -> Pipeline b -> Pipeline a #

runPipeline :: HPgConnection -> Pipeline a -> IO a Source #

Runs a pipeline of statements, that is, sends multiple SQL statements in a single round-trip to the server.

Note on thread safety: the thread that runs this must be the thread that consumes the results of every query in the supplied pipeline _in order_, until all query results are consumed or an error occurs. Anything else is not officially supported by Hpgsql and may result in deadlocks or undefined behaviour.

pipelineS :: FromPgRow a => Query -> Pipeline (IO (Stream (Of a) IO ())) Source #

Fetches any number of rows by streaming them directly from the socket.

pipelineSWith :: RowDecoder a -> Query -> Pipeline (IO (Stream (Of a) IO ())) Source #

Fetches any number of rows by streaming them directly from the socket, with a custom row decoder.

pipelineSMWith :: RowDecoderMonadic a -> Query -> Pipeline (IO (Stream (Of a) IO ())) Source #

Prefer to use pipelineS and pipelineSWith, because RowDecoder can typecheck PostgreSQL results even when no rows are returned by queries, and RowDecoderMonadic cannot.

pipeline :: FromPgRow a => Query -> Pipeline (IO [a]) Source #

Fetches any number of rows from a query.

pipelineWith :: RowDecoder a -> Query -> Pipeline (IO [a]) Source #

Fetches any number of rows from a query with a custom row decoder.

pipelineExec :: Query -> Pipeline (IO Int64) Source #

Returns the count of affected rows of the given query.

pipeline1 :: FromPgRow a => Query -> Pipeline (IO a) Source #

Fetch exactly one row (not zero, not more than one) or throw an exception otherwise.

pipeline1With :: RowDecoder a -> Query -> Pipeline (IO a) Source #

Fetch exactly one row (not zero, not more than one) or throw an exception otherwise.