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
(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 or overrided.
In general tmp-postgres
is useful if you want a temporary
postgres
which will not clash with open ports.
Here are some different use cases for tmp-postgres
and there 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.
The level of custom configuration is extensive but with great power comes the
ability to screw everything up. tmp-postgres
doesn't validate any custom
configuration and one can easily create a Config
that would not allow
postgres
to start.
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 :: PartialProcessConfig
- 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 ()
- toConnectionString :: DB -> ByteString
- toConnectionOptions :: DB -> Options
- toDataDirectory :: DB -> FilePath
- data StartError
- data DB
- prettyPrintDB :: DB -> String
- data Config = Config {}
- prettyPrintConfig :: Config -> String
- data DirectoryType
- data PartialDirectoryType
- data SocketClass
- data PartialSocketClass
- data PartialEnvVars = PartialEnvVars {}
- data PartialCommandLineArgs = PartialCommandLineArgs {}
- data PartialProcessConfig = PartialProcessConfig {}
- data ProcessConfig = ProcessConfig {}
- data PartialPostgresPlan = PartialPostgresPlan {}
- data PostgresPlan = PostgresPlan {}
- data PostgresProcess = PostgresProcess {}
- data PartialPlan = PartialPlan {}
- data Plan = Plan {}
Exception safe interface
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
.
defaultConfig
appends the following config by default
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
To append additional lines to "postgresql.conf" file create a
custom Config
like the following.
let custom = defaultConfig <> mempty { configPlan = mempty { partialPlanConfig = [ "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
Arguments
:: (DB -> IO a) |
|
-> IO (Either StartError a) |
Default expectation safe interface. Equivalent to withConfig
the
defaultConfig
Arguments
:: Config |
|
-> (DB -> IO a) |
|
-> 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.
Separate start and stop interface.
start :: IO (Either StartError DB) Source #
Default start behavior. Equivalent to calling startConfig
with the
defaultConfig
Arguments
:: Config |
|
-> 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 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"
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
.
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
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()
.
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
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 |
|
InitDbFailed ExitCode |
|
CreateDbFailed ExitCode |
|
CompletePlanFailed String [String] | The |
Instances
Eq StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core | |
Ord StartError Source # | |
Defined in Database.Postgres.Temp.Internal.Core Methods 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 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 # |
Main resource handle
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.
Configuration Types
The high level options for overriding default behavior.
Constructors
Config | |
Fields
|
Instances
Generic Config Source # | |
Semigroup Config Source # | |
Monoid Config Source # | |
Pretty Config Source # | |
Defined in Database.Postgres.Temp.Internal.Partial | |
type Rep Config Source # | |
Defined in Database.Postgres.Temp.Internal.Partial type Rep Config = D1 (MetaData "Config" "Database.Postgres.Temp.Internal.Partial" "tmp-postgres-1.7.0.0-25MmWr407e6L41bppYxubS" 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)))))) |
Directory configuration
data DirectoryType Source #
A type to track whether a file is temporary and needs to be cleaned up.
Instances
Eq DirectoryType Source # | |
Defined in Database.Postgres.Temp.Internal.Partial Methods (==) :: DirectoryType -> DirectoryType -> Bool # (/=) :: DirectoryType -> DirectoryType -> Bool # | |
Ord DirectoryType Source # | |
Defined in Database.Postgres.Temp.Internal.Partial Methods compare :: DirectoryType -> DirectoryType -> Ordering # (<) :: DirectoryType -> DirectoryType -> Bool # (<=) :: DirectoryType -> DirectoryType -> Bool # (>) :: DirectoryType -> DirectoryType -> Bool # (>=) :: DirectoryType -> DirectoryType -> Bool # max :: DirectoryType -> DirectoryType -> DirectoryType # min :: DirectoryType -> DirectoryType -> DirectoryType # | |
Show DirectoryType Source # | |
Defined in Database.Postgres.Temp.Internal.Partial Methods showsPrec :: Int -> DirectoryType -> ShowS # show :: DirectoryType -> String # showList :: [DirectoryType] -> ShowS # | |
Pretty DirectoryType Source # | |
Defined in Database.Postgres.Temp.Internal.Partial |
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
Listening socket configuration
data SocketClass Source #
A type for configuring the listening address of the postgres
process.
postgres
can listen on several types of sockets simulatanously but we
don't support that behavior. One can either listen on a IP based socket
or a UNIX domain socket.
Constructors
IpSocket String | IP socket type. The |
UnixSocket DirectoryType | UNIX domain socket |
Instances
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
An environment variables monoid
data PartialEnvVars Source #
The environment variables can be declared to inherit from the running process or they can be specifically added.
Constructors
PartialEnvVars | |
Fields |
Instances
An command line monoid
data PartialCommandLineArgs Source #
A type to help combine command line arguments.
Constructors
PartialCommandLineArgs | |
Fields
|
Instances
Process configuration
data PartialProcessConfig Source #
The monoidial version of ProcessConfig
. Used to combine overrides with
defaults when creating a ProcessConfig
.
Constructors
PartialProcessConfig | |
Fields
|
Instances
data ProcessConfig Source #
ProcessConfig
contains the configuration necessary for starting a
process. It is essentially a stripped down CreateProcess
.
Constructors
ProcessConfig | |
Fields
|
Instances
Pretty ProcessConfig Source # | |
Defined in Database.Postgres.Temp.Internal.Core |
postgres
process configuration
data PartialPostgresPlan Source #
PartialPostgresPlan
Constructors
PartialPostgresPlan | |
Fields
|
Instances
data PostgresPlan Source #
PostgresPlan
is used be startPostgresProcess
to start the postgres
and then attempt to connect to it.
Constructors
PostgresPlan | |
Fields
|
Instances
Pretty PostgresPlan Source # | |
Defined in Database.Postgres.Temp.Internal.Core |
postgres
process handle. Includes the client options for connecting
data PostgresProcess Source #
The output of calling startPostgresProcess
.
Constructors
PostgresProcess | |
Fields
|
Instances
Pretty PostgresProcess Source # | |
Defined in Database.Postgres.Temp.Internal.Core |
Database plans. This is used to call initdb
, postgres
and createdb
data PartialPlan Source #
The monoidial version of Plan
. Used to combine overrides with defaults
when creating a plan.
Constructors
PartialPlan | |
Instances
Plan
is the low level configuration necessary for creating a database
starting postgres
and creating a database. There is no validation done
on the Plan
. It is recommend that one use the higher level functions
such as start
which will generate plans that
are valid. Plan
s are used internally but are exposed if the higher
level plan generation is not sufficent.
Constructors
Plan | |
Fields |