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