tmp-postgres-1.7.1.0: Start and stop a temporary postgres

Safe HaskellNone
LanguageHaskell2010

Database.Postgres.Temp

Contents

Description

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.

Here is an example using the expection safe with function:

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

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

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

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

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
Synopsis

Exception safe interface

with Source #

Arguments

:: (DB -> IO a)

action continuation.

-> IO (Either StartError a) 

Default expectation safe interface. Equivalent to withConfig the defaultConfig

withConfig Source #

Arguments

:: Config

extraConfiguration. Combined with the generated Config. See startConfig for more info

-> (DB -> IO a)

action continuation

-> IO (Either StartError a) 

Exception safe default database create. Takes an action continuation which is given a DB it can use to connect to (see toConnectionString or postgresProcessClientOptions). All of the database resources are automatically cleaned up on completion even in the face of exceptions. Based on the value of configSocket a "postgresql.conf" is created with

  listen_addresses = 'IP_ADDRESS'

if it is IpSocket. If is UnixSocket then the lines

  listen_addresses = ''
  unix_socket_directories = SOCKET_DIRECTORY

are added. This occurs as a side effect of calling withConfig.

Separate start and stop interface.

start :: IO (Either StartError DB) Source #

Default start behavior. Equivalent to calling startConfig with the defaultConfig

startConfig Source #

Arguments

:: Config

extraConfiguration that is mappended to the generated Config. The extra config is mappended second, e.g. generatedConfig <> extraConfiguration

-> IO (Either StartError DB) 

Create temporary resources and use them to make a Config. The generated Config is combined with the passed in extraConfiguration to create a Plan that is used to create a database. The output DB includes references to the temporary resources for cleanup and the final plan that was used to generate the database and processes

stop :: DB -> IO () Source #

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

defaultConfig :: Config Source #

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 on a random port. Additionally it will use append the following onto the "postgresql.conf" which is optimized for performance.

   shared_buffers = 12MB
   fsync = off
   synchronous_commit = off
   full_page_writes = off
   log_min_duration_statement = 0
   log_connections = on
   log_disconnections = on
   client_min_messages = ERROR

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.

defaultConfig also sets the partialPlanInitDb to pure standardProcessConfig and partialPostgresPlanProcessConfig to standardProcessConfig.

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

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

Or using the provided lenses and your favorite lens library

 custom = defaultConfig & configPlanL . partialPlanConfigL <>~
   [ "wal_level = replica"
   , "archive_mode = on"
   , "max_wal_senders = 2"
   , "fsync = on"
   , "synchronous_commit = on"
   ]

This is common enough there is defaultPostgresConf which is a helper to do this.

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

defaultPostgresConf :: [String] -> Config Source #

mappend the defaultConfig with a Config that provides additional "postgresql.conf" lines. Equivalent to

defaultPostgresConf extra = defaultConfig <> mempty
  { configPlan = mempty
    { partialPlanConfig = extra
    }
  }

standardProcessConfig :: PartialProcessConfig Source #

The standardProcessConfig sets the handles to stdin, stdout and stderr and inherits the environment variables from the calling process.

Custom Config builder helpers

optionsToDefaultConfig :: Options -> Config Source #

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 among other use cases.

Starting and Stopping postgres without removing the temporary directory

restart :: DB -> IO (Either StartError DB) Source #

Restart the postgres using the Plan from the DB (e.g. resourcesPlan . dbResources)

stopPostgres :: DB -> IO ExitCode Source #

Only stop the postgres process but leave any temporary resources. Useful for testing backup strategies when used in conjunction with restart or withRestart.

withRestart :: DB -> (DB -> IO a) -> IO (Either StartError a) Source #

Exception safe version of restart

Reloading the config

reloadConfig :: DB -> IO () Source #

Reload the configuration file without shutting down. Calls pg_reload_conf().

Main resource handle

data DB Source #

Handle for holding temporary resources, the postgres process handle and postgres connection information. The DB also includes the final Plan that was used to start initdb, createdb and postgres. See toConnectionString for converting a DB to postgresql connection string.

