module Database.PostgreSQL.Embedded.Postgres ( startPostgres , stopPostgres , checkPostgresStarted ) where import Control.Concurrent (threadDelay) import Control.Exception (SomeException, try) import Data.Conduit.Shell (rm, run, shell) import Data.List (isInfixOf) import Data.Monoid ((<>)) import Network (PortID (..), connectTo) import System.FilePath.Posix (()) import System.Info (os) import System.IO (Handle) import Database.PostgreSQL.Embedded.Download import Database.PostgreSQL.Embedded.Types startPostgres :: StartupConfig -> DBConfig -> IO RuntimeConfig startPostgres (StartupConfig version_ t) dConfig@(DBConfig p u) = do e <- downloadPostgres getOS version_ let d = e "data" run $ do shell $ e "bin" "initdb" <> " -A trust -U " <> u <> " -D " <> d <> " -E UTF-8" shell $ e "bin" "pg_ctl" <> " -D " <> d <> " -o \"-F -p " <> (show p) <> "\"" <> " -l " <> (e "log") <> " start" checkPostgresStarted dConfig t return $ RuntimeConfig e d where getOS | "darwin" `isInfixOf` os = OSX | "linux" `isInfixOf` os = Linux | "win" `isInfixOf` os = Win | otherwise = error $ "Unsupported platform" <> os stopPostgres :: RuntimeConfig -> IO () stopPostgres (RuntimeConfig e d) = run $ do shell $ e "bin" "pg_ctl" <> " -D " <> d <> " stop" rm "-rf" d checkPostgresStarted :: DBConfig -> Int -> IO () checkPostgresStarted config secs = checkPostgresStarted_ config secs >>= \_ -> return () where checkPostgresStarted_ :: DBConfig -> Int -> IO Bool checkPostgresStarted_ (DBConfig p _) n = do let oneSec = 1000000 res <- try $ connectTo "localhost" (PortNumber $ fromInteger p) :: IO (Either SomeException Handle) case res of Left e -> if (n > 0) then print e >>= \_ -> threadDelay oneSec >>= \_ -> checkPostgresStarted_ config (n - 1) else return False Right _ -> return True