{- This file is part of Vervis. - - Written in 2016 by fr33domlover . - - ♡ Copying is an act of love. Please copy, reuse and share. - - The author(s) have dedicated all copyright and related and neighboring - rights to this software to the public domain worldwide. This software is - distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along - with this software. If not, see - . -} module Vervis.Migration ( migrateDB ) where import Prelude import Control.Monad.IO.Class (MonadIO) import Control.Monad.Trans.Reader (ReaderT, runReaderT) import Data.Maybe (fromMaybe) import Database.Persist import Database.Persist.Sql (SqlBackend, toSqlKey) import Database.Persist.Schema import Database.Persist.Schema.PostgreSQL (schemaBackend) import Vervis.Model key :: SchemaVersionId key = toSqlKey 1 getDbSchemaVersion :: MonadIO m => ReaderT SqlBackend m (Maybe Int) getDbSchemaVersion = fmap schemaVersionNumber <$> get key setDbSchemaVersion :: MonadIO m => Int -> ReaderT SqlBackend m () setDbSchemaVersion v = update key [SchemaVersionNumber =. v] -- | Run the migration system. The second parameter is the list of migration -- actions in chronological order. The migration process is: -- -- * Check the schema version of the DB -- * Compare to the schema version of the app, which is the length of the list -- * If any migrations are required, run them -- * Update the schema version in the DB runMigrations :: MonadIO m => SchemaBackend SqlBackend -> [SchemaT SqlBackend m ()] -> ReaderT SqlBackend m () runMigrations sb migrations = do dver <- fromMaybe 0 <$> getDbSchemaVersion let aver = length migrations case compare aver dver of LT -> error "Older app version running with newer DB schema version" EQ -> return () GT -> do let migs = drop dver migrations runReaderT (sequence migs) sb setDbSchemaVersion aver changes :: MonadIO m => [SchemaT SqlBackend m ()] changes = [ ] migrateDB :: MonadIO m => ReaderT SqlBackend m () migrateDB = runMigrations schemaBackend changes