Instances
Pretty DB Source # 
Instance details

Defined in Database.Postgres.Temp.Internal

Methods

pretty :: DB -> Doc #

prettyList :: [DB] -> Doc #

DB manipulation

prettyPrintDB :: DB -> String Source #

Display a DB

toConnectionString :: DB -> ByteString Source #

Convert a DB to a connection string. Alternatively one can access the Options using toConnectionOptions

toConnectionOptions :: DB -> Options Source #

Convert a DB to a connection Options type.

toDataDirectory :: DB -> FilePath Source #

Access the data directory. This was either generated or specified explicitly when creating the Config

makeDataDirPermanent :: DB -> DB Source #

Make the data directory permanent. Useful for debugging. If you are using with or withConfig this function will not modify the DB that is passed for cleanup. You will need to setup your own bracket like

   bracket (fmap makeDataDirPermanent start) (either mempty stop)

Monoidial Configuration Types

Config

data Config Source #

The high level options for overriding default behavior.

Constructors

Config 

Fields

Instances
Generic Config Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep Config :: Type -> Type #

Methods

from :: Config -> Rep Config x #

to :: Rep Config x -> Config #

Semigroup Config Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid Config Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty Config Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Methods

pretty :: Config -> Doc #

prettyList :: [Config] -> Doc #

type Rep Config Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep Config = D1 (MetaData "Config" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "Config" PrefixI True) ((S1 (MetaSel (Just "configPlan") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialPlan) :*: S1 (MetaSel (Just "configSocket") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialSocketClass)) :*: (S1 (MetaSel (Just "configDataDir") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialDirectoryType) :*: S1 (MetaSel (Just "configPort") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last (Maybe Int))))))

Config Lenses

PartialPlan

data PartialPlan Source #

The monoidial version of Plan. Used to combine overrides with defaults when creating a plan.

Instances
Generic PartialPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialPlan :: Type -> Type #

