{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ScopedTypeVariables #-} module Main where import Database.Schema.Migrations.Backend.HDBC (hdbcBackend) import Database.Schema.Migrations.Test.BackendTest as BackendTest import Control.Exception (catch, catches, finally, Handler(..), SomeException ) import Database.HDBC ( IConnection(disconnect) ) import qualified Database.HDBC as HDBC import qualified Database.HDBC.PostgreSQL as PostgreSQL import System.Exit import System.IO ( stderr ) import System.Process ( system ) import Test.HUnit data PostgreSQLBackendConnection = forall a. HDBC.IConnection a => HDBCConnection a instance BackendConnection PostgreSQLBackendConnection where supportsTransactionalDDL = const True makeBackend (HDBCConnection c) = hdbcBackend c commit (HDBCConnection c) = HDBC.commit c withTransaction (HDBCConnection c) transaction = HDBC.withTransaction c (transaction . HDBCConnection) getTables (HDBCConnection c) = HDBC.getTables c catchAll (HDBCConnection _) act handler = act `catches` [ Handler (\(_ :: HDBC.SqlError) -> handler) ] loadTests :: IO [Test] loadTests = do pgConn <- setupPostgresDb let backendConnection :: PostgreSQLBackendConnection = HDBCConnection pgConn testAct = (BackendTest.tests backendConnection) `finally` (disconnect pgConn >> teardownPostgresDb) return [ ("PostgreSQL backend tests") ~: test testAct ] tempDatabase :: String tempDatabase = "dbmigrations_test" ignoreException :: SomeException -> IO () ignoreException _ = return () setupPostgresDb :: IO PostgreSQL.Connection setupPostgresDb = do teardownPostgresDb `catch` ignoreException -- create database status <- system $ "createdb " ++ tempDatabase case status of ExitSuccess -> return () ExitFailure _ -> error $ "Failed to create PostgreSQL database " ++ (show tempDatabase) -- return test db connection PostgreSQL.connectPostgreSQL $ "dbname=" ++ tempDatabase teardownPostgresDb :: IO () teardownPostgresDb = do -- drop database status <- system $ "dropdb " ++ tempDatabase ++ " 2>/dev/null" case status of ExitSuccess -> return () ExitFailure _ -> error $ "Failed to drop PostgreSQL database " ++ (show tempDatabase) main :: IO () main = do tests_ <- loadTests (testResults, _) <- runTestText (putTextToHandle stderr False) $ test tests_ if errors testResults + failures testResults > 0 then exitFailure else exitSuccess