我已经使用 Haskell 一年左右了,它非常棒。我最近开始使用Servant;我想使用像 Selda 这样的 SQL 库,这样一切都是类型安全的。(与 Elm 结合使用真是令人难以置信!:))
这里有一个例子: https: //github.com/dmjio/servant-selda,将 Selda 与 Servant 一起使用,但仅适用于 postgres。在最初的开发过程中,我发现使用 SQLite 非常有用。
我觉得这应该是可能的,但我似乎找不到任何例子。我尝试查看类型签名,以了解如何将 SQLite 作为池传递;但这有点超出我的哈斯克尔技能!
有没有人有使用 Selda 的经验,或者在 Servant 中使用另一个类型安全的 sql 库取得过成功?我愿意使用 Selda 以外的其他库;我想使用 UUID 作为主键,当我尝试这样做时,持久性不太高兴。
谢谢
小智 0
解决方案是用作SeldaT您的自定义servant monad(基于https://docs.servant.dev/en/stable/cookbook/using-custom-monad/UsingCustomMonad.html)
最小的例子:
{-# LANGUAGE TypeApplications #-}
module Main where
import Control.Exception (bracket)
import Data.Aeson (ToJSON)
import Database.Selda (SeldaT)
import Database.Selda.Backend (SeldaConnection, runSeldaT)
import Database.Selda.SQLite (SQLite, seldaClose, sqliteOpen)
import Network.Wai.Handler.Warp (run)
import Servant (Application, EmptyAPI (EmptyAPI), Get, Handler, HasServer (ServerT), JSON, Proxy (Proxy), emptyServer, hoistServer, serve)
type YourAPI = EmptyAPI -- replace with your API type
yourApi :: Proxy YourAPI
yourApi = Proxy @YourAPI
type AppM = SeldaT SQLite Handler
server :: ServerT YourAPI AppM
server = emptyServer -- replace with your API implementation
nt :: SeldaConnection SQLite -> AppM a -> Handler a
nt = flip runSeldaT
app :: SeldaConnection SQLite -> Application
app conn = serve yourApi $ hoistServer yourApi (nt conn) server
main :: IO ()
main =
bracket
(sqliteOpen "sqlite.db")
seldaClose
(run 3000 . app)
Run Code Online (Sandbox Code Playgroud)
请注意,并发支持没有详细记录(并且可能受支持)。发现这个问答可能会提供有关 Haskell 中的 sqlite 并发性的更多详细信息What are the Rules about concurrently accessing a permanent database。与 类似persistent-sqlite,selda-sqlite依赖于direct-sqlite底层库。