Copyright | Flipstone Technology Partners 2023 |
---|---|
License | MIT |
Stability | Stable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Facilities for performing some database migrations automatically.
See autoMigrateSchema
as a primary, high-level entry point.
Since: 1.0.0.0
Synopsis
- data MigrationOptions
- defaultOptions :: MigrationOptions
- autoMigrateSchema :: MonadOrville m => MigrationOptions -> [SchemaItem] -> m ()
- data SchemaItem where
- SchemaTable :: TableDefinition key writeEntity readEntity -> SchemaItem
- SchemaDropTable :: TableIdentifier -> SchemaItem
- SchemaSequence :: SequenceDefinition -> SchemaItem
- SchemaDropSequence :: SequenceIdentifier -> SchemaItem
- schemaItemSummary :: SchemaItem -> String
- data MigrationPlan
- generateMigrationPlan :: MonadOrville m => MigrationOptions -> [SchemaItem] -> m MigrationPlan
- migrationPlanSteps :: MigrationPlan -> [MigrationStep]
- executeMigrationPlan :: MonadOrville m => MigrationOptions -> MigrationPlan -> m ()
- data MigrationStep
- data MigrationDataError
- data MigrationLockId
- defaultLockId :: MigrationLockId
- nextLockId :: MigrationLockId -> MigrationLockId
- withMigrationLock :: MonadOrville m => MigrationLockId -> m a -> m a
- data MigrationLockError
Documentation
data MigrationOptions Source #
Options to control how autoMigrateSchema
and similar functions behave. You
should use defaultOptions
to construct a MigrationOptions
value
and then use the record accessors to change any values you want to customize.
Since: 1.0.0.0
defaultOptions :: MigrationOptions Source #
The default MigrationOptions
, which is to run both the schema changes and
concurrent index creations together using the default Orville migration lock.
Since: 1.0.0.0
autoMigrateSchema :: MonadOrville m => MigrationOptions -> [SchemaItem] -> m () Source #
This function compares the list of SchemaItem
s provided against the current
schema found in the database to determine whether any migrations are
necessary. If any changes need to be made, this function executes. You can
call generateMigrationPlan
and executeMigrationPlan
yourself if you want
to have more control over the process, but must then take care to ensure that
the schema has not changed between the two calls. This function uses a
PostgreSQL advisory lock to ensure that no other calls to autoMigrateSchema
(potentially on other processes) attempt to modify the schema at the same
time.
Since: 1.0.0.0
data SchemaItem where Source #
A SchemaItem
represents a single item in a database schema such as a table,
index or constraint. The constructor functions below can be used to create
items from other types (such as TableDefinition
) to put them into
a list to be used with autoMigrateSchema
.
Since: 1.0.0.0
SchemaTable :: TableDefinition key writeEntity readEntity -> SchemaItem | Constructs a |
SchemaDropTable :: TableIdentifier -> SchemaItem | Constructs a |
SchemaSequence :: SequenceDefinition -> SchemaItem | Constructs a |
SchemaDropSequence :: SequenceIdentifier -> SchemaItem | Constructs a |
schemaItemSummary :: SchemaItem -> String Source #
Returns a one-line string describing the SchemaItem
, suitable for a human
to identify it in a list of output.
For example, a SchemaItem
constructed via SchemaTable
gives Table <table
name>
.
Since: 1.0.0.0
data MigrationPlan Source #
A MigrationPlan
contains an ordered list of migration steps. Each one is a
single DDL statement to make a specific database change. The steps are ordered
such that dependencies from earlier steps will be in place before a later step
is executed (e.g. new columns are added before foreign keys referring to them).
While most steps are executed together in a single transaction this is not possible for indexes being created concurrently. Any such steps are executed last after the transaction for the rest of the schema changes has been successfully committed.
Since: 1.0.0.0
generateMigrationPlan :: MonadOrville m => MigrationOptions -> [SchemaItem] -> m MigrationPlan Source #
Compares the list of SchemaItem
s provided against the current schema found
in the database and returns a MigrationPlan
that could be executed to make
the database schema match the items given.
You can execute the MigrationPlan
yourself using the executeMigrationPlan
convenience function, though autoMigrateSchema
is usually a better option
because it uses a database lock to ensure that no other processes are also
using autoMigrateSchema
to apply migrations at the same time. If you use
generateMigrationPlan
and executeMigrationPlan
separately, you are
responsible for ensuring that the schema has not changed between the time the
plan is generated and executed yourself.
Since: 1.0.0.0
migrationPlanSteps :: MigrationPlan -> [MigrationStep] Source #
Returns all the MigrationStep
s found in a MigrationPlan
together in a
single list. This is useful if you merely want to examine the steps of a plan
rather than execute them. You should always use executeMigrationPlan
to
execute a migration plan to ensure that the transactional steps are done
within a transaction while the concurrent index steps are done afterward
outside of it.
Since: 1.0.0.0
executeMigrationPlan :: MonadOrville m => MigrationOptions -> MigrationPlan -> m () Source #
Executes a MigrationPlan
that has been previously devised via
generateMigrationPlan
. Normally all the steps in a migration plan are
executed in a transaction so that they will all be applied together
successfully or all rolled-back if one of them fails. Any indexes using the
Concurrent
creation strategy cannot be created this way, however,
because PostgreSQL does not allow CREATE INDEX CONCURRENTLY
to be used from
inside a transaction. If a MigrationPlan
includes any indexes whose
creation strategy is set to Concurrent
, Orville will create indexes
after the rest of the migration steps have been committed successfully. This
function will wait until all of the migration steps that it runs to finish
before returning. If one of the concurrent indexes fails during creation, it
will be left in an invalid state (as is the default PostgreSQL behavior). You
should check on the status of indexes created this way manually to ensure
they were created successfully. If they could not be, you can drop them and
Orville will re-attempt creating them the next time migration is performed.
Since: 1.0.0.0
data MigrationStep Source #
A single SQL statement that will be executed in order to migrate the database
to the desired result. You can use generateMigrationPlan
to get a list
of these yourself for inspection and debugging.
Since: 1.0.0.0
Instances
SqlExpression MigrationStep Source # | Since: 1.0.0.0 |
Defined in Orville.PostgreSQL.AutoMigration toRawSql :: MigrationStep -> RawSql Source # |
data MigrationDataError Source #
A MigrationDataError
will be thrown from the migration functions if data
necessary for migration cannot be found.
Since: 1.0.0.0
Instances
Exception MigrationDataError Source # | Since: 1.0.0.0 |
Show MigrationDataError Source # | Since: 1.0.0.0 |
Defined in Orville.PostgreSQL.AutoMigration showsPrec :: Int -> MigrationDataError -> ShowS # show :: MigrationDataError -> String # showList :: [MigrationDataError] -> ShowS # |
data MigrationLockId Source #
Identifies a PostgreSQL advisory lock to to be aquired by the application. Use
defaultLockId
to obtain the default value and nextLockId
to create custom
values if you need them.
Since: 1.0.0.0
defaultLockId :: MigrationLockId Source #
The lock id that Orville uses by default to ensure that just one copy of the application is attempting to run migrations at a time.
Since: 1.0.0.0
nextLockId :: MigrationLockId -> MigrationLockId Source #
Increments the id of the given MigrationLockId
, creating a new distinct lock
id. You can use this to create your own custom MigrationLockId
values as
necessary if you need to control migration runs in a custom manner.
Since: 1.0.0.0
withMigrationLock :: MonadOrville m => MigrationLockId -> m a -> m a Source #
Executes an Orville action with a PostgreSQL advisory lock held that indicates to other Orville processes that a database migration is being done and no others should be performed concurrently.
Since: 1.0.0.0
data MigrationLockError Source #
Raised if withMigrationLock
cannot acquire the migration lock in a
timely manner.
Since: 1.0.0.0
Instances
Exception MigrationLockError Source # | |
Show MigrationLockError Source # | |
Defined in Orville.PostgreSQL.Internal.MigrationLock showsPrec :: Int -> MigrationLockError -> ShowS # show :: MigrationLockError -> String # showList :: [MigrationLockError] -> ShowS # |