其他
快速用 Haskell 构建超级简单的 Web 技术栈!
会话,用户可以刷新页面,或者关闭页面后再打开,但在打开之后应该看到相同的内容。 持久化和数据库访问,我们需要将每个用户的定时器和笔记保存下来。另一个需求是定时器需要维持剩余的时间(用户设置了一个30分钟的定时器,然后不小心关闭了页面,应该如何?) 运行时的配置,因为我们不能把数据库连接的信息硬编码到代码里。 日志。日志对于Web应用的作用不言而喻。
import Web.Spock as Spock
import Web.Spock.Config as Spock
import Data.Aeson as A
main :: IO ()
main = do
spockCfg <- defaultSpockCfg () PCNoDatabase ()
runSpock 3000 $ spock spockCfg $ do
get root $ do
Spock.html "<div>Hello world!</div>"
get "users" $ do
Spock.json (A.object [ "users" .= users ])
get ("users" <//> var <//> "friends") $ \userID -> do
Spock.json (A.object [ "userID" .= (userID :: Int), "friends" .= A.Null ])
where users :: [String]
users = ["bob", "alice"]
数据库访问:postgresql-simple
postgresql-simple基本上只允许您对数据库运行原始SQL查询,而没有多余的装饰,例如防止注入攻击。它可以实现您的期望,仅此而已。
{-# LANGUAGE OverloadedStrings #-}
import Database.PostgreSQL.Simple
userLoginsQuery :: Query
userLoginsQuery =
"SELECT l.user_id, COUNT(1) FROM logins l GROUP BY l.user_id;"
getUserLogins :: Connection -> IO [(Int, Int)]
getUserLogins conn = query_ conn userLoginsQuery
import Database.PostgreSQL.Simple
userLoginsQuery :: Query
userLoginsQuery =
"SELECT l.user_id, COUNT(1) FROM logins l GROUP BY l.user_id;"
getUserLogins :: Connection -> IO [(Int, Int)]
getUserLogins conn = query_ conn userLoginsQuery
app_name = "The Whispering Fog"
db {
pool {
stripes = 4
resource_ttl = 300
}
username = "pallas"
password = "thefalloflatinium"
dbname = "italy"
}
import Data.Configurator as Cfg
import Database.PostgreSQL.Simple
data MyAppConfig = MyAppConfig
{ appName :: String
, appDBConnection :: Connection
}
getAppConfig :: IO MyAppConfig
getAppConfig = do
cfgFile <- Cfg.load ["app-configuration.cfg"]
name <- Cfg.require cfgFile "app_name"
conn <- do
username <- Cfg.require cfgFile "db.username"
password <- Cfg.require cfgFile "db.password"
dbname <- Cfg.require cfgFile "db.dbname"
connect $ defaultConnectInfo
{ connectUser = username
, connectPassword = password
, connectDatabase = dbname
}
pure $ MyAppConfig
{ appName = name
, appDBConnection = conn
}
logMsg :: Log.LoggerSet -> String -> IO ()
logMsg logSet msg =
Log.pushLogStrLn logSet (Log.toLogStr msg)
doSomething :: IO ()
doSomething = do
logSet <- Log.newStderrLoggerSet Log.defaultBufSize
logMsg logSet "message 1"
logMsg logSet "message 2"
import Data.ByteString.Lazy
import Text.Blaze.Html5 as HTML
import Text.Blaze.Html5.Attributes as HTML hiding ( title )
import Text.Blaze.Html.Renderer.Utf8 as HTML
dashboardHTML :: HTML.Html
dashboardHTML = HTML.html $
HTML.docTypeHtml $ do
HTML.head $ do
HTML.title "Timers and Notes"
HTML.meta ! HTML.charset "utf-8"
HTML.script ! HTML.src "/js/bundle.js" $ ""
HTML.body $ do
HTML.div ! HTML.id "content" $ ""
dashboardBytes :: ByteString
dashboardBytes = HTML.renderHtml dashboardHTML
【End】
热 文 推 荐
☞量子算命,在线掷筊:一个IBM量子云计算机的应用实践,代码都有了