HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduletmp-postgres-1.35.0.0Haskell2010

Database.Postgres.Temp

This module provides functions for creating a temporary postgres instance. By default it will create a temporary data directory and a temporary directory for a UNIX domain socket for postgres to listen on in addition to listening on 127.0.0.1 and ::1.

Here is an example using the expection safe with function:

with $ \db -> bracket
   (PG.connectPostgreSQL (toConnectionString db))
   PG.close $
   \conn -> PG.execute_ conn "CREATE TABLE foo (id int)"

To extend or override the defaults use withConfig (or startConfig).

tmp-postgres ultimately calls initdb (optionally), postgres and createdb (optionally).

All of the command line, environment variables and configuration files that are generated by default for the respective executables can be extended or overriden.

In general tmp-postgres is useful if you want a clean temporary postgres and do not want to worry about clashing with an existing postgres instance (or needing to ensure postgres is already running).

Here are some different use cases for tmp-postgres and their respective configurations:

  • The default with and start functions can be used to make a sandboxed temporary database for testing.

  • By disabling initdb one could run a temporary isolated postgres on a base backup to test a migration.

  • By using the stopPostgres and withRestart functions one can test backup strategies.

WARNING! Ubuntu's PostgreSQL installation does not put initdb on the PATH. We need to add it manually. The necessary binaries are in the /usr/lib/postgresql/VERSION/bin/ directory, and should be added to the PATH

echo "export PATH=$PATH:/usr/lib/postgresql/VERSION/bin/" >> /home/ubuntu/.bashrc
  • 14 types
  • 32 values

Start and Stop postgres

0 declarations

Exception safe interface

Configuration

Defaults

valuedefaultConfig :: Config
#

