{-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-} module Arbor.Postgres.Config ( optsPostgresConfig , optsConnectInfo , configToConnectInfo , connectInfoToConfig , PostgresConfig (..) ) where import Arbor.Postgres.Password import Data.Semigroup ((<>)) import Data.String (IsString) import Data.Text (Text, pack, unpack) import Database.PostgreSQL.Simple as PG import GHC.Generics import Options.Applicative data PostgresConfig = PostgresConfig { host :: Text , database :: Text , user :: Text , password :: Maybe Password } deriving (Eq, Show, Generic) hostOption :: IsString s => String -> Parser s hostOption prefix = strOption ( long (prefix <> "-db-host") <> metavar "DB_HOST" <> help "The postgres hostname" ) databaseOption :: IsString s => String -> Parser s databaseOption prefix = strOption ( long (prefix <> "-db-name") <> metavar "DB_NAME" <> help "The postgres db name" ) userOption :: IsString s => String -> Parser s userOption prefix = strOption ( long (prefix <> "-db-user") <> metavar "DB_USER" <> help "The postgres user" ) passwordOption :: IsString s => String -> Parser s passwordOption prefix = strOption ( long (prefix <> "-db-password") <> metavar "DB_PASSWORD" <> help "The postgres password" ) optsPostgresConfig :: String -> Parser PostgresConfig optsPostgresConfig prefix = do host <- hostOption prefix database <- databaseOption prefix user <- userOption prefix password <- optional $ Password <$> passwordOption prefix return PostgresConfig {..} optsConnectInfo :: String -> Parser PG.ConnectInfo optsConnectInfo prefix = do let connectPort = 5432 connectHost <- hostOption prefix connectDatabase <- databaseOption prefix connectUser <- userOption prefix connectPassword <- passwordOption prefix return PG.ConnectInfo {..} configToConnectInfo :: PostgresConfig -> PG.ConnectInfo configToConnectInfo pgc = let pass = case password pgc of Nothing -> "" Just (Password p) -> p in ConnectInfo { connectHost = unpack $ host pgc , connectDatabase = unpack $ database pgc , connectUser = unpack $ user pgc , connectPassword = unpack pass , connectPort = 5432 } connectInfoToConfig :: PG.ConnectInfo -> PostgresConfig connectInfoToConfig pgc = let pass = case connectPassword pgc of "" -> Nothing p -> Just . Password . pack $ p in PostgresConfig { host = pack $ connectHost pgc , database = pack $ connectDatabase pgc , user = pack $ connectUser pgc , password = pass }