获取我的模型的持久性字段定义

时间:2017-10-07 12:48:30

标签: haskell yesod haskell-persistent

给出这样的持久模型定义:

mkPersist sqlSettings [persistLowerCase|
Person
    name String
    age Int
    deriving Show
|]

我正在寻找一种方法来获取此模型的字段定义。 FieldDef看起来像一个有前途的数据类型,但是持久性不会生成getPersonFields :: [FieldDef]函数,那么如何才能完成?

如果这是XY问题 - 这是背景: 我希望在json解析错误的情况下返回某种元数据。如果我尝试发布一个新人,但json是错误的,我想回答类似的事情:

{
    "result": "error",
    "code": 8,
    "message": "Could not parse payload as person",
    "fields": [
        {
            "name": "name",
            "type": "string"
        },
        {
            "name": "age",
            "type": "int"
        }
    ]
}

1 个答案:

答案 0 :(得分:2)

示例演示如何完成:

#!/usr/bin/env stack
{- stack
     --resolver lts-9.0
     --install-ghc
     runghc
     --package persistent
     --package persistent-sqlite
     --package persistent-template
-}

{-# LANGUAGE EmptyDataDecls             #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeFamilies               #-}
import           Control.Monad.IO.Class  (liftIO)
import           Database.Persist
import           Database.Persist.Sqlite
import           Database.Persist.TH

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
BlogPost
    title String
    authorId PersonId
    deriving Show
|]

main :: IO ()
main = let efields = entityFields $ entityDef (undefined :: Maybe Person)
       in print efields

演示:

$ stack efield.hs
[FieldDef {fieldHaskell = HaskellName {unHaskellName = "name"}, fieldDB = DBName {unDBName = "name"}, fieldType = FTTypeCon Nothing "String", fieldSqlType = SqlString, fieldAttrs = [], fieldStrict = True, fieldReference = NoReference},FieldDef {fieldHaskell = HaskellName {unHaskellName = "age"}, fieldDB = DBName {unDBName = "age"}, fieldType = FTTypeCon Nothing "Int", fieldSqlType = SqlInt64, fieldAttrs = ["Maybe"], fieldStrict = True, fieldReference = NoReference}]