The default configuration. This will create a database called "postgres" via initdb (it's default behavior). It will create a temporary directory for the data and a temporary directory for a unix socket and listen on 127.0.0.1 and ::1 on a random port. Additionally it will use the following "postgresql.conf" which is optimized for performance.

shared_buffers = 12MB
fsync = off
synchronous_commit = off
full_page_writes = off
log_min_messages = PANIC
log_min_error_statement = PANIC
log_statement = none
client_min_messages = ERROR
commit_delay = 100000
wal_level = minimal
archive_mode = off
max_wal_senders = 0

defaultConfig also passes the --no-sync flag to initdb.

If you would like to customize this behavior you can start with the defaultConfig and overwrite fields or combine a defaultConfig with another Config using <> (mappend).

Alternatively you can eschew defaultConfig altogether, however your postgres might start and run faster if you use defaultConfig.

The defaultConfig redirects all output to /dev/null. See verboseConfig for a version that logs more output.

To append additional lines to "postgresql.conf" file create a custom Config like the following.

custom = defaultConfig <> mempty
  { postgresConfigFile =
      [ ("wal_level", "replica")
      , ("archive_mode", "on")
      , ("max_wal_senders", "2")
      , ("fsync", "on")
      , ("synchronous_commit", "on")
      ]
  }

As an alternative to using defaultConfig one could create a config from connections parameters using optionsToDefaultConfig.

Default configuration for PostgreSQL versions 9.3 and greater but less than 10.

If you get an error that "--no-sync" is an invalid parameter then you should use this config.

valueautoExplainConfig
  1. :: Int

    Minimum number of milliseconds to log. Use 0 to log all queries.

  2. -> Config
#

A config which loads and configures auto_explain. Useful for understanding slow queries plans.

Custom Config builder helpers

Attempt to create a Config from a Options. Useful if you want to create a database

  • owned by a specific user you will also login with

  • with a specific name (i.e. not the default name, "postgres")

among other use cases. Changing the connectionOptions field of Config does not achieve these results and you are likely to see unexpected behaviour if you try to.

Main resource handle

datadata DB
#

Handle for holding temporary resources, the postgres process handle and postgres connection information. The DB also includes the final plan used to start initdb, createdb and postgres.

Instances1Pretty
  • Pretty DBDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal

DB accessors

DB modifiers

DB debugging

Separate start and stop interface.

valuestartConfig
  1. :: Config

    extra configuration that is mappended last to the generated Config. generated <> extra.

  2. -> IO (Either StartError DB)
#

Create zero or more temporary resources and use them to make a Config.

The passed in config is inspected and a generated config is created. The final config is built by

generated <> extra

Based on the value of socketDirectory a "postgresql.conf" is created with:

listen_addresses = '127.0.0.1, ::1'
unix_socket_directories = 'SOCKET_DIRECTORY'

Additionally the generated Config also:

All of these values can be overrided by the extra config.

The returned DB requires cleanup. startConfig should be used with a bracket and stop, e.g.

withConfig :: Config -> (DB -> IO a) -> IO (Either StartError a)
withConfig plan f = bracket (startConfig plan) (either mempty stop) $
  either (pure . Left) (fmap Right . f)

or just use withConfig. If you are calling startConfig you probably want withConfig anyway.

valuestop :: DB -> IO ()
#

Stop the postgres process and cleanup any temporary resources that might have been created.

Faster Startup

2 declarations

with and related functions are fast by themselves but by utilizing various forms of caching we can make them much faster.

The slowest part of starting a new postgres cluster is the initdb call which initializes the database files. However for a given initdb version and configuration parameters the output is the same.

To take advantage of this idempotent behavior we can cache the output of initdb and copy the outputted database cluster files instead of recreating them. This leads to a 4x improvement in startup time.

See withDbCache and related functions for more details.

Additionally one can take snapshots of a database cluster and start new postgres instances using the snapshot as an initial database cluster.

This is useful if one has tests that require a time consuming migration process. By taking a snapshot after the migration we can start new isolated clusters from the point in time after the migration but before any test data has tainted the database.

See withSnapshot for details.

initdb cache configuration.

datadata CacheConfig
#

Configuration for the initdb data directory cache.

Constructors

initdb cache handle.

datadata Cache
#

A handle to cache temporary resources and configuration.

Instances3Generic, NFData, Rep

Separate start and stop interface.

Data Directory Snapshots

Exception safe interface

valuewithSnapshot :: DB -> (Snapshot -> IO a) -> IO (Either StartError a)
#

Exception safe method for taking a file system level copy of the database cluster.

Snapshots are useful if you would like to start every test from a migrated database and the migration process is more time consuming then copying the additional data.

Here is an example with caching and snapshots:

withDbCache $ \cache -> withConfig (cacheConfig cache) $ \db ->
  migrate db
  withSnapshot Temporary db $ \snapshot -> do
    withConfig (snapshotConfig db) $ \migratedDb -> ...
    withConfig (snapshotConfig db) $ \migratedDb -> ...
    withConfig (snapshotConfig db) $ \migratedDb -> ...

The Snapshots are ephemeral. If you would like the Snapshots to persistent consider using cacheAction instead.

Snapshot handle

newtypenewtype Snapshot
#

A type to track a possibly temporary snapshot directory

Instances3Generic, NFData, Rep

Separate start and stop interface.

Conditional caching of DB actions

valuecacheAction
  1. :: FilePath

    Location of the data directory cache.

  2. -> (DB -> IO ())

    action to cache.

  3. -> Config

    initial Config.

  4. -> IO (Either StartError Config)
#

Check to see if a cached data directory exists.

If the file path does not exist the initial config is used to start a postgres instance. After which the action is applied, the data directory is cached and postgres is shutdown.

cacheAction mappends a config to copy the cached data directory on startup onto the initial config and returns it. In other words:

initialConfig <> configFromCachePath

cacheAction can be used to create a snapshot of migrated database and not remigrate as long as the migration does not change. See withSnapshot for a ephemeral version of taking snapshots.

You can nest calls to cacheAction and safe to call it from several threads. However cacheAction uses locks internal to prevent multiple threads from stomping on each other.

If one makes a nested call and accidently uses the same cache directory in both calls the calls will deadlock. If this occurs on the same thread RTS will throw an exception. However do not rely on this and just be careful to not reuse the same cache path when nesting calls.

There is no good reuse the cache path when nesting so one is unlikely to run into this.

Errors

1 declaration
datadata StartError
#

A list of failures that can occur when starting. This is not and exhaustive list but covers the errors that the system catches for the user.

Constructors

Instances3Eq, Show, Exception
  • Eq StartErrorDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core
  • Show StartErrorDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core
  • Exception StartErrorDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core

Configuration Types

0 declarations

Config

datadata Config
#

The high level options for overriding default behavior.

Constructors

Instances5Generic, Semigroup, Monoid, Pretty, Rep

ProcessConfig

datadata ProcessConfig
#

Process configuration

Constructors

Instances7Eq, Show, Generic, Semigroup, Monoid, Pretty, …

EnvironmentVariables

datadata EnvironmentVariables
#

The environment variables can be declared to inherit from the running process or they can be specifically added.

Instances7Eq, Show, Generic, Semigroup, Monoid, Pretty, …

CommandLineArgs

datadata CommandLineArgs
#

A type to help combine command line Args.

Constructors

  • CommandLineArgs
    • keyBased :: Map String (Maybe String)

      Args of the form -h foo, --host=foo and --switch. The key is mappended with value so the key should include the space or equals (as shown in the first two examples respectively). The Dual monoid is used so the last key wins.

    • indexBased :: Map Int String

      Args that appear at the end of the key based Args. The Dual monoid is used so the last key wins.

Instances7Eq, Show, Generic, Semigroup, Monoid, Pretty, …

DirectoryType

datadata DirectoryType
#

Used to specify a Temporary folder that is automatically cleaned up or a Permanent folder which is not automatically cleaned up.

Constructors

Instances6Eq, Ord, Show, Semigroup, Monoid, Pretty

CompleteDirectoryType

A type to track whether a file is temporary and needs to be cleaned up.

Instances7Eq, Ord, Show, Generic, NFData, Pretty, …

Accum

datadata Accum a
#

Accum is a monoid.

It's <> behavior is analogous to 1 and 0 with *. Think of DontCare as 1 and Zlich as 0.

The behavior of Merge is like Justs.

Constructors

Instances7Functor, Applicative, Eq, Ord, Show, Semigroup, …
  • Functor AccumDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Applicative AccumDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Eq a => Eq (Accum a)Defined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Ord a => Ord (Accum a)Defined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Show a => Show (Accum a)Defined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Semigroup a => Semigroup (Accum a)Defined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config
  • Monoid a => Monoid (Accum a)Defined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Config

Logger

Internal events passed to the logger .

datadata Event
#

Internal events for debugging

Constructors

  • StartPlan String

    The first event. This useful for debugging what is actual passed to the initdb, createdb and postgres.

  • StartPostgres

    The second event. Postgres is about to get called

  • WaitForDB

    The third event. Postgres started. We are now about to setup a reconnect loop (racing with a process checker)

  • TryToConnect

    The fourth event and (possibly all subsequent events). We are looping trying to successfully connect to the postgres process.

Instances3Eq, Ord, Show
  • Eq EventDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core
  • Ord EventDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core
  • Show EventDefined in tmp-postgres-1.35.0.0 · Database.Postgres.Temp.Internal.Core