-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

{- | Type-safe migrations of UStore.

This implements imperative approach to migration when we make user
write a code of migration and track whether all new fields were indeed added
and all unnecessary fields were removed.

You can find migration examples in tests.

== How to write your simple migration

1. Start with migration template:

    @
    migration :: 'UStoreMigration' V1.Storage V2.Storage
    migration = 'mkUStoreMigration' $ do
      -- migration code to be put here
      'migrationFinish'
    @

    You will be prompted with a list of fields which should be added or removed.

2. Add/remove necessary fields using 'migrateAddField', 'migrateExtractField'
and other instructions.
They allow you to operate with 'MUStore' — it is similar to 'UStore'
but used within 'mkUStoreMigration' to track migration progress.

3. Use 'migrationToScript' or 'migrationToTestScript' to turn 'UStoreMigration'
into something useful.

Note that here you will get a solid 'MigrationScript', thus migration has
to fit into single Tezos transaction. If that's an issue, see the next section.

== How to write batched migration

1. Insert migration template.

    It looks like:

    @
    migration :: 'UStoreMigration' V1.Storage V2.Storage
    migration = 'mkUStoreBatchedMigration' $
      -- place for migration blocks
      'migrationFinish'
    @

2. Fill migration code with blocks like

    @
    'mkUStoreBatchedMigration' $
      'muBlock' '$:' do
        -- code for block 1
      '<-->'
      'muBlock' '$:' do
        -- code for block 2
      '<-->'
      'migrationFinish'
    @

    Migration blocks have to be the smallest actions which can safely be mixed
    and splitted across migration stages.

3. Compile migration with 'compileBatchedMigration'.

    Here you have to supply batching implementation. Alternatives include

    * 'mbNoBatching';
    * 'mbBatchesAsIs';
    * Functions from 'Lorentz.UStore.Migration.Batching' module.

4. Get the required information about migration.

    * 'migrationToScripts' picks the migration scripts, each has to be put
      in a separate Tezos transaction.

    * 'buildMigrationPlan' - dump description of each migration stage.

== Manual migrations

If for some reasons you need to define migration manually, you can use
functions from @Manual migrations@ section of "Lorentz.UStore.Migration.Base".

-}
module Lorentz.UStore.Migration
  ( module Exports
  ) where

import Lorentz.UStore.Migration.Base as Exports
import Lorentz.UStore.Migration.Batching as Exports
import Lorentz.UStore.Migration.Blocks as Exports