Yesod 新的数据类型定义和映射

Yesod new data type definition and mapping

在Yesod中,我想定义一个新的数据类型:

data Status = Read | Reviewed | Learned

我正在使用脚手架示例。那么在最佳实践中,我应该在哪里声明上述数据呢?在 Foundation.hsApplication.hs 或其他地方?

然后我将创建一个数据库 table,其中一个列作为此 Status 类型。 这是如何映射到我的 Postgresql 后端的?哪种 sql 数据类型应对应于此 Status 类型?

So in the best practice where should I declare the above data? In the Foundation.hs or Application.hs or elsewhere?

这两个地方我都没有定义。我通常为它创建一个新模块并在那里定义类型。但最终归结为个人品味。我不建议在 Foundation.hs 中这样做,因为这是一个模块,您的主应用程序类型和它是各种 Yesod 相关类型类的实例所在的模块。类似地,我不会将它添加到 Application.hs 中,因为这是一个模块,您的应用程序设置和 Wai Application 相关功能所在的模块。但这只是我的口味。 :-)

I will then create a database table with one of the column as this Status type. How is this mapped to my Postgresql backend? Which sql data type should correspond to this Status type?

您可以使用Status代数类型来定义。一个例子:

#!/usr/bin/env stack
{- stack
     --resolver lts-6.19
     --install-ghc
     runghc
     --package persistent
     --package aeson
     --package persistent-postgresql
     --package text
     --package persistent-template
     --package time
     --package mtl
-}

{-# LANGUAGE EmptyDataDecls             #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE FlexibleInstances#-}
{-# LANGUAGE TypeFamilies               #-}

import           Database.Persist
import           Database.Persist.Postgresql
import           Database.Persist.TH
import           Control.Monad.IO.Class  (liftIO)
import           Control.Monad.Logger    (runStderrLoggingT)
import Data.Time
import Data.Text
import Data.Aeson
import ModelSum

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
    name Text
    age Int
    status Status
    deriving Show
|]

connStr = "host=localhost dbname=test user=postgres password=postgres port=5432"

main :: IO ()
main = mockMigration migrateAll

ModelSum 文件:

{-# LANGUAGE TemplateHaskell #-}

module ModelSum where

import Database.Persist.TH

data Status
  = Read
  | Reviewed
  | Learned
  deriving (Show, Eq, Read)

derivePersistField "Status"

执行后,你会得到:

$ ./script.hs
CREATe TABLE "user"("id" SERIAL8  PRIMARY KEY UNIQUE,"name" VARCHAR NOT NULL,"age" INT8 NOT NULL,"status" VARCHAR NOT NULL)

您可以看到 status 列创建为 varchar。在内部它使用 ShowRead 个实例。