@@ -12,11 +12,12 @@ import qualified Data.ByteString.Char8 as BS
1212import qualified Data.ByteString.Lazy as LBS
1313import qualified Hasql.Transaction.Sessions as SQL
1414import qualified Options.Applicative as O
15+ import System.IO.Error (isDoesNotExistError )
1516
1617import PostgREST.AppState (AppState )
1718import PostgREST.Config (AppConfig (.. ))
1819import PostgREST.Observation (Observation (.. ))
19- import PostgREST.SchemaCache (querySchemaCache )
20+ import PostgREST.SchemaCache (SchemaCache , querySchemaCache )
2021import PostgREST.Version (prettyVersion )
2122
2223import qualified PostgREST.App as App
@@ -28,25 +29,32 @@ import Protolude
2829
2930
3031main :: CLI -> IO ()
31- main CLI {cliCommand, cliPath} = do
32+ main CLI {cliCommand, cliPath, cliSchemaCachePath } = do
3233 conf <-
3334 either panic identity <$> Config. readAppConfig mempty cliPath Nothing mempty mempty
3435 case cliCommand of
3536 Client adminCmd -> runClientCommand conf adminCmd
36- Run runCmd -> runAppCommand conf runCmd
37+ Run runCmd -> runAppCommand conf cliSchemaCachePath runCmd
3738
3839-- | Run command using http-client to communicate with an already running postgrest
3940runClientCommand :: AppConfig -> ClientCommand -> IO ()
4041runClientCommand conf CmdReady = Client. ready conf
4142
4243-- | Run postgrest with command
43- runAppCommand :: AppConfig -> RunCommand -> IO ()
44- runAppCommand conf@ AppConfig {.. } runCmd = do
44+ runAppCommand :: AppConfig -> Maybe FilePath -> RunCommand -> IO ()
45+ runAppCommand conf@ AppConfig {.. } schemaCachePath runCmd = do
46+ initAppState <- case runCmd of
47+ CmdRun -> do
48+ initialSchemaCache <- join <$> traverse readSchemaCacheDump schemaCachePath
49+ pure $ maybe (AppState. init conf) (AppState. initWithSchemaCache conf) initialSchemaCache
50+ _ ->
51+ pure $ AppState. init conf
52+
4553 -- Per https://github.com/PostgREST/postgrest/issues/268, we want to
4654 -- explicitly close the connections to PostgreSQL on shutdown.
4755 -- 'AppState.destroy' takes care of that.
4856 bracket
49- ( AppState. init conf)
57+ initAppState
5058 AppState. destroy
5159 (\ appState -> case runCmd of
5260 CmdDumpConfig -> do
@@ -55,7 +63,8 @@ runAppCommand conf@AppConfig{..} runCmd = do
5563 CmdDumpSchema -> do
5664 when configDbConfig $ AppState. readInDbConfig True appState
5765 putStrLn =<< dumpSchema appState
58- CmdRun -> App. run appState)
66+ CmdRun ->
67+ App. run appState)
5968
6069-- | Dump SchemaCache schema to JSON
6170dumpSchema :: AppState -> IO LBS. ByteString
@@ -70,10 +79,23 @@ dumpSchema appState = do
7079 exitFailure
7180 Right (sCache, _) -> return $ JSON. encode sCache
7281
82+ readSchemaCacheDump :: FilePath -> IO (Maybe SchemaCache )
83+ readSchemaCacheDump path =
84+ fmap decodeSchemaCache <$> catch (Just <$> LBS. readFile path) handleReadError
85+ where
86+ decodeSchemaCache =
87+ fromRight (panic $ " Error loading schema cache dump from " <> toS path) . JSON. eitherDecode
88+
89+ handleReadError :: IOException -> IO (Maybe LBS. ByteString )
90+ handleReadError e
91+ | isDoesNotExistError e = pure Nothing
92+ | otherwise = throwIO e
93+
7394-- | Command line interface options
7495data CLI = CLI
75- { cliCommand :: Command
76- , cliPath :: Maybe FilePath
96+ { cliCommand :: Command
97+ , cliPath :: Maybe FilePath
98+ , cliSchemaCachePath :: Maybe FilePath
7799 }
78100
79101data Command
@@ -120,12 +142,19 @@ readCLIShowHelp =
120142 CLI
121143 <$> (dumpConfigFlag <|> dumpSchemaFlag <|> readyFlag)
122144 <*> O. optional configFileOption
145+ <*> O. optional loadSchemaCacheOption
123146
124147 configFileOption =
125148 O. strArgument $
126149 O. metavar " FILENAME"
127150 <> O. help " Path to configuration file"
128151
152+ loadSchemaCacheOption =
153+ O. strOption $
154+ O. long " load-schema-cache"
155+ <> O. metavar " FILENAME"
156+ <> O. help " Load schema cache from JSON dump at startup if the file exists"
157+
129158 dumpConfigFlag =
130159 O. flag (Run CmdRun ) (Run CmdDumpConfig ) $
131160 O. long " dump-config"
0 commit comments