diff options
| author | Gregor Kleen <gkleen@yggdrasil.li> | 2017-03-14 01:06:28 +0100 |
|---|---|---|
| committer | Gregor Kleen <gkleen@yggdrasil.li> | 2017-03-14 01:06:28 +0100 |
| commit | d84b462a711ce95593ff05a7581e722562c3835a (patch) | |
| tree | 41e5af455fea925b2680b29718b24ba2876e803a /Application.hs | |
| download | bar-d84b462a711ce95593ff05a7581e722562c3835a.tar bar-d84b462a711ce95593ff05a7581e722562c3835a.tar.gz bar-d84b462a711ce95593ff05a7581e722562c3835a.tar.bz2 bar-d84b462a711ce95593ff05a7581e722562c3835a.tar.xz bar-d84b462a711ce95593ff05a7581e722562c3835a.zip | |
Implement old bar.hs
Diffstat (limited to 'Application.hs')
| -rw-r--r-- | Application.hs | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/Application.hs b/Application.hs new file mode 100644 index 0000000..048a316 --- /dev/null +++ b/Application.hs | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | {-# OPTIONS_GHC -fno-warn-orphans #-} | ||
| 2 | module Application | ||
| 3 | ( getApplicationDev | ||
| 4 | , appMain | ||
| 5 | , develMain | ||
| 6 | , makeFoundation | ||
| 7 | , makeLogWare | ||
| 8 | -- * for DevelMain | ||
| 9 | , getApplicationRepl | ||
| 10 | , shutdownApp | ||
| 11 | -- * for GHCI | ||
| 12 | , handler | ||
| 13 | , db | ||
| 14 | ) where | ||
| 15 | |||
| 16 | import Control.Monad.Logger (liftLoc, runLoggingT) | ||
| 17 | import Database.Persist.Postgresql (createPostgresqlPool, pgConnStr, | ||
| 18 | pgPoolSize, runSqlPool) | ||
| 19 | import Import | ||
| 20 | import Language.Haskell.TH.Syntax (qLocation) | ||
| 21 | import Network.Wai (Middleware) | ||
| 22 | import Network.Wai.Handler.Warp (Settings, defaultSettings, | ||
| 23 | defaultShouldDisplayException, | ||
| 24 | runSettings, setHost, | ||
| 25 | setOnException, setPort, getPort) | ||
| 26 | import Network.Wai.Middleware.RequestLogger (Destination (Logger), | ||
| 27 | IPAddrSource (..), | ||
| 28 | OutputFormat (..), destination, | ||
| 29 | mkRequestLogger, outputFormat) | ||
| 30 | import System.Log.FastLogger (defaultBufSize, newStdoutLoggerSet, | ||
| 31 | toLogStr) | ||
| 32 | |||
| 33 | -- Import all relevant handler modules here. | ||
| 34 | -- Don't forget to add new modules to your cabal file! | ||
| 35 | import Handler.InventoryListing | ||
| 36 | import Handler.UpdateItem | ||
| 37 | import Handler.OpenItem | ||
| 38 | import Handler.DeleteItem | ||
| 39 | import Handler.Item | ||
| 40 | |||
| 41 | -- This line actually creates our YesodDispatch instance. It is the second half | ||
| 42 | -- of the call to mkYesodData which occurs in Foundation.hs. Please see the | ||
| 43 | -- comments there for more details. | ||
| 44 | mkYesodDispatch "App" resourcesApp | ||
| 45 | |||
| 46 | -- | This function allocates resources (such as a database connection pool), | ||
| 47 | -- performs initialization and returns a foundation datatype value. This is also | ||
| 48 | -- the place to put your migrate statements to have automatic database | ||
| 49 | -- migrations handled by Yesod. | ||
| 50 | makeFoundation :: AppSettings -> IO App | ||
| 51 | makeFoundation appSettings = do | ||
| 52 | -- Some basic initializations: HTTP connection manager, logger, and static | ||
| 53 | -- subsite. | ||
| 54 | appHttpManager <- newManager | ||
| 55 | appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger | ||
| 56 | |||
| 57 | -- We need a log function to create a connection pool. We need a connection | ||
| 58 | -- pool to create our foundation. And we need our foundation to get a | ||
| 59 | -- logging function. To get out of this loop, we initially create a | ||
| 60 | -- temporary foundation without a real connection pool, get a log function | ||
| 61 | -- from there, and then create the real foundation. | ||
| 62 | let mkFoundation appConnPool = App { appStatic = eStatic, ..} | ||
| 63 | -- The App {..} syntax is an example of record wild cards. For more | ||
| 64 | -- information, see: | ||
| 65 | -- https://ocharles.org.uk/blog/posts/2014-12-04-record-wildcards.html | ||
| 66 | tempFoundation = mkFoundation $ error "connPool forced in tempFoundation" | ||
| 67 | logFunc = messageLoggerSource tempFoundation appLogger | ||
| 68 | |||
| 69 | -- Create the database connection pool | ||
| 70 | pool <- flip runLoggingT logFunc $ createPostgresqlPool | ||
| 71 | (pgConnStr $ appDatabaseConf appSettings) | ||
| 72 | (pgPoolSize $ appDatabaseConf appSettings) | ||
| 73 | |||
| 74 | -- Perform database migration using our application's logging settings. | ||
| 75 | runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc | ||
| 76 | |||
| 77 | -- Return the foundation | ||
| 78 | return $ mkFoundation pool | ||
| 79 | |||
| 80 | -- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and | ||
| 81 | -- applying some additional middlewares. | ||
| 82 | makeApplication :: App -> IO Application | ||
| 83 | makeApplication foundation = do | ||
| 84 | logWare <- makeLogWare foundation | ||
| 85 | -- Create the WAI application and apply middlewares | ||
| 86 | appPlain <- toWaiAppPlain foundation | ||
| 87 | return $ logWare $ defaultMiddlewaresNoLogging appPlain | ||
| 88 | |||
| 89 | makeLogWare :: App -> IO Middleware | ||
| 90 | makeLogWare foundation = | ||
| 91 | mkRequestLogger def | ||
| 92 | { outputFormat = | ||
| 93 | if appDetailedRequestLogging $ appSettings foundation | ||
| 94 | then Detailed True | ||
| 95 | else Apache | ||
| 96 | (if appIpFromHeader $ appSettings foundation | ||
| 97 | then FromFallback | ||
| 98 | else FromSocket) | ||
| 99 | , destination = Logger $ loggerSet $ appLogger foundation | ||
| 100 | } | ||
| 101 | |||
| 102 | |||
| 103 | -- | Warp settings for the given foundation value. | ||
| 104 | warpSettings :: App -> Settings | ||
| 105 | warpSettings foundation = | ||
| 106 | setPort (appPort $ appSettings foundation) | ||
| 107 | $ setHost (appHost $ appSettings foundation) | ||
| 108 | $ setOnException (\_req e -> | ||
| 109 | when (defaultShouldDisplayException e) $ messageLoggerSource | ||
| 110 | foundation | ||
| 111 | (appLogger foundation) | ||
| 112 | $(qLocation >>= liftLoc) | ||
| 113 | "yesod" | ||
| 114 | LevelError | ||
| 115 | (toLogStr $ "Exception from Warp: " ++ show e)) | ||
| 116 | defaultSettings | ||
| 117 | |||
| 118 | -- | For yesod devel, return the Warp settings and WAI Application. | ||
| 119 | getApplicationDev :: IO (Settings, Application) | ||
| 120 | getApplicationDev = do | ||
| 121 | settings <- getAppSettings | ||
| 122 | foundation <- makeFoundation settings | ||
| 123 | wsettings <- getDevSettings $ warpSettings foundation | ||
| 124 | app <- makeApplication foundation | ||
| 125 | return (wsettings, app) | ||
| 126 | |||
| 127 | getAppSettings :: IO AppSettings | ||
| 128 | getAppSettings = loadYamlSettings [configSettingsYml] [] useEnv | ||
| 129 | |||
| 130 | -- | main function for use by yesod devel | ||
| 131 | develMain :: IO () | ||
| 132 | develMain = develMainHelper getApplicationDev | ||
| 133 | |||
| 134 | -- | The @main@ function for an executable running this site. | ||
| 135 | appMain :: IO () | ||
| 136 | appMain = do | ||
| 137 | -- Get the settings from all relevant sources | ||
| 138 | settings <- loadYamlSettingsArgs | ||
| 139 | -- fall back to compile-time values, set to [] to require values at runtime | ||
| 140 | [configSettingsYmlValue] | ||
| 141 | |||
| 142 | -- allow environment variables to override | ||
| 143 | useEnv | ||
| 144 | |||
| 145 | -- Generate the foundation from the settings | ||
| 146 | foundation <- makeFoundation settings | ||
| 147 | |||
| 148 | -- Generate a WAI Application from the foundation | ||
| 149 | app <- makeApplication foundation | ||
| 150 | |||
| 151 | -- Run the application with Warp | ||
| 152 | runSettings (warpSettings foundation) app | ||
| 153 | |||
| 154 | |||
| 155 | -------------------------------------------------------------- | ||
| 156 | -- Functions for DevelMain.hs (a way to run the app from GHCi) | ||
| 157 | -------------------------------------------------------------- | ||
| 158 | getApplicationRepl :: IO (Int, App, Application) | ||
| 159 | getApplicationRepl = do | ||
| 160 | settings <- getAppSettings | ||
| 161 | foundation <- makeFoundation settings | ||
| 162 | wsettings <- getDevSettings $ warpSettings foundation | ||
| 163 | app1 <- makeApplication foundation | ||
| 164 | return (getPort wsettings, foundation, app1) | ||
| 165 | |||
| 166 | shutdownApp :: App -> IO () | ||
| 167 | shutdownApp _ = return () | ||
| 168 | |||
| 169 | |||
| 170 | --------------------------------------------- | ||
| 171 | -- Functions for use in development with GHCi | ||
| 172 | --------------------------------------------- | ||
| 173 | |||
| 174 | -- | Run a handler | ||
| 175 | handler :: Handler a -> IO a | ||
| 176 | handler h = getAppSettings >>= makeFoundation >>= flip unsafeHandler h | ||
| 177 | |||
| 178 | -- | Run DB queries | ||
| 179 | db :: ReaderT SqlBackend (HandlerT App IO) a -> IO a | ||
| 180 | db = handler . runDB | ||