Semigroup PartialPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialPlan = D1 (MetaData "PartialPlan" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PartialPlan" PrefixI True) ((S1 (MetaSel (Just "partialPlanLogger") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last Logger)) :*: (S1 (MetaSel (Just "partialPlanInitDb") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe PartialProcessConfig)) :*: S1 (MetaSel (Just "partialPlanCreateDb") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe PartialProcessConfig)))) :*: (S1 (MetaSel (Just "partialPlanPostgres") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialPostgresPlan) :*: (S1 (MetaSel (Just "partialPlanConfig") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [String]) :*: S1 (MetaSel (Just "partialPlanDataDirectory") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last String))))))

PartialPlan lenses

PartialPostgresPlan

data PartialPostgresPlan Source #

postgres process config and corresponding client connection Options.

Constructors

PartialPostgresPlan 

Fields

Instances
Generic PartialPostgresPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialPostgresPlan :: Type -> Type #

Semigroup PartialPostgresPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialPostgresPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialPostgresPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialPostgresPlan Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialPostgresPlan = D1 (MetaData "PartialPostgresPlan" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PartialPostgresPlan" PrefixI True) (S1 (MetaSel (Just "partialPostgresPlanProcessConfig") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialProcessConfig) :*: S1 (MetaSel (Just "partialPostgresPlanClientConfig") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Options)))

PartialPostgresPlan lenses

PartialProcessConfig

data PartialProcessConfig Source #

The monoidial version of ProcessConfig. Used to combine overrides with defaults when creating a ProcessConfig.

Constructors

PartialProcessConfig 

Fields

Instances
Eq PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Show PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Generic PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialProcessConfig :: Type -> Type #

Semigroup PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialProcessConfig Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialProcessConfig = D1 (MetaData "PartialProcessConfig" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PartialProcessConfig" PrefixI True) ((S1 (MetaSel (Just "partialProcessConfigEnvVars") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialEnvVars) :*: S1 (MetaSel (Just "partialProcessConfigCmdLine") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialCommandLineArgs)) :*: (S1 (MetaSel (Just "partialProcessConfigStdIn") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last Handle)) :*: (S1 (MetaSel (Just "partialProcessConfigStdOut") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last Handle)) :*: S1 (MetaSel (Just "partialProcessConfigStdErr") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last Handle))))))

PartialProcessConfig Lenses

PartialEnvVars

data PartialEnvVars Source #

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

Instances
Eq PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Show PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Generic PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialEnvVars :: Type -> Type #

Semigroup PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialEnvVars Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialEnvVars = D1 (MetaData "PartialEnvVars" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PartialEnvVars" PrefixI True) (S1 (MetaSel (Just "partialEnvVarsInherit") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last Bool)) :*: S1 (MetaSel (Just "partialEnvVarsSpecific") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Map String String))))

PartialEnvVars Lenses

PartialCommandLineArgs

data PartialCommandLineArgs Source #

A type to help combine command line arguments.

Constructors

PartialCommandLineArgs 

Fields

Instances
Eq PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Show PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Generic PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialCommandLineArgs :: Type -> Type #

Semigroup PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialCommandLineArgs Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialCommandLineArgs = D1 (MetaData "PartialCommandLineArgs" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PartialCommandLineArgs" PrefixI True) (S1 (MetaSel (Just "partialCommandLineArgsKeyBased") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Map String (Maybe String))) :*: S1 (MetaSel (Just "partialCommandLineArgsIndexBased") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Map Int String))))

PartialCommandLineArgs Lenses

PartialDirectoryType

data PartialDirectoryType Source #

The monoidial version of DirectoryType. Used to combine overrides with defaults when creating a DirectoryType. The monoid instance treats PTemporary as mempty and takes the last PPermanent value.

Constructors

PPermanent FilePath

A permanent file that should not be generated.

PTemporary

A temporary file that needs to generated.

Instances
Eq PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Ord PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Show PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Semigroup PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialDirectoryType Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

PartialSocketClass

data PartialSocketClass Source #

The monoidial version of SocketClass. Used to combine overrides with defaults when creating a SocketClass. The monoid instance treats 'PUnixSocket mempty' as mempty and combines the

Constructors

PIpSocket (Last String)

The monoid for combining IP address configuration

PUnixSocket PartialDirectoryType

The monoid for combining UNIX socket configuration

Instances
Eq PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Ord PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Show PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Generic PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Associated Types

type Rep PartialSocketClass :: Type -> Type #

Semigroup PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Monoid PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

Pretty PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialSocketClass Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Partial

type Rep PartialSocketClass = D1 (MetaData "PartialSocketClass" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.1.0-Fl2f8QVtDW2J2btYcu2iIC" False) (C1 (MetaCons "PIpSocket" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last String))) :+: C1 (MetaCons "PUnixSocket" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PartialDirectoryType)))

Logger

type Logger = Event -> IO () Source #

A way to log internal Events

Internal events passed to the partialPlanLogger .

data Event Source #

Internal events for debugging

Instances
Eq Event Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Core

Methods

(==) :: Event -> Event -> Bool #

(/=) :: Event -> Event -> Bool #

Ord Event Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Core

Methods

compare :: Event -> Event -> Ordering #

(<) :: Event -> Event -> Bool #

(<=) :: Event -> Event -> Bool #

(>) :: Event -> Event -> Bool #

(>=) :: Event -> Event -> Bool #

max :: Event -> Event -> Event #

min :: Event -> Event -> Event #

Show Event Source # 
Instance details

Defined in Database.Postgres.Temp.Internal.Core

Methods

showsPrec :: Int -> Event -> ShowS #

show :: Event -> String #

showList :: [Event] -> ShowS #

Errors

data StartError Source #

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

StartPostgresFailed ExitCode

postgres failed before a connection succeeded. Most likely this is due to invalid configuration

InitDbFailed ExitCode

initdb failed. This can be from invalid configuration or using a non-empty data directory

CreateDbFailed ExitCode

createdb failed. This can be from invalid configuration or the database might already exist.

CompletePlanFailed String [String]

The PartialPlan was missing info and a complete Plan could not be created.