{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} module Database.Mallard.File ( importDirectory , importFile ) where import Control.Exception import Control.Lens import Control.Monad.Catch import Control.Monad.Reader import Data.Foldable import qualified Data.HashMap.Strict as Map import qualified Data.Text.IO as T import Database.Mallard.Parser import Database.Mallard.Types import Path import Path.IO import Text.Megaparsec scanDirectoryForFiles :: (MonadIO m, MonadThrow m) => Path Abs Dir -> m [Path Abs File] scanDirectoryForFiles dir = concat <$> walkDirAccum Nothing (\_ _ c -> return [c]) dir importDirectory :: (MonadIO m, MonadThrow m) => Path Abs Dir -> m (MigrationTable, TestTable) importDirectory root = do files <- scanDirectoryForFiles root migrations <- mapM importFile' files return $ sortActions $ concat migrations importFile :: (MonadIO m, MonadThrow m) => Path Abs File -> m (MigrationTable, TestTable) importFile = fmap sortActions . importFile' sortActions :: [Action] -> (MigrationTable, TestTable) sortActions actions = foldl' sortFn (Map.empty, Map.empty) actions where sortFn (mm, tm) (ActionMigration m) = (Map.insert (m ^. migrationName) m mm, tm) sortFn (mm, tm) (ActionTest t) = (mm, Map.insert (t ^. testName) t tm) importFile' :: (MonadIO m, MonadThrow m) => Path Abs File -> m [Action] importFile' file = do fileContent <- liftIO $ T.readFile (toFilePath file) let parseResult = runParser parseActions (toFilePath file) fileContent case parseResult of Left er -> throw $ ParserException file er Right m -> return m