We usually miss adding or changing the example config file when we do changes to our configurations. Moving the example config file from CLI module to Config module would make it less easy to miss doing the associated changes to the example config file. Signed-off-by: Taimoor Zaeem <taimoorzaeem@gmail.com>
145 lines
4.5 KiB
Haskell
145 lines
4.5 KiB
Haskell
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
module PostgREST.CLI
|
|
( main
|
|
, CLI (..)
|
|
, Command (..)
|
|
, readCLIShowHelp
|
|
) where
|
|
|
|
import qualified Data.Aeson as JSON
|
|
import qualified Data.ByteString.Char8 as BS
|
|
import qualified Data.ByteString.Lazy as LBS
|
|
import qualified Hasql.Transaction.Sessions as SQL
|
|
import qualified Options.Applicative as O
|
|
|
|
import PostgREST.AppState (AppState)
|
|
import PostgREST.Config (AppConfig (..))
|
|
import PostgREST.Observation (Observation (..))
|
|
import PostgREST.SchemaCache (querySchemaCache)
|
|
import PostgREST.Version (prettyVersion)
|
|
|
|
import qualified PostgREST.App as App
|
|
import qualified PostgREST.AppState as AppState
|
|
import qualified PostgREST.Client as Client
|
|
import qualified PostgREST.Config as Config
|
|
|
|
import Protolude
|
|
|
|
|
|
main :: CLI -> IO ()
|
|
main CLI{cliCommand, cliPath} = do
|
|
conf <-
|
|
either panic identity <$> Config.readAppConfig mempty cliPath Nothing mempty mempty
|
|
case cliCommand of
|
|
Client adminCmd -> runClientCommand conf adminCmd
|
|
Run runCmd -> runAppCommand conf runCmd
|
|
|
|
-- | Run command using http-client to communicate with an already running postgrest
|
|
runClientCommand :: AppConfig -> ClientCommand -> IO ()
|
|
runClientCommand conf CmdReady = Client.ready conf
|
|
|
|
-- | Run postgrest with command
|
|
runAppCommand :: AppConfig -> RunCommand -> IO ()
|
|
runAppCommand conf@AppConfig{..} runCmd = do
|
|
-- Per https://github.com/PostgREST/postgrest/issues/268, we want to
|
|
-- explicitly close the connections to PostgreSQL on shutdown.
|
|
-- 'AppState.destroy' takes care of that.
|
|
bracket
|
|
(AppState.init conf)
|
|
AppState.destroy
|
|
(\appState -> case runCmd of
|
|
CmdDumpConfig -> do
|
|
when configDbConfig $ AppState.readInDbConfig True appState
|
|
putStr . Config.toText =<< AppState.getConfig appState
|
|
CmdDumpSchema -> do
|
|
when configDbConfig $ AppState.readInDbConfig True appState
|
|
putStrLn =<< dumpSchema appState
|
|
CmdRun -> App.run appState)
|
|
|
|
-- | Dump SchemaCache schema to JSON
|
|
dumpSchema :: AppState -> IO LBS.ByteString
|
|
dumpSchema appState = do
|
|
conf@AppConfig{..} <- AppState.getConfig appState
|
|
result <-
|
|
let transaction = if configDbPreparedStatements then SQL.transaction else SQL.unpreparedTransaction in
|
|
AppState.usePool appState
|
|
(transaction SQL.ReadCommitted SQL.Read $ querySchemaCache conf)
|
|
case result of
|
|
Left e -> do
|
|
let observer = AppState.getObserver appState
|
|
observer $ SchemaCacheErrorObs configDbSchemas configDbExtraSearchPath e
|
|
exitFailure
|
|
Right sCache -> return $ JSON.encode sCache
|
|
|
|
-- | Command line interface options
|
|
data CLI = CLI
|
|
{ cliCommand :: Command
|
|
, cliPath :: Maybe FilePath
|
|
}
|
|
|
|
data Command
|
|
= Client ClientCommand
|
|
| Run RunCommand
|
|
|
|
data ClientCommand
|
|
= CmdReady
|
|
|
|
data RunCommand
|
|
= CmdRun
|
|
| CmdDumpConfig
|
|
| CmdDumpSchema
|
|
|
|
-- | Read command line interface options. Also prints help.
|
|
readCLIShowHelp :: IO CLI
|
|
readCLIShowHelp =
|
|
O.customExecParser prefs opts
|
|
where
|
|
prefs = O.prefs $ O.showHelpOnError <> O.showHelpOnEmpty
|
|
opts = O.info parser $ O.fullDesc <> progDesc
|
|
parser = O.helper <*> versionFlag <*> exampleParser <*> cliParser
|
|
|
|
progDesc =
|
|
O.progDesc $
|
|
"PostgREST "
|
|
<> BS.unpack prettyVersion
|
|
<> " / create a REST API to an existing Postgres database"
|
|
|
|
versionFlag =
|
|
O.infoOption ("PostgREST " <> BS.unpack prettyVersion) $
|
|
O.long "version"
|
|
<> O.short 'v'
|
|
<> O.help "Show the version information"
|
|
|
|
exampleParser =
|
|
O.infoOption Config.exampleConfigFile $
|
|
O.long "example"
|
|
<> O.short 'e'
|
|
<> O.help "Show an example configuration file"
|
|
|
|
cliParser :: O.Parser CLI
|
|
cliParser =
|
|
CLI
|
|
<$> (dumpConfigFlag <|> dumpSchemaFlag <|> readyFlag)
|
|
<*> O.optional configFileOption
|
|
|
|
configFileOption =
|
|
O.strArgument $
|
|
O.metavar "FILENAME"
|
|
<> O.help "Path to configuration file"
|
|
|
|
dumpConfigFlag =
|
|
O.flag (Run CmdRun) (Run CmdDumpConfig) $
|
|
O.long "dump-config"
|
|
<> O.help "Dump loaded configuration and exit"
|
|
|
|
dumpSchemaFlag =
|
|
O.flag (Run CmdRun) (Run CmdDumpSchema) $
|
|
O.long "dump-schema"
|
|
<> O.help "Dump loaded schema as JSON and exit (for debugging, output structure is unstable)"
|
|
|
|
readyFlag =
|
|
O.flag (Run CmdRun) (Client CmdReady) $
|
|
O.long "ready"
|
|
<> O.help "Checks the health of PostgREST by doing a request on the admin server /ready endpoint"
|