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 | ||