| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
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(toConnectionStringdb))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
withandstartfunctions can be used to make a sandboxed temporary database for testing. - By disabling
initdbone could run a temporary isolated postgres on a base backup to test a migration. - By using the
stopPostgresandwithRestartfunctions 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)
- withRestart :: DB -> (DB -> IO a) -> IO (Either StartError a)
- withNewDb :: DB -> (DB -> IO a) -> IO (Either StartError a)
- withNewDbConfig :: ProcessConfig -> DB -> (DB -> IO a) -> IO (Either StartError a)
- start :: IO (Either StartError DB)
- startConfig :: Config -> IO (Either StartError DB)
- stop :: DB -> IO ()
- restart :: DB -> IO (Either StartError DB)
- stopPostgres :: DB -> IO ExitCode
- startNewDb :: DB -> IO (Either StartError DB)
- startNewDbConfig :: ProcessConfig -> DB -> IO (Either StartError DB)
- stopNewDb :: DB -> IO ()
- data DB
- toConnectionString :: DB -> ByteString
- toConnectionOptions :: DB -> Options
- toDataDirectory :: DB -> FilePath
- toTemporaryDirectory :: DB -> FilePath
- makeDataDirPermanent :: DB -> DB
- reloadConfig :: DB -> IO ()
- prettyPrintDB :: DB -> String
- data StartError
- defaultConfig :: Config
- defaultPostgresConf :: [String] -> Config
- standardProcessConfig :: ProcessConfig
- silentConfig :: Config
- silentProcessConfig :: ProcessConfig
- optionsToDefaultConfig :: Options -> Config
- module Database.Postgres.Temp.Config
Exception safe interface
Arguments
| :: (DB -> IO a) |
|
| -> IO (Either StartError a) |
Arguments
| :: 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.
Since: 1.12.0.0
withRestart :: DB -> (DB -> IO a) -> IO (Either StartError a) Source #
Exception safe version of restart.
Since: 1.12.0.0
Arguments
| :: DB | The original |
| -> (DB -> IO a) | The modified |
| -> IO (Either StartError a) |
Use the current database as a template and make a copy. Give the copy a random name.
Equivalent to:
withNewDb=withNewDbConfigmempty
See startNewDbConfig for more details.
Since: 1.12.0.0
Arguments
| :: ProcessConfig |
|
| -> DB | The original |
| -> (DB -> IO a) | The modified |
| -> IO (Either StartError a) |
Exception safe version of startNewDbConfig. Creates a
temporary database using the current database as a template.
See startNewDbConfig for more details.
Since: 1.12.0.0
Separate start and stop interface.
start :: IO (Either StartError DB) Source #
Default start behavior. Equivalent to calling startConfig with the
defaultConfig.
Since: 1.12.0.0
Arguments
| :: 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
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.
Additionally the generated Config also does the following:
- Sets a
connectionTimeoutof one minute. - Logs internal
Events. - Sets the processes to use the standard input and output handles.
- Sets the
dataDirectoryStringto file path generated fromdataDirectory.
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 (EitherStartErrora)withConfigplan f =bracket(startConfigplan) (either memptystop) $ either (pure . Left) (fmap Right . f)
or just use withConfig. If you are calling startConfig you
probably want withConfig anyway.
Since: 1.12.0.0
Stop the postgres process and cleanup any temporary resources that
might have been created.
Since: 1.12.0.0
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.
Since: 1.12.0.0
Arguments
| :: DB | The original |
| -> IO (Either StartError DB) |
Use the current database as a template and make a copy. Give the copy a random name.
Equivalent to:
startNewDb=startNewDbConfigmempty
See startNewDbConfig for more details.
Since: 1.13.0.0
Arguments
| :: ProcessConfig |
|
| -> DB | The original |
| -> IO (Either StartError DB) |
Use the current database as a template and make a copy. Give the copy a random name.
Copying a database from a template can be faster than creating a new
postgres and migrating a database from scratch. In artifical benchmarks
it appears to be about 2x faster.
To use the current database as a template all connections to the database must be terminated first.
To override the arguments passed to createdb one can pass in extra
ProcessConfig. The combined process is created by mappended the
generated with the extra ProcessConfig, e.g.
combined = generated <> extra
The current implementation has a few known issues.
If a connection is made between the termination command and the createdb
call the createdb call will fail.
Additionally the generated name is 32 character random name of characters "a" to "z". It is possible, although unlikeily that a duplicate database name could be generated and this would also cause a failure.
startNewDbConfig requires cleanup so it best to use a bracket along
with stopNewDb. This is equivalient to withNewDbConfig.
The only reason to use startNewDbConfig over withNewDbConfig is
if you are unable to use withNewDbConfig for some reason.
Since: 1.13.0.0
stopNewDb :: DB -> IO () Source #
Cleanup the temporary database created by startNewDbConfig
or startNewDb.
Since: 1.13.0.0
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 or toConnectionOptions
for converting a DB to postgresql connection string.
Since: 1.12.0.0
DB accessors
toConnectionString :: DB -> ByteString Source #
Convert a DB to a connection string. Alternatively one can access the
Options using toConnectionOptions.
Since: 1.12.0.0
toConnectionOptions :: DB -> Options Source #
toDataDirectory :: DB -> FilePath Source #
Access the data directory. This was either generated or
specified explicitly when creating the Config
Since: 1.12.0.0
toTemporaryDirectory :: DB -> FilePath Source #
Get the directory that is used to create other temporary directories
Since: 1.12.0.0
DB modifiers
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 (fmapmakeDataDirPermanentstart) (either memptystop)
Since: 1.12.0.0
reloadConfig :: DB -> IO () Source #
Reload the configuration file without shutting down. Calls
pg_reload_conf().
Since: 1.12.0.0
DB debugging
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.
Since: 1.12.0.0
Constructors
| StartPostgresFailed ExitCode |
|
| InitDbFailed |
|
Fields | |
| CreateDbFailed |
|
Fields | |
| CompletePlanFailed String [String] | The |
| CompleteProcessConfigFailed String [String] | The |
| ConnectionTimedOut | Timed out waiting for |
| DeleteDbError SqlError | |
Instances
| Eq StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core | |
| Show StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core Methods showsPrec :: Int -> StartError -> ShowS # show :: StartError -> String # showList :: [StartError] -> ShowS # | |
| Exception StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core Methods toException :: StartError -> SomeException # fromException :: SomeException -> Maybe StartError # displayException :: StartError -> String # | |
Configuration
Defaults
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 the following "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.
The defaultConfig also disables the logging of internal Events.
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.
Since: 1.12.0.0
defaultPostgresConf :: [String] -> Config Source #
mappend the defaultConfig with a Config that provides additional
"postgresql.conf" lines. Equivalent to:
defaultPostgresConfextra =defaultConfig<> mempty {plan= mempty {postgresConfigFile= extra } }
or with lenses:
defaultPostgresConfextra =defaultConfig&planL.postgresConfigFile<>~extra
Since: 1.12.0.0
standardProcessConfig :: ProcessConfig Source #
The standardProcessConfig sets the handles to stdin, stdout and
stderr and inherits the environment variables from the calling
process.
Since: 1.12.0.0
silentConfig :: Config Source #
The same as defaultConfig but all the handles are set to devnull.
See silentProcessConfig as well.
Since: 1.12.0.0
silentProcessConfig :: ProcessConfig Source #
silentProcessConfig sets the handles to devnull and
inherits the environment variables from the calling process.
Since: 1.12.0.0