    -- | This module documents tools and utilities for running SQL migrations.
    --
    -- A 'Migration' is (currently) an alias for a 'WriterT' of
    module Database.Persist.Sql.Migration
      (
        -- * Types
        Migration
      , CautiousMigration
      , Sql
        -- * Using a 'Migration'
      , showMigration
      , parseMigration
      , parseMigration'
      , printMigration
      , getMigration
      , runMigration
      , runMigrationQuiet
      , runMigrationSilent
      , runMigrationUnsafe
      , runMigrationUnsafeQuiet
      , migrate
      -- * Utilities for constructing migrations
      -- | While 'migrate' is capable of creating a 'Migration' for you, it's not
      -- the only way you can write migrations. You can use these utilities to write
      -- extra steps in your migrations.
      --
      -- As an example, let's say we want to enable the @citext@ extension on
      -- @postgres@ as part of our migrations.
      --
      -- @
      -- 'Database.Persist.TH.share' ['Database.Persist.TH.mkPersist' sqlSettings, 'Database.Persist.TH.mkMigration' "migrateAll"] ...
      --
      -- migration :: 'Migration'
      -- migration = do
      --     'runSqlCommand' $
      --         'rawExecute_' "CREATE EXTENSION IF NOT EXISTS \"citext\";"
      --     migrateAll
      -- @
      --
      -- For raw commands, you can also just write 'addMigration':
      --
      -- @
      -- migration :: 'Migration'
      -- migration = do
      --     'addMigration' "CREATE EXTENSION IF NOT EXISTS \"citext\";"
      --     migrateAll
      -- @
      , reportErrors
      , reportError
      , addMigrations
      , addMigration
      , runSqlCommand
      -- * If something goes wrong...
      , PersistUnsafeMigrationException(..)
      ) where

    import Control.Exception (throwIO)
    import Control.Monad (liftM, unless)
    import Control.Monad.IO.Unlift
    import Control.Monad.Trans.Class (MonadTrans(..))
    import Control.Monad.Trans.Reader (ReaderT(..), ask)
    import Control.Monad.Trans.Writer
    import Data.Text (Text, isPrefixOf, pack, snoc, unpack)
    import qualified Data.Text.IO
    import GHC.Stack
    import System.IO
    import System.IO.Silently (hSilence)

    import Database.Persist.Sql.Orphan.PersistStore ()
    import Database.Persist.Sql.Raw
    import Database.Persist.Sql.Types
    import Database.Persist.Sql.Types.Internal
    import Database.Persist.Types
    import Control.Exception (Exception(..))

    type Sql = Text

    -- | A list of SQL operations, marked with a safety flag. If the 'Bool' is
    -- 'True', then the operation is *unsafe* - it might be destructive, or
    -- otherwise not idempotent. If the 'Bool' is 'False', then the operation
    -- is *safe*, and can be run repeatedly without issues.
    type CautiousMigration = [(Bool, Sql)]

    -- | A 'Migration' is a four level monad stack consisting of:
    --
    -- * @'WriterT' ['Text']@ representing a log of errors in the migrations.
    -- * @'WriterT' 'CautiousMigration'@ representing a list of migrations to
    --   run, along with whether or not they are safe.
    -- * @'ReaderT' 'SqlBackend'@, aka the 'SqlPersistT' transformer for
    --   database interop.
    -- * @'IO'@ for arbitrary IO.
    type Migration = WriterT [Text] (WriterT CautiousMigration (ReaderT SqlBackend IO)) ()

    allSql :: CautiousMigration -> [Sql]
    allSql :: CautiousMigration -> [Text]
    allSql = ((Bool, Text) -> Text) -> CautiousMigration -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (Bool, Text) -> Text
    forall a b. (a, b) -> b
    snd

    safeSql :: CautiousMigration -> [Sql]
    safeSql :: CautiousMigration -> [Text]
    safeSql = CautiousMigration -> [Text]
    allSql (CautiousMigration -> [Text])
    -> (CautiousMigration -> CautiousMigration)
    -> CautiousMigration
    -> [Text]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((Bool, Text) -> Bool) -> CautiousMigration -> CautiousMigration
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> ((Bool, Text) -> Bool) -> (Bool, Text) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool, Text) -> Bool
    forall a b. (a, b) -> a
    fst)

    -- | Given a 'Migration', this parses it and returns either a list of
    -- errors associated with the migration or a list of migrations to do.
    parseMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    parseMigration :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    parseMigration =
        ReaderT SqlBackend IO (Either [Text] CautiousMigration)
    -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    forall {m :: * -> *} {r} {a}.
    MonadIO m =>
    ReaderT r IO a -> ReaderT r m a
    liftIOReader (ReaderT SqlBackend IO (Either [Text] CautiousMigration)
     -> ReaderT SqlBackend m (Either [Text] CautiousMigration))
    -> (Migration
        -> ReaderT SqlBackend IO (Either [Text] CautiousMigration))
    -> Migration
    -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (([Text], CautiousMigration) -> Either [Text] CautiousMigration)
    -> ReaderT SqlBackend IO ([Text], CautiousMigration)
    -> ReaderT SqlBackend IO (Either [Text] CautiousMigration)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM ([Text], CautiousMigration) -> Either [Text] CautiousMigration
    forall {a} {b}. ([a], b) -> Either [a] b
    go (ReaderT SqlBackend IO ([Text], CautiousMigration)
     -> ReaderT SqlBackend IO (Either [Text] CautiousMigration))
    -> (Migration -> ReaderT SqlBackend IO ([Text], CautiousMigration))
    -> Migration
    -> ReaderT SqlBackend IO (Either [Text] CautiousMigration)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterT CautiousMigration (ReaderT SqlBackend IO) [Text]
    -> ReaderT SqlBackend IO ([Text], CautiousMigration)
    forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
    runWriterT (WriterT CautiousMigration (ReaderT SqlBackend IO) [Text]
     -> ReaderT SqlBackend IO ([Text], CautiousMigration))
    -> (Migration
        -> WriterT CautiousMigration (ReaderT SqlBackend IO) [Text])
    -> Migration
    -> ReaderT SqlBackend IO ([Text], CautiousMigration)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Migration
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) [Text]
    forall (m :: * -> *) w a. Monad m => WriterT w m a -> m w
    execWriterT
      where
        go :: ([a], b) -> Either [a] b
    go ([], b
    sql) = b -> Either [a] b
    forall a b. b -> Either a b
    Right b
    sql
        go ([a]
    errs, b
    _) = [a] -> Either [a] b
    forall a b. a -> Either a b
    Left [a]
    errs

        liftIOReader :: ReaderT r IO a -> ReaderT r m a
    liftIOReader (ReaderT r -> IO a
    m) = (r -> m a) -> ReaderT r m a
    forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
    ReaderT ((r -> m a) -> ReaderT r m a) -> (r -> m a) -> ReaderT r m a
    forall a b. (a -> b) -> a -> b
    $ IO a -> m a
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO a -> m a) -> (r -> IO a) -> r -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . r -> IO a
    m

    -- | Like 'parseMigration', but instead of returning the value in an
    -- 'Either' value, it calls 'error' on the error values.
    parseMigration' :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m CautiousMigration
    parseMigration' :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m CautiousMigration
    parseMigration' Migration
    m = do
      x <- Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)
    parseMigration Migration
    m
      case x of
          Left [Text]
    errs -> [Char] -> ReaderT SqlBackend m CautiousMigration
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> ReaderT SqlBackend m CautiousMigration)
    -> [Char] -> ReaderT SqlBackend m CautiousMigration
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> [Char]
    unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ (Text -> [Char]) -> [Text] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> [Char]
    unpack [Text]
    errs
          Right CautiousMigration
    sql -> CautiousMigration -> ReaderT SqlBackend m CautiousMigration
    forall a. a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CautiousMigration
    sql

    -- | Prints a migration.
    printMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m ()
    printMigration :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m ()
    printMigration Migration
    m = Migration -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m [Text]
    showMigration Migration
    m
                   ReaderT SqlBackend m [Text]
    -> ([Text] -> ReaderT SqlBackend m ()) -> ReaderT SqlBackend m ()
    forall a b.
    ReaderT SqlBackend m a
    -> (a -> ReaderT SqlBackend m b) -> ReaderT SqlBackend m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Text -> ReaderT SqlBackend m ())
    -> [Text] -> ReaderT SqlBackend m ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ (IO () -> ReaderT SqlBackend m ()
    forall a. IO a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> ReaderT SqlBackend m ())
    -> (Text -> IO ()) -> Text -> ReaderT SqlBackend m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> IO ()
    Data.Text.IO.putStrLn)

    -- | Convert a 'Migration' to a list of 'Text' values corresponding to their
    -- 'Sql' statements.
    showMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m [Text]
    showMigration :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m [Text]
    showMigration Migration
    m = (Text -> Text) -> [Text] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Text -> Char -> Text) -> Char -> Text -> Text
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Text -> Char -> Text
    snoc Char
    ';') ([Text] -> [Text])
    -> ReaderT SqlBackend m [Text] -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    `liftM` Migration -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (MonadIO m, HasCallStack) =>
    Migration -> ReaderT SqlBackend m [Text]
    getMigration Migration
    m

    -- | Return all of the 'Sql' values associated with the given migration.
    -- Calls 'error' if there's a parse error on any migration.
    getMigration :: (MonadIO m, HasCallStack) => Migration -> ReaderT SqlBackend m [Sql]
    getMigration :: forall (m :: * -> *).
    (MonadIO m, HasCallStack) =>
    Migration -> ReaderT SqlBackend m [Text]
    getMigration Migration
    m = do
      mig <- Migration -> ReaderT SqlBackend m CautiousMigration
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m CautiousMigration
    parseMigration' Migration
    m
      return $ allSql mig

    -- | Runs a migration. If the migration fails to parse or if any of the
    -- migrations are unsafe, then this throws a 'PersistUnsafeMigrationException'.
    runMigration :: MonadIO m
                 => Migration
                 -> ReaderT SqlBackend m ()
    runMigration :: forall (m :: * -> *).
    MonadIO m =>
    Migration -> ReaderT SqlBackend m ()
    runMigration Migration
    m = Migration -> Bool -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> Bool -> ReaderT SqlBackend m [Text]
    runMigration' Migration
    m Bool
    False ReaderT SqlBackend m [Text]
    -> ReaderT SqlBackend m () -> ReaderT SqlBackend m ()
    forall a b.
    ReaderT SqlBackend m a
    -> ReaderT SqlBackend m b -> ReaderT SqlBackend m b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> ReaderT SqlBackend m ()
    forall a. a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Same as 'runMigration', but does not report the individual migrations on
    -- stderr. Instead it returns a list of the executed SQL commands.
    --
    -- This is a safer/more robust alternative to 'runMigrationSilent', but may be
    -- less silent for some persistent implementations, most notably
    -- persistent-postgresql
    --
    -- @since 2.10.2
    runMigrationQuiet :: MonadIO m
                      => Migration
                      -> ReaderT SqlBackend m [Text]
    runMigrationQuiet :: forall (m :: * -> *).
    MonadIO m =>
    Migration -> ReaderT SqlBackend m [Text]
    runMigrationQuiet Migration
    m = Migration -> Bool -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> Bool -> ReaderT SqlBackend m [Text]
    runMigration' Migration
    m Bool
    True

    -- | Same as 'runMigration', but returns a list of the SQL commands executed
    -- instead of printing them to stderr.
    --
    -- This function silences the migration by remapping 'stderr'. As a result, it
    -- is not thread-safe and can clobber output from other parts of the program.
    -- This implementation method was chosen to also silence postgresql migration
    -- output on stderr, but is not recommended!
    runMigrationSilent :: MonadUnliftIO m
                       => Migration
                       -> ReaderT SqlBackend m [Text]
    runMigrationSilent :: forall (m :: * -> *).
    MonadUnliftIO m =>
    Migration -> ReaderT SqlBackend m [Text]
    runMigrationSilent Migration
    m = ((forall a. ReaderT SqlBackend m a -> IO a) -> IO [Text])
    -> ReaderT SqlBackend m [Text]
    forall b.
    ((forall a. ReaderT SqlBackend m a -> IO a) -> IO b)
    -> ReaderT SqlBackend m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. ReaderT SqlBackend m a -> IO a) -> IO [Text])
     -> ReaderT SqlBackend m [Text])
    -> ((forall a. ReaderT SqlBackend m a -> IO a) -> IO [Text])
    -> ReaderT SqlBackend m [Text]
    forall a b. (a -> b) -> a -> b
    $ \forall a. ReaderT SqlBackend m a -> IO a
    run ->
      [Handle] -> IO [Text] -> IO [Text]
    forall a. [Handle] -> IO a -> IO a
    hSilence [Handle
    stderr] (IO [Text] -> IO [Text]) -> IO [Text] -> IO [Text]
    forall a b. (a -> b) -> a -> b
    $ ReaderT SqlBackend m [Text] -> IO [Text]
    forall a. ReaderT SqlBackend m a -> IO a
    run (ReaderT SqlBackend m [Text] -> IO [Text])
    -> ReaderT SqlBackend m [Text] -> IO [Text]
    forall a b. (a -> b) -> a -> b
    $ Migration -> Bool -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> Bool -> ReaderT SqlBackend m [Text]
    runMigration' Migration
    m Bool
    True

    -- | Run the given migration against the database. If the migration fails
    -- to parse, or there are any unsafe migrations, then this will error at
    -- runtime. This returns a list of the migrations that were executed.
    runMigration'
        :: (HasCallStack, MonadIO m)
        => Migration
        -> Bool -- ^ is silent?
        -> ReaderT SqlBackend m [Text]
    runMigration' :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> Bool -> ReaderT SqlBackend m [Text]
    runMigration' Migration
    m Bool
    silent = do
        mig <- Migration -> ReaderT SqlBackend m CautiousMigration
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m CautiousMigration
    parseMigration' Migration
    m
        if any fst mig
            then liftIO . throwIO $ PersistUnsafeMigrationException mig
            else mapM (executeMigrate silent) $ sortMigrations $ safeSql mig

    -- | Like 'runMigration', but this will perform the unsafe database
    -- migrations instead of erroring out.
    runMigrationUnsafe :: MonadIO m
                       => Migration
                       -> ReaderT SqlBackend m ()
    runMigrationUnsafe :: forall (m :: * -> *).
    MonadIO m =>
    Migration -> ReaderT SqlBackend m ()
    runMigrationUnsafe Migration
    m = Bool -> Migration -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Bool -> Migration -> ReaderT SqlBackend m [Text]
    runMigrationUnsafe' Bool
    False Migration
    m ReaderT SqlBackend m [Text]
    -> ReaderT SqlBackend m () -> ReaderT SqlBackend m ()
    forall a b.
    ReaderT SqlBackend m a
    -> ReaderT SqlBackend m b -> ReaderT SqlBackend m b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> ReaderT SqlBackend m ()
    forall a. a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Same as 'runMigrationUnsafe', but returns a list of the SQL commands
    -- executed instead of printing them to stderr.
    --
    -- @since 2.10.2
    runMigrationUnsafeQuiet :: (HasCallStack, MonadIO m)
                            => Migration
                            -> ReaderT SqlBackend m [Text]
    runMigrationUnsafeQuiet :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m [Text]
    runMigrationUnsafeQuiet = Bool -> Migration -> ReaderT SqlBackend m [Text]
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Bool -> Migration -> ReaderT SqlBackend m [Text]
    runMigrationUnsafe' Bool
    True

    runMigrationUnsafe' :: (HasCallStack, MonadIO m)
                        => Bool
                        -> Migration
                        -> ReaderT SqlBackend m [Text]
    runMigrationUnsafe' :: forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Bool -> Migration -> ReaderT SqlBackend m [Text]
    runMigrationUnsafe' Bool
    silent Migration
    m = do
        mig <- Migration -> ReaderT SqlBackend m CautiousMigration
    forall (m :: * -> *).
    (HasCallStack, MonadIO m) =>
    Migration -> ReaderT SqlBackend m CautiousMigration
    parseMigration' Migration
    m
        mapM (executeMigrate silent) $ sortMigrations $ allSql mig

    executeMigrate :: MonadIO m => Bool -> Text -> ReaderT SqlBackend m Text
    executeMigrate :: forall (m :: * -> *).
    MonadIO m =>
    Bool -> Text -> ReaderT SqlBackend m Text
    executeMigrate Bool
    silent Text
    s = do
        Bool -> ReaderT SqlBackend m () -> ReaderT SqlBackend m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless Bool
    silent (ReaderT SqlBackend m () -> ReaderT SqlBackend m ())
    -> ReaderT SqlBackend m () -> ReaderT SqlBackend m ()
    forall a b. (a -> b) -> a -> b
    $ IO () -> ReaderT SqlBackend m ()
    forall a. IO a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> ReaderT SqlBackend m ())
    -> IO () -> ReaderT SqlBackend m ()
    forall a b. (a -> b) -> a -> b
    $ Handle -> [Char] -> IO ()
    hPutStrLn Handle
    stderr ([Char] -> IO ()) -> [Char] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Migrating: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Text -> [Char]
    unpack Text
    s
        Text -> [PersistValue] -> ReaderT SqlBackend m ()
    forall (m :: * -> *) backend.
    (MonadIO m, BackendCompatible SqlBackend backend) =>
    Text -> [PersistValue] -> ReaderT backend m ()
    rawExecute Text
    s []
        Text -> ReaderT SqlBackend m Text
    forall a. a -> ReaderT SqlBackend m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    s

    -- | Sort the alter DB statements so tables are created before constraints are
    -- added.
    sortMigrations :: [Sql] -> [Sql]
    sortMigrations :: [Text] -> [Text]
    sortMigrations [Text]
    x =
        (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Text -> Bool
    isCreate [Text]
    x [Text] -> [Text] -> [Text]
    forall a. [a] -> [a] -> [a]
    ++ (Text -> Bool) -> [Text] -> [Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Bool
    isCreate) [Text]
    x
      where
        -- Note the use of lower-case e. This (hack) allows backends to explicitly
        -- choose to have this special sorting applied.
        isCreate :: Text -> Bool
    isCreate Text
    t = [Char] -> Text
    pack [Char]
    "CREATe " Text -> Text -> Bool
    `isPrefixOf` Text
    t

    -- |  Given a list of old entity definitions and a new 'EntityDef' in
    -- @val@, this creates a 'Migration' to update the old list of definitions
    -- with the new one.
    migrate :: [EntityDef]
            -> EntityDef
            -> Migration
    migrate :: [EntityDef] -> EntityDef -> Migration
    migrate [EntityDef]
    allDefs EntityDef
    val = do
        conn <- WriterT CautiousMigration (ReaderT SqlBackend IO) SqlBackend
    -> WriterT
         [Text]
         (WriterT CautiousMigration (ReaderT SqlBackend IO))
         SqlBackend
    forall (m :: * -> *) a. Monad m => m a -> WriterT [Text] m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (WriterT CautiousMigration (ReaderT SqlBackend IO) SqlBackend
     -> WriterT
          [Text]
          (WriterT CautiousMigration (ReaderT SqlBackend IO))
          SqlBackend)
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) SqlBackend
    -> WriterT
         [Text]
         (WriterT CautiousMigration (ReaderT SqlBackend IO))
         SqlBackend
    forall a b. (a -> b) -> a -> b
    $ ReaderT SqlBackend IO SqlBackend
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) SqlBackend
    forall (m :: * -> *) a.
    Monad m =>
    m a -> WriterT CautiousMigration m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift ReaderT SqlBackend IO SqlBackend
    forall (m :: * -> *) r. Monad m => ReaderT r m r
    ask
        res <- liftIO $ connMigrateSql conn allDefs (getStmtConn conn) val
        either reportErrors addMigrations res

    -- | Report a single error in a 'Migration'.
    --
    -- @since 2.9.2
    reportError :: Text -> Migration
    reportError :: Text -> Migration
    reportError = [Text] -> Migration
    forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
    tell ([Text] -> Migration) -> (Text -> [Text]) -> Text -> Migration
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Text]
    forall a. a -> [a]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- | Report multiple errors in a 'Migration'.
    --
    -- @since 2.9.2
    reportErrors :: [Text] -> Migration
    reportErrors :: [Text] -> Migration
    reportErrors = [Text] -> Migration
    forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
    tell

    -- | Add a migration to the migration plan.
    --
    -- @since 2.9.2
    addMigration
        :: Bool
        -- ^ Is the migration unsafe to run? (eg a destructive or non-idempotent
        -- update on the schema). If 'True', the migration is *unsafe*, and will
        -- need to be run manually later. If 'False', the migration is *safe*, and
        -- can be run any number of times.
        -> Sql
        -- ^ A 'Text' value representing the command to run on the database.
        -> Migration
    addMigration :: Bool -> Text -> Migration
    addMigration Bool
    isUnsafe Text
    sql = WriterT CautiousMigration (ReaderT SqlBackend IO) () -> Migration
    forall (m :: * -> *) a. Monad m => m a -> WriterT [Text] m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (CautiousMigration
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) ()
    forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
    tell [(Bool
    isUnsafe, Text
    sql)])

    -- | Add a 'CautiousMigration' (aka a @[('Bool', 'Text')]@) to the
    -- migration plan.
    --
    -- @since 2.9.2
    addMigrations
        :: CautiousMigration
        -> Migration
    addMigrations :: CautiousMigration -> Migration
    addMigrations = WriterT CautiousMigration (ReaderT SqlBackend IO) () -> Migration
    forall (m :: * -> *) a. Monad m => m a -> WriterT [Text] m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (WriterT CautiousMigration (ReaderT SqlBackend IO) () -> Migration)
    -> (CautiousMigration
        -> WriterT CautiousMigration (ReaderT SqlBackend IO) ())
    -> CautiousMigration
    -> Migration
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CautiousMigration
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) ()
    forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
    tell

    -- | Run an action against the database during a migration. Can be useful for eg
    -- creating Postgres extensions:
    --
    -- @
    -- runSqlCommand $ 'rawExecute' "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" []
    -- @
    --
    -- @since 2.13.0.0
    runSqlCommand :: SqlPersistT IO () -> Migration
    runSqlCommand :: SqlPersistT IO () -> Migration
    runSqlCommand = WriterT CautiousMigration (ReaderT SqlBackend IO) () -> Migration
    forall (m :: * -> *) a. Monad m => m a -> WriterT [Text] m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (WriterT CautiousMigration (ReaderT SqlBackend IO) () -> Migration)
    -> (SqlPersistT IO ()
        -> WriterT CautiousMigration (ReaderT SqlBackend IO) ())
    -> SqlPersistT IO ()
    -> Migration
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SqlPersistT IO ()
    -> WriterT CautiousMigration (ReaderT SqlBackend IO) ()
    forall (m :: * -> *) a.
    Monad m =>
    m a -> WriterT CautiousMigration m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift

    -- | An exception indicating that Persistent refused to run some unsafe
    -- migrations. Contains a list of pairs where the Bool tracks whether the
    -- migration was unsafe (True means unsafe), and the Sql is the sql statement
    -- for the migration.
    --
    -- @since 2.11.1.0
    newtype PersistUnsafeMigrationException
      = PersistUnsafeMigrationException [(Bool, Sql)]

    -- | This 'Show' instance renders an error message suitable for printing to the
    -- console. This is a little dodgy, but since GHC uses Show instances when
    -- displaying uncaught exceptions, we have little choice.
    instance Show PersistUnsafeMigrationException where
      show :: PersistUnsafeMigrationException -> [Char]
    show (PersistUnsafeMigrationException CautiousMigration
    mig) =
        [[Char]] -> [Char]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat
          [ [Char]
    "\n\nDatabase migration: manual intervention required.\n"
          , [Char]
    "The unsafe actions are prefixed by '***' below:\n\n"
          , [[Char]] -> [Char]
    unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
    forall a b. (a -> b) -> a -> b
    $ ((Bool, Text) -> [Char]) -> CautiousMigration -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map (Bool, Text) -> [Char]
    displayMigration CautiousMigration
    mig
          ]
        where
          displayMigration :: (Bool, Sql) -> String
          displayMigration :: (Bool, Text) -> [Char]
    displayMigration (Bool
    True,  Text
    s) = [Char]
    "*** " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Text -> [Char]
    unpack Text
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ";"
          displayMigration (Bool
    False, Text
    s) = [Char]
    "    " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Text -> [Char]
    unpack Text
    s [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ";"

    instance Exception PersistUnsafeMigrationException