summaryrefslogtreecommitdiff
path: root/Application.hs
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2017-03-14 01:06:28 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2017-03-14 01:06:28 +0100
commitd84b462a711ce95593ff05a7581e722562c3835a (patch)
tree41e5af455fea925b2680b29718b24ba2876e803a /Application.hs
downloadbar-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.hs180
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 #-}
2module 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
16import Control.Monad.Logger (liftLoc, runLoggingT)
17import Database.Persist.Postgresql (createPostgresqlPool, pgConnStr,
18 pgPoolSize, runSqlPool)
19import Import
20import Language.Haskell.TH.Syntax (qLocation)
21import Network.Wai (Middleware)
22import Network.Wai.Handler.Warp (Settings, defaultSettings,
23 defaultShouldDisplayException,
24 runSettings, setHost,
25 setOnException, setPort, getPort)
26import Network.Wai.Middleware.RequestLogger (Destination (Logger),
27 IPAddrSource (..),
28 OutputFormat (..), destination,
29 mkRequestLogger, outputFormat)
30import 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!
35import Handler.InventoryListing
36import Handler.UpdateItem
37import Handler.OpenItem
38import Handler.DeleteItem
39import 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.
44mkYesodDispatch "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.
50makeFoundation :: AppSettings -> IO App
51makeFoundation 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.
82makeApplication :: App -> IO Application
83makeApplication foundation = do
84 logWare <- makeLogWare foundation
85 -- Create the WAI application and apply middlewares
86 appPlain <- toWaiAppPlain foundation
87 return $ logWare $ defaultMiddlewaresNoLogging appPlain
88
89makeLogWare :: App -> IO Middleware
90makeLogWare 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.
104warpSettings :: App -> Settings
105warpSettings 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.
119getApplicationDev :: IO (Settings, Application)
120getApplicationDev = do
121 settings <- getAppSettings
122 foundation <- makeFoundation settings
123 wsettings <- getDevSettings $ warpSettings foundation
124 app <- makeApplication foundation
125 return (wsettings, app)
126
127getAppSettings :: IO AppSettings
128getAppSettings = loadYamlSettings [configSettingsYml] [] useEnv
129
130-- | main function for use by yesod devel
131develMain :: IO ()
132develMain = develMainHelper getApplicationDev
133
134-- | The @main@ function for an executable running this site.
135appMain :: IO ()
136appMain = 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--------------------------------------------------------------
158getApplicationRepl :: IO (Int, App, Application)
159getApplicationRepl = do
160 settings <- getAppSettings
161 foundation <- makeFoundation settings
162 wsettings <- getDevSettings $ warpSettings foundation
163 app1 <- makeApplication foundation
164 return (getPort wsettings, foundation, app1)
165
166shutdownApp :: App -> IO ()
167shutdownApp _ = return ()
168
169
170---------------------------------------------
171-- Functions for use in development with GHCi
172---------------------------------------------
173
174-- | Run a handler
175handler :: Handler a -> IO a
176handler h = getAppSettings >>= makeFoundation >>= flip unsafeHandler h
177
178-- | Run DB queries
179db :: ReaderT SqlBackend (HandlerT App IO) a -> IO a
180db = handler . runDB