bluefin-postgresql: bluefin support for mid-level PostgreSQL operations.

[ bsd3, database, library ] [ Propose Tags ] [ Report a vulnerability ]

See the README for an overview, or the documentation in Bluefin.PostgreSQL.


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
enable-otel

Enable OpenTelemetry instrumentation support using hs-opentelemetry-instrumentation-postgresql-simple.

Disabled
Automatic Flags
NameDescriptionDefault
enable-pool

Enable support for connection pools using unliftio-pool. You can disable this for a lighter dependency footprint if you don't need support for connection pools.

Enabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.1.0.0, 0.2.0.0
Change log CHANGELOG.md
Dependencies base (>=4 && <5), bluefin (>=0.2.7 && <0.11), postgresql-simple (>=0.7 && <0.8), unliftio-pool (>=0.4.1 && <0.5) [details]
Tested with ghc ==9.0.2, ghc ==9.2.4, ghc ==9.2.8, ghc ==9.4.5, ghc ==9.6.1, ghc ==9.6.7, ghc ==9.8.2, ghc ==9.10.2
License BSD-3-Clause
Copyright Copyright(c) Frederick Pringle 2025
Author Frederick Pringle
Maintainer frederick.pringle@fpringle.com
Uploaded by fpringle at 2026-09-22T15:26:15Z
Category Database
Home page https://github.com/fpringle/bluefin-postgresql
Distributions
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 22 total (3 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for bluefin-postgresql-0.2.0.0

[back to package description]

bluefin-postgresql

This package provides bluefin effects for postgresql-simple's Connection type.

It defines:

  • a dynamic WithConnection effect to allow effectful functions to use a Connection, without worrying about where that Connection comes from.
  • a dynamic PostgreSQL effect ro run database operations from postgresql-simple.

For a higher-level effect library using Opaleye, see bluefin-opaleye.

Effectful functions

In the WithConnection effect we can always request a Connection and use it as we normally would:

import Bluefin.PostgreSQL as BP
import qualified Database.PostgreSQL.Simple as PSQL

insertAndList ::
  (e :> es, e1 :> es) =>
  WithConnection e ->
  IOE e1 ->
  Eff es [User]
insertAndList wc ioe = BP.withConnection wc $ \conn -> do
  effIO ioe $ PSQL.execute conn "insert into users (first_name) values (?)" ["Nuala"]
  effIO ioe $ PSQL.query conn "select * from users where first_name in ?" $ PSQL.Only $ PSQL.In ["Anna", "Boris", "Carla"]

The PostgreSQL effect lets us completely forget about Connection and rewrite the above to:


import Bluefin.PostgreSQL

insertAndList ::
  (e :> es) =>
  PostgreSQL e ->
  Eff es [User]
insertAndList psql = do
  BP.execute psql "insert into users (first_name) values (?)" ["Nuala"]
  BP.query psql "select * from users where first_name in ?" $ PSQL.Only $ PSQL.In ["Anna", "Boris", "Carla"]

The same goes for other functions:

-- use a transaction
insertAndListCarefully ::
  (e :> es) =>
  PostgreSQL e ->
  Eff es [User]
insertAndListCarefully psql = BP.withTransaction psql $ insertAndList psql

-- stream + fold over results (in Eff)
countUsersIneffeciently ::
  (e :> es, e1 :> es) =>
  PostgreSQL e ->
  IOE e1 ->
  Eff es Int
countUsersIneffeciently psql ioe =
  BP.fold_ psql "select * from users" 0 $ \acc (row :: User) -> do
    effIO ioe . putStrLn $ "User: " <> show row
    pure $ acc + 1

Interpreters

In order to discharge the PostgreSQL effect we use the WithConnection effect:

dischargePostgreSQL :: (e :> es, e1 :> es) => WithConnection e -> IOE e1 -> Eff es [User]
dischargePostgreSQL withConn ioe =
  runPostgreSQL withConn ioe $ \psql -> insertAndListCarefully psql

Alternatively we can use the OpenTelemetry support provided by hs-opentelemetry-instrumentation-postgresql-simple (note that this requires enabling the enable-opentel cabal flag):

dischargePostgreSQLUsingOpenTelemetry :: (e :> es, e1 :> es) => WithConnection e -> IOE e1 -> Eff es [User]
dischargePostgreSQLUsingOpenTelemetry withConn ioe =
  runPostgreSQLOT withConn ioe $ \psql -> insertAndListCarefully psql

The simplest way of running the WithConnection effect is by just providing a Connection, which we can get in the normal ways:

import Bluefin.PostgreSQL as BP
import qualified Database.PostgreSQL.Simple as PSQL

usingConnection :: IO ()
usingConnection =
  runEff $ \ioe ->
    bracket (effIO ioe $ PSQL.connectPostgreSQL "") (effIO ioe . PSQL.close) $ \conn ->
      BP.runWithConnection conn $ \wc -> 
        BP.runPostgreSQL wc ioe $ \psql -> 
          insertAndListCarefully wc ioe >>= effIO ioe . print

usingConnectInfo :: IO ()
usingConnectInfo =
  runEff $ \ioe ->
    BP.runWithConnectInfo ioe PSQL.defaultConnectInfo $ \wc ->
      BP.runPostgreSQL wc ioe $ \psql -> 
        insertAndListCarefully psql >>= effIO ioe . print

Alternatively, we can use a connection pool (from resource-pool and unliftio-pool), which is much better suited to long-running processes like servers.

import Bluefin.PostgreSQL as BP
import qualified Database.PostgreSQL.Simple as PSQL
import qualified UnliftIO.Pool as P

usingConnectionPool :: IO ()
usingConnectionPool = do
  poolCfg <- P.mkDefaultPoolConfig (PSQL.connectPostgreSQL "") PSQL.close 5.0 10
  pool <- P.newPool poolCfg
  runEff $ \ioe ->
    BP.runWithConnectionPool ioe pool $ \wc ->
      insertAndListCarefully wc ioe >>= effIO ioe . print