X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FTSN%2FDbImport.hs;h=7a420d380afc38bbc2903b9f334fc4b253ae577e;hb=f9a9d6fdcdd2ee0e6bb1882ed2eba936535a52ac;hp=8884a9eef4708597aaca4b2ac22b6d5530f7391c;hpb=a913a63f7679b59f9b650619e8fbfc6e81f3f8d3;p=dead%2Fhtsn-import.git diff --git a/src/TSN/DbImport.hs b/src/TSN/DbImport.hs index 8884a9e..7a420d3 100644 --- a/src/TSN/DbImport.hs +++ b/src/TSN/DbImport.hs @@ -1,21 +1,39 @@ -- | Definition of the DbImport typeclass. +-- +-- When we parse an XML tree, there are two functions that we would +-- like to call on the result independent of its type. First, we +-- would like to be able to run the database migrations for that +-- type. The migrations are kept separate from insertion because, at +-- some later point, it make make sense to disable automatic +-- migrations. +-- +-- Next we want to import the thing. +-- +-- Neither of these should depend on the type -- we should just be +-- able to call 'dbmigrate' followed by 'dbimport' on the +-- datastructure and have the right thing happen. That is the +-- purpose of the 'DbImport' typeclass. It allows the XML types to +-- define their own \"migrate me\" and \"insert me\" functions that +-- the rest of the application doesn't have to care about. +-- module TSN.DbImport ( DbImport(..), ImportResult(..), - dbimport_generic, run_dbmigrate ) where -- System imports -import Control.Monad.IO.Class ( MonadIO ) -import Database.Groundhog ( - runMigration ) -import Database.Groundhog.Core ( Migration, PersistBackend ) +import Control.Monad ( forM_ ) +import Control.Monad.IO.Class ( MonadIO( liftIO ) ) +import qualified Data.Map as Map ( elems ) +import Database.Groundhog ( executeRaw ) +import Database.Groundhog.Generic ( + createMigration, + getQueries, + mergeMigrations ) +import Database.Groundhog.Core ( Migration, NamedMigrations, PersistBackend ) import Network.Services.TSN.Report ( report_info ) --- Local imports -import TSN.XmlImport ( XmlImport(..) ) - -- | The type that will be returned from every file import attempt. -- @@ -31,32 +49,31 @@ data ImportResult = -- The second field should contain info. --- | Instances of this type know how to insert themselves into a --- Groundhog database. +-- | Instances of this type know how to run their own database +-- migrations and insert themselves into a database. -- class DbImport a where -- | Import an instance of type @a@. dbimport :: (PersistBackend m) => a -> m ImportResult -- | This must migrate *all* stuffs that can potentially be - -- created/used by the type @a@. + -- created/used by the type @a@. dbmigrate :: (MonadIO m, PersistBackend m) => a -> m () --- | The simplest possible implementation of 'dbimport', for types --- which happen to be members of the XmlImport typeclass. --- -dbimport_generic :: (XmlImport a, MonadIO m, PersistBackend m) - => a - -> m ImportResult -dbimport_generic x = insert_xml x >> return ImportSucceeded - - -- | A migration runner that will use our normal info reporting --- mechanism. +-- mechanism. The top-level code was stolen from 'runMigration' in +-- "Data.Groundhog.Generic" and the 'execute_pretty' code was stolen +-- from 'executeMigration'' in the same module. +-- run_dbmigrate :: (MonadIO m, PersistBackend m) => Migration m -> m () -run_dbmigrate = - runMigration pretty_migration_logger +run_dbmigrate migration = createMigration migration >>= execute_pretty where - pretty_migration_logger x = - report_info ("Migration: " ++ x ++ ";") + execute_pretty :: (PersistBackend m, MonadIO m) => NamedMigrations -> m () + execute_pretty m = do + let migs = getQueries False $ mergeMigrations $ Map.elems m + case migs of + Left errs -> fail $ unlines errs + Right qs -> forM_ qs $ \q -> do + liftIO $ report_info ("Migration: " ++ q ++ ";") + executeRaw False q []