Safe Haskell | None |
---|---|
Language | Haskell2010 |
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
andstart
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
andwithRestart
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
- with :: (DB -> IO a) -> IO (Either StartError a)
- withConfig :: Config -> (DB -> IO a) -> IO (Either StartError a)
- start :: IO (Either StartError DB)
- startConfig :: Config -> IO (Either StartError DB)
- stop :: DB -> IO ()
- defaultConfig :: Config
- defaultPostgresConf :: [String] -> Config
- standardProcessConfig :: ProcessConfig
- optionsToDefaultConfig :: Options -> Config
- restart :: DB -> IO (Either StartError DB)
- stopPostgres :: DB -> IO ExitCode
- withRestart :: DB -> (DB -> IO a) -> IO (Either StartError a)
- reloadConfig :: DB -> IO ()
- data DB
- prettyPrintDB :: DB -> String
- toConnectionString :: DB -> ByteString
- toConnectionOptions :: DB -> Options
- toDataDirectory :: DB -> FilePath
- toTemporaryDirectory :: DB -> FilePath
- makeDataDirPermanent :: DB -> DB
- data Config = Config {}
- prettyPrintConfig :: Config -> String
- planL :: Lens' Config Plan
- socketClassL :: Lens' Config SocketClass
- dataDirectoryL :: Lens' Config DirectoryType
- portL :: Lens' Config (Last (Maybe Int))
- data Plan = Plan {}
- postgresConfigFileL :: Lens' Plan [String]
- createDbConfigL :: Lens' Plan (Maybe ProcessConfig)
- dataDirectoryStringL :: Lens' Plan (Last String)
- initDbConfigL :: Lens' Plan (Maybe ProcessConfig)
- partialPlanLoggerL :: Lens' Plan (Last Logger)
- postgresPlanL :: Lens' Plan PostgresPlan
- data PostgresPlan = PostgresPlan {}
- connectionOptionsL :: Lens' PostgresPlan Options
- postgresConfigL :: Lens' PostgresPlan ProcessConfig
- data ProcessConfig = ProcessConfig {}
- commandLineL :: Lens' ProcessConfig CommandLineArgs
- environmentVariablesL :: Lens' ProcessConfig EnvironmentVariables
- stdErrL :: Lens' ProcessConfig (Last Handle)
- stdInL :: Lens' ProcessConfig (Last Handle)
- stdOutL :: Lens' ProcessConfig (Last Handle)
- data EnvironmentVariables = EnvironmentVariables {}
- inheritL :: Lens' EnvironmentVariables (Last Bool)
- specificL :: Lens' EnvironmentVariables (Map String String)
- data CommandLineArgs = CommandLineArgs {}
- indexBasedL :: Lens' CommandLineArgs (Map Int String)
- keyBasedL :: Lens' CommandLineArgs (Map String (Maybe String))
- data DirectoryType
- data SocketClass
- type Logger = Event -> IO ()
- data Event
- data StartError
Exception safe interface
:: (DB -> IO a) |
|
-> IO (Either StartError a) |
Default expectation safe interface. Equivalent to
with
= withConfig'defaultConfig
:: Config |
|
-> (DB -> IO a) |
|
-> IO (Either StartError a) |
Exception safe database create with options. See startConfig
for more
details. Calls stop
even in the face of exceptions.
Separate start and stop interface.
start :: IO (Either StartError DB) Source #
Default start behavior. Equivalent to calling startConfig
with the
defaultConfig
:: Config |
|
-> 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
Returns a DB
that requires cleanup. startConfig
should be
used with a bracket
and stop
, e.g.
withConfig
::Config
-> (DB
-> IO a) -> IO (EitherStartError
a)withConfig
plan f =bracket
(startConfig
plan) (either memptystop
) $ either (pure . Left) (fmap Right . f)
or just use withConfig
. If you are calling startConfig
you
probably want withConfig
anyway.
Based on the value of socketClass
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.
Stop the postgres
process and cleanup any temporary resources 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 initDbConfig
to
pure
standardProcessConfig
and
postgresConfig
to standardProcessConfig
.
To append additional lines to "postgresql.conf" file create a
custom Config
like the following.
custom = defaultConfig <> mempty { plan = mempty { postgresConfigFile = [ "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 &planL
.postgresConfigFile
<>~ [ "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 { plan = mempty { postgresConfigFile = extra } }
standardProcessConfig :: ProcessConfig Source #
The standardProcessConfig
sets the handles to stdin
, stdout
and
stderr
and inherits the environment variables from the calling
process.
Custom Config builder helpers
Starting and Stopping postgres without removing the temporary directory
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
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
. See toConnectionString
for converting a DB
to
postgresql connection string.
DB
manipulation
toConnectionString :: DB -> ByteString Source #
Convert a DB
to a connection string. Alternatively one can access the
Options
using toConnectionOptions
toDataDirectory :: DB -> FilePath Source #
Access the data directory. This was either generated or
specified explicitly when creating the Config
toTemporaryDirectory :: DB -> FilePath Source #
Get the directory that is used to create other temporary directories
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 (fmapmakeDataDirPermanent
start
) (either memptystop
)
Monoidial Configuration Types
Config
The high level options for overriding default behavior.
Config | |
|
Instances
Generic Config Source # | |
Semigroup Config Source # | |
Monoid Config Source # | |
Pretty Config Source # | |
Defined in Database.Postgres.Temp.Internal.Config | |
type Rep Config Source # | |
Defined in Database.Postgres.Temp.Internal.Config type Rep Config = D1 (MetaData "Config" "Database.Postgres.Temp.Internal.Config" "tmp-postgres-1.9.0.1-FJ4HAodaX7XB3jorcEb9kM" False) (C1 (MetaCons "Config" PrefixI True) ((S1 (MetaSel (Just "plan") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Plan) :*: S1 (MetaSel (Just "socketClass") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 SocketClass)) :*: (S1 (MetaSel (Just "dataDirectory") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 DirectoryType) :*: (S1 (MetaSel (Just "port") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last (Maybe Int))) :*: S1 (MetaSel (Just "temporaryDirectory") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Last FilePath)))))) |
Config
Lenses
socketClassL :: Lens' Config SocketClass Source #
Lens for socketClass
dataDirectoryL :: Lens' Config DirectoryType Source #
Lens for dataDirectory
Plan
The monoidial version of CompletePlan
. Used to combine overrides with defaults
when creating a plan.
Instances
Plan
lenses
postgresConfigFileL :: Lens' Plan [String] Source #
Lens for postgresConfigFile
createDbConfigL :: Lens' Plan (Maybe ProcessConfig) Source #
Lens for createDbConfig
dataDirectoryStringL :: Lens' Plan (Last String) Source #
Lens for dataDirectoryString
initDbConfigL :: Lens' Plan (Maybe ProcessConfig) Source #
Lens for initDbConfig
postgresPlanL :: Lens' Plan PostgresPlan Source #
Lens for postgresPlan
PostgresPlan
data PostgresPlan Source #
postgres
process config and corresponding client connection
Options
.
PostgresPlan | |
|
Instances
PostgresPlan
lenses
connectionOptionsL :: Lens' PostgresPlan Options Source #
Lens for connectionOptions
postgresConfigL :: Lens' PostgresPlan ProcessConfig Source #
Lens for postgresConfig
ProcessConfig
data ProcessConfig Source #
The monoidial version of ProcessConfig
. Used to combine overrides with
defaults when creating a ProcessConfig
.
ProcessConfig | |
|
Instances
ProcessConfig
Lenses
commandLineL :: Lens' ProcessConfig CommandLineArgs Source #
Lens for commandLine
environmentVariablesL :: Lens' ProcessConfig EnvironmentVariables Source #
Lens for environmentVariables
EnvironmentVariables
data EnvironmentVariables Source #
The environment variables can be declared to inherit from the running process or they can be specifically added.
Instances
EnvironmentVariables
Lenses
CommandLineArgs
data CommandLineArgs Source #
A type to help combine command line Args.
Instances
CommandLineArgs
Lenses
indexBasedL :: Lens' CommandLineArgs (Map Int String) Source #
Lens for indexBased
DirectoryType
data DirectoryType Source #
The monoidial version of CompleteDirectoryType
. Used to combine overrides with
defaults when creating a CompleteDirectoryType
. The monoid instance treats
Temporary
as mempty
and takes the last Permanent
value.
Permanent FilePath | A permanent file that should not be generated. |
Temporary | A temporary file that needs to generated. |
Instances
SocketClass
data SocketClass Source #
The monoidial version of CompleteSocketClass
. Used to combine overrides with
defaults when creating a CompleteSocketClass
. The monoid instance treats
'UnixSocket mempty' as mempty
and combines the
IpSocket (Last String) | The monoid for combining IP address configuration |
UnixSocket DirectoryType | The monoid for combining UNIX socket configuration |
Instances
Logger
Internal events passed to the logger
.
Internal events for debugging
StartPlan String | The first event. This useful for debugging
what is actual passed to the |
StartPostgres | The second event. Postgres is about to get called |
WaitForDB | The third event. Postgres started. We are not 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 |
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.
StartPostgresFailed ExitCode |
|
InitDbFailed ExitCode |
|
CreateDbFailed ExitCode |
|
CompletePlanFailed String [String] | The |
Instances
Eq StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core (==) :: StartError -> StartError -> Bool # (/=) :: StartError -> StartError -> Bool # | |
Ord StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core compare :: StartError -> StartError -> Ordering # (<) :: StartError -> StartError -> Bool # (<=) :: StartError -> StartError -> Bool # (>) :: StartError -> StartError -> Bool # (>=) :: StartError -> StartError -> Bool # max :: StartError -> StartError -> StartError # min :: StartError -> StartError -> StartError # | |
Show StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core showsPrec :: Int -> StartError -> ShowS # show :: StartError -> String # showList :: [StartError] -> ShowS # | |
Exception StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core toException :: StartError -> SomeException # fromException :: SomeException -> Maybe StartError # displayException :: StartError -> String # |