module Database.Rivet where import Data.Text (Text) data Direction = Up | Down data Syntax m = SQL Text Text | App (m ()) (m ()) data Migration m v = Migration { migValue :: v , migSteps :: [Syntax m]} instance Functor (Migration m) where fmap f m = m { migValue = f (migValue m) } instance Applicative (Migration m) where pure v = Migration v [] (<*>) (Migration f ss) (Migration v ss') = Migration (f v) (ss ++ ss') instance Monad (Migration m) where (>>=) (Migration v ss) f = let (Migration v' ss') = f v in Migration v' (ss ++ ss') return v = Migration v [] data Adaptor m = Adaptor { runHandler :: m () -> IO () , runSQL :: Text -> IO () , checkMigration :: Text -> IO Bool , markMigration :: Text -> Direction -> IO () } runMigration :: Direction -> Adaptor m -> Text -> Migration m () -> IO () runMigration dir ad n m = do sequence_ (map (runStep dir ad) (migSteps m)) markMigration ad n dir runStep :: Direction -> Adaptor m -> Syntax m -> IO () runStep Up (Adaptor h _ _ _) (App up _) = h up runStep Down (Adaptor h _ _ _) (App _ down) = h down runStep Up (Adaptor _ s _ _) (SQL up _) = s up runStep Down (Adaptor _ s _ _) (SQL _ down) = s down