【发布时间】:2021-06-23 15:40:52
【问题描述】:
您好,感谢您抽出宝贵时间。 我正在尝试创建一个网站,其中包含一个增加计数器的按钮。我希望当前计数器保持不变,如果有人访问我的页面,则应显示当前计数器。 每次单击按钮以增加计数器时,都应该发送一个请求。该请求不包含有关计数器值的任何信息。服务器 - 在我的例子中是一个 warp Web 服务器 - 应该更新数据库中的计数器值,读取更新后的值,然后如果成功则将其发送到前端,如果不成功则发送错误消息。
到目前为止,只有更新有效,因为我没有设法弄清楚如何将数据从数据库获取到前端。 这是我的存储库模块中应该进行更新的代码:
{-# LANGUAGE EmptyDataDecls, FlexibleContexts, GADTs, GeneralizedNewtypeDeriving#-}
{-# LANGUAGE MultiParamTypeClasses, OverloadedStrings, QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell, TypeFamilies, DataKinds, FlexibleInstances#-}
{-# LANGUAGE DerivingStrategies, StandaloneDeriving, UndecidableInstances #-}
module Repository (increaseCounter) where
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Logger (runStderrLoggingT)
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import Control.Monad.Reader
import Data.Text
import Data.Maybe
-- setting up the Counter entity with a unique key so I can use the getBy function
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Counter
counterName String
counterCount Int Maybe
UniqueCounterName counterName
deriving Show
|]
increaseCounter :: IO ()
increaseCounter =
runStderrLoggingT $ withSqliteConn "//absolute/path/database.db" $ runSqlConn $ do
runMigration migrateAll -- only for developing
updateWhere [CounterCounterName ==. "unique name"] [CounterCounterCount +=. Just 1]
counterEntity <- getBy $ UniqueCounterName name
liftIO $ print counterEntity
这会编译并实际保存计数器并在每次调用时更新值。但是从类型中可以看出,更新后它只会将计数器值打印到控制台。 我似乎无法理解如何使用从 getBy 函数返回的数据。 文档说:
getBy :: (PersistUniqueRead backend, MonadIO m, PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
'backend m' 基本上是一个嵌套的 monad 吗?
假设我只想发送计数器的值,如果它是Just Int,如果它是Nothing,我想返回-1。
我假设我无法修改 increaseCounter 函数,使其类型为Maybe Int。但是如何将函数传递到 monad/访问内部的值以向前端发送响应?
如果这个问题是肤浅的和/或我目前缺乏太多知识,您能否推荐好的信息来源?像一个好的教程或 youtube 频道之类的东西?
谢谢!
【问题讨论】:
-
如果您使用 Warp,那么您提供给 Warp 的 run 的 Application 是处理请求并返回响应的内容 - 但您不共享任何此代码。我对您拥有什么以及正在使用什么感到有些困惑。
标签: haskell persistent