import Control.Arrow ( (&&&), arr, returnA )
import Control.Monad ( when )
-import Control.Monad.IO.Class ( liftIO )
+import Control.Monad.IO.Class ( MonadIO, liftIO )
import Database.Groundhog (
defaultMigrationLogger,
insert,
migrate,
runMigration )
-import Database.Groundhog.Core ( PersistEntity )
+import Database.Groundhog.Core ( PersistBackend, PersistEntity )
import Database.Groundhog.Generic ( runDbConn )
import Database.Groundhog.Sqlite (
withSqliteConn )
-- it's easy to eta reduce all of the import_foo functions that call
-- this.
--
-import_generic :: (XmlPickler a, PersistEntity b)
+import_generic :: (XmlPickler a, MonadIO m, PersistEntity b, PersistBackend m)
=> b -- ^ Dummy Listing instance needed for 'migrate'
-> (a -> [b]) -- ^ listings getter
- -> Configuration
-> XmlTree
- -> IO (Maybe Int) -- ^ Return the number of records inserted.
-import_generic dummy g cfg xml
- | backend cfg == Postgres = withPostgresqlConn cs go
- | otherwise = withSqliteConn cs go
- where
- -- | Pull the real connection String out of the configuration.
- cs :: String
- cs = get_connection_string $ connection_string cfg
-
- -- Needs NoMonomorphismRestriction to be allowed to return
- -- different types in the two cases above.
- go = runDbConn $ do
- runMigration defaultMigrationLogger $ migrate dummy
- let root_element = unpickleDoc xpickle xml
- case root_element of
- Nothing -> do
- let msg = "Could not unpickle document in import_generic."
- liftIO $ report_error msg
- return Nothing
- Just elt -> do
- ids <- mapM insert (g elt)
- return $ Just (length ids)
+ -> m (Maybe Int) -- ^ Return the number of records inserted.
+import_generic dummy g xml = do
+ -- Needs NoMonomorphismRestriction to be allowed to return
+ -- different types in the two cases above.
+ runMigration defaultMigrationLogger $ migrate dummy
+ let root_element = unpickleDoc xpickle xml
+ case root_element of
+ Nothing -> do
+ let msg = "Could not unpickle document in import_generic."
+ liftIO $ report_error msg
+ return Nothing
+ Just elt -> do
+ ids <- mapM insert (g elt)
+ return $ Just (length ids)
-- | Import TSN.News from an 'XmlTree'.
-import_news :: Configuration -> XmlTree -> IO (Maybe Int)
-import_news =
+import_news :: (MonadIO m, PersistBackend m)
+ => XmlTree
+ -> m (Maybe Int)
+import_news = -- This implementation is wrroooonnnnngggg.
import_generic
(undefined :: News.Message)
- id
+ (\m -> [m] :: [News.Message]) -- Turn a Message into a [Message]
-- | Import TSN.Injuries from an 'XmlTree'.
-import_injuries :: Configuration -> XmlTree -> IO (Maybe Int)
+import_injuries :: (MonadIO m, PersistBackend m)
+ => XmlTree
+ -> m (Maybe Int)
import_injuries =
import_generic
(undefined :: Injuries.Listing)
Injuries.listings
-- | Import TSN.InjuriesDetail from an 'XmlTree'.
-import_injuries_detail :: Configuration -> XmlTree -> IO (Maybe Int)
+import_injuries_detail :: (MonadIO m, PersistBackend m)
+ => XmlTree
+ -> m (Maybe Int)
import_injuries_detail =
import_generic
(undefined :: InjuriesDetail.PlayerListing)
-- | Takes a 'Doctype', 'XmlTree' pair and uses the 'Doctype' to
-- determine which function to call on the 'XmlTree'.
import_with_dtd :: (String, XmlTree) -> IO (Maybe Int)
- import_with_dtd (dtd,xml)
- | dtd == "injuriesxml.dtd" = import_injuries cfg xml
- | dtd == "Injuries_Detail_XML.dtd" = import_injuries_detail cfg xml
- | dtd == "newsxml.dtd" = import_news cfg xml
- | otherwise = do
- report_info $ "Unrecognized DTD in " ++ path ++ ": " ++ dtd ++ "."
- return Nothing
+ import_with_dtd (dtd,xml) =
+ if backend cfg == Postgres
+ then withPostgresqlConn cs $ runDbConn $ importer xml
+ else withSqliteConn cs $ runDbConn $ importer xml
+ where
+ -- | Pull the real connection String out of the configuration.
+ cs :: String
+ cs = get_connection_string $ connection_string cfg
+
+ importer
+ | dtd == "injuriesxml.dtd" = import_injuries
+ | dtd == "Injuries_Detail_XML.dtd" = import_injuries_detail
+ | dtd == "newsxml.dtd" = import_news
+ | otherwise = \_ -> do -- Dummy arg simplifies the other cases.
+ let errmsg = "Unrecognized DTD in " ++ path ++ ": " ++ dtd ++ "."
+ liftIO $ report_info errmsg
+ return Nothing
+
+
main :: IO ()
main